feat(binding): capture a revision against the binding in force - #53
Merged
Merged
Conversation
`binding capture` now revises when the device holds a binding in force. The prior document comes from the runtime's `commissioning binding-export`, or from a signed envelope named by --revise when preparing away from the device. Either way it is bound to the inventory's account of the binding in force before a question is asked. Each recorded fact is shown and the installer is asked only whether it changed. Unchanged zones and fields are carried byte for byte, and the prior value of anything changed is carried into the draft's reason. Before any proof is asked for, capture names the fresh legs the contract requires: for a change to a zone's sensor, its actuator identity or its mapping, for a rename onto another retained zone's name, or for a declared like-for-like replacement. A leg not redone is recorded undemonstrated (the circuit leg) or left absent (the control leg), never carried onto a changed zone. A revision needing fresh legs on a line the binding in force still drives is refused as soon as the change is declared, since the proof operation cannot claim a line an active zone owns. The draft is checked against the retained state with the same revision rule the runtime applies, so a document the runtime would refuse is refused before it is written. The Go verifier follows the restated rule: every claimed leg is held to its own retained time, zones are matched by name, actuator or sensor, and a rename is held to the zone whose name it takes. The corpus and the published misreading table are vendored under the manifest. The adequacy test builds its rule and misreadings from that table and fails unless every misreading gets some vector wrong. A seeded test compares the table's reference rule with the production verifier, and an in-suite check holds every vendored file to its manifest digest.
13 of 19 tasks
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 free
to 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.
What does this PR do?
It completes the revision half of the commissioning ceremony. When a clamp is recalibrated, a contactor replaced or a polarity corrected,
binding capturecurrently treats the site as new: it asks every question again and learns about fresh proof only from the runtime's refusal after the document is signed.With this change,
binding capturerevises when the device holds a binding in force:commissioning binding-export.--revise <file>(or-for stdin) names a signed envelope for preparing a revision away from the device. Either prior must match the inventory's account of the binding in force, bybinding_seqand canonical hash, before any question is asked.reason.capturenames the fresh legs the contract requires. That is required for a change to a zone's sensor, actuator identity or mapping, for a rename onto another retained zone's name, and for a declared like-for-like replacement. A circuit leg not redone is recordedundemonstrated, and a control leg not redone is left absent. Neither is ever carried onto a changed zone.The Go verifier follows the restated rule in ori-platform/ori-specs#201:
The corpus and the published misreading table are vendored under the manifest, and three tests guard them:
The vendored files are pinned to ori-platform/ori-specs@7d9a6e8, the merge of ori-platform/ori-specs#201, and
scripts/refresh-binding-vectors.shreports them matching. This merges after ori-platform/ori-runtime#642.Type of change
feat- new CLI command, output mode, bridge integration, or operator workflowfix- bug fix or command behavior correctiondocs- documentation onlytest- tests onlyrefactor- no behavior changesecurity- touches tokens, deploy keys, credentials, or local runtime authoritycontract-change- changes bridge, output JSON, cloud, Hub, or SDK contract usageRequired checklist
go test ./...passesgo vet ./...passes.gofile has the Apache-2.0 license header--output jsonis supportedCLI authority and safety checklist
ori.yamlindependentlyExternal integration checklist
If you used AI assistance
Related issue
Refs #34. This delivers the revision criteria: capture against the binding in force, fresh proof named before the installer begins, and tests for text and JSON output including every refusal. #34 stays open for profile activation, which waits on the runtime's safety-registry cutover.
Depends on ori-platform/ori-specs#201 (the contract) and on ori-platform/ori-runtime#642, which adds
commissioning binding-export.Testing notes
go vet ./...andgofmtare clean.go test -p 1 ./...passes. Under default parallelisminternal/bridgecan time out, which is internal/bridge fails under go test ./... but passes alone #46 and unrelated to this change.