From 1d700c400027558afb5aef0b0c884b34a60fee14 Mon Sep 17 00:00:00 2001 From: Antoine Toussaint Date: Sun, 16 Aug 2026 20:09:52 -0400 Subject: [PATCH 1/2] docs: record the deferred solution method-policy questions in-code (#297) The four remaining tasks from #295 are cross-repo (the CLI solution command group and the host executor) or consumer-dependent, so they have no substantive code deliverable in core. Give them a durable home next to the enforcement code so closing the tracker loses no context, and sharpen the Ceiling doc that over-stated "provenance": the gate enforces caller-asserted intent, not an authority-derived grant. Co-Authored-By: Claude Opus 4.8 --- solution/policy.go | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/solution/policy.go b/solution/policy.go index 85ac0317..c15f0d5a 100644 --- a/solution/policy.go +++ b/solution/policy.go @@ -11,6 +11,17 @@ // Solution contract has no host-brokered callback path: a plugin's real // filesystem and registry writes are unmediated. Enforcing declared effects // against plugin behavior would require a broker this contract does not define. +// +// Two properties of the gate stay provisional until a real host caller drives +// the lifecycle through Client. The ceiling is caller-asserted intent, not an +// authority-derived grant: the constructors below stop a host from hand-widening +// its own bounds, but nothing yet binds the ceiling to an authorized +// principal/operation/environment at a trusted chokepoint, so the gate prevents +// an honest host's accidental over-reach, not a hostile one's. And the tier +// vocabulary (Inspect/Scaffold/Render/Publish) and Render's REGISTRY_READ reach +// — which assumes the executor pulls the artifact from artifact_reference rather +// than receiving host-resolved local content — are cut to match host operations +// that do not exist in this repo yet; both may need recutting once they do. package solution import ( @@ -34,12 +45,15 @@ const solutionServiceName protoreflect.FullName = "codefly.services.solution.v0. // are at or below the ceiling. // // The fields are unexported and a ceiling is obtained only through the named -// operation constructors below. That gives the ceiling a provenance: a caller -// declares the operation it is performing (inspect/scaffold/publish) rather than -// hand-assembling bounds, so it cannot silently widen its own privilege with a -// struct literal, and the interceptor can never receive an incoherent ceiling -// (e.g. registry network with only read-only effect). The intent→ceiling mapping -// lives here as the single audited chokepoint. +// operation constructors below. That gives the ceiling an intent provenance: a +// caller declares the operation it is performing (inspect/scaffold/render/ +// publish) rather than hand-assembling bounds, so it cannot silently widen its +// own privilege with a struct literal, and the interceptor can never receive an +// incoherent ceiling (e.g. registry network with only read-only effect). The +// intent→ceiling mapping lives here as the single audited chokepoint. Binding +// that intent to an authorized principal is a separate, still-open step (see the +// package doc): the constructor proves which operation a caller named, not that +// the caller was entitled to it. type Ceiling struct { network solutionv0.SolutionNetworkMode effect solutionv0.SolutionEffect From 15e7b8887b0173c6511dde1dca9866651064a59a Mon Sep 17 00:00:00 2001 From: Antoine Toussaint Date: Sun, 16 Aug 2026 20:16:57 -0400 Subject: [PATCH 2/2] docs: state the solution gate's limits as design properties, not status (#297) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The review found the added package-doc paragraph reported cross-repo *status* ("stay provisional until", "nothing yet binds", "still-open step", "do not exist in this repo yet") for work that happens in another repo. No change in core would ever prompt updating it, so it goes false — and actively misleading, right beside the enforcement code — the day the codefly CLI wires a real provenance-derived ceiling. Reshape to the durable design properties instead: the gate enforces caller-asserted intent (not authority), and the tier cut plus Render's REGISTRY_READ vs OFFLINE classification are the consuming host's to establish. Also collapse the re-derived artifact_reference rationale to a pointer at solution.proto, its source of truth, so the two copies can't drift; and align the TestOperationCeilingsAdmitExactlyTheirRPCs comment on "intent-provenance" so the test's vocabulary matches the type doc. Co-Authored-By: Claude Opus 4.8 --- solution/policy.go | 23 +++++++++++------------ solution/policy_internal_test.go | 2 +- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/solution/policy.go b/solution/policy.go index c15f0d5a..bc233445 100644 --- a/solution/policy.go +++ b/solution/policy.go @@ -12,16 +12,15 @@ // filesystem and registry writes are unmediated. Enforcing declared effects // against plugin behavior would require a broker this contract does not define. // -// Two properties of the gate stay provisional until a real host caller drives -// the lifecycle through Client. The ceiling is caller-asserted intent, not an -// authority-derived grant: the constructors below stop a host from hand-widening -// its own bounds, but nothing yet binds the ceiling to an authorized +// Two properties bound what the gate guarantees. First, it enforces +// caller-asserted intent, not authority: the constructors below stop a host from +// hand-widening its own bounds, but the ceiling is not bound to an authorized // principal/operation/environment at a trusted chokepoint, so the gate prevents -// an honest host's accidental over-reach, not a hostile one's. And the tier -// vocabulary (Inspect/Scaffold/Render/Publish) and Render's REGISTRY_READ reach -// — which assumes the executor pulls the artifact from artifact_reference rather -// than receiving host-resolved local content — are cut to match host operations -// that do not exist in this repo yet; both may need recutting once they do. +// an honest host's accidental over-reach, not a hostile one's. Second, the tier +// vocabulary (Inspect/Scaffold/Render/Publish) is shaped by this contract alone: +// its fit to a host's real operations, and whether Render's reach stays +// REGISTRY_READ or becomes OFFLINE (which follows from how the host resolves the +// artifact — see solution.proto), are the consuming host's to establish. package solution import ( @@ -51,9 +50,9 @@ const solutionServiceName protoreflect.FullName = "codefly.services.solution.v0. // own privilege with a struct literal, and the interceptor can never receive an // incoherent ceiling (e.g. registry network with only read-only effect). The // intent→ceiling mapping lives here as the single audited chokepoint. Binding -// that intent to an authorized principal is a separate, still-open step (see the -// package doc): the constructor proves which operation a caller named, not that -// the caller was entitled to it. +// that intent to an authorized principal is a separate concern the constructors +// do not address (see the package doc): the constructor proves which operation a +// caller named, not that the caller was entitled to it. type Ceiling struct { network solutionv0.SolutionNetworkMode effect solutionv0.SolutionEffect diff --git a/solution/policy_internal_test.go b/solution/policy_internal_test.go index b42cbc92..e096e0a2 100644 --- a/solution/policy_internal_test.go +++ b/solution/policy_internal_test.go @@ -36,7 +36,7 @@ func TestAdmitsEnforcesBothAxesAndFailsClosed(t *testing.T) { require.Error(t, admits(create, Ceiling{})) } -// TestOperationCeilingsAdmitExactlyTheirRPCs pins the provenance chokepoint: each +// TestOperationCeilingsAdmitExactlyTheirRPCs pins the intent-provenance chokepoint: each // named operation ceiling admits exactly the Solution RPCs that operation is // allowed to invoke and denies the rest. A drift in the intent→ceiling mapping // (or an RPC's declared policy) surfaces here rather than silently widening what