Skip to content

fix: load composition grants for local fixture roles - #4

Merged
antoinetoussaint-byte merged 2 commits into
mainfrom
fix/local-roles-from-catalog
Oct 26, 2026
Merged

antoinetoussaint-byte merged 2 commits into
mainfrom
fix/local-roles-from-catalog

Conversation

@antoinetoussaint-byte

Copy link
Copy Markdown
Collaborator

Local compositions can now grant existing fixture roles the permissions their modules serve. Previously only the developer role followed the delivered catalog; editor/admin grants had to be added to the authority fixture, leaking consumer vocabulary into this repository.

This is a fix in the local authority, using Codefly's existing public workspace configuration documents (fixture-roles) and the existing Role/Scope schema, resource matcher compiler and person grant resolver. The delivered catalog has no editor/admin organisation-role-class mapping. The loader runs before listeners start, preserves existing grants, and atomically refuses unknown roles, generated roles, malformed matchers, unknown fields, empty actions, null/empty documents and trailing documents. No authority interface or generated file changes, and no document-store scopes are added here. The document-store playground supplies its own publish/freeze grants and will pin this revision in obin-ai/module-document-store#583.

Validation: the complete local-authority go test ./... suite passed, including in-process conformance. Focused tests exercise composition grants, resource narrowing, named method refusals, atomic rejection and Codefly file loader → SDK document delivery → startup hook. Independent platform review accepted reuse and ownership. Existing host-package grant-resolution parity remains an owner obligation; this adds no resolver and does not claim SaaS parity.

Live qualification remains incomplete: codefly run service authority/local --env local --headless --local-agents --naming-scope fixture-roles-check in the consumer playground stops before service initialization with service-secrets secret-store: name cannot be empty. A compatible CLI and the composed store run are still needed to verify editor publication, admin freeze and viewer refusals against the running store.

🤖 Generated with Claude Code

Reuse Codefly workspace documents and the existing fixture grant resolver so compositions own their module permissions. Refuse malformed grants atomically before listeners start.

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

Copy link
Copy Markdown
Collaborator Author

Live delivery evidence for 69d55c8. I ran it from obin-ai/module-document-store#583's playground, which now pins this commit (85f2e302, eaf9db1f, 3fc387a6). The CLI was built from codefly-dev/cli#1158 at e6b56962. The run was codefly run service … --env local:

authority/local > (INFO) (local) the composition grants acme/editor: documents.collection:[publish]
authority/local > (INFO) (local) the composition grants acme/admin: documents.collection:[publish freeze]

The run also showed that a composition which supplies no document boots unchanged. The new fixture-roles dependency, when absent, raised no refusal. go test ./... and go vet ./... pass on this head.

Not verified live: the browser/edge journey (an editor publishes, an admin freezes, a viewer is refused). It stops before the store starts, for reasons outside this PR:

  1. The CLI (#1158, efb61fd1) refuses a module whose bindings target a module the run does not compose. It names the store's runtime-admission and tracing bindings: binding runtime-admission targets runtime, which has no selected local identity workload.
  2. The model gateway at the pinned f4315836 still asks for codefly.dev/authority@0.1.0. Main implements 0.2.0, so the run answers "no provider in scope satisfies it".
  3. python-fastapi 0.0.121 runs src/openapi.py at init. The model gateway deleted that file in 4d07bb7, along with its REST face.

🤖 Generated with Claude Code

… adds the rest (review r49)

The embedded fixture granted robin, tracing, evaluation, records, documents and
directory kinds, stood in for the model and installed a solution. It now holds
organisations, people and roles in the authority's own vocabulary
(console.identity) and nothing else. What a composition's modules and
solutions need arrives through the versioned fixture-composition document
(schema codefly.dev/authority/fixture-composition/v1): grants on the fixture's
roles, installations and stand-in modules, each through the fixture's own path.

- B1: the authority module ships an empty default document
  (modules/authority/configurations/local), which a composing workspace's own
  replaces whole. doctor reports it provided by the composed module, and a
  workspace composing the authority alone, with neither federation nor
  fixture-composition, boots ("the composition adds nothing to the fixture").
- M1: wildcard kinds and actions are refused by name.
- M2: module grants, the wiki installations and the model stand-in leave the
  fixture. The authority playground supplies grants for the modules it
  composes. The test kit applies them as a composition does
  (testkit/testdata/composition.yaml). The test asserting the fixture's
  documents grant is gone; the composition tests use synthetic kinds only.
- m1: an empty or null document, a null section, an unversioned document and
  kinds or actions outside the grammar (whitespace included) are refused.
- m2: the local authority refuses to start in a pod.
- m3: the document is versioned, and the README states its contract.

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

Copy link
Copy Markdown
Collaborator Author

Review r49: all findings addressed at 4d1217c (dispositions recorded as x35). The document is now fixture-composition, schema codefly.dev/authority/fixture-composition/v1. It has three sections: roles (grants), installations and modules (stand-ins).

  • B1, fixed. The authority module ships an empty default document, modules/authority/configurations/local/fixture-composition.yaml, which a composing workspace's own document replaces whole. I checked it in a workspace that composes only the authority and supplies neither federation nor fixture-composition:
    • codefly doctor workspace --service local reports fixture-composition — provided by composed module "authority" and federation derived from host for the native delivery service, and the workspace is ready.
    • A live codefly run service authority/local boots and logs the composition adds nothing to the fixture.
  • M1, fixed. A wildcard kind or action is refused by name, then anything outside the kind/action grammar. The same check covers stand-in kinds.
  • M2, fixed. The fixture is down to organisations, people and roles in the authority's own vocabulary (console.identity). The module grants, the wiki installations, the derived\x1fwiki matcher and the model stand-in are gone from it.
    • The authority playground supplies grants for documents, records and directory.
    • The test kit applies its grants, installations and model stand-in through ApplyComposition (testkit/testdata/composition.yaml).
    • The test asserting the fixture's documents grant is deleted. The new tests use only synthetic kinds (ledger.*, oracle, atlas).
    • Module playgrounds updated: document-store #583 (5674152, verified live with all 8 grants logged) and tracing #103 (796f8a3).
  • m1, fixed. These are now refused: an empty document, null, {} (no schema), any section spelled null, and padded kinds or actions. The unreachable trailing-document check is removed.
  • m2, fixed. The local authority refuses to start when native.InPod().
  • m3, fixed. The document is versioned, and the README states that its sections and the fixture's ids are a contract with consumers.

Checks: go vet ./... and go test -race ./... pass in modules/authority/services/local/code.

Not done:

  • Robin's document. My instructions forbid touching module-robin.
  • Renaming the remaining test-only vocabulary (documents/wiki in the test kit's manifests and about 40 existing test files) to synthetic names. It changes nothing in the shipped fixture.
  • Record-store, directory, model gateway and the core-solutions wiki each need their own document before they repin past 4d1217c.

🤖 Generated with Claude Code

@antoinetoussaint-byte
antoinetoussaint-byte merged commit a263f39 into main Oct 26, 2026
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