Skip to content

authority-core: what a second host needs (memberships, journal, delivery reading, method admission, store contract) and two cases every host runs - #35

Merged
antoinetoussaint-byte merged 18 commits into
mainfrom
core/hosts-share-the-rules
Oct 27, 2026
Merged

antoinetoussaint-byte merged 18 commits into
mainfrom
core/hosts-share-the-rules

Conversation

@antoinetoussaint-byte

@antoinetoussaint-byte antoinetoussaint-byte commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator

What we are doing

The owner's settled design: one host-independent authority core with unit tests, and the local authority and SaaS accounts as thin wrappers around it. The local authority already runs on libraries/authority-core/go. This PR adds what accounts needs to run on the same core (codefly-dev/module-saas-starter, the companion PR, which pins this branch), and moves the host-agnostic logic that still lived in the local authority's plugins into the core, so neither host keeps a copy.

What changed

Core extensions accounts needs, each host-agnostic and unit tested:

  • Tx.Member(org, id). A person may belong to several organizations. Accounts has multi-organization users, and memstore assumed one organization per person. The core now reads what a person holds through Member. Person(id) only answers whether the principal is a person. A caller acts only in the organization their session was opened at (memberAs). memstore keeps one membership per (person, organization) and gains DeleteMember. Test: TestAPersonOfTwoOrganizationsActsOnlyAsTheMemberOfTheSessions.
  • Config.Journal. Each change of authority is journaled inside the write transaction that makes it, so a host's audit record commits with the change or not at all. The changes are: module applied or withdrawn; installation requested, activated or uninstalled; role granted or revoked; delegation granted or revoked; resource attached, detached or transferred. A journal that refuses aborts the change. Test: TestEveryChangeIsJournaledInItsOwnTransaction.
  • OrganizationAdded, ReconcileOrganizations. An organization created after the modules were delivered holds them, as earlier organizations do. The local fixture load now uses this.
  • Config.HostInstallsModules (security review blocker 2). A host whose administrators install each module by their own consent sets it, and its store answers those installations from the host's records. The core then installs no module at delivery, for a new organization or when reconciling; withdrawal leaves the host's records to the host; UninstallAsHost refuses a module. A narrowing redelivery still raises the installation's revision, which the store applies to the host's record. Unset (the local authority), every composed module is installed at every organization, as before. Tests: TestAHostThatInstallsModulesIsTheOnlyOneThatDoes, TestAWorkloadIsIssuedOnlyWhereItsHostInstalledIt (table-driven, including a capability ending with its installation and staying dead after a reinstall).
  • Workload.Organization. A workload bound to one organization (its credential's) is issued nothing at another, and an issue naming none acts there. A workload issue also refuses an installation that is not active.
  • installationOf prefers the active installation of a target, so a host keeping retired installation records beside a new one seals to the live one.
  • Resource-scoped organization roles (security review blocker 1, a2f1c56, ddc87c4). decide.OrgScopes carries a role's id matchers as the held scope's resource ids, so an ask beyond them, or for the whole kind, is refused and an empty ask carries exactly the held ids.
  • GrantRoleAsHost. Trusted host setup decides a grant the way GrantRole decides it for the organization's administrator.
  • Composed. Reads a composed module as it was delivered.
  • domain.ErrAlreadyInstalled. The install refusal can be tested by sentinel.
  • ReconcileOrganizations makes one read and writes only for an organization that is missing a module installation.
  • storetest asserts that an empty id names no member. This caught a bug in accounts' Postgres store, fixed in the companion PR.
  • Delegation rules. A delegation must name a module installed at the grantor's organization, and its purpose is at most 1024 characters. The grantor or an administrator of the delegation's organization may end it. Anyone else gets NotFound, never a Denied that would confirm the delegation exists. Accounts enforced these rules on its own before; they now live once in the core. The local test moves from ErrRefused to ErrUnknown.

Moved out of the local authority into the core, so accounts reuses them instead of keeping a second copy:

  • Package delivered. Reads a verified delivery as the authority's module: FromCore, scope ceilings, roles, installation-owned roles, method policies, owner-aware, the pairing of the authority document with its carrier (VerifyDocument, Pair), and the withdrawal refusal. A host decodes its own generated AuthorityManifestV1 into delivered.Document. The core links no generated interface package, because a second registration of the same proto file panics. Tests: delivered/delivered_test.go.
  • decide.AdmitMethod and Service.CheckMethod. Method admission and HTTP route matching. Advisory mode returns the same refusal that an enforced check reports. Table test: TestMethodAdmission, 26 rows.
  • ApplyModule changes. It now refuses a delivery that names a resource owner anywhere, and joins the kinds a module's methods require to what it serves (decide.Served). These checks were in local's applyManifestLocked.

Package storetest. The contract every authority.Store must meet: transactions are all or nothing, a missing record wraps ErrNotFound, every record reads back as written, grants are idempotent, every revision and epoch only grows, and identity reads return what the host seeded. It runs on memstore here and on accounts' Postgres store in the companion PR. It uses fresh ids, so it can run against a database other tests share.

Conformance: two new cases every host runs. The local authority passes all 49 cases, and accounts passes the same 49.

  • every installation call stays inside the caller's organization, and an absent installation answers as a foreign one:
    • an administrator gets PermissionDenied naming the organization from Review, Install, List, ListRoleGrants, GrantRole and RevokeRole at another organization;
    • an absent installation answers exactly as a foreign one does;
    • a module nobody composed is NotFound by name in Delegate and Review;
    • another organization's administrator can neither read nor end a delegation.
  • only the hop registers an admission key, published apart from the Work Context keys:
    • the key id is stamp.KeyID and the purpose is hop-admission;
    • a renewal is idempotent;
    • the key is published exactly once among admission_keys and never among keys;
    • another workload is refused by name, and a 16-byte key is InvalidArgument.
  • Fixture gains OtherAdminToken, HopCredential and InstallModule (a host that installs modules by consent installs the ones the suite delivers; SolutionPrincipalCase.InstallModule likewise). The admission-key case signs each registration (stamp.ProveRegistration, over the audience the hop's credential names), as interface 0.3.4 requires. The conformance module's authority-client pin moves to main (7b6569e1).
  • Main merged (656d23bf, fix: hop registration proves possession; REST callers keep {"error"}; setup page hardened (#28, #30 follow-ups) #32): the local authority takes main's authority-client pin; generated contracts merged without conflict and the package gate passes.

Use cases → tests, on both hosts

The shared suite (conformance.Run) runs against the local authority (plugins/registry_test) and against accounts (pkg/adapters/host_interface_conformance_test.go). Each of the following passes on both.

Use case Shared case(s) Core unit tests
Sign-in and session a fixture person signs in…, every fixture person listed…, Current names…, a page asks who its bearer is… —
Issue for a person; child = current grants ∩ binding; narrowing never recovered; held = last actor's granted scopes a person is issued, checked…; a child hop attenuates…; child target projection preserves explicit delegation restrictions; parent per-kind limits survive audience changes; a delegate chain inherits…; a lookup through a binding… child_intersection_test, child_provenance_test, scope/model_test
Delegation a delegation issues as its grantor…, a delegation is bounded…, isolation (another organization's delegation) delegation_rules_test, journal_test
Solution roles, including installation_owned_scopes a delivered solution role…, a solution role cannot exceed…, installation-owned role scopes cover only what the installation owns decide/installation_owned_test, principal_test
Install with consent bound to target, generation, revision, digest and operation (replay, redelivery, supersede, revoke) installation acknowledgement gates exposure and revocation ends authority; fresh approval supersedes pending attempt (accounts) consent_test
Role grant and revoke to people and teams a callee refuses what does not verify (revoke), a solution viewer reaches…, the lifecycle case (team grant) revocation_test, organization_added_test (GrantRoleAsHost)
Installation-owned resources (create-attach, transfer-attach, detach, refusals by name) installation-owned role scopes cover only what the installation owns attachment_test
owner_aware delivery a solution binding root…, a module tool binding… r143_test, decide_test
Tool and operation checks per method policy a check naming a method applies…, a delivered solution route…, a resource-limited scope passes method admission… decide/method_test
Admission keys (hop only, purpose separation, renewal) only the hop registers an admission key… host unit tests: local issuer/admission_test, accounts host_interface_admission_test and the Postgres lease tests
Cross-tenant isolation every installation call stays inside the caller's organization…; an installation issue cannot name a different organization; empty workload organization cases membership_test
Absent installation or module an installation issue verifies the installation exists; isolation (absent installation, not-composed module); every refusal reaches the caller… r152_test
Store contract — storetest (memstore here, Postgres in accounts)

Fix or hack

Every item is a fix placed where the behaviour belongs.

Evidence

At head e0b04b28:

  • go vet ./... and go test -count=1 ./... (GOWORK=off) pass in all 12 Go modules, including tools/packagegate (contracts match codefly generate contracts) and tools/noproxygate.
  • Local authority: the shared suite passes 50 of 50 (main's Current case included) and the solution-principal target passes.
  • Accounts (feat(accounts): the host interfaces are decided by the shared authority core module-saas-starter#1257, pinned here): 50 of 50 shared cases, 18 of 18 target cases and 7 harness cases, with every module installed by administrator consent through InstallModule.

Not verified

  • No composed playground run.
  • The hop-admission rule (proof, per-instance pin) is still each host's own: the local authority's in memory, accounts' in Postgres. Moving it into the core is not done here.

🤖 Generated with Claude Code

antoinetoussaint-byte and others added 8 commits October 26, 2026 20:10
…eading, method admission and a store contract, shared by every host

A person may belong to several organizations: Tx.Member(org, id) is what the
core reads what they hold from, and a caller acts only in their session's
organization. The reading of a verified delivery (FromCore, ceilings, roles,
installation-owned roles, methods, owner-aware, the document's pairing) moves
from the local composition plugin into package delivered; method admission
moves from the local state into decide.AdmitMethod and Service.CheckMethod;
the owner refusal and the method-served kinds move into ApplyModule; module
installations at an organization added later are Service.OrganizationAdded.
Package storetest is the contract every Store meets, run here on memstore.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… and the host grants a role as the administrator would

ReconcileOrganizations holds every composed module at every organization (what
a host runs at start; the local authority's fixture load now calls it), and
GrantRoleAsHost is trusted host setup deciding a grant as GrantRole decides it
for the organization's administrator.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ransaction that makes it

Config.Journal receives each change (a module applied or withdrawn, an
installation requested, activated or uninstalled, a role granted or revoked, a
delegation granted or revoked, a resource attached, detached or transferred)
inside its write transaction; a journal that refuses aborts the change. A host
maps it onto its audit record; nil journals nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ounded purpose, and an administrator may end it

A delegation names a module installed at the grantor's organization (nothing
could issue from one to a module installed nowhere there) and a purpose of at
most 1024 characters. Its grantor or an administrator of its organization,
acting there, ends it; anyone else learns nothing of it, not even that it
exists (NotFound, no longer a Denied that confirmed it).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… and only the hop registers an admission key

Two cases every host now runs: an administrator acts on no organization but
the session's (Review, Install, List, ListRoleGrants, GrantRole, RevokeRole),
an absent installation answers as a foreign one, a module nobody composed is
NotFound by name, and another organization's delegation is never read or
ended; and only the hop registers an admission key, published once among the
admission keys with the hop-admission purpose and never among the Work
Context keys, renewed by registering it again, refused by name to another
workload and for a key that is not 32 bytes. Fixture gains OtherAdminToken and
HopCredential; the local authority passes both (49 cases).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…it (domain.ErrAlreadyInstalled)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
antoinetoussaint-byte and others added 10 commits October 26, 2026 21:27
…odule installation is missing

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the whole kind

decide.OrgScopes dropped RoleScope.Resources, so a person holding
collection:read on store-x alone held the whole kind at Issue: an empty
ask was issued kind-wide, an ask naming store-y was issued on store-y,
and every child inherited it. Only ListResources answered correctly, so
any module deciding from the token's claims over-granted.

OrgScopes now carries a role's ID matchers as the held scope's resource
ids (a scope naming none, or All, stays the whole kind and absorbs), so
Issue refuses any other id or the whole kind and an empty ask carries
exactly the held ids. A token cannot carry a prefix or a pattern, so one
holds only the ids the decision names (the ask, or the parent capability
of a hop or a delegation) that it matches: an empty ask carries none of
it, fail closed. held/throughSolutions pass what each decision names.

The shared suite's "which resources a context covers" case now issues on
the covered ids, requires an empty ask never to carry the kind whole, and
requires an ask naming an uncovered id (beside a covered one) or the
whole kind to be refused. Local tests that encoded the kind-wide token
are updated to the new contract; decide and authority tests cover exact
ids, asks beyond, children, patterns, whole-kind roles and mixed roles.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings #34 into #35 so CI tests the resource-scope fix against main's
current_test.go, which the next commit corrects.

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

TestCurrentInstallationIsConfinedToTheAuthenticatedAudience (from main,
#34) issued rob and omar whole-kind read though their role reads store-x
alone: the escalation the previous commit closes. The test is about
installation confinement, so each asks for what they hold.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…only one that does

Config.HostInstallsModules says the host decides which organizations hold
each composed module, by its own administrators' consent, and its store
answers those installations from the host's records. The core then installs
no module at delivery, for a new organization or when reconciling; withdrawal
leaves the host's records to the host; UninstallAsHost refuses a module. A
narrowing redelivery still raises the installation's revision, which the
store applies to the host's record. Unset, every composed module is installed
at every organization, as before.

Workload.Organization binds a workload to the organization its credential is
bound to: an issue naming another is refused, and an issue naming none acts
there. A workload issue also refuses an installation that is not active.

installationOf prefers an organization's active installation of a target, so
a host that keeps the records of retired installations beside the one it made
again seals capabilities to the live one; a capability sealed to the retired
one stays refused after the reinstall.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… which every host's store writes

A host that installs modules by consent keeps a module's installations in its
own records (Config.HostInstallsModules), so the contract proves atomicity on
the installation the core writes for every host.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…he ones the suite delivers

Fixture.InstallModule (and SolutionPrincipalCase.InstallModule) has a host
whose administrators install each module by their own consent install a
module the suite just composed, through the host's own path. nil keeps
delivery installing a module at every organization, as the local authority
does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The local authority takes main's authority-client pin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s interface 0.3.4 requires

After main's per-instance hop admission key (#32), RegisterAdmissionKey
requires a fresh proof signed by the key it registers over the credential and
the authority's audience. The case signs each registration
(stamp.ProveRegistration) with the audience the hop's credential names, and
the library takes main's authority-client.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
antoinetoussaint-byte added a commit to codefly-dev/module-saas-starter that referenced this pull request Oct 27, 2026
…dministrator's consent

Security review blocker 2: every composed module was active at every
organization in the authority core, so a module workload could be issued
its headless scopes, and a member a person capability at its audience, in an
organization that never installed it, outside its envelope tenant pin, or
after an administrator uninstalled it.

- The core is configured with HostInstallsModules (codefly-dev/authority#35):
  it installs no module at delivery, organization creation or start. A
  module's installation is accounts' own installations row of kind module
  (an administrator's install with consent, within the module envelope),
  which the Postgres store answers as the core's installation, live. A native
  uninstall or a narrowed ceiling ends it in the core at once; a capability
  sealed to it fails its next check and stays dead after a reinstall. The
  core's one write, a revision raise on a narrowing redelivery, is kept in
  authority_core_module_revisions (migration 56).
- A workload is bound to the organization the module envelope pins it to
  (Workload.Organization), read from the fenced registry.
- Re-pinned to #35 at e0b04b28, which carries the resource-scope fix
  (blocker 1) and authority main (656d23bf): the fixture's suite viewer gains
  an organization-wide role; InstallationService.Current is served through
  the core; RegisterAdmissionKey verifies the 0.3.4 registration proof, uses
  each nonce once and pins one key per hop instance (migration 58);
  module.codefly.yaml declares authority 0.3.4 and installation 0.3.0.
- The harness installs every delivered module through accounts' own install
  path (Fixture.InstallModule) and proves a workload is refused where the
  module is not installed, outside its pin and after an uninstall.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@antoinetoussaint-byte
antoinetoussaint-byte merged commit 50e76eb into main Oct 27, 2026
16 checks passed
crisfiorini-oss pushed a commit to crisfiorini-oss/module-saas-starter that referenced this pull request Oct 27, 2026
…ty core (codefly-dev#1257)

* wip: accounts serves the host interfaces through the shared authority core

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

* wip: regenerate

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

* wip: legacy delegations into the core, gates, store contract

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

* wip: product fixture installs kept beside the core's; suite isolation and admission cases on accounts

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

* docs(accounts): HOST_INTERFACE.md describes the host interfaces as served now; pin authority 8093104c

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

* test(accounts): the solution-principal target runs against accounts; the suite at authority main runs in CI; an empty id names no member

The shared solution-principal target (18 cases) now runs in the harness
beside the suite. Membership loss is applied to accounts' membership rows
directly, a labelled stand-in for accounts' own policy-logged membership
narrowing. A new CI job runs the suite at authority main whenever main
contains the pinned revision. Member(org, "") read as every member; it now
names nobody (codefly-dev/authority storetest pins it). Role grants, revokes
and listings leave the tenant decision to the core, which answers another
organization's installation and an absent one alike. Pins authority 8846431f.

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

* feat(accounts): a narrowing of authority applies directly, recorded in the audit journal

Owner decision (2026-10-27): removing a team or organization member, and every
other change that only reduces access, applies directly, its audit record in
the same transaction. No policy-log witness is asked first; widening paths are
unchanged.

- business/narrowing.go is the one path every narrowing takes; the policy log
  (append, receipt, commit, serving gate, reconciliation) is deleted, with its
  Postgres and warehouse adapters, its interceptor gate and its refusals.
- The module envelope writer writes a narrowing like a grant: the row, the
  installations the ceiling no longer allows and the audit event commit in one
  transaction. The pure-grant classification that only chose the witness is
  deleted.
- A withdrawn solution target closes in its apply transaction.
- Migration 57 drops policy_log_commits and policy_log_cursor.
- The policy-log service, which only witnessed narrowings and was never wired,
  is deleted with its declarations, configuration and generated topology.
- Member removal audit events name the person removed (user_id).
- The solution-principal target removes team and organization members through
  RemoveTeamMember and RemoveOrgMember; the harness proves the removal is in
  the audit journal and that the leaver's earlier session is issued nothing.
- "Host interface conformance (authority main)" is a required context and a
  release gate; its script reads authority's ancestry from a blobless clone,
  retried, never the rate-limited API.
- Proto doc comments, contracts, the SDK bindings and the docs say narrowings
  apply directly.

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

* fix(accounts): a module is installed at an organization only by its administrator's consent

Security review blocker 2: every composed module was active at every
organization in the authority core, so a module workload could be issued
its headless scopes, and a member a person capability at its audience, in an
organization that never installed it, outside its envelope tenant pin, or
after an administrator uninstalled it.

- The core is configured with HostInstallsModules (codefly-dev/authority#35):
  it installs no module at delivery, organization creation or start. A
  module's installation is accounts' own installations row of kind module
  (an administrator's install with consent, within the module envelope),
  which the Postgres store answers as the core's installation, live. A native
  uninstall or a narrowed ceiling ends it in the core at once; a capability
  sealed to it fails its next check and stays dead after a reinstall. The
  core's one write, a revision raise on a narrowing redelivery, is kept in
  authority_core_module_revisions (migration 56).
- A workload is bound to the organization the module envelope pins it to
  (Workload.Organization), read from the fenced registry.
- Re-pinned to codefly-dev#35 at e0b04b28, which carries the resource-scope fix
  (blocker 1) and authority main (656d23bf): the fixture's suite viewer gains
  an organization-wide role; InstallationService.Current is served through
  the core; RegisterAdmissionKey verifies the 0.3.4 registration proof, uses
  each nonce once and pins one key per hop instance (migration 58);
  module.codefly.yaml declares authority 0.3.4 and installation 0.3.0.
- The harness installs every delivered module through accounts' own install
  path (Fixture.InstallModule) and proves a workload is refused where the
  module is not installed, outside its pin and after an uninstall.

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

* fix(contracts): the exported proto trees carry the recorded interface digests

The interface protos' DIGESTS.sha256 moved after the contracts were last
generated; codefly generate contracts copies it into both exported trees.

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

* chore(source-read-sdk): regenerate for the accounts contract digest

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

* fix(go): accounts and auth-gateway pin frontendpayload at a commit on main

They required module/frontendpayload at 0d423cb, a commit on no branch,
so a fresh module cache could not fetch it. They now require it at
6fd56da, main's latest change to that module.

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

* chore: run CI against the corrected pull request body

A re-run replays the event payload it started with, so the naming gate kept
reading the body before its correction; a new commit carries the current one.

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

* fix(accounts): the authority core issues within what each module installation consented to

Review finding N1: the core read a module installation's status and revision
only, so a new workload issue used the delivered binding, ignoring an
administrator's narrowing (Capabilities off, a binding dropped), the module
envelope's per-binding ceiling, and a widening redelivery not yet
re-consented. Before this PR the native mint honoured all three.

- codefly-dev/authority#36 adds Installation.Bindings, one ceiling every
  issue through a binding applies (workload, installation, hop, delegation).
- accounts' store fills it for each module installation from the consent
  recorded on it, decided as the native mint decides it
  (business/authority_core_consent.go: the registry grant, manifest within
  envelope, intersected with the consent by consentedGrant). An installation
  whose consent allows no capability, or that awaits re-consent, is not
  active for the core. The registry is fenced against the envelope revision
  committed in the core's own transaction.
- The harness proves, beside the native mint: an installation narrowed to no
  capability issues nothing, a binding dropped from the consent or from the
  module's grant within the envelope issues nothing, and a redelivery that
  widens a binding issues no more than was consented. A module's consent is
  given again through the fixture's install path at each delivery.
- Pins authority at codefly-dev#36's head (93bc9f58), which carries codefly-dev#35's merge.
- The NarrowInstallationScope comment no longer names a policy receipt.

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

* fix(accounts): an envelope write ends every core capability decided under the ceiling it replaced

Review finding N3: an envelope narrowing a module's binding changed what the
core issued next, but a capability issued before it kept passing Check until
its TTL, because the revision the core seals to and checks never moved.

The module installation revision accounts reports to the core now adds the
envelope revision committed in the core's own transaction, beside accounts'
own revision and the core's raise, so every envelope write ends what was
issued under the ceiling it replaced; codefly-dev/authority#36's workload
fence (N2) refuses a mint that straddles the write.

The harness writes a real envelope revision narrowing a binding: the earlier
capability fails its next check, the next issue fails closed until the
registry is derived again, then issues only what the narrowed ceiling
allows. Without the revision change the case fails.

Pins authority at codefly-dev#36's head (22b86ccb).

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

---------

Co-authored-by: Antoine Toussaint <312536060+antoinetoussaint-byte@users.noreply.github.com>
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