Skip to content

Dev - #31

Open
Shaan-Shoukath wants to merge 979 commits into
mainfrom
dev
Open

Dev#31
Shaan-Shoukath wants to merge 979 commits into
mainfrom
dev

Conversation

@Shaan-Shoukath

Copy link
Copy Markdown
Collaborator

Summary

Related issue

Type of change

  • Bug fix
  • New feature
  • Documentation
  • Refactor or maintenance
  • Breaking change

How tested

Checklist

  • Tests pass locally for the affected areas.
  • Documentation and OpenAPI artifacts are updated if endpoints changed.
  • The change follows the project's contribution terms and licensing requirements.
  • I understand that contributions are licensed under AGPL-3.0-or-later.

Contributions to Space Works are made under the GNU Affero General Public License,
version 3 or any later version (AGPL-3.0-or-later).

Shaan-Shoukath and others added 30 commits October 30, 2026 10:37
…space archives, preview, confirm, apply

Per-space archives (format tenant_slice_v1) are encrypted to the platform key and
this server's restore key (#111 Q3); nightly for every live space, a few per tick
off the automatic-backups switch, rotating 7 daily + 4 weekly (Q4). A
MakerspaceRestoreOperation moves requested -> staging -> preview_ready -> applying
-> completed|failed|aborted: the preview is read-only and blocks on dangling
cross-space rows (#113); apply takes a mandatory safety backup (Q16), closes the
space's source gate, re-checks the live fingerprint and restores in one
transaction, then restores object bytes, audits every step in the space and
notifies its Space Managers by email plus a console notice (Q15). Superadmin API
with OpenAPI; decrypted material never outlives a step (#50b).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e, back up now, preview, confirm, progress, schedule

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…icker, space timeline, back up now, preview, confirm, live progress, schedule

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y sweep and platform-route masking; retire the superadmin access field

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nt purge context, blocks on staff added after the restore point, and types integrity failures

A row with its own makerspace column naming another space now counts as that
space's (a collaborator row), so it blocks instead of cascading.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…#128 C-17) once merged_into exists

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rt links, discoverability, offline pages, online delivery, embed card, share image (L1)

At merge: events/0059_l1_public_surface re-chained as 0061 after pairwise judging; the shared
website-embed route no longer serves the events kind (owner decision #143); seed_showcase runs both
the pairwise hackathon and L1's events; re-pin CATALOG_SCHEMA_SHA256; regenerate OpenAPI and api.ts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sify their ids as deployment-local in tenant dumps

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e snapshot time, not its completion

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…is tenant-scoped, not a deployment-global uniqueness risk

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…analytics and closures (R2 L2)

Nine per-space switches (events.broadcast_templates, approval_digest, anonymous_feedback,
submission_integrity, mentor_chat_alerts, organization_sender; notifications.escalation,
web_push, inbox_snooze). events/0060 chains after L1's 0059 and keeps today's anonymous
feedback on for existing spaces. New coordination rows are classified as omitted from
exports and dropped from tenant dumps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nd designs, 5-second undo, delivery tallies, draft autosave (G6, X41)

Send now schedules at confirmation + 5 s and cancel inside the hold is the undo; after it
the accepted-mail rule holds. Tallies count recipients by best outcome, never names.
Drafts PATCH with expected_version so a second tab cannot overwrite silently. Templates
and the accent-band, photo-header and letter designs ride events.broadcast_templates.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…charts, waitlist conversion, series turnout, short-link visits; org insights with k>=10 suppression (G8)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…o window, ticket re-send on a verified new email, 12 h fresh-signup reminder skip, join link in confirmations (G7, L1 seam)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… mentors are on shift; outbound text only (G9)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rage cleanup receipts and daily reconciliation that adopts imported assets once (G10, G11)

The flag is information for judges and organisers only: it never disqualifies, hides or
scores; GitHub failures fail safe (no flag, retried, then unavailable).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…o-certificate mode (G36)

Anonymous rows keep no registration, account or IP; a form marked anonymous while the
switch is off accepts nothing rather than collecting identified answers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, #115a); staff-grant invitations also offered on the invitee's own chat channels (X37)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ations (VAPID, cryptography only), escalation re-ping, dead chat rooms switched off with a staff notice (X38)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…istory; unanswered requests wiped after 90 days (X31)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…loud catalogue, gate policy) and the VAPID / resubmit settings

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…efore deleting, and name the row a restore cannot insert

Ownership predicates join through parents, so reading a child's live set after its
parent was deleted found nothing and left it in place.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…red or platform account, nor what depends on it

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… staff added after the restore point

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r Desk chat-room picker (G8, G9)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d mode on the public form (G36)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t flow and review history (X31)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tification opt-in with a narrow-scope worker; organisation event-email sender settings (X38, X2)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…S, SOURCE-MAP and the events guides; setup-area and storage-tail lines made truthful (G12)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tes; name the browser-alert and snooze schemas

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Shaan-Shoukath and others added 30 commits November 3, 2026 11:28
…e account per person)

The console, member area, kiosk and scanner share the person session; only the superadmin
keeps a platform session (?context=platform). The member and staff:<slug> contexts are gone,
refresh sends person or platform, and a shared mfa_enrollment_required signal lets the
console route to enrolment without signing the person out (#128 C-1, shared with S-D).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…oles or a delegated grant

The staff login is gone: people sign in with MemberAuthPanel and the superadmin keeps its own
platform sign-in. The console opens for the spaces where the person holds a staff role or a
delegated grant and lets a person with roles in several spaces pick one. During the 3-day
staff MFA grace it shows a banner; afterwards (or on a mid-session mfa_enrollment_required)
it asks for two-step sign-in and links back after enrolment. Member screens are never blocked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… invite, change, revoke, reset authenticator)

ListLayout panel over admin-staff-roles: add staff by granting to a community member or
inviting by email, change roles and machine scopes, revoke and restore, reset the
authenticator when S-A's rule allows it. No password controls and no invitation links.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ur staff account merge flow

The invitation page asks for sign-in, then a fresh emailed code. The member account page
offers linking a second account over U-C's merge API (start, prove, review the privilege
diff, confirm), with the two-step set-up path when the survivor becomes staff; it is
suggested when the payload says merge_suggested. spaceRestoreApi gains merged_since and
merged_followed (U-D).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…U-B)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s them; the opt-in page authenticates claim tokens

The schedule seam had landed on update_schedule instead of complete_due, which would have let a
covering Technician change a machine's schedule. The opt-in view keeps default authentication so
a claim session is refused, as the claim-route matrix requires.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ngs › Public stats, events and community sections, small-number suppression, TV mode (L26, #170)

Merged at 0c0e359; the lane's OpenAPI regen 7c128727 is dropped and regenerated on staging.
makerspaces 0119_public_stats_settings collided with S-A's 0119 and is renumbered 0120 after it.
L26's delegable route joins the release-2 rows in delegated_route_catalog_r2.py.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…napshot and api.ts for L26 (public stats settings)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…c blocks and Turnstile (S-C)

LoginIPGuardMiddleware (before axes) acts on every view flagged login_ip_guard plus the
passkey sign-in routes and admin:login: an allow rule beats everything, a deny rule always
answers 429 ip_blocked, and a source that fails against LOGIN_IP_BLOCK_DISTINCT_ACCOUNTS
different accounts inside the window gets an IPAutoBlock for one fixed hour (/32, IPv6 /64;
private, proxy and short-chain sources never count; a remembered sw_device bypasses auto
blocks only until it fails ten times itself). Failures come from user_login_failed and,
once S-B adds it, security_signals.login_refused. Keys and audit meta are HMACs.

Cloudflare Turnstile is active only with both keys on a verified origin in
TURNSTILE_HOSTNAMES: on the CAPTCHA routes it is asked after TURNSTILE_AFTER_FAILURES, always
on a space domain set to always, and instead of the 429 for an auto-blocked source;
siteverify checks success, action and hostname and fails open by default. /api/v1/config
publishes turnstile_site_key, the SPA CSP allows challenges.cloudflare.com only when the
frontend container has the key, and an OpenAPI hook documents the new errors on every
guarded route. accounts.W002 warns about BEHIND_TRUSTED_PROXY with no proxy count.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ty host command, telemetry retention (S-C)

Superadmin-only screens behind the control step-up (both models in GLOBAL_ADMIN_MODELS and
CONTROL_AUTHORITY_MODELS): IP rules CRUD with canonical CIDRs, audited saves and deletes,
and a form that refuses a deny rule covering the editor's own address unless an allow rule
covers it; Automatic blocks with an audited Unblock action instead of delete. Login methods
shows the Turnstile, breached-password and IP-blocking status. manage.py login_security
--list | --allow <cidr> | --unblock <ip|all> is the host recovery path beside axes_reset_ip.
A daily bounded task deletes IPAutoBlock rows 7 days after they end and django-axes rows
after 30 days (cloud-jobs catalogue, beat, source-gate exemption). Auto-blocks never email.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ORS -- HIBP k-anonymity, fail-open (S-C)

BreachedPasswordValidator runs last in AUTH_PASSWORD_VALIDATORS, so every validate_password
caller refuses a breached password (sign-up, change, reset and restore confirmation,
invitation accept, admin-set passwords, the /control/ reset form) without touching their
code. Only the 5-character SHA-1 prefix leaves the server (range API, Add-Padding, httpx,
PASSWORD_BREACH_CHECK_TIMEOUT_SECONDS); padding rows never match; a timeout, network error or
non-200 answer accepts the password. Sign-up, change and both reset confirmations add
code: password_breached beside the field messages; each refusal is audited against the
account with no actor.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rol/ security page edits every kind (S-C)

security.staff_ip_allowlist and security.captcha_on_sign_in join the per-space registry
(#110c, #128 C-2). The allow-list is enforced at the staff surface check, never at the shared
sign-in door: a staff route needs the client inside each targeted space's non-empty list, a
space-less staff route inside every non-empty list across the person's staff spaces, else
403 staff_network_refused (new contract code). CAPTCHA "always" applies on the space's
verified custom domain through the Turnstile guard. The /control/ Security page now sets and
locks number, choice and list rows, and a lock on an on/off row forces its stricter value
(so passkeys_allowed locks off).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… (S-C)

INVARIANTS fills "IP blocking, allow/deny rules and CAPTCHA"; the environment reference
expands TRUSTED_PROXY_COUNT (what a wrong count does to throttles, axes and blocking) and the
Turnstile keys and hostnames; the privacy note discloses address handling and that Cloudflare
sees whoever is asked to solve a CAPTCHA; PROJECT-STATUS gains the host recovery command;
SOURCE-MAP and the history line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ne reachable space skip the picker

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ut of presentation; declare the session sweep fan-out and MachineSession.machine_type projection

machines/sessions_service.py passes its action through `_audit`, so it joins the reviewed
wrapper sites; the free-text guard forbids presenting `reason`, which stays in the raw row.
run_session_sweep opens a per-tenant fan-out boundary, and a session's machine type resolves
through the built-in/custom type map.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eep honours the frozen-tenant skip on its own line, and L15's three SQL functions join the managed catalog

The presentation and reference guards discover only literal audit.record actions, so the
session service drops its `_audit` wrapper (the wrapper-prefix route denies metadata). The
fan-out guard needs `if not go: continue` by itself. bookings_booking_price_guard and the
two L15 payment guards were unclassified application functions since the L15 merge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, retire the staff-account entries nothing emits

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…blocks and rules, the login_security host command, HIBP breached-password validator, Turnstile, per-space staff IP allow-list and CAPTCHA rows (S-C)

Merged at c48b8a1; the lane's OpenAPI regen d7ec9c5b is dropped and regenerated on staging.
Unions keep L23's and S-C's cloud jobs, beat entries and gate declarations; staging's
passkey source-gate exemptions (f809daa) stay.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… files (S-C)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ging (login guard errors, password_breached, turnstile_site_key); CATALOG unchanged

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ned-in staff invitations with a code, /control/ disable and re-enable, sessions collapsed to person|platform, one console sign-in, the Link your staff account flow (U-B)

Merged at 3af1a30; the lane's OpenAPI regen 4da00e59 is dropped and regenerated on staging.
The invitation accept view is signed-in (U-B) and keeps S-C's login_ip_guard; OwnerCancel
keeps L12's useOwner hook on the person token; the presentation barrel keeps S-C's and U-B's
fragments. U-B's staff_role change/restore/revoke and staff_invitation accept/sent audit IDs
join the unified-accounts audit references.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ging; L12's job and waitlist screens use the person session

U-B collapses browser sessions to person|platform, so the L12 member job shell, identity
hook and waitlist join read and refresh the "person" token instead of "member".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…echnicians and issue reports

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…collided with the handover IssueReject)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…onent rename

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n role), issue reporting, repairs on work orders, technician contacts and dispatch, per-parent maintenance, service state and repair payouts (L16)

The lane's OpenAPI regens e047d4c and e3038ff are dropped; staging regenerates them.
makerspaces 0119/0120_technician_* collided with S-A's 0119 and L26's 0120 and are renumbered
0121/0122 (maintenance/0005 now depends on 0122). Registry barrels, catalogs and features.ts
are unions; L16's authority entries join tenant_dump_authority_r2.py; staffAccounts.ts stays
deleted (U-B) and MemberActivity keeps L23's sessions link beside L16's Report a problem.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…es in audit_references_meta_r2.py (pure move; the barrel crossed 300 lines)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…napshot and api.ts for L16 (repairs, technicians, issue reports)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y policy

The repair timeline writes every issue step through maintenance/repairs/history.step,
whose action is a parameter, and the technician-default and service-state calls pick
their action or build their metadata at runtime. The presentation guard failed with 43
drift errors on the merged tree. history.py is now a reviewed wrapper with an exact
action list, the two branch-chosen actions and two runtime-meta actions are declared,
and the catalogue drops the wrapper-only entries and permits no metadata for the
denied ones. The raw audit rows are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The projection FK registry was missing TechnicianCoverage.machine_type and
TechnicianDefault.machine_type (they now resolve through the built-in/custom type map
like every other machine_type edge), and the deployment-global uniqueness registry
declared five technician/assignment constraints that include a tenant-owned column and
so carry no cross-tenant risk.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant