feat(model): type the plugin operation binding on Approval - #6
Conversation
Spec §9.3 binds a host-risk approval to the exact code and inputs that produced its plan: plugin id, version, artifact digest, service, method, request hash, and the full target set. The server had somewhere for only two of those — Plugin and a singular NodeID — so the rest had to be smuggled into the free-form Plan string and recovered by hashing it. Give them real columns. Each is compared to live state at execute time and each is what the operator's review is accountable for, so each should be a typed field, not a value parsed back out of a blob. ApprovalView carries them too, so a reviewer sees what will actually run — which plugin version, which artifact, which nodes. Every field is omitempty and additive: an approval that is not a plugin operation (nft, dns, agent update) serializes exactly as before, and NodeID stays the first target so the per-node approval machinery is unchanged. Tests: model build + proto contract test green.
|
[ack] — zeus review, Olympus TASK-0001 item 4 (sdk half) (2026-07-26) Six additive Note on record: the columns were applied a second time on the sdk |
|
Closed as landed — zeus, operator-approved sweep (2026-07-26, rules/01 §8.5): commit |
Adds typed columns to
model.Approvalfor the Bundle V2 §9.3 host-risk operation binding, so the server can bind an approval to the exact code and inputs that produced its plan without stuffing them into the free-formPlanstring.What
Six additive,
omitemptyfields onApproval:plugin_versionartifact_digestservice/methodrequest_sha256targetstargets[0])Same fields added to the
ApprovalViewproto message (15–20) and the proto contract test, so the wire type carries the binding and a reviewer sees which plugin version, which artifact, which nodes will actually run.Why typed columns instead of a hashed blob
The server's first cut at §9.3 (lattice-server #12) put this tuple inside the
Planstring and relied on the plan hash to bind it. That works, but it makes the binding a property of "the hash of a JSON blob" rather than of individual fields. Typed columns let each field be compared to live state directly at execute time — which is exactly what §9.3 step 3 asks for — and make the binding legible in the audit trail and the review UI.Compatibility
Every field is
omitemptyand additive. An approval that is not a plugin operation (nft, dns, agent-update) serializes byte-identically to before, andNodeIDis unchanged, so the existing per-node approval machinery keeps working.Consumed by
lattice-server's §9.3 rework points its
go.modat this branch's commit and switches from the envelope-in-Plan approach to these typed fields. Re-point to the tagged SDK release before merge.Test plan
go build ./...+go test ./...(model + proto contract) greenhttps://claude.ai/code/session_01FzYExyy6G7Cb7QpXoUEY78