Skip to content

feat: implement the reference host-risk operation flow (§9.3) - #3

Draft
lr00rl wants to merge 1 commit into
feat/declare-service-backingfrom
feat/execute-reference
Draft

feat: implement the reference host-risk operation flow (§9.3)#3
lr00rl wants to merge 1 commit into
feat/declare-service-backingfrom
feat/execute-reference

Conversation

@lr00rl

@lr00rl lr00rl commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Stacked on #2 (feat/declare-service-backing). Gives lattice-server #12 (the §9.3 execute protocol) a real caller, and establishes the shape production plugins copy.

The template said it was runtime-backed but only answered describe/health/plan. It now implements the whole §9.3 flow end to end.

The flow

  1. plan — the plan-effect method returns a PluginOperationPlan (summary, targets, redacted preview, steps, rollback, opaque data). Applies nothing. The server bounds it, authorizes every target, and stores a pending approval with the binding in typed columns.
  2. approve — an operator reads the preview and approves the exact plan hash; the server re-checks every bound column against live state.
  3. execute — the approval executor (and nothing else) invokes the execute action with a one-time grant bound host-side. The plugin never receives the grant.
  4. enqueue — the plugin calls task.enqueue once per approved node. task:run is eligibility; the grant is authorization. The host refuses any task outside the approved plan and applies the operator's own task validation.

What makes it a good reference

  • Never applies directly — the only host-changing path is plan → approve → execute → task.enqueue.
  • Injection-safe — the approval id and node id are single-quoted into the sh command; a test feeds a'; rm -rf /; echo ' and asserts it stays a string literal.
  • Honest conformance — an empty-target plan is a validation error, not unsupported method, so the conformance probe still counts the method as served.
  • Surfaces host refusals verbatim (unapproved node / exhausted grant / kill switch) rather than swallowing them.
  • README documents the flow and the rules a production plugin keeps (redact previews, use the §9.4 secret store, quote interpolations, declare task:run + backing: "runtime").

Artifact + signing

Manifest gains task:run, bumped to 0.2.1-alpha.4 in lockstep with the Go const and ui/package.json, re-packed and re-signed with the publisher key. The new bundle digest was computed with the CI toolchain (go1.26.4 via GOTOOLCHAIN) and verified to equal a deterministic double-pack — I reproduced the previous committed digest byte-for-byte first to confirm my environment matches CI, so the digest gate passes without a rebuild.

Depends on

The runtime side is lattice-server #12. No production deployment ships this execute path until #12 lands — which is the order the spec asks for.

Test plan

  • go test ./... (system-go): describe / health / plan-returns-operation-plan / empty-targets / execute-per-target / host-refusal / injection-quoting / conformance
  • UI npm test + typecheck + build green
  • Double-pack determinism: digest == manifest.bundle.digest_sha256; version parity manifest = ui = go const
  • Manual end-to-end plan→approve→execute against a live server once #12 is deployed

https://claude.ai/code/session_01FzYExyy6G7Cb7QpXoUEY78

The template declared it was runtime-backed but only answered describe/health/plan.
Now it implements the whole §9.3 flow end to end, so a new plugin has a correct
shape to copy and so the server's execute protocol has a real caller.

The plan-effect method returns a PluginOperationPlan — summary, targets, redacted
preview, steps, rollback, opaque data — that the server turns into a pending
approval. The new execute action, which only the approval executor can reach,
enqueues one bounded task per approved target through the task.enqueue host call.
The plugin applies nothing itself and never sees the operation grant: it asks the
host to enqueue, and the host refuses anything outside the approved plan.

The reference is deliberately careful where a real plugin must be: it single-quotes
the approval id and node id into the sh command so neither can break out, it treats
an empty-target plan as a validation error rather than an unsupported method (so the
conformance probe stays honest), and it surfaces a host refusal verbatim rather than
swallowing it. README documents the flow and the rules a production plugin keeps.

The manifest gains task:run, is bumped to 0.2.1-alpha.4 in lockstep with the go
const and ui/package.json, and is re-packed and re-signed: the bundle digest was
recomputed with the CI toolchain (go1.26.4) and verified to match a deterministic
double-pack, so the digest gate passes without a rebuild in CI.

Tests: system-go green (describe/health/plan/execute/injection-quoting/conformance);
UI test + typecheck + build green; double-pack digest == manifest digest.
@lr00rl

lr00rl commented Jul 26, 2026

Copy link
Copy Markdown
Contributor Author

[ack] — zeus review, Olympus TASK-0007 (2026-07-26): the reference §9.3 flow mirrors the server-side semantics I verified in lattice-server#12 (plan applies nothing; execute only via the approval executor's one-time host-bound grant; task.enqueue per approved node under the operator's own task validation). shellSingleQuote uses the standard '\'' escape with a real injection test; empty-target plan is a validation error so conformance still counts the method as served; version lockstep verified three ways (manifest = ui = Go const, 0.2.1-alpha.4); GOTOOLCHAIN digest-reproduction procedure matches the recorded law. Suite green at this head: gofmt/vet clean, go test -race ./... ok.

Manual end-to-end (plan→approve→execute→task on a live server with #12) still owed before any production plugin copies this path — on record in Olympus. Merge disposition: merge-ready behind template#2, lands when this repo's integration branch exists (operator queue); no production deploy of the execute path until server#12 ships in a release.

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