Skip to content

Commit 8f9b2ba

Browse files
Sync Boatstack from Intelligence Flow Labs @ c6d00bbcf9de (#96)
Co-authored-by: operator-stack-publisher[bot] <operator-stack-publisher[bot]@users.noreply.github.com>
1 parent 1858db8 commit 8f9b2ba

11 files changed

Lines changed: 654 additions & 34 deletions

File tree

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
# Contributing
44

5-
Boatstack is a generated content distribution. Propose changes to workflow semantics, templates, evidence rules, or generated presentation in [Intelligence Flow](https://github.com/operatorstack/intelligence-flow/tree/666b0631c31ee9509a4b3cb0f1242fe865a97c24/labs/12-product-engineering-loop).
5+
Boatstack is a generated content distribution. Propose changes to workflow semantics, templates, evidence rules, or generated presentation in [Intelligence Flow](https://github.com/operatorstack/intelligence-flow/tree/c6d00bbcf9defd9df85ead397ec1612efb650aee/labs/12-product-engineering-loop).
66

77
The Boatstack repository receives product/runtime changes through a generated pull request. Review the PR's `UPSTREAM.json`, tests, adapter diff, and context-size change; do not hand-edit generated output on `main`. `.github/workflows` is the exception: it is Boatstack's executable control plane, excluded from scheduled projection and changed only through a separate manually reviewed Boatstack PR.
88

UPSTREAM.json

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212
},
1313
"files": {
1414
".gitignore": "a7079e923a776f14f1bb3a6aa0a11a133a8e1dfb35af020f327623357b7e3957",
15-
"CONTRIBUTING.md": "e937fe6f4cedacad98619d49538da76a0543f95990b2d51db271ffd03bcc1280",
15+
"CONTRIBUTING.md": "b55a6677dc3d5180d97b25564268ae62e660633158ae6319210d78a7b7079959",
1616
"README.md": "125b47671a68556df382f19756fb61fa18925606cbbaf54d6bc9df8872b36870",
1717
"assets/boatstack-journey.svg": "e465befc50c8ce30f3e07e8fd97012931beeb053392c8fbf38ad645023b3cc63",
1818
"assets/boatstack-mark.svg": "be1f984da1bfa69fa5d1f986d8343d21f7e20921b71db888c928b4d2e54b09b5",
1919
"assets/boatstack-portability.svg": "66dfdfa85db857b3bd18b32047a6975f1fbbfc4dc091158e8277193f9969a346",
20-
"boatstack/AGENTS.md": "8694b4f13fb8b0553ea065a5bb0fa216aefc69389dfc0e7ad7703d8b81baff4d",
20+
"boatstack/AGENTS.md": "39574398c3c3f82c22077299b45fd46a587926e1c9a35b66998c65ab8a756554",
2121
"boatstack/BUG-worktree-delivery-state.md": "02469cf51c3849dad5743783e248e5c04583e4240507fbef0e3f890cd6a95724",
2222
"boatstack/SKILL.md": "7c7b3568d836cb176c92762a8315fa834cd61a531a629c97a5cd98d6f7689be0",
2323
"boatstack/agents/gemini.yaml": "cbf43b387399e456fa6178f86d83e6e35567e6142ff800f8de6ffca306fa963e",
@@ -40,14 +40,15 @@
4040
"boatstack/capture_test.go": "63fa1177738081f1e862364d7a4257f5e259f8e9c36276ba1775b8085b277105",
4141
"boatstack/changelog.go": "6b06be7cd9738de29ba6e87aa2569f3b027a2e618b04524f5abd7abaa17945bf",
4242
"boatstack/changelog_test.go": "ce792f23a7fe1e09fb3096cd1314130a6ab69321d4877b12a8e994027541baf7",
43-
"boatstack/cmd/boatstack-helper/main.go": "e5eea92ddc73622566c4b66b3d99c63b998268617f7b3fa77be953f75a971a75",
43+
"boatstack/cmd/boatstack-helper/main.go": "a388d8b607475350fe8989c096a54caad944273969c64f83e0ae15d8fbd2d6f0",
4444
"boatstack/cmd/boatstack-helper/main_test.go": "ff73003b6a5157202fa09ddf1129fb13c3d79702b2e05a8721ce5a11bf5ab779",
4545
"boatstack/command.go": "4726ac515dedab4947be7eb48f88c6cb8b53d674124504b69f03e6396b080ee8",
4646
"boatstack/command_test.go": "9f707abba3640add81c3e97ba7e72fedbf98f3394b1c060a9ca4b4a28e919968",
4747
"boatstack/config_documentation_test.go": "0632366edc5e88145bb080083ea03c6515da07b0162ce404d63e51bb5bc0774e",
4848
"boatstack/decision.go": "257ca328da6ae19ab252f10ee5d06bd7daf49dd8141d083ab1b32f106ea7a94c",
4949
"boatstack/decision_test.go": "1a92ff832610f9559bd47ccac7fc1755a8b4f8261c35bc72a092830dff05f7c0",
50-
"boatstack/delivery.go": "f7c780d9860e0d5456ecfad5f61242337b2ba1068fceec9eda7232f24374c03c",
50+
"boatstack/delivery.go": "10098124cfb34d0c1d99885b7293ecaccb64c5b5cd80c08f1e2bd1ef43f8a756",
51+
"boatstack/delivery_boundary_conformance_test.go": "800cd722d8d2a696a0529e8343d3523e453bb052f0917c8a2cad2990296ac1b3",
5152
"boatstack/delivery_reactivation_test.go": "573a2dba0034bc4290478414e3bdd8670b06a326128eb0295d77e748ecc8689e",
5253
"boatstack/delivery_test.go": "45c48ff7581c911bcaf821c3e4241d4ae2a9bb4aa682485cc58b6ad8fe1c85bf",
5354
"boatstack/evidence.go": "497a31e6ff632cb1d7c3adfc9f269af3f6aa84e948dd5d417c162767542a27df",
@@ -71,7 +72,7 @@
7172
"boatstack/mutation_test.go": "68d5049c7f96c1ac558e4c781151f67e8deee2f8d6b9bf293b90d44e769ef7c6",
7273
"boatstack/mutation_undo.go": "697d11b600a276ddbcabe6a9f8040d4f7283e017a0e8fd689ef53a274638946c",
7374
"boatstack/mutation_undo_test.go": "39540e717e3f2136bf975594043a3db9072b28ebe61c6cb0b982cea5e8b1e14e",
74-
"boatstack/next.go": "29644ff0b03974fa9bce290c09695a46282c1fd3ca608c245b6027cf7588529e",
75+
"boatstack/next.go": "07ec5fc7bf26975605fb18477c70bd66a3a1c9ac769d788f3e329c49a3128b25",
7576
"boatstack/next_test.go": "d442d22023831ba39fcfbbf73f1a2da4170a83fc2aab5ce1b44f10cf9d88e173",
7677
"boatstack/operation.go": "62f97bf2091f33eb2ca91915bf08bee73d53387611b673e849355bfd516ca467",
7778
"boatstack/operation_test.go": "2d624eaba342b2c81b45cdf50918a65a9c002b5376a02041b24180658ee6a25a",
@@ -132,10 +133,10 @@
132133
"docs/benchmark-corpus-audit.md": "f2d206fe8579a514f9da82b2c96c19b343ac004be67617e1bd34f0f8e0e5e6c6",
133134
"docs/benchmark-submission-audit.md": "9518abdd17690729c6423f87cab20418ed47b0915b5faa44b9ef975e9e9c3b79",
134135
"docs/configuration.md": "df054f49d532c8b1b7d94184810d1b3b5bf18cdc30eb985b4b6d0639162e341a",
135-
"docs/evidence-engineered-coding.md": "65056f8f744b7ef5693bad2c3fd8c7f3ebff3989098ee074ede8ebc250bc1373",
136+
"docs/evidence-engineered-coding.md": "dad43a315165883e40d73c428f610480b20d3e9c36830c99bb16762f7ed5afc2",
136137
"docs/generated-files.md": "437791765b0a4015032ae21d1a6618563cad92b7402819e4f963bf5ae16284a3",
137138
"docs/getting-started.md": "f314270c5ed1a55bbef5f3ddbcb5596693dbee9374e5f0d3df8838cefbd68052",
138-
"docs/public-claims.json": "a5923a6b53d922b3d515e64ce91d03ea4c251c7fcb00ef39be6ac0d056b11018",
139+
"docs/public-claims.json": "657bf4734ca4e169e3c1b17054df383f65ab3500dc4af5428d5b36b54a76acd0",
139140
"docs/public-surface.md": "713f7a050b5f339cf948299103ef3800417dccfecf2cc1a4166397ea6f978907",
140141
"docs/research-and-design.md": "8d78678108f0a6c924e1ff9b32c0f81aae9d1f779e0082843b6f99ad993ae2b6",
141142
"docs/safety.md": "7b9b5c515d36e683767ec8d3d9d6d119ac93650b2f629d351deadd4c600ed6a6",
@@ -149,7 +150,7 @@
149150
"labs/diagram-json/compiled/evidence.md": "1ba1c989ade070a8ef9a508fbd788d100d7292f2dbacbb2bce895468019f619d",
150151
"labs/diagram-json/compiled/tasks.json": "88f60851abf79d851e9fccc754ff3040034ae595306bc87d64784c19eb403e71",
151152
"labs/diagram-json/compiled/test-matrix.json": "424657ff505768e50fa113801fd8363364a18269d5297480907a993d44063a39",
152-
"labs/diagram-json/plan.lock.json": "bb709ce18133d8d49a8b96249bb2e2d534d37f004b01df9027a6c3dd070dcd6a",
153+
"labs/diagram-json/plan.lock.json": "b28d8bb0d854dc65fcd7201920e1dbea95fc7a14afb551fc8c3bdb017216bd45",
153154
"labs/diagram-json/plan.md": "3cc4f533b8d69386deff16b3a594a3ba09d4c0c3db636cccd8c4380084ce6a51",
154155
"labs/diagram-json/questions.md": "74733b015002c8a6777c558e7e997fa48c94850b9bd39054fe9366c97ecf728d",
155156
"labs/diagram-json/request.md": "0808fc41c36779c404f4a3a121167da6e76cac56df526e70f9ed6d3e0d4c02ed",
@@ -223,6 +224,7 @@
223224
"release-notes/2026-07-23-sync-title-contract.md": "2869d6d084ea60402e57ffe985d0fc4cd83ef9bb09958cc53e349157d3383202",
224225
"release-notes/2026-07-23-visual-evidence-external-host.md": "09edbe5e6e1bfc866cf5ee744a5001d678f7a67f0f330cf43bd5157eedf04276",
225226
"release-notes/2026-07-24-auto-hydrate-missing-runtime.md": "b376f75f7c9132f30b362392e0b31c05715edcef58c14dfa20e1fc0a17836b41",
227+
"release-notes/2026-07-24-discard-delivery.md": "1a11ed133b9abab6f3ef79524feefbf5b2aae85d2b3dc3364cedc7599ec51e5f",
226228
"release-notes/2026-07-24-ignored-deliveries-publication-authority.md": "a25f8469316276101490c79a57c1a236c18072dfbb23682bb1778871d247067d",
227229
"release-notes/2026-07-24-provenance-verified-binary-install.md": "b64f3a8dbd750afb28bf6964489eb0f5f8519efa65fcee871db64b9e60c2fdb2",
228230
"release-notes/2026-07-24-publication-nonblocking-control.md": "2b9d8ea817896783273a843ec183fbf00bb2f7ac420b4ce3409aeda7f59b7fb5",
@@ -233,7 +235,7 @@
233235
"generator": "operatorstack/intelligence-flow:boatstack-distribution",
234236
"schema_version": 1,
235237
"source": {
236-
"commit": "666b0631c31ee9509a4b3cb0f1242fe865a97c24",
238+
"commit": "c6d00bbcf9defd9df85ead397ec1612efb650aee",
237239
"path": "labs/12-product-engineering-loop",
238240
"repository": "operatorstack/intelligence-flow"
239241
}

boatstack/AGENTS.md

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,107 @@ python3 labs/12-product-engineering-loop/scripts/release_notes.py \
6060

6161
Do not write "no release note required" for a change under this lab — a note is
6262
always required. State which note you added.
63+
64+
## Boundary Conformance Requirement
65+
66+
For every requested change, determine whether it creates, modifies, relies on,
67+
or crosses a system boundary.
68+
69+
A boundary is any point where authority, state, data, effects, trust, or
70+
responsibility moves between components, actors, processes, repositories,
71+
services, or execution stages.
72+
73+
If the change affects a boundary, boundary conformance is part of the definition
74+
of done. If it does not, say so explicitly (`Boundary-conformance impact: none`)
75+
and do not invent artificial tests.
76+
77+
The standing rule, in three lines:
78+
79+
```text
80+
Every boundary implies a control law.
81+
Every control law implies conformance evidence.
82+
Every relevant path must be shown to reach the boundary.
83+
```
84+
85+
### 1. State the control law
86+
87+
Before implementation, describe the boundary and write the invariant it must
88+
enforce, in this form:
89+
90+
```text
91+
Boundary: <where the transition occurs>
92+
Control law: <what must always be true>
93+
Authorized actor: <who may perform the transition>
94+
Required evidence: <what must be verified before acceptance>
95+
Failure behavior: <deny, reject, retry, escalate, or fail closed>
96+
Release condition: <what makes the transition admissible>
97+
```
98+
99+
### 2. Enforce at the correct boundary
100+
101+
Do not only patch the observed symptom. Trace the paths that can violate the
102+
control law and enforce it at the earliest safe shared boundary that closes the
103+
failure class without unnecessary scope expansion.
104+
105+
If the correct fix requires materially broader work, do not silently expand the
106+
change. Ask whether to (1) expand the current delivery, (2) split the shared
107+
boundary into a prerequisite delivery, or (3) apply bounded local containment
108+
and record the remaining risk.
109+
110+
### 3. Add boundary-conformance tests
111+
112+
Tests must prove the control law, not merely exercise the implementation. Add
113+
the applicable classes:
114+
115+
- **Positive conformance** — the authorized actor completes the valid transition
116+
when all required evidence is present.
117+
- **Negative conformance** — unauthorized actors, invalid states, missing/stale
118+
evidence, and malformed requests are rejected.
119+
- **Relation conformance** — every relevant entry path reaches the intended
120+
boundary; test `request → boundary → decision → effect → resulting state`, not
121+
just the component in isolation.
122+
- **Bypass conformance** — the protected effect cannot be reached through an
123+
alternate path that avoids the boundary.
124+
- **Failure-state conformance** — rejection leaves the protected state unchanged
125+
and does not partially apply the effect.
126+
- **Correlation and replay** (where relevant) — request/response identities
127+
match; receipts cannot cross runs; duplicate/reordered events fail correctly;
128+
replay reproduces the original decision; changed policy or evidence invalidates
129+
replay.
130+
- **Idempotency and reversal** (where relevant) — repeating an accepted
131+
transition does not duplicate the effect; stale base state is rejected; a
132+
recorded mutation reverses deterministically when its post-state still matches.
133+
134+
### 4. Map tests to control laws
135+
136+
Every boundary test must identify which control law it proves. Use a name or a
137+
`control-law: <slug>` comment. Avoid tests that pass without demonstrating the
138+
invariant.
139+
140+
### 5. Preserve deterministic authority
141+
142+
The model may propose implementation and tests. The deterministic boundary
143+
decides admissibility. Never treat an LLM assertion, completion claim, or
144+
generated summary as conformance evidence unless policy explicitly allows it.
145+
Prefer exact hashes, repository state, test results, validated schemas,
146+
correlated receipts, deterministic path checks, and authoritative external state.
147+
148+
### 6. Report completion evidence
149+
150+
Before declaring the work complete, report:
151+
152+
```text
153+
Boundary:
154+
Control law:
155+
Affected paths:
156+
Tests added:
157+
Positive case:
158+
Negative case:
159+
Relation or bypass proof:
160+
Failure-state behavior:
161+
Residual risk:
162+
Conformance status:
163+
```
164+
165+
The change is not complete while a material boundary control law remains
166+
untested or unsupported by evidence.

boatstack/cmd/boatstack-helper/main.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,38 @@ func ignoreDeliveryCommand(arguments []string) int {
793793
return 0
794794
}
795795

796+
func discardDeliveryCommand(arguments []string) int {
797+
flags := flag.NewFlagSet("discard-delivery", flag.ContinueOnError)
798+
repo := flags.String("repo", ".", "repository containing the Boatstack installation")
799+
feature := flags.String("feature", "", "feature slug of the delivery whose state should be discarded")
800+
force := flags.Bool("force", false, "discard even a delivery that has published slices (git history and merged PRs are unaffected)")
801+
if err := flags.Parse(arguments); err != nil {
802+
return 2
803+
}
804+
if *feature == "" {
805+
return fail(fmt.Errorf("discard-delivery requires --feature"))
806+
}
807+
result, err := boatstack.DiscardDelivery(*repo, *feature, *force)
808+
if err != nil {
809+
return fail(err)
810+
}
811+
switch result.Action {
812+
case "discarded":
813+
fmt.Printf("PASS: delivery %s discarded; state archived to %s\n", result.Feature, result.ArchivePath)
814+
return 0
815+
case "none":
816+
fmt.Printf("PASS: %s\n", result.Reason)
817+
return 0
818+
default: // refused
819+
if len(result.Published) > 0 {
820+
fmt.Printf("BLOCKED: delivery %s has published slices (%s); %s\n", result.Feature, strings.Join(result.Published, ", "), result.Reason)
821+
} else {
822+
fmt.Printf("BLOCKED: delivery %s: %s\n", result.Feature, result.Reason)
823+
}
824+
return 1
825+
}
826+
}
827+
796828
func doctorCommand(arguments []string) int {
797829
flags := flag.NewFlagSet("doctor", flag.ContinueOnError)
798830
repo := flags.String("repo", ".", "repository whose Boatstack installation should be checked")
@@ -1221,6 +1253,8 @@ func run() int {
12211253
return recordChangeCommand(os.Args[2:])
12221254
case "ignore-delivery":
12231255
return ignoreDeliveryCommand(os.Args[2:])
1256+
case "discard-delivery":
1257+
return discardDeliveryCommand(os.Args[2:])
12241258
case "record-delivery-gate":
12251259
return recordDeliveryGateCommand(os.Args[2:])
12261260
case "record-pr-visual-evidence":

0 commit comments

Comments
 (0)