Uh oh!
There was an error while loading. Please reload this page.
feat: add codefly:solution agent kind (#287) - #288
Merged
antoinetoussaint-byte merged 2 commits intoAug 16, 2026
Merged
Conversation
Add the seventh agent kind, codefly:solution — the executor that scaffolds a solution, packages it as an OCI artifact, and renders its manifests into a gitops repository. Mirrors the codefly:provider precedent: dynamically installable, stays out of the application graph, and operates on a codefly-agnostic solution spec. - Registry entry, proto enum value (SOLUTION = 7), and IsSolution(). - Solution executor manifest schema: identity, services, api exposes/consumes, events, ui extensions, needs, permissions, lifecycle — with canonical/digest support for OCI packaging. - Solution proto contract: Create/Update/Package/Render plus GetSolutionInformation. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This was referenced Aug 16, 2026
…on (#287) Review findings from PR #288, in severity order. D1 (the central invariant): the manifest Lifecycle and the proto SolutionCapabilities were two unlinked descriptions of the same fact, with nothing to catch drift — the provider precedent's admission check (runtime advertisement ⊆ packaged manifest) was absent. Add Manifest.AdmitInformation: the advertised manifest digest must equal the packaged manifest's digest, and every advertised lifecycle capability must have been declared in the packaged manifest. A runtime may implement a subset but never advertise an operation the audited manifest did not declare. This closes the silent authorization gap where a host trusting one representation over the other would invoke an undeclared op. D2: Permission.Resource was never validated — an empty or "*" resource loaded clean. Require a bounded resource identifier. Also harden secondary fields the schema left unvalidated (services.name, ui.slot, needs.kind now required) and bound the created/updated/rendered path result lists (max_items), matching the diagnostics fields' existing defensive posture. Align sortedEventDeclarations with its siblings' sort.Slice idiom. D3 (host-enforceable per-method effect/network policy) and D4 (agents.Serve wiring so the contract is servable) are tracked as follow-ups in #289 and #290; the proto now documents each RPC's effect and states plainly that nothing enforces it yet, so "loads and validates" is not mistaken for "enforces". Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This was referenced Aug 16, 2026
Uh oh!
There was an error while loading. Please reload this page.
antoinetoussaint-byte added a commit
that referenced
this pull request
Aug 16, 2026
… per-call ceiling
Review pushback was right: the previous refutations were dodges. Fixing the
real causes.
Finding 2 (no consumer): the host's single agent-connection factory is
agents/manager.loader (grpc.NewClient), and the connection it returns is
long-lived and reused across operations (AgentConn.GRPCConn). The interceptor
was built in a vacuum against neither fact. A ceiling baked in at dial time is
therefore the wrong shape — the ceiling belongs to the operation, which varies
per call over one shared connection. Carry it in the call context
(WithCeiling/CeilingFrom), install EnforcingClientInterceptor in the loader dial
options so it is genuinely wired (no-ops for non-Solution methods, safe on every
agent), and fail closed when a Solution RPC carries no ceiling.
Finding 4 (correlated axes): keeping two axes is only honest if they cannot go
incoherent. Add TestSolutionMethodPolicyAxesAreCoherent asserting registry
network iff registry effect, so an annotation like {OFFLINE, REGISTRY_WRITE}
(push while offline) fails the build instead of being silently accepted by the
ordered ceiling checks.
Finding 5 (reproducibility): verified empirically that committed v1.6.1 and
freshly regenerated v1.6.2 differ only in the header line — bodies byte-
identical — so matching #288's baseline is correct, not a Frankenstein file.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes#287.
Summary
codefly:solution— the executor that scaffolds a solution, packages it (OCI), and renders its manifests into a gitops repo — following thecodefly:providerprecedent: dynamically installable, out of the application graph, operating on a codefly-agnostic solution spec.SOLUTION = 7) +IsSolution(); solution executor manifest schema (identity,services,apiexposes/consumes,events,ui,needs,permissions,lifecycle) with canonical-bytes/digest for OCI packaging; and aSolutionproto contract (Create/Update/Package/Render+GetSolutionInformation).Manifest.AdmitInformation): binds a runtime's advertised capabilities to the packaged, audited manifest — the advertised manifest digest must match and every advertised lifecycle op must have been declared. Mirrors provider's "runtime advertisement ⊆ packaged manifest" invariant, closing the drift/authorization gap where a host trusting one representation over the other would invoke an undeclared operation.Review follow-ups (out of this PR by design)
provider_method_policy). Not added here because there is no host broker to enforce it yet; the proto documents each RPC's effect and states plainly that nothing enforces it.SolutionServerintoagents.Serve()so a plugin can actually expose the contract.Scope note
Core-side registry/proto/manifest slice for the kind. The end-to-end deploy tracer bullet (obin-ai/lodestar#17) and the CLI command group are separate.
Test plan
go build ./...go test ./resources/— registry exhaustiveness + path tests coverSOLUTIONgo test ./solution/...— manifest load/validate, order-independent canonical digest, unknown-field/multi-doc rejection, identity + declaration validation (incl. boundedpermission.resource, requiredservices.name/ui.slot/needs.kind), descriptor-only solution, andAdmitInformation(digest match, subset-ok, undeclared-capability rejection)go test ./agents/ ./policy/ ./standards/greencodefly generate proto --localreproduces the committed generated code (unrelated plugin-version churn reverted)