Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# Contributing

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).
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).

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.

Expand Down
20 changes: 11 additions & 9 deletions UPSTREAM.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
},
"files": {
".gitignore": "a7079e923a776f14f1bb3a6aa0a11a133a8e1dfb35af020f327623357b7e3957",
"CONTRIBUTING.md": "e937fe6f4cedacad98619d49538da76a0543f95990b2d51db271ffd03bcc1280",
"CONTRIBUTING.md": "b55a6677dc3d5180d97b25564268ae62e660633158ae6319210d78a7b7079959",
"README.md": "125b47671a68556df382f19756fb61fa18925606cbbaf54d6bc9df8872b36870",
"assets/boatstack-journey.svg": "e465befc50c8ce30f3e07e8fd97012931beeb053392c8fbf38ad645023b3cc63",
"assets/boatstack-mark.svg": "be1f984da1bfa69fa5d1f986d8343d21f7e20921b71db888c928b4d2e54b09b5",
"assets/boatstack-portability.svg": "66dfdfa85db857b3bd18b32047a6975f1fbbfc4dc091158e8277193f9969a346",
"boatstack/AGENTS.md": "8694b4f13fb8b0553ea065a5bb0fa216aefc69389dfc0e7ad7703d8b81baff4d",
"boatstack/AGENTS.md": "39574398c3c3f82c22077299b45fd46a587926e1c9a35b66998c65ab8a756554",
"boatstack/BUG-worktree-delivery-state.md": "02469cf51c3849dad5743783e248e5c04583e4240507fbef0e3f890cd6a95724",
"boatstack/SKILL.md": "7c7b3568d836cb176c92762a8315fa834cd61a531a629c97a5cd98d6f7689be0",
"boatstack/agents/gemini.yaml": "cbf43b387399e456fa6178f86d83e6e35567e6142ff800f8de6ffca306fa963e",
Expand All @@ -40,14 +40,15 @@
"boatstack/capture_test.go": "63fa1177738081f1e862364d7a4257f5e259f8e9c36276ba1775b8085b277105",
"boatstack/changelog.go": "6b06be7cd9738de29ba6e87aa2569f3b027a2e618b04524f5abd7abaa17945bf",
"boatstack/changelog_test.go": "ce792f23a7fe1e09fb3096cd1314130a6ab69321d4877b12a8e994027541baf7",
"boatstack/cmd/boatstack-helper/main.go": "e5eea92ddc73622566c4b66b3d99c63b998268617f7b3fa77be953f75a971a75",
"boatstack/cmd/boatstack-helper/main.go": "a388d8b607475350fe8989c096a54caad944273969c64f83e0ae15d8fbd2d6f0",
"boatstack/cmd/boatstack-helper/main_test.go": "ff73003b6a5157202fa09ddf1129fb13c3d79702b2e05a8721ce5a11bf5ab779",
"boatstack/command.go": "4726ac515dedab4947be7eb48f88c6cb8b53d674124504b69f03e6396b080ee8",
"boatstack/command_test.go": "9f707abba3640add81c3e97ba7e72fedbf98f3394b1c060a9ca4b4a28e919968",
"boatstack/config_documentation_test.go": "0632366edc5e88145bb080083ea03c6515da07b0162ce404d63e51bb5bc0774e",
"boatstack/decision.go": "257ca328da6ae19ab252f10ee5d06bd7daf49dd8141d083ab1b32f106ea7a94c",
"boatstack/decision_test.go": "1a92ff832610f9559bd47ccac7fc1755a8b4f8261c35bc72a092830dff05f7c0",
"boatstack/delivery.go": "f7c780d9860e0d5456ecfad5f61242337b2ba1068fceec9eda7232f24374c03c",
"boatstack/delivery.go": "10098124cfb34d0c1d99885b7293ecaccb64c5b5cd80c08f1e2bd1ef43f8a756",
"boatstack/delivery_boundary_conformance_test.go": "800cd722d8d2a696a0529e8343d3523e453bb052f0917c8a2cad2990296ac1b3",
"boatstack/delivery_reactivation_test.go": "573a2dba0034bc4290478414e3bdd8670b06a326128eb0295d77e748ecc8689e",
"boatstack/delivery_test.go": "45c48ff7581c911bcaf821c3e4241d4ae2a9bb4aa682485cc58b6ad8fe1c85bf",
"boatstack/evidence.go": "497a31e6ff632cb1d7c3adfc9f269af3f6aa84e948dd5d417c162767542a27df",
Expand All @@ -71,7 +72,7 @@
"boatstack/mutation_test.go": "68d5049c7f96c1ac558e4c781151f67e8deee2f8d6b9bf293b90d44e769ef7c6",
"boatstack/mutation_undo.go": "697d11b600a276ddbcabe6a9f8040d4f7283e017a0e8fd689ef53a274638946c",
"boatstack/mutation_undo_test.go": "39540e717e3f2136bf975594043a3db9072b28ebe61c6cb0b982cea5e8b1e14e",
"boatstack/next.go": "29644ff0b03974fa9bce290c09695a46282c1fd3ca608c245b6027cf7588529e",
"boatstack/next.go": "07ec5fc7bf26975605fb18477c70bd66a3a1c9ac769d788f3e329c49a3128b25",
"boatstack/next_test.go": "d442d22023831ba39fcfbbf73f1a2da4170a83fc2aab5ce1b44f10cf9d88e173",
"boatstack/operation.go": "62f97bf2091f33eb2ca91915bf08bee73d53387611b673e849355bfd516ca467",
"boatstack/operation_test.go": "2d624eaba342b2c81b45cdf50918a65a9c002b5376a02041b24180658ee6a25a",
Expand Down Expand Up @@ -132,10 +133,10 @@
"docs/benchmark-corpus-audit.md": "f2d206fe8579a514f9da82b2c96c19b343ac004be67617e1bd34f0f8e0e5e6c6",
"docs/benchmark-submission-audit.md": "9518abdd17690729c6423f87cab20418ed47b0915b5faa44b9ef975e9e9c3b79",
"docs/configuration.md": "df054f49d532c8b1b7d94184810d1b3b5bf18cdc30eb985b4b6d0639162e341a",
"docs/evidence-engineered-coding.md": "65056f8f744b7ef5693bad2c3fd8c7f3ebff3989098ee074ede8ebc250bc1373",
"docs/evidence-engineered-coding.md": "dad43a315165883e40d73c428f610480b20d3e9c36830c99bb16762f7ed5afc2",
"docs/generated-files.md": "437791765b0a4015032ae21d1a6618563cad92b7402819e4f963bf5ae16284a3",
"docs/getting-started.md": "f314270c5ed1a55bbef5f3ddbcb5596693dbee9374e5f0d3df8838cefbd68052",
"docs/public-claims.json": "a5923a6b53d922b3d515e64ce91d03ea4c251c7fcb00ef39be6ac0d056b11018",
"docs/public-claims.json": "657bf4734ca4e169e3c1b17054df383f65ab3500dc4af5428d5b36b54a76acd0",
"docs/public-surface.md": "713f7a050b5f339cf948299103ef3800417dccfecf2cc1a4166397ea6f978907",
"docs/research-and-design.md": "8d78678108f0a6c924e1ff9b32c0f81aae9d1f779e0082843b6f99ad993ae2b6",
"docs/safety.md": "7b9b5c515d36e683767ec8d3d9d6d119ac93650b2f629d351deadd4c600ed6a6",
Expand All @@ -149,7 +150,7 @@
"labs/diagram-json/compiled/evidence.md": "1ba1c989ade070a8ef9a508fbd788d100d7292f2dbacbb2bce895468019f619d",
"labs/diagram-json/compiled/tasks.json": "88f60851abf79d851e9fccc754ff3040034ae595306bc87d64784c19eb403e71",
"labs/diagram-json/compiled/test-matrix.json": "424657ff505768e50fa113801fd8363364a18269d5297480907a993d44063a39",
"labs/diagram-json/plan.lock.json": "bb709ce18133d8d49a8b96249bb2e2d534d37f004b01df9027a6c3dd070dcd6a",
"labs/diagram-json/plan.lock.json": "b28d8bb0d854dc65fcd7201920e1dbea95fc7a14afb551fc8c3bdb017216bd45",
"labs/diagram-json/plan.md": "3cc4f533b8d69386deff16b3a594a3ba09d4c0c3db636cccd8c4380084ce6a51",
"labs/diagram-json/questions.md": "74733b015002c8a6777c558e7e997fa48c94850b9bd39054fe9366c97ecf728d",
"labs/diagram-json/request.md": "0808fc41c36779c404f4a3a121167da6e76cac56df526e70f9ed6d3e0d4c02ed",
Expand Down Expand Up @@ -223,6 +224,7 @@
"release-notes/2026-07-23-sync-title-contract.md": "2869d6d084ea60402e57ffe985d0fc4cd83ef9bb09958cc53e349157d3383202",
"release-notes/2026-07-23-visual-evidence-external-host.md": "09edbe5e6e1bfc866cf5ee744a5001d678f7a67f0f330cf43bd5157eedf04276",
"release-notes/2026-07-24-auto-hydrate-missing-runtime.md": "b376f75f7c9132f30b362392e0b31c05715edcef58c14dfa20e1fc0a17836b41",
"release-notes/2026-07-24-discard-delivery.md": "1a11ed133b9abab6f3ef79524feefbf5b2aae85d2b3dc3364cedc7599ec51e5f",
"release-notes/2026-07-24-ignored-deliveries-publication-authority.md": "a25f8469316276101490c79a57c1a236c18072dfbb23682bb1778871d247067d",
"release-notes/2026-07-24-provenance-verified-binary-install.md": "b64f3a8dbd750afb28bf6964489eb0f5f8519efa65fcee871db64b9e60c2fdb2",
"release-notes/2026-07-24-publication-nonblocking-control.md": "2b9d8ea817896783273a843ec183fbf00bb2f7ac420b4ce3409aeda7f59b7fb5",
Expand All @@ -233,7 +235,7 @@
"generator": "operatorstack/intelligence-flow:boatstack-distribution",
"schema_version": 1,
"source": {
"commit": "666b0631c31ee9509a4b3cb0f1242fe865a97c24",
"commit": "c6d00bbcf9defd9df85ead397ec1612efb650aee",
"path": "labs/12-product-engineering-loop",
"repository": "operatorstack/intelligence-flow"
}
Expand Down
104 changes: 104 additions & 0 deletions boatstack/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,107 @@ python3 labs/12-product-engineering-loop/scripts/release_notes.py \

Do not write "no release note required" for a change under this lab — a note is
always required. State which note you added.

## Boundary Conformance Requirement

For every requested change, determine whether it creates, modifies, relies on,
or crosses a system boundary.

A boundary is any point where authority, state, data, effects, trust, or
responsibility moves between components, actors, processes, repositories,
services, or execution stages.

If the change affects a boundary, boundary conformance is part of the definition
of done. If it does not, say so explicitly (`Boundary-conformance impact: none`)
and do not invent artificial tests.

The standing rule, in three lines:

```text
Every boundary implies a control law.
Every control law implies conformance evidence.
Every relevant path must be shown to reach the boundary.
```

### 1. State the control law

Before implementation, describe the boundary and write the invariant it must
enforce, in this form:

```text
Boundary: <where the transition occurs>
Control law: <what must always be true>
Authorized actor: <who may perform the transition>
Required evidence: <what must be verified before acceptance>
Failure behavior: <deny, reject, retry, escalate, or fail closed>
Release condition: <what makes the transition admissible>
```

### 2. Enforce at the correct boundary

Do not only patch the observed symptom. Trace the paths that can violate the
control law and enforce it at the earliest safe shared boundary that closes the
failure class without unnecessary scope expansion.

If the correct fix requires materially broader work, do not silently expand the
change. Ask whether to (1) expand the current delivery, (2) split the shared
boundary into a prerequisite delivery, or (3) apply bounded local containment
and record the remaining risk.

### 3. Add boundary-conformance tests

Tests must prove the control law, not merely exercise the implementation. Add
the applicable classes:

- **Positive conformance** — the authorized actor completes the valid transition
when all required evidence is present.
- **Negative conformance** — unauthorized actors, invalid states, missing/stale
evidence, and malformed requests are rejected.
- **Relation conformance** — every relevant entry path reaches the intended
boundary; test `request → boundary → decision → effect → resulting state`, not
just the component in isolation.
- **Bypass conformance** — the protected effect cannot be reached through an
alternate path that avoids the boundary.
- **Failure-state conformance** — rejection leaves the protected state unchanged
and does not partially apply the effect.
- **Correlation and replay** (where relevant) — request/response identities
match; receipts cannot cross runs; duplicate/reordered events fail correctly;
replay reproduces the original decision; changed policy or evidence invalidates
replay.
- **Idempotency and reversal** (where relevant) — repeating an accepted
transition does not duplicate the effect; stale base state is rejected; a
recorded mutation reverses deterministically when its post-state still matches.

### 4. Map tests to control laws

Every boundary test must identify which control law it proves. Use a name or a
`control-law: <slug>` comment. Avoid tests that pass without demonstrating the
invariant.

### 5. Preserve deterministic authority

The model may propose implementation and tests. The deterministic boundary
decides admissibility. Never treat an LLM assertion, completion claim, or
generated summary as conformance evidence unless policy explicitly allows it.
Prefer exact hashes, repository state, test results, validated schemas,
correlated receipts, deterministic path checks, and authoritative external state.

### 6. Report completion evidence

Before declaring the work complete, report:

```text
Boundary:
Control law:
Affected paths:
Tests added:
Positive case:
Negative case:
Relation or bypass proof:
Failure-state behavior:
Residual risk:
Conformance status:
```

The change is not complete while a material boundary control law remains
untested or unsupported by evidence.
34 changes: 34 additions & 0 deletions boatstack/cmd/boatstack-helper/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,38 @@ func ignoreDeliveryCommand(arguments []string) int {
return 0
}

func discardDeliveryCommand(arguments []string) int {
flags := flag.NewFlagSet("discard-delivery", flag.ContinueOnError)
repo := flags.String("repo", ".", "repository containing the Boatstack installation")
feature := flags.String("feature", "", "feature slug of the delivery whose state should be discarded")
force := flags.Bool("force", false, "discard even a delivery that has published slices (git history and merged PRs are unaffected)")
if err := flags.Parse(arguments); err != nil {
return 2
}
if *feature == "" {
return fail(fmt.Errorf("discard-delivery requires --feature"))
}
result, err := boatstack.DiscardDelivery(*repo, *feature, *force)
if err != nil {
return fail(err)
}
switch result.Action {
case "discarded":
fmt.Printf("PASS: delivery %s discarded; state archived to %s\n", result.Feature, result.ArchivePath)
return 0
case "none":
fmt.Printf("PASS: %s\n", result.Reason)
return 0
default: // refused
if len(result.Published) > 0 {
fmt.Printf("BLOCKED: delivery %s has published slices (%s); %s\n", result.Feature, strings.Join(result.Published, ", "), result.Reason)
} else {
fmt.Printf("BLOCKED: delivery %s: %s\n", result.Feature, result.Reason)
}
return 1
}
}

func doctorCommand(arguments []string) int {
flags := flag.NewFlagSet("doctor", flag.ContinueOnError)
repo := flags.String("repo", ".", "repository whose Boatstack installation should be checked")
Expand Down Expand Up @@ -1221,6 +1253,8 @@ func run() int {
return recordChangeCommand(os.Args[2:])
case "ignore-delivery":
return ignoreDeliveryCommand(os.Args[2:])
case "discard-delivery":
return discardDeliveryCommand(os.Args[2:])
case "record-delivery-gate":
return recordDeliveryGateCommand(os.Args[2:])
case "record-pr-visual-evidence":
Expand Down
Loading
Loading