Admin constitution — genesis role schema + the two owner identities (superadmin)#50
Merged
Merged
Conversation
…ils-closed proof
Schema addendum ahead of constituting real identities: allowlist entries become
{ pubkey|did, role } with role: "superadmin" | "admin" (required). The role is
genesis DATA, not a runtime capability switch — superadmin means governance
authority over the allowlist exercised through repository merge rights (add/
remove admin = PR; revocation = commit + deploy; there is NO in-app write-path
to the admin set) plus the highest capability tier when Phases 5-6 differentiate
capabilities; admin is assigned by superadmins via PR. Today every allowlisted
identity passes the same gate — differentiated enforcement lands with the
features that need it. adminRoleFor() exposes the recorded role; matchers ignore
malformed entries as before (a typo can never grant access).
Test trap-check (standing rule): the suite DID prove fails-closed against the
COMMITTED allowlist, which would silently change meaning the moment identities
land. Refactored: fails-closed is now proven against an explicit EMPTY fixture
(invariant to the committed list), the default-deps wiring is pinned with an
uncommitted random key, and a new test validates every committed entry for
well-formedness + a valid role. The allowlist remains EMPTY in this commit.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVPyHAtQ1cdK76RpFasafP
…peradmin
The genesis commit of admin governance: the operator's two identities enter the
committed allowlist, both role: "superadmin".
nostr b359989af4fd4d3e38c7f09292848303eb5b18a16ebf0339a94048f35bf76501
(npub1kdve3xh5l4xnuwx87zff9pyrq044kx9pd6lsxwdfgpy0xklhv5qs96rgqv)
atproto did:plc:nli4gouip2eswhsrzqbiatyz (monteroxr.bsky.social)
Provenance, per entry comments: the Nostr hex was verified three independent
ways (in-repo nip19 decode round-tripped; independent decode; the NIP-98-proven
subject of the owner's live sign-in in the production auth store). The DID is
the store-authoritative subject of his completed AT-Proto OAuth session,
confirmed against live resolveHandle — the handle is recorded as a comment only;
the stable DID is what elevation compares.
Merging this activates /console/ login for exactly these two identities and no
one else; every other identity — valid signatures included — remains rejected,
and removal of an entry revokes live sessions on their next request (per-request
enforcement, PR #49). Nothing else changes.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVPyHAtQ1cdK76RpFasafP
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
wecanjustbuildthings | 314f387 | Jul 04 2026, 09:40 AM |
MartinMontero
marked this pull request as ready for review
July 4, 2026 09:49
10 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Admin governance entering through review. Two commits:
970fe4d— Genesis role schema. Allowlist entries become{ pubkey|did, role }withrole: "superadmin" | "admin"(required). Role is genesis data, not a runtime capability switch: superadmin = governance authority over the allowlist exercised through repository merge rights (add/remove admin = PR; revocation = commit + deploy, effective on the revoked identity's next request per PR fix(admin): per-request allowlist enforcement on the cookie path (revocation takes effect next request) #49; there is no in-app write-path to the admin set) plus the highest capability tier when Phases 5–6 differentiate capabilities; admin = assigned by superadmins via PR. Today every allowlisted identity passes the same gate — differentiated enforcement lands with the features that need it.adminRoleFor()exposes the role; malformed entries still never match.Trap-check outcome (standing rule): the suite did import the committed allowlist for its fails-closed proof — refactored in this commit to an explicit EMPTY fixture (invariant to the committed list), a default-deps pin using an uncommitted random key, and a well-formedness validator over whatever is committed.
314f387— The constitution. Both owner identities committed,role: "superadmin":nip19decode (round-tripped), independent decode, and the NIP-98-proven subject of the owner's live sign-in in the production auth store. DID is store-authoritative from his completed AT-Proto OAuth session, confirmed via liveresolveHandle.Type of change
Required checks
npm run check· [x]npm run enforce· [x]npm test(291, 0 fail) · [x]npm run buildFor catalog entries / recipes
Not applicable.
Deploy semantics — read before merging
Merging IS a production deploy, and it activates
/console/login for exactly these two identities — every other identity, valid signatures included, remains rejected (fails-closed proven against the empty fixture; live prod already demonstrated it against the owner's own real signer pre-merge). Removal of an entry revokes live sessions on their next request.Post-merge verification battery (owner)
/console/→ Sign in with extension (Alby) → whoami shows the hex above +method: nostr./console/→ Elevate → whoami showsdid:plc:nli4gouip2eswhsrzqbiatyz.__Host-wcjbt_admin— HttpOnly, Secure, SameSite=Strict, Path=/.bunker://URI himself → the signature flow completes and the allowlist rejects — that proves the full NIP-46 pipeline (relay wss under the prod CSP, remote signing, server verify) up to the list check. Rejection = PASS. ([2]-positive is N/A by owner custody choice — extension user; BYOK is satisfied by software support + tests.)Agent-side after merge: deploy poll + read-only negative set (no-credential 401s, unknown-path 404, non-staged-key NIP-98 probe 401,
/console/CSP single-header withwss:).Queued follow-ups (not in this PR)
CLAUDE.md:125references.github/CODEOWNERS, which does not exist — creating it (scopingworker/admin/allowlist.tsto the owner) would close that drift and add a second review gate on the admin set.Draft on purpose — do not mark ready-for-review, do not merge; merge is the owner's alone and is a production deploy.
🤖 Generated with Claude Code
https://claude.ai/code/session_01LVPyHAtQ1cdK76RpFasafP
Generated by Claude Code