feat: declare core backing and hold the artifact to the manifest - #2
feat: declare core backing and hold the artifact to the manifest#2lr00rl wants to merge 1 commit into
Conversation
This plugin's manifest declared interface methods its own artifact cannot serve. It worked only because lattice-server routed any service core happened to own, whose publisher string was "latticenet", to an in-core handler. So the manifest claimed one thing, core quietly did another, and no operator or auditor could see the difference. The arrangement itself is right: the engine belongs in core so the trust base stays small (ADR-001 D5), and what this plugin owns is the UI, the validation, and the workflow intent. What was wrong was leaving that implicit. Each service now says `"backing": "core"` in the signed manifest, so who serves a method is a declared, signed fact rather than an inference from a publisher name. The conformance test is the point. It walks every method the manifest declares and probes the artifact: a core-backed method must NOT be answerable here, and a runtime-backed one must be. Flip these declarations to "runtime" and the build goes red on every method — which is exactly what should have happened all along. Nothing caught this before because every suite covered what the artifact DOES, never what the manifest CLAIMS. The artifact is untouched: bundle digest and version are unchanged, and only the manifest's signed metadata differs. Requires a server that understands `backing` — an older one rejects the manifest outright with unknown field "backing".
|
[ack] — zeus review, Olympus TASK-0007 backing family (2026-07-26): |
The old backing-declaration PRs carried the right regression test, but the integration merges only preserved the manifest surface. Add the SDK-era conformance test directly on integration lineage so runtime-backed methods must answer and core-backed methods must remain unserved by the subprocess. Constraint: Zeus verification requested that the #2 backing PR conformance tests make it across before stale PR closure. Constraint: Test-only change must not alter bundle bytes or require signing. Rejected: Merge the stale #2 branch | its request envelope predates the SDK runtime loop and would reintroduce old manifest edits. Confidence: high Scope-risk: narrow Directive: Keep this test aligned with lattice.plugin.call envelope changes. Tested: focused conformance test; go vet ./...; go test -race -cover -count=1 ./... Not-tested: pluginpack/UI, unaffected by _test.go-only change
The stale backing PR carried coverage that integration still needed after the content merges. Land the SDK-era conformance test so runtime-backed manifest methods must be served by the artifact and core-backed methods must stay unserved by the subprocess. Constraint: Zeus requested verification that #2 backing PR conformance tests made it across before stale PR closure. Constraint: This is test-only and must not change signed artifact bytes. Rejected: Merge the stale #2 branch directly | it uses the pre-SDK request envelope and would replay obsolete manifest edits. Confidence: high Scope-risk: narrow Directive: Keep this test aligned with lattice.plugin.call envelope changes. Tested: pending merge-head system-go gate Not-tested: pluginpack/UI, unaffected by _test.go-only change
|
Closing as superseded by integration. Manifest backing is present on integration, and the missing conformance test has now been carried forward in test-only merge 8ee86b2. Verified on merge head: focused TestManifestInterfacesAreServedAsDeclared, go vet ./..., go test -race -cover -count=1 ./... (system-go 83.8%). No digest/signature fields changed. |
What
Each service in this manifest now carries
"backing": "core", and the manifest is re-signed with thelatticenetpublisher key. A newconformance_test.goholds the artifact to what the manifest promises.Why
This plugin declared interface methods its own artifact cannot serve — its backend stops at
planand returnsunsupported actionforcall. It worked only because lattice-server routed any service core happened to own, whose publisher string waslatticenet, to an in-core handler. The manifest claimed one thing; core quietly did another; no operator or auditor could tell.The arrangement is right — the mistake was leaving it implicit. The engine belongs in core so the trust base stays small (ADR-001 D5); what this plugin owns is the UI, validation, and workflow intent. Now that split is a declared, signed fact instead of an inference from a publisher string.
The conformance test is the real deliverable
It walks every method the manifest declares and probes the artifact:
backing: core→ the artifact must not answer it (the engine is elsewhere).backing: runtime→ the artifact must answer it (a payload-validation error counts as an answer;unsupported methoddoes not).Falsification proof: flipping these declarations back to
runtime— i.e. the claim the manifest implicitly made before — turns the build red on every declared method (unsupported action "call"). That is exactly what should have happened all along. Nothing caught it because every suite covered what the artifact does, never what the manifest claims.Safety of this change
bundle.digest_sha256andversionare unchanged — only the manifest's signed metadata differs. CI's rebuild-and-compare digest gate therefore still passes without a rebuild.backingisomitemptyand does not perturb existing signed manifests. Declaring it does change the payload (wireguard: 1107 → 1124 bytes), so the claim cannot be swapped in after signing.Deploy the server first. The loader uses
DisallowUnknownFields, so a server withoutbackingsupport rejects this manifest outright:decode manifest: json: unknown field "backing". It fails closed (the plugin does not load) rather than degrading, but plugins must not be updated ahead of lattice-server#8.Requires: LatticeNet/lattice-server#8.
Test plan
go test ./... -race -count=1insystem-go— greencore; red on all declared methods when flipped toruntimegofmtcleanPart of the 2026-07-14 plugin-boundary architecture review (§4.1).
https://claude.ai/code/session_01FzYExyy6G7Cb7QpXoUEY78