Repository navigation
feat: the authority core's state layer: Store, in-memory store, seal sources, roles and lifecycle - #19
Merged
Conversation
The service runs every operation as reads from a Store, a decision (package decide), writes, and a capability minted or verified with core's workcontext. The signer and keys are the host's (Config.Signer, Keys); the clock and id sources are injected. Seal, epoch, binding and revision state answer core's verifier from the store: a revoke bumps the (person, installation) epoch, leaving a team or the organization the person epoch, and withdrawing owner-aware checking the audience's owner-aware revision, carried as the binding's incarnation and folded into a solution's seal. memstore is the in-memory Store. Tests encode the conformance target over it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A parent at page holding page.entry, collection and profiles, hopping through a binding that covers collection alone: the child's effective scopes, as issued and as checked, are collection read/write only, and asking for profiles through that binding is refused as a widening. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The service takes r124's decisions: RoleScopes refusing an installation with no principal, HeldRoles per installation, Child revealing no grant (the unused own-grants read is gone), a revoke that outlives its subject, and an absent installation answering as a foreign one, with service tests for the last two. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… foreign answers echo the request, readers gated in CI - m1: ChangeRole returns for a revoke right after the exactly-one-subject check, before the active and role-declared checks; tested in decide and in the service with a reinstall that reuses the id and a role retired then declared again. - m2: RoleChange carries the requested id, which ForeignInstallation echoes; the service resolves the installation by (organization, id) before reading anything else, so a foreign and an absent installation do the same work and answer the same text. - m4: clients.yml runs the authority client's Python and TypeScript tests, the other two readers of the shared claims.json. - m5: hop requires the authority client at f688c54, main's merge commit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nization's capabilities, the store is transactional; issuance moves to its own PR - B2: an installation principal's epoch is its revision, which grows on every install and uninstall, so a reinstall never repeats an epoch an earlier incarnation's capabilities were sealed at. - M1: Uninstall moves its organization's authorization revision, ending a hop through the solution sealed to another installation. - M2: Uninstall(ctx, caller, organization, id) checks an administrator as Install does, and answers another organization's installation as an absent one, changing nothing. - B3: modules/authority/services/local/code is tidied for hop's client bump. - m2: memstore.Write undoes every write of a failing fn; the Store contract says so and names ErrConflict for an adapter that gives up retrying. - m3: the seal revision's invariant is documented and tested across revoke, narrowing, owner-aware withdrawal, uninstall and reinstall; a module keeps its principal for life (ApplyModule refuses a rename). - m6: ApplyModule refuses a principal naming a person or an installed solution's principal. - m7: the replay store is required; nothing defaults to memory. - Split (m5): issuance, check, transfer and delegation, with B1, m1 and m4, move to the next PR. This one keeps the store, the in-memory store, the seal sources, roles and lifecycle, with source-level revocation tests: a revoke moves only its subject's seal on that installation, a team revoke its members', a leave the person's epoch, and a revoked grant stays gone across reinstall and a re-declared role. Each new test was run against its fix reverted and failed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 26, 2026
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 we are trying to do
This is step 2b of the solution-principal work (spec #11, #14). The core's decisions landed in #18. This PR adds the core's state layer: the transactional
Storethat both hosts implement, an in-memory store, the seal, epoch and revision sources that core's verifier reads, and the role and lifecycle operations that move them. Issuance builds on it in the next PR, which I open from main once this one merges, as split per r137 (m5). saas is untouched.The change
libraries/authority-core/go:authority/store.go: theStore(Read,Write) andTxcontract.Writeis all or nothing.ErrConflict.memstore: the in-memory store.Writeundoes a failing transaction's writes.authority/service.go:New(store, Config). The host injects the signer, the keys, the clock, the id sources and the replay store. Replay is required: nothing defaults to memory.authority/roles.go:GrantRolemoves nothing.RevokeRolemoves the subject's grant epoch on that installation.ListRoleGrants.PersonChangedmoves the person's epoch.authority/lifecycle.go:ApplyModule: a narrowing or an owner-aware withdrawal invalidates earlier capabilities. A module keeps its principal for life, and a principal never names a person or an installed solution's principal.WithdrawModule.Install: pending until its step converges. The host's own setup resumes a pending attempt.Uninstall(caller, organization, id): an administrator's act. It moves its organization's authorization revision and clears the installation's grants. A foreign installation is answered as an absent one.Installations.Also in this PR:
.github/workflows/clients.ymlruns the Python and TypeScript readers.f688c549.r132 and r137
IssueForInstallation's foreign answer) and m4 (Checkverifying before it reads). That PR also carries token-level tests for B2 and M1.Size
1,136 hand-written non-test lines (370 of them the in-memory store) and 581 test lines, under the ~2,000 budget.
Reuse and classification
decide's, from feat: the authority core's decisions, and readers that honour resource owners #18.Tests
go vetandgo test -race -count=1 ./...withGOWORK=offpass inlibraries/authority-core/go,libraries/hop/go,libraries/conformance/goandmodules/authority/services/local/code.sources_test.go):🤖 Generated with Claude Code