Skip to content

Admin constitution — genesis role schema + the two owner identities (superadmin)#50

Merged
MartinMontero merged 2 commits into
mainfrom
claude/wcjbt-admin-constitution
Jul 4, 2026
Merged

Admin constitution — genesis role schema + the two owner identities (superadmin)#50
MartinMontero merged 2 commits into
mainfrom
claude/wcjbt-admin-constitution

Conversation

@MartinMontero

Copy link
Copy Markdown
Owner

What does this PR do?

Admin governance entering through review. Two commits:

  1. 970fe4dGenesis role schema. Allowlist entries become { pubkey|did, role } with role: "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.
  2. 314f387The constitution. Both owner identities committed, role: "superadmin":
    nostr   b359989af4fd4d3e38c7f09292848303eb5b18a16ebf0339a94048f35bf76501
            (npub1kdve3xh5l4xnuwx87zff9pyrq044kx9pd6lsxwdfgpy0xklhv5qs96rgqv)
    atproto did:plc:nli4gouip2eswhsrzqbiatyz  (monteroxr.bsky.social — DID stored, handle is a comment)
    
    Provenance (in entry comments): Nostr hex verified three independent ways — in-repo nip19 decode (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 live resolveHandle.

Type of change

  • Enforcement engine / tooling · [x] Other — admin governance (allowlist constitution)

Required checks

  • npm run check · [x] npm run enforce · [x] npm test (291, 0 fail) · [x] npm run build

CI is pull_request-only; this draft is these commits' first CI run.

For 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)

  • [1] /console/ → Sign in with extension (Alby) → whoami shows the hex above + method: nostr.
  • [3] Sign in with Bluesky in the site header first, then /console/ → Elevate → whoami shows did:plc:nli4gouip2eswhsrzqbiatyz.
  • [5] Devtools: __Host-wcjbt_admin — HttpOnly, Secure, SameSite=Strict, Path=/.
  • Negative (strongest live demo): sign in with the test account (tavernx) → Elevate → must be rejected (authenticated real identity, not allowlisted).
  • [2]-mechanics (recommended): owner-created throwaway bunker identity → paste its 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 with wss:).

Queued follow-ups (not in this PR)

  • Admin-rejection logging parity: reason-token warn logs on admin auth rejections (never credential material).
  • CODEOWNERS on the allowlist path (owner's optional call): CLAUDE.md:125 references .github/CODEOWNERS, which does not exist — creating it (scoping worker/admin/allowlist.ts to 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

claude added 2 commits July 4, 2026 09:33
…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
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
wecanjustbuildthings 314f387 Jul 04 2026, 09:40 AM

@MartinMontero
MartinMontero marked this pull request as ready for review July 4, 2026 09:49
@MartinMontero
MartinMontero merged commit 8bcfc34 into main Jul 4, 2026
14 checks passed
@MartinMontero
MartinMontero deleted the claude/wcjbt-admin-constitution branch July 4, 2026 09:49
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.

2 participants