Skip to content

Deliver through composition and validate generated permissions before execution - #1128

Merged
antoinetoussaint-byte merged 62 commits into
mainfrom
delivery/through-the-composition-interface
Oct 25, 2026
Merged

antoinetoussaint-byte merged 62 commits into
mainfrom
delivery/through-the-composition-interface

Conversation

@antoinetoussaint-byte

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

Copy link
Copy Markdown
Contributor

The orchestration start boundary now supports synchronous admission before every local Runtime.Start RPC, including restarts. Refusal or cancellation blocks the RPC. Real dependency/full-stack starts in test mode emit Running through the existing lifecycle hook; the synthetic target barrier does not. docs/orchestration.md documents this behavior and the serial action loop. Launcher wiring remains unfinished: this support seam alone does not establish pre-start authority.

A native run now delivers through the host's codefly.dev/composition interface when declared, carrying signed module and authority documents, scope ceilings, solution roles, and method policies. This removes the launcher's dependence on that host's private delivery routes while preserving HTTP delivery for hosts without the interface.

Native delivery now settles a generation from both Core content and a captured authority declaration. A method, ceiling or role-only edit advances once; unchanged paired content replays. The existing generation file is reserved atomically before signing or sending under a cancellable shared file lock, so a lost response cannot reuse a generation for different policy. Withdrawals retain their terminal reservation even after failed signing or an ambiguous response. Legacy live records advance once into paired settlement; unchanged terminal records retain their generation. The production launcher uses this path; direct already-settled callers retain Post.

The branch selects Core 4ebc360ec9f9, retaining Core-owned self-audience resolution and audience-list binding expansion: CLI consumes the resolved per-audience bindings and logs their IDs. Solution roles and own ceilings now come exclusively from Core's canonical module contract; the former separate roles.codefly.yaml is refused by name. Missing method declarations are required where the composition host consumes method policies or the module opts into strictness; malformed policies still fail. Runnable calls can select their resolved endpoint through the environment while preserving the owner's operation contract.

At cf1e3c5d, native withdrawal completion consumes the existing composition Applied callback instead of the private HTTP observer. The generated RPC response must acknowledge the sent generation; its request identity supplies the exact binding/digest/release/removal evidence for that synchronous attempt. Legacy hosts keep their HTTP observer. The new regressions fail before the repair; full GitOps/run-command suites, focused race tests and whole-repository lint pass. Independent architecture/Go review found no blocker. docs/development.md explains that this is not remote observation after restart or live launcher qualification.

At fffafc0b, signed withdrawal no longer reads or sends live method policies, scope ceilings or solution roles. This fixes the adapter mismatch with the authority's terminal withdrawal semantics and allows withdrawal after module source disappears. Module and solution regressions fail before repair and pass after it through the generated composition client; full GitOps/run-command suites, focused race checks, whole-repository lint (zero issues), and build pass. Independent architecture review verifies the correction. Documentation: docs/development.md. Actual launcher shutdown/restart is not qualified by these transport tests; the completion-observation repair is also included below.

Permissions come from the published contracts used by delivery. codefly generate permissions emits typed Go and TypeScript values and method tables; generate contracts --permissions --check detects source/export and generated-vocabulary drift. Initial runs, run refreshes, and control/MCP lifecycle paths inspect the selected composition before starting agents. Local adoption logs warnings; source-backed deploy, CI deploy, render and publication paths reject invalid declarations before their execution effects. Conflicting policies for the same published method fail explicitly.

Source preflight now compares each existing protobuf endpoint's exported proto snapshot with the source selected for that service. Changed, added, deleted or missing inputs warn locally and refuse strict delivery. Published packages do not require a source checkout; existing materialization receipts distinguish packages from local paths and git clones. Explicit development --path is checked against the source actually built, including when replacing a packaged service. GitOps checks the selected dependency closure (including invocation-selected configuration references) before effects, and checks a whole composition before its first module render.

Proto generation now respects the repository Buf template’s declared inputs and path selection. Previously, Codefly supplied a positional input that overrode those declarations, generating excluded imports and omitting additional inputs. The fix delegates selection to Buf, preserves the default input for templates without declarations, and preserves explicit --path override semantics.

The branch also retains optional-binding omission/diagnostics, Python-service permission-generation handling, and the documented warning when a narrowed local run drops an out-of-run configuration reference. The current Core pin retains the owner’s generated-file ownership repair.

The branch also carries Connect/foreign-proto client generation fixes, protobuf HTTP-route and OpenAPI policy extraction, call-derived binding scopes, and environment-declared local secret generation. The authority delivery dependency is pinned to dc41de4126aea7453008dd9de499458e0c750397.

Classification: fixes at the CLI integration owner. Reuses Core's module-closure and contract resolution, invocation-aware configuration inputs, existing materialization receipts and the generation tree comparator, the existing digest-checked MethodPolicies reader, authority's shared declaration validator, generated composition bindings and Core's atomic writer. No separate permission parser, authorization engine, hand-written client or dev server is introduced. Modules retain domain/resource/installation checks.

Native delivery now cancels active readiness/RPC calls and serialization waits on run cancellation, stop, supersession or deadline. The registered Running hook preserves run cancellation, and shutdown stops delivery before waiting for service teardown. Timeout diagnostics retain the phase and prior refusal while reporting unconfirmed completion: a canceled response does not prove the host did not apply the manifest. This reuses Go contexts and the existing x/sync semaphore; delivery still begins after Running and does not yet make authority available during startup.

Detailed CLI logs now have one exclusive directory per invocation. Helper contexts reuse one Core forwarding sink, rotation stays in the same invocation, and older shutdown writes cannot enter a newer invocation's files or displace its default discovery. Existing explicit-file reads, legacy fallback and fixed-descriptor follow remain. Writer and reader reuse Core's Codefly home resolver. This isolates detailed JSON files of separate CLI processes, not caller-owned stdout capture or multiple flows inside a long-lived control process.

Validation:

  • At 23ad484a, native manifests distinguish explicitly declared workload membership from ready routed services, retaining the old started-only behavior when no declaration is supplied. Explicit frontend deferral omits the current page; it does not retain an old one. Full GitOps/run race suites and fresh architecture/Go review pass in this renderer scope. The launcher does not yet supply these inputs; startup admission, real host application and page lifecycle remain unqualified. Docs: docs/module-manifests.md.

  • At 088c402e, after retaining incoming host policy, self-audience and Python helper-preservation commits through 1d1bab1b: full race suites for orchestration, GitOps, composition and run pass. Independent review accepts the support seam; socket-boundary regressions cover repeated starts, refusal and cancellation. No composed startup or UI is claimed.

  • At a18c3032: full GitOps/composition/run suites, focused paired-generation and canonical-role race tests, and exact pinned Core role tests pass. A fresh independent combined-revision review also reran focused preflight, CI/deploy, runnable/environment and generator tests with no blocking finding. Authority's corresponding consumed-role admission repair is 819765d in authority PR #1. This proves local integration/test compatibility, not live CLI-to-Authority admission or changed person-child policy.

  • At 6173ce55 after retaining 2694c2cb: full pkg/gitops, pkg/composition and cmd/run suites; focused race tests; isolated CLI build; and Authority composition/state suites pass. Final ec9470da diagnostic-loop follow-up tests pass and whole-repository lint reports zero issues. Independent design, implementation, Go and fresh combined-revision reviews found no remaining blocker in this offline scope. Regressions cover policy-only changes, byte-identical replay after lost acknowledgement, policy snapshot mutation, old live/terminal migration, concurrent writers, cancellation, reservation/sign failures and terminal revival refusal. The actual launcher factory produces generations 1,1,2,2 for a role-only edit through the generated client. Docs: docs/module-manifests.md. This does not qualify automatic reload or live effective permissions; source reads are not a filesystem transaction, and lost generation records cannot reconstruct host history.

  • At d6858f1d: full pkg/cli, cmd/common, and cmd suites, focused race, whole-repository lint (zero issues), regenerated reference check and build pass. Two actual subprocesses verify late shutdown/rotation isolation; repeated contexts use Core’s real forwarding path without duplicate records. Built-CLI --plugin-path, path/raw/explicit reads, latest-started selection and following across a later invocation pass. Independent architecture/Go review found no blocking isolation defect. Its minor flag wording finding was corrected and the reference regenerated.

  • At 0dcbb758, after retaining concurrent Core update 436478b9: full cmd/run, pkg/gitops, pkg/orchestration, pkg/generators, and cmd/generate suites pass; focused delivery/withdrawal race tests, whole-repository lint (zero issues), CLI reference and build pass. Regressions fail before repair for active-call cancellation, queued serialization and production Running-hook cancellation. A generated composition client calling a stalled loopback gRPC peer proves transport cancellation, not host admission or rollback. Fresh independent review closes the lifecycle and diagnostic findings on the combined revision.

  • At d7dbfcec after integrating origin ea939d21: full pkg/gitops, pkg/composition, pkg/generators, cmd/generate, cmd/deploy, and pkg/orchestration suites pass; focused source/preflight/optional-binding race tests pass; whole-repository lint reports zero issues; CLI reference and build pass. The incoming permission generator's shadowed local error was renamed without changing behavior. Fresh combined-revision review is recorded separately from prior patch reviews.

  • Source preflight regressions reproduce the stale-export, explicit-development-source and configuration-only-callee gaps before repair, and pass after repair. Cases cover artifact-only packages, stale receipts, multiple endpoint snapshots, missing inputs, overrides, selected/unselected dependencies and render refusal before output. The existing full regeneration gate remains separate.

  • At a097b27c, the full cmd/generate unit suite passes. A real pinned-companion regression reproduces the unwanted output before the fix and passes after it: selected and second-root files generated, excluded file absent; explicit path override and clean output also pass. Independent source, argument and staging review found no blocker in this repair.

  • GOWORK=off go test -race ./cmd/generate ./pkg/gitops ./pkg/orchestration ./cmd/run ./cmd/deploy ./cmd/ci ./pkg/control ./pkg/environments ./pkg/deploysecrets passes against published dependency pins.

  • Full golangci-lint run ./... reports zero issues; CLI reference test and CLI build pass. A final atomic-writer simplification was additionally checked by generator race tests and package lint.

  • Regressions exercise invalid source render and CI deploy before agents/output, selected-closure isolation, refresh checks before admission without disrupting withdrawal retries, generated Go compilation, unknown-symbol failure, stale/missing output and conflicting policies.

  • Built CLI generated Robin's actual published permission vocabulary into an isolated directory: standalone --check, Go compilation and strict TypeScript typecheck pass. A misspelled TS literal fails TS2820. This is an exercised consumer check, not a durable TS CI regression.

  • Fresh architecture follow-up, lint follow-up and Go elegance reviews found no blocking issue within this slice. The new, unmerged EnvironmentSecretGenerator.Encoding method now has a pointer receiver; inspected callers remain compatible, but the value method set narrows. AppliedManifest makes the existing delivery callback's return type nameable.

Docs changed in this PR: docs/commands.md, docs/module-manifests.md, docs/development.md, docs/orchestration.md, generated docs/cli-reference.md, alongside the existing branch's related delivery/generation documentation.

Limits: snapshot preflight covers existing protobuf exports, not new unpublished endpoints, OpenAPI source edits, external import changes or descriptor derivation. Keep generate contracts --permissions --check for full regeneration/output freshness. Declared inputs must remain reachable inside the existing companion mount; arbitrary external input projection was not added. Explicit --path replaces each input’s paths, not their intersection. Core’s persisted nested settings writer/reader mismatch remains open at its owner. This does not qualify a deployment or the entire authority migration. Historical rollback and packaged-solution renders lack complete artifact-bound policy evidence; source validation is not proof of those artifacts. Literal binding scopes still need callee-vocabulary validation. Authority now admits explicit consumed solution-role grants at 819765d; person-child role policy and production-host installation parity remain open. Incoming 1d1bab1b contains the Python root-helper preservation repair; full generator verification is recorded by its owner and is separate from the four-package race run above. No live refresh/browser/provider journey, cluster deployment, production-host conformance, merge or release is claimed by these checks. Prior branch evidence of a live authority delivery remains historical evidence; this change did not restart that run.

Log-isolation limits: the original playground capture path/launch command has not been supplied, so its incident is not declared resolved. External stdout capture remains its launcher’s responsibility. Claude reports the handbook usage correction applied at 471ac36a. Default invocation ordering assumes advancing wall-clock timestamps; file ownership itself is exclusive. Following does not reopen a rotation segment automatically.

The additional catalog, configuration, frontend and credential repairs are fixes at their existing owners:

  • CLI 8de0f667 pins Core 4e7f8ef01ed2 and publishes implemented interface procedures across protobuf packages, including the host procedures. It reuses the listener inventory and Core descriptor validation. Core's configuration loader supports explicit configuration-extensions: disjoint environment keys merge, declared list keys append, and YAML maps/sequences compose; scalar conflicts refuse by full key name. This extends the existing import/profile/provenance mechanism, without another runtime resolver.
  • CLI 61824c66 builds a declared frontend before native delivery through the existing deployed frontend builder and the service's package build script. Current source, including local edits and sibling packages, selects BuildKit's content cache; old local output is not build evidence. Build failures name the component and include build output. No second builder or cache protocol was introduced.
  • CLI 9d782b1d's credential refresh repair polls wall-clock expiry every five seconds and renews when at most 120 seconds remain. It reuses Core's issuer, 600-second lifetime and atomic writer. Failed renewals log the workload and underlying reason, remain due for retry, and do not block other renewals. A clock-jump regression and deterministic poll/logging/retry test cover the repair; restoring the long timer fails the retry regression.

Docs for these fixes: docs/commands.md, generated docs/cli-reference.md, and docs/module-manifests.md. Affected package suites and repository-wide go vet pass; credential/run race suites, generated reference check and isolated CLI build pass. Whole-repository lint reports zero issues after using Go's rooted filesystem API for frontend staging writes, avoiding catalog value copies and removing shadowed errors. Real Docker qualification checks unchanged bundle reuse and invalidation after source edits. Core configurations/composition/resources suites passed for the pinned companion change. No actual Saas regeneration, complete platform-obin delivery/browser flow, laptop suspend, or live Robin scoring was exercised.

CI landing repairs: c6326921 replaces the unconfigured reader-app inputs with the existing organization GH_PAT already used for companion checkout and publication, through the same repository-scoped module downloader. It also pins Core PR #835 at 88f4434c68c749c03b88b80e83150cff69643b74. 625e66f1 integrates current main and repairs its secret rotation call to reuse EnvironmentSecretGenerator.Encoding, eliminating the merge-build undefined: generatorFormat error. These are fixes at the CI authentication and generator integration owners; no gate, required check, or vulnerability rule was skipped or allowlisted. Docs: docs/development.md, docs/deployment-secret-safety.md, and the install action input contract.

For these repairs, actionlint, shell validation, deployment-secret/environment/deploy-command tests, the pinned-Core affected suites, repository-wide go vet, whole-repository lint (zero issues), and generated reference verification pass locally. All thirteen applicable hosted checks pass at 625e66f1: bootstrap-audit, control-integration, coverage, race, lint, dashboard, contract, pr-base-guard, and all five native qualifications (Go, Go-gRPC, Next.js, Python-FastAPI, Rust). The pins job remains schedule-only, unchanged. The PR is ready for review and the required merge queue.

AntoineToussaint and others added 2 commits October 23, 2026 13:04
…ost implements it

The launcher delivered a module's manifest by posting to one host's private
routes and writing its envelope through that host's gateway, so a run could
deliver to that host and to nothing else. When the run's host service declares,
in its module's interface endpoints, that it implements codefly.dev/composition,
the launcher now carries the signed manifest and the module's delivery
credential to ApplyManifest over the host's endpoint, reads the applied state
from the synchronous answer, writes no envelope (the manifest is the ceiling
there) and requires no gateway. The native deliverer gains two optional hooks,
Post and Applied; the HTTP delivery remains for a host that does not implement
the interface. Refusals map onto the statuses the run already classifies.

Fix at the owner: the CLI knows Codefly interfaces, never a host's routes. Not
released; proven with a local build against codefly-dev/authority.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
With each manifest delivered through codefly.dev/composition, the run now
delivers the authority's own document beside it: every method the module's
published protobuf contracts serve, with what each declares with the
authority.hop.v1.policy option, read from the module package (each contract
refused unless its bytes are the digest the package names). The document names
the core manifest's module, generation and digest, and is signed in the same
envelope format by the run's release key, through the authority's delivery
library. A module with no package declares no method policy and sends none.

The CLI learns no host route and no policy vocabulary of its own: it reads the
authority's option and speaks the authority's composition interface, both from
codefly-dev/authority at bc4d129 (authority client, delivery and hop
libraries).

Proven live with codefly-dev/authority's console: the delivery is applied, the
authority's Check admits Maya's WhoAmI and Version through the hop from the
delivered policy, answers an unserved method NotFound, and refuses a method
check for a module no signed document described.

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

Copy link
Copy Markdown
Contributor Author

Added in 13f7a3e: the delivery now carries the authority's signed method policies.

With each manifest sent through codefly.dev/composition, the run also sends the authority's own document, AuthorityManifestV1. It lists every method the module's published protobuf contracts serve, with what each declares through the authority.hop.v1.policy option. The CLI reads each contract from the module package and refuses one whose bytes do not match the digest the package names. The document names the core manifest's module, generation and digest, and is signed with the run's release key in the same envelope format. Core's manifest is unchanged.

The authority's Check now takes the method and decides from the delivered policy. That is codefly-dev/authority bc4d129, with the suite line "a check naming a method applies what the module's delivery declares".

Proven live with the authority repo's console. Maya's calls pass the hop on the delivered policy, an unserved method is answered NotFound, and a module whose delivery carried no document fails closed.

🤖 Generated with Claude Code

…ither

--exclude-workspace-configuration trimmed a group from resolution but not from
the groups the CLI renders itself for a native run (module-authority). A run
excluding module-authority still rendered it, and refused to start when the
environment's host names no gateway, which is every run against the authority
interface rather than the saas host. The render now sees the service's declared
groups less the excluded ones; the declared service is not mutated.

Test: an excluded group is not handed to the renderer; a run excluding nothing
passes the service through.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
antoinetoussaint-byte pushed a commit to codefly-dev/authority that referenced this pull request Oct 24, 2026
Core's manifest names a module's own resource kinds without their actions, so
the authority served each with any action. A person's ask for everything they
hold at such a module could not be enumerated and was refused ("declares
runtime.tasks without its actions"): the runtime's playground could not start a
task for anyone.

- Composition interface (a contract change): AuthorityManifestV1 gains
  scope_ceilings, each of the module's own kinds with the actions its contract
  declares.
- Gateway: a delivered kind takes its ceiling's actions in place of any action;
  a ceiling naming a kind core's manifest does not declare, or no action, is
  refused, so the document narrows and never adds. Tested and sabotage-checked.

Generated with codefly generate proto (gateway) and codefly generate client
(authority-client). The CLI fills the field from the module contract
(codefly-dev/cli#1128).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AntoineToussaint and others added 9 commits October 23, 2026 23:13
Core's manifest names a module's own resource kinds without their actions, so
an authority receiving it can only serve each kind with any action, and a
person's ask for everything they hold there cannot be enumerated: the runtime's
playground refused every task ("declares runtime.tasks without its actions").

The authority's document delivered with each manifest now carries the module's
scope ceilings, read from its module contract (gitops.ScopeCeilings), beside the
method policies; the document is sent when the module declares either. The
field is the composition interface's (codefly-dev/authority 064127b), which the
authority client moves to.

Tests: the document carries the ceilings (sabotage-checked), and ceilings are
read from a contract kind by kind, none without one.

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

The authority now admits an HTTP request by its route ("<VERB> <template>",
codefly-dev/authority 801bf7a), so the delivery reads a module's published
OpenAPI contracts as it reads its protobuf ones: each operation is the route
"<VERB> <path>" and its x-codefly-authority-policy is the same
authority.hop.v1.Policy a proto method marks itself with (decoded with
protojson). An unmarked operation is listed with nothing set, so the authority
refuses it by name; an extension that is not a policy refuses the delivery.

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

The export decided whether a rest endpoint carries a contract by asking the
module's exported endpoint, which is read from the interface and carries no
API details, so every REST face was skipped as "no OpenAPI document" — a
go-grpc service's openapi/api.swagger.json and a FastAPI service's alike.
It now asks the service for the file core loads a REST contract from
(standards.OpenAPIPath), as it already asks for proto/buf.yaml; a REST face
whose service carries none is still skipped as reachability only.

Found publishing the model gateway's route policies (its OpenAPI document).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keeps main's core (v0.19.7 pre-release) with this branch's authority libraries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An environment declares the secrets a cell's store holds as random values
under service-secrets.generate, which codefly deploy secrets honours; a local
run ignored the same declaration, so every playground generated its secrets
from a make target or script calling codefly config generate before it ran.

A run now generates, before it loads configuration, every key its
environment's generators declare that the workspace's secret configuration
does not hold yet: the same generator (EnvironmentSecretGenerator.Encoding,
moved from deploysecrets), into the file codefly config generate writes,
never rotating a held value and never printing one. A service-scope generator
names its services; a local run guesses none.

An environment run locally names no store, so service-secrets may now declare
generators alone (Stored reports whether it names one). A block with neither
is refused, and a render or deploy secrets refuses an environment that names
no store, since a render carries secrets only as references into one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…es for them

A module contract may name, per operation, the audience's methods a binding
calls instead of a ceiling (core 99d67976, contracts/module calls). The render
resolves each contract with the composed callees' own method policies, read
from their published contracts as delivery already reads them
(MethodPolicies): the operation's ceiling is what the calls require, so the
delivered manifest carries plain kinds to whichever host answers, and the
caller names none of the callee's kinds. A call the callee does not serve, one
it serves declaring nothing, and a callee this workspace does not compose are
each refused by name.

The module-contract kit's new fixture renders here against two composed
callees (a protobuf and an OpenAPI contract), and its ceilings are asserted.
Core moves to 99d67976 (its 257e6b23 plus calls).

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

A module declares the methods it serves from a protocol it does not own in
its module contract (core a57ef6ce, foreign_methods); MethodPolicies now
delivers them beside the methods its published contracts declare, so the
authority decides a call to an OpenTelemetry Export at the module like any
other, and a caller's binding may name it among its calls. A foreign method a
published contract also serves is refused. Core moves to a57ef6ce.

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

The module-contract kit renders through this CLI again: c18e661 shipped with
the kit's foreign-methods fixture naming a principal the render refuses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
grpcio, which the *_pb2_grpc stubs check at import against the grpc_tools
the companion pins (1.71.0); on the proto-sources path, the shared modules
the contract imports (googleapis-common-protos), as the descriptor-set path
already did. A dependency counts as declared by its distribution name, so a
developer's own pin is kept. buf/validate maps to no distribution: none on
PyPI ships it, and the companion (core) now drops an import used only for
an option. Core pinned to the companion 0.0.17 commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
antoinetoussaint-byte pushed a commit to codefly-dev/authority that referenced this pull request Oct 24, 2026
Generated with the companion 0.0.17 (codefly-dev/cli#1128): its bindings
import only google.protobuf, grpcio and googleapis-common-protos, so a Python
module can ask the authority to Issue its context.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AntoineToussaint and others added 10 commits October 24, 2026 13:41
A method bound with google.api.http is listed under each route,
"<VERB> <template>", with the method's own policy, so the hop's HTTP face
decides a REST call to a proto-declared module by its route without a
second contract. The proto is the one place a module declares both.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
"{name=a/*}" is listed as "a/{name}", "{name=*}" as "{name}" and "{name=**}"
stays, so the authority matches segments and never reads a variable's
sub-template.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…he protos

`--from module/service/endpoint` copied the endpoint's declared Package,
which is empty for every service that declares none in service.codefly.yaml,
and the library's contract was then refused ("package is required"). The
package is settled the way `generate contracts` settles it: the one the
service's own protos declare their services in.

Proven on obin-ai/module-evaluation (registry/grpc declares no package):
go, typescript and python clients generated.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The catalog's routes[].path joined the group's path and the route's, which
core already holds to start with it: every REST catalog read
"/v1/x/y/v1/x/y". One helper lists the routes for both `generate contracts`
and `generate client`.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A Connect endpoint serves the service's protobuf contract over the Connect
protocol family, so `--from module/service/connect` selects it and builds
the same descriptor set a grpc endpoint does.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…he loader does

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…tor path

Compiled as sources, a vendored copy of codefly/base or authority/hop under
the service's own proto tree was emitted again as the library's own
bindings; the descriptor path marks it as an import with core's rule
(core 95d56f5f: those namespaces are foreign to a Go library). Proven on
the document store: its Go client now carries gen/documents alone.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A `kind: solution` could not be composed through a native run on an authority
that implements codefly.dev/composition: nothing read the solution's roles, so
the authority's document carried none and the host refused the solution for
declaring no installer.

- A solution declares its own kinds and its roles in `roles.codefly.yaml`
  beside its solution manifest (schema codefly/solution-roles/v1): the kinds it
  serves under `scope_ceilings`, in the module contract's spelling, and `roles`,
  each a name and the scopes it grants within those kinds, one of them
  `installer`. Neither existing file could carry them: core's module contract
  has scope ceilings and no roles, and a composed solution asks for authority
  from its solution manifest, not a contract; core's solution manifest's
  `permissions` are what a solution requires, not what it grants a person; the
  host's `permissions.codefly.yaml` is one host's vocabulary contribution with
  no roles. The declaration folds into core's module contract when core's full
  manifest carries roles.
- `SolutionRoles` reads it strictly and refuses by name, naming the file: no
  installer, no roles, no kinds, a role beyond the kinds' actions or on an
  undeclared kind, a role named twice, granting nothing or not a name, a kind
  named twice or with no action, another schema, an unknown key.
- The render names the declared kinds in the core manifest's authority block
  (the authority's document ceils and grants roles only on kinds the core
  manifest names); the delivery carries the kinds as scope ceilings and the
  roles in `AuthorityManifestV1.roles` (authority 39f45e9d); the launcher wires
  the reader beside MethodPolicies and ScopeCeilings.

Tests: the declaration is read as written and refused by rule; the signed
document carries the roles; a scoped and an unscoped solution name their kinds
in the manifest and a broken declaration fails the render. go test ./pkg/gitops/
./cmd/run/ green.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@antoinetoussaint-byte antoinetoussaint-byte changed the title run: a native run delivers through codefly.dev/composition when the host implements it Deliver through composition and validate generated permissions before execution Oct 25, 2026
AntoineToussaint and others added 2 commits October 24, 2026 22:10
…l endpoint

--naming-scope resolves every address in the scope the run uses, with
`codefly run`'s rule: omitted keeps the environment's declared scope, an
explicit empty value clears it. Local addresses now come from
common.ResolvePreferredNative, so a live run of that scope answers with its
concrete allocation and the static hash stays the offline fallback.

--call-endpoint <module>/<service>/<endpoint> names a declared HTTP-based
endpoint (parsed by core's ParseEndpointReference, loaded from the
workspace) every prepared call is sent to instead of the owner's listener:
the composition's hop. It is applied only after the owner's served Connect
surface and published contract are verified, and moves only call.address;
operation, procedure or REST route, contract, digest and policy stay the
owner's. EncodePrepared/VerifyPrepared are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The default output was <module>/pkg/gen/permissions, outside every Go
module, so no service could import it without --output.

Each Go service now gets its own table at
<service>/<source-dir>/pkg/gen/permissions: source-dir is core's Go agent
setting (golang.GoAgentSettings, "code" by default), its module root from
golang.SplitSourceDir is where go.mod lives, and pkg/gen is the tree the
go-grpc layout generates its bindings into. A service's table holds the
methods its own published contracts serve (gitops.ServiceMethodPolicies,
which MethodPolicies is now built on) plus the module contract's foreign
methods, which name no service. TypeScript stays beside the Go file: no
generator places TypeScript per service. A service that publishes a
contract with no go.mod at its Go source root fails by name. --output
still writes the whole module's table to one directory; --check with no
flags checks every default destination.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
antoinetoussaint-byte and others added 9 commits October 25, 2026 09:03
The environment's `egress:` block named each service's external hosts
for the cell file alone, so a service that admits only its declared
hosts (a mesh egress guard) had to keep a hand-written copy of the list
in an authored group.

A service that declares the `egress` workspace configuration group now
receives `egress/HOSTS`: its own declared hosts as comma-separated
host:port, sorted, every port explicit (the list the cell file carries),
or empty when the environment declares none for it. The shared
resolution generates it, so a native or container run and a render
deliver the same value. Like the other CLI-owned groups it is never a
manager dependency, an authored file for it is refused by the render, a
run profile can exclude it, and `doctor workspace` reports it as
generated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ts service carries

A solution backend serves plain HTTP (the runtime finds its own port by the
`http` endpoint), and the authority holds each of its routes to the
"<VERB> <template>" rows the CLI derives from a published OpenAPI contract's
x-codefly-authority-policy. `generate contracts` wrote that contract only for
`rest` endpoints, so no solution route could be delivered a policy.

An `http` endpoint whose service carries openapi/api.swagger.json (core's
standards.OpenAPIPath, where a rest endpoint's document lives) now exports it
as its contract, through core's REST loader and the rest writer: the same
openapi.json, catalog routes and package api-contracts entry, so the route
policy rows are derived for a solution exactly as for a rest module. No agent
is loaded for it: an http endpoint reports no API details at Load. An http
endpoint whose service carries no document is still skipped, said so.

Docs: commands.md and the generated reference say what the document is for.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…root it lacks

A package manifest without the contracts artifact root made `generate
contracts` print only "module contract negotiation failed" unless --debug
was set, and only after it had rewritten the manifest.

Two causes, each fixed where it lives:

- Plain-mode error display showed the innermost layer alone. A sentinel
  wrapped as fmt.Errorf("%w: reason", ErrX) is innermost, so the reason
  was dropped. actionableRoot now shows the layer above when it reads
  "root: ...", so every composition.ErrContract refusal keeps its reason.
- generate contracts now checks, before the catalog or the manifest is
  written, that the manifest's artifact-roots cover every contract path it
  records. The returned error wraps composition.ErrContract and names the
  manifest file, the root to add, and the uncovered contract path.

Tests: TestGenerateContractsNamesTheMissingArtifactRoot (error names the
manifest, the root and the path; manifest untouched) and
TestActionableRootKeepsTheReasonASentinelWasWrappedWith. Both fail on the
previous code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Three interfaces one endpoint implements (the authority, session and
installation interfaces on saas accounts' Connect endpoint) bind three
dependencies to one producer. GetDependenciesNetworkMappings appended the
producer's mappings once per dependency, and core refused the second copy:
"service dependency saas/accounts received duplicate endpoint name".

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

A host service implementing codefly.dev/composition on one endpoint (saas
accounts on connect) was sent every manifest through ApplyManifest even
when host.delivery names its signed REST route, and ApplyManifest there is
internal: "the host refused the module manifest of tracing through the
composition interface: PermissionDenied: internal service credential
required". HostImplements now judges the delivery endpoint, for the
delivery path and the policy preflight alike.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In a run, the host gateway's own startup carriers already skip a route
that cannot be resolved and report it. A module's delivery did not: one
solution consuming an endpoint the module no longer declares (the wiki's
documents/documents/rest, gone with the module's REST face) failed the
whole manifest, so the host never learned the module. A run now warns
and delivers without that route; a render still refuses it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A local run reported every host route with no mapping as "this run has
not allocated <producer>'s address yet", including a route to an
endpoint the producer no longer declares, which no allocation will ever
answer. The run now reads the producer's declared endpoints first: a
declared one still waits on its address; an undeclared one is refused
as `<producer> declares no endpoint named "<endpoint>"`, as a render
already says, and a producer whose endpoints cannot be read says so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@antoinetoussaint-byte antoinetoussaint-byte added the working Claimed by a lazybox agent; cleared when the session ends. label Oct 25, 2026
@antoinetoussaint-byte

antoinetoussaint-byte commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor Author

lazybox has finished working on this. codex (o3v4x6448qzrr2qh5
└ #11 exporting to client directory
#11 copying files 83B done
#11 DONE 0.0s
+ 41 lines (⌃t to expand)
• Ran python3 - <<'PY' …
└ (no output)
+ Show details
• All four affected suites pass: cmd/run, pkg/solutionrun, pkg/gitops, and pkg/composition. The CLI build and whole-repository go vet pass too.

The real Docker qualification is progressing slowly—the first tiny context copy took over four minutes—but it has reached the owner build command. I also narrowed source exclusions so a sibling dependency’s shipped dist remains available; only this frontend’s output is excluded.

› Ask Codex to do anything

GPT-6-Astra · high) held it from 2026-10-25 15:55 UTC until 2026-10-26 12:13 UTC. The working label has been removed; this comment is the record.

claim detail
Lazybox-Claim-Device: effacd542b611010656e
Lazybox-Claim-Session: ab6003d111
Lazybox-Claim-Workspace: github-codefly-dev-cli-1128
Lazybox-Claim-Agent: codex
Lazybox-Claim-Model: o3v4x6448qzrr2qh5
  └ #11 exporting to client directory
    #11 copying files 83B done
    #11 DONE 0.0s
    + 41 lines (⌃t to expand)                                                                                                                                         
• Ran python3 - <<'PY' …
  └ (no output)
    + Show details                                                                                                                                                    
• All four affected suites pass: cmd/run, pkg/solutionrun, pkg/gitops, and pkg/composition. The CLI build and whole-repository go vet pass too.

  The real Docker qualification is progressing slowly—the first tiny context copy took over four minutes—but it has reached the owner build command. I also narrowed    source exclusions so a sibling dependency’s shipped dist remains available; only this frontend’s output is excluded.


› Ask Codex to do anything

  GPT-6-Astra · high
Lazybox-Claim-Started: 2026-10-25T15:55:25Z
Lazybox-Claim-Heartbeat: 2026-10-26T12:13:14Z
Lazybox-Claim-Expires: 2026-10-25T19:54:03Z
Lazybox-Claim-Released: 2026-10-26T12:13:14Z

Fixes at the catalog publication and configuration owners. The generated listener inventory may span protobuf packages, including all 14 host procedures. Validate it through Core rather than filtering by one owned package; reject missing catalogs for multi-package policy delivery.

Pins Core 4e7f8ef01ed2 for additive workspace configuration extensions, named key conflicts, explicit env-list append and YAML map/list assembly. Reuses the existing profile reader, key matching, origin tracking and listener inventory; no second runtime configuration resolver or domain-specific role merger.

Docs: docs/commands.md and regenerated docs/cli-reference.md in this commit. Regressions fail before the fixes. GOWORK=off tests pass for cmd/generate, pkg/generators, cmd/config, cmd/environment, pkg/orchestration and pkg/gitops; go vet ./..., reference check and isolated CLI build pass. Core configurations, composition and resources tests and go vet ./... pass. No live deployment or SaaS contract regeneration was exercised.
Fix at the native delivery integration owner. Reuses the deployed frontend builder and the owner package.json build script, BuildKit content caching, canonical archives and the artifact cache. No second builder, hand-written frontend command or parallel cache receipt is introduced.

Native builds snapshot current Git-selected source, including edits and sibling packages, without old frontend output or node_modules. Build failures and missing manifests refuse by component name with build output; stale dist is never a fallback. Docs: docs/commands.md and docs/module-manifests.md.

The regression reproduces the original missing-mf-manifest refusal before repair. GOWORK=off tests pass for cmd/run, pkg/solutionrun, pkg/gitops and pkg/composition; go vet ./... and an isolated CLI build pass. Real Docker qualification proves unchanged inputs reuse a random build marker and a source edit invalidates it; the deployed builder qualification also passes. The final local-source adjustment was rechecked with both local suites, vet and the real cache test. No full platform-obin run, live host admission or browser rendering was exercised. PR #1135 overlaps only in deployed builder selection; this change reuses the existing frontend build seam.
Fix at the native launcher and projection owners. Poll every five seconds and renew each projection when at most 20% of its lifetime remains, using wall time without a monotonic component so laptop sleep counts. Track successful issuance conservatively; failed writes remain due, report the workload and underlying reason in the run log, and do not prevent other renewals.

Reuses Core's native issuer, lifetime, atomic credential writer and Wool logging. No JWT parser, second issuer or token cache is introduced. Documentation: docs/module-manifests.md.

Validation: affected identity and run suites, including race checks; wall-clock jump, threshold, partial failure, logged reason, next-poll retry and cancellation regressions. Restoring the old timer fails the retry regression. Repository-wide go vet, generated reference check and isolated CLI build pass. No real laptop suspend or live Robin scoring flow was exercised.

Branch lint follow-up uses os.Root for frontend staging writes as well as reads, avoids catalog value copies, and removes shadowed errors. Full golangci-lint reports zero issues. The affected GitOps, solutionrun and orchestration suites also cover these changes.
The Go and native gates failed before compilation because the reader-app ID and key are not configured. Reuse the existing organization GH_PAT already used for companion checkout and publication, passing it only to the existing repository-scoped module downloader/bootstrap. Missing credentials still refuse; no test, requirement or permission check is skipped. Apply the same authentication fix to companion and release downloads.

Pin the coordinator's Core PR #835 revision 88f4434c68c749c03b88b80e83150cff69643b74. Docs: docs/development.md and the install action input contract. Actionlint and shell syntax checks pass; Go validation and hosted CI will verify the new pin and configured credential.
GitHub's merge build failed because main's new rotation path still called generatorFormat after this PR moved encoding/default resolution to EnvironmentSecretGenerator.Encoding. Use the shared owner for rotation too. Preserve current main's already-landed changes without rewriting this PR's history.

Docs: docs/deployment-secret-safety.md. Deployment-secret, environment, deploy-command and environment-command suites pass on the combined tree, as do go vet ./... and generated CLI reference verification. No gate is skipped or allowlisted.
@antoinetoussaint-byte
antoinetoussaint-byte marked this pull request as ready for review October 25, 2026 18:43
@antoinetoussaint-byte
antoinetoussaint-byte added this pull request to the merge queue Oct 25, 2026
Merged via the queue into main with commit 672416b Oct 25, 2026
16 checks passed
@antoinetoussaint-byte

Copy link
Copy Markdown
Contributor Author

Pushed ba150660 and efb61fd1 to the existing delivery/through-the-composition-interface branch, preserving coordinator 625e66f1. #1128 was already merged; these new commits are not on main merely because they share that branch. No second PR opened. Coordinator: integrate these commits with the agreed merge-commit delivery flow.

The first fix resolves generated native federation before requiring an authored group, preserving authored secrets and validation. The second uses Core main e501's runtime prerequisites, selected Start participants and the existing signed delivery/identity mechanisms to admit declarations before dependent Start, remove failed-attempt readiness, and fence stale completions. It preserves the coordinator's wall-clock refresh and frontend preparation. Classification: fixes at the CLI lifecycle/configuration owner; no parallel scheduler or issuer. Documentation: docs/module-manifests.md.

Focused reconciled race checks, affected vet and golangci-lint pass. Independent architecture/Go reconciliation review found no new blocker. A lint-only local-variable rename followed that review and passed targeted race checks. Normal-dependency build uses merged Core e501, no replacement. The live binary predates only that variable rename.

Normal make playground with the rebuilt isolated CLI now starts Runtime890e4f7 + Records43a7968 + Authority69b71f0 in scope rtpg. Browser verified developer sign-in, three real cards, revision/receipt history, own/org execution history, catalog, and empty interaction/trigger states. No Documents or paid providers started; unknown-outcome task never retried. This is startup/read-path evidence, not new-effect, deployment, all-mode or full cancellation/extension qualification. Existing controlled lifecycle tests cover failure cleanup; the broader limits remain in startup-coordinator-reconciliation-review.md.

I am continuing Runtime's hosted Authority consumer migration on #311. Authority #1 remains at69b71f0 pending Documents reader adoption and SaaS effective-scope/ParentLimits evidence already handed to their owner.

@antoinetoussaint-byte

Copy link
Copy Markdown
Contributor Author

Follow-up is pushed on the existing branch delivery/through-the-composition-interface: eee37c1. No new PR was opened; #1128 was already merged before these follow-ups. Coordinator must integrate the branch through the existing delivery flow, preserving one PR per repo and merge commits only.

This pairs with Authority authority/vision cac1f6b3dcb6c9bca8a6fa7ee3f8135b8f5175ae (routing cc6ac29 plus shared mesh transport repair). CLI go.mod pins the published Authority client and hop library at that commit, with no replacement. The new hop requires the matching CLI-generated hop-routes group, so adopt them together.

Generated routes use existing Core configuration, module closure, service dependency/visibility, address resolution and cell-consumer seams. Actual watcher admission rejects changed catalogs before Stop; local and remote Init preserve previously accepted mappings when a changed address is refused. Documentation is in docs/orchestration.md. These are owner integration fixes, not a second graph or permission evaluator.

Clean dependency validation (GOWORK=off, no temporary modfile): full orchestration race passed 77.095s; gitops race passed 141.022s; cmd/run race passed 5.437s; vet passed; pinned golangci-lint reports zero issues; CLI reference passed; CLI built to /tmp/codex-service-routing-cli without replacing the shared executable. Earlier independent reviewers reproduced and then verified closure of run-closure, cell consumer, watcher and mapping-publication defects. Incoming Authority transport work was retained and corrected at its owner for the handbook mesh assertion.

Still unqualified: an actual multiservice composition on these pins, live mesh, SaaS parity, semantic catalog-to-artifact membership in Core's load-time validator. No Robin edit, Documents startup or paid provider call. The existing Runtime rtpg stays alive on its earlier accepted pins; no effect task was retried.

Full local handoff: /Users/antoine/.lazybox/v2/github-obin-ai-handbook/context/.lazybox/artifacts/CODEX-ROUTING-HANDOFF.md . Runtime CI remains separately blocked by reader App GET /repos/codefly-dev/authority/installation returning 404; an org administrator must give that App access to the private repository.

antoinetoussaint-byte added a commit that referenced this pull request Oct 25, 2026
…after the #1128 squash

Brings in ba15066 (native host federation), efb61fd (pre-start admission of
selected workloads) and eee37c1 (hop routes through composition
configuration; authority at cac1f6b). 625e66f's tree is the squash 672416b,
so only those three commits' changes are merged.

Conflicts are resolved keeping both sets of fixes:
- One composition connection per run (compositionHost) instead of the
  per-attempt CloseTransport.
- A ready delivery builds its frontend before the delivery lock. Admission
  builds nothing and keeps the payload already published.
- nativeHostServices uses the fail-closed HostImplements.
- NativeWorkload.Declared/DeferFrontend and the runtime-start seam are kept,
  now that admission consumes them.
- The admission tests name the host's delivery endpoint.
- All three authority libraries are pinned at cac1f6b.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
antoinetoussaint-byte added a commit that referenced this pull request Oct 26, 2026
Since #1128 preserved a template's declared inputs, a caller --path was added
beside them. buf applies --path to every input, so a template with two inputs
(module-document-store: its own protos and ../proto-deps) failed with "no
.proto files were targeted" for the input that does not hold the path, and
the store's runnables agent fell back to v0.1.212. A caller's --path names
files of --proto, so it now selects --proto as the positional input, which
replaces the template's inputs as buf defines; with no --path the template's
inputs are used as declared.

Tests: the invocation for a two-input template with a caller path (unit), and
the store's layout through the pinned companion (fails on main with the
store's error, passes here). Reproduced and fixed on module-document-store
authority/behind-the-hop: tools/generate-service-proto.sh fails on main
(5536d73) and leaves the committed output byte-identical with this build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@antoinetoussaint-byte antoinetoussaint-byte removed the working Claimed by a lazybox agent; cleared when the session ends. label 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.

2 participants