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/569709dad427c28f7e866a1bd72ca0312d7b2f1b/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/ae167a3ce7759793d4dfbd710eea7ecbbf577058/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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ That is all you need to learn up front. Boatstack shows one next action at a tim

When you return after an interruption, run `/boatstack-next` in Claude Code or Cursor, or `$boatstack next` in Codex. Boatstack reports the repository-verified stage and one next action without changing state; if nothing remains active, it reports **Feature complete**.

`$boatstack run` in Codex or `/boatstack-run` in Claude Code and Cursor drives every verified slice through PR publication. It fetches `origin`, checks branch freshness, and pauses for `a`, product decisions, and `o` or `u`; it never merges or deploys.

In Claude Code and Cursor, that guidance moves through `/plan-gate` → `/build` → `/test-gate` → `/review-gate` → `/ship-gate`. In Codex, use the same operation names after `$boatstack`.

> The diagram shows what Boatstack guides—not a checklist you need to memorize.
Expand Down
31 changes: 17 additions & 14 deletions UPSTREAM.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"canonical_context": {
"characters": 40064,
"estimated_tokens": 10016,
"characters": 41894,
"estimated_tokens": 10474,
"estimator": "ceil(total characters / 4); compactness signal, not provider billing",
"files": [
"product-engineering-loop/references/workflow.md",
Expand All @@ -12,12 +12,12 @@
},
"files": {
".gitignore": "a7079e923a776f14f1bb3a6aa0a11a133a8e1dfb35af020f327623357b7e3957",
"CONTRIBUTING.md": "4512dadf5f809ce83323766bd62b8b85498718273d21a498635bfc0aca1afbc0",
"README.md": "b624739fd939fe1e94c2c75bc5e30f9517214fdd4c518b8830975257cd22f072",
"CONTRIBUTING.md": "fb54f9f378de5d12f0f2f4fdbd8136cfd7c89142966884d26da448973f738eae",
"README.md": "4526095079a7063ca6f4c7db367447c11be607bf86348ba7c5b94f080b7724ec",
"assets/boatstack-journey.svg": "c1f7fe2741f5e9ca66bb3fe9b103e6364ba5acbca8b7a8054768ffd85cf325ea",
"assets/boatstack-mark.svg": "ec96165583b15cfd446c27049d49217973f3e9b1defa5771cc08eec0c9542ce4",
"assets/boatstack-portability.svg": "ce648f5581d16586d25824d3a8132ef1b3d88b73329179173120129d4f74fd24",
"boatstack/SKILL.md": "a6dc11f9010d2029d7ed1ee3f8f1555988c8ec7e603b6eb83b48ed6c7748af5d",
"boatstack/SKILL.md": "44657cc7a55359bfd0025eae501e31b829f9665005a02d24f3b6ccbef3db3bf0",
"boatstack/agents/openai.yaml": "68a30a60859556c5a26e16d184594ca243a6043d99c8cf7d66b5dd6d50a93cd1",
"boatstack/assets/templates/adr.md": "c577a3c1c1319061f61deb053597e6e853657022185fe28b8f733327e2a78565",
"boatstack/assets/templates/approval.md": "74b0b816703a6dce3c96c8f95f981af910b020b6908e7f76cf5630778637e9f5",
Expand All @@ -31,11 +31,11 @@
"boatstack/assets/templates/test-plan.md": "6db8a9f27dd171fb80222a501cae50eb051e7278c04703fa43b5ff86dd4d2df4",
"boatstack/atomic_unix.go": "89f2723361591de2bb8bd22ce7e34ec529d3278509f0df78fd5c4a7d4140fbe9",
"boatstack/atomic_windows.go": "cefd775cbe7e7c3bd8a3f5673b11cdd784c6d3ebd6de7dcb8f39406b0bee511f",
"boatstack/cmd/boatstack-helper/main.go": "dc30a087003f5a1e432d69052178a7594d544b91a75cb0b99881a6f67c451260",
"boatstack/cmd/boatstack-helper/main.go": "b4b8b43d80dbf60f15e18885ff8ee01637df6e47c0249938714d885163350539",
"boatstack/delivery.go": "907a0ff8dc3e6120387eef3c7d97cdadb0b9dd8f788cb39e149aa7a6c4a6260a",
"boatstack/delivery_test.go": "744d166757deafe5b9fc4f66b79b324de43dcc36a26a317572eaec73a8b21044",
"boatstack/export.go": "c78647482118b80eb6e8283a3939234d400f324f9f576d069317dfb7d2046ed3",
"boatstack/export_test.go": "fb6d85a984e5e03e21dcb0878fc89dc6ec9ea5e12467a21495287784bf31bf6e",
"boatstack/export.go": "d8117e8c2da549a9a5e96794440f163053d82a4e945624a11f168133f430a761",
"boatstack/export_test.go": "d98aa90e24bb4dbe7947ab36243a36cb967889456186e5a775abd3d999c779e5",
"boatstack/go.mod": "57c377eccea51372d6664de4169e2ca45806b046f7e8a98a1e35a9eb454b4b8d",
"boatstack/hooks.go": "1d5d8c4bf7e6e867c8bf07e391d86158347269f856647a5d256f345bbb8d3c96",
"boatstack/hooks_test.go": "c3f359416ea53f258d8747d0247381e8946efd4d4a5bcf072c4147f885475ad3",
Expand All @@ -55,9 +55,11 @@
"boatstack/references/failure-moves.md": "1d35126348d0b681976e8819665e16fd745fd65eca271492603cb80aab75bf49",
"boatstack/references/irreversible-operation-boundary.md": "2a695f2d7de95cfc8750f107bef9c86581712aa1f02e7233b69b850d8c2af42e",
"boatstack/references/portability.md": "fb683095991bb0cb06ec56fb8884c49038b283172a7d2f8b203483b7cacb4bae",
"boatstack/references/workflow.md": "c604f5e6372a1f32adf4e49360395bfba6869a249db2e077cf678792c0241eac",
"boatstack/references/workflow.md": "9edba7fe6cac8a4f67120058ba3c567a86a5982c49c65758b00dcfbb6dacfb13",
"boatstack/release.go": "fa2ac926df89c90c5844e938a2e02d4b8dbbaefbf85bb7a1a89fc51690bea520",
"boatstack/release_test.go": "5cf2d76fe9b836a91ca68eba53d5585e2c4be5b9421aaf939ea0723063a24690",
"boatstack/run.go": "a9afb239c5e2cb80f96dab594f0dc94852f2f16625b1de05c5110ee85f61cfaa",
"boatstack/run_test.go": "fdc416f15e787b5c8401fc0f0e3aeb58b4891c828a8a869c8dce4e8f1541d809",
"boatstack/runtime.go": "f393745950e8ba2da7e25d5539ad536a6239a10c17109224bad20cf48445c380",
"boatstack/runtime_cache.go": "60c4eb0c7dde91d40d6ef3f05adc1a1282d17ff1ca12470d0a008454f7ca7489",
"boatstack/runtime_cache_test.go": "4cbca9dec7800d7df6e3ec0d74c7ecbe1508e5c5a288d863f35fc8d22986c308",
Expand All @@ -71,10 +73,10 @@
"docs/account-recovery-walkthrough.md": "676034974594a7d1a559b24dbed31d7ccc429eb81404b203ca07bbdaa19ec3d3",
"docs/benchmark-corpus-audit.md": "f2d206fe8579a514f9da82b2c96c19b343ac004be67617e1bd34f0f8e0e5e6c6",
"docs/benchmark-submission-audit.md": "9518abdd17690729c6423f87cab20418ed47b0915b5faa44b9ef975e9e9c3b79",
"docs/evidence-engineered-coding.md": "9a6e1770ed903a22ade4be804a35e5fc0a557d369b438b449cce967b761f6943",
"docs/evidence-engineered-coding.md": "2935abc292b02c6842ea17ace5af9eecd5464ea1f24a17f5d594dd2a49a1c003",
"docs/generated-files.md": "136422baf0c7fc2bd5100cfe0ebdb3d9d0705dfd7e7d54bf745dd1037e63492c",
"docs/getting-started.md": "2a642a8ef072502f1a099e211cb599a0179023d1b48b41b4d6b407881494e594",
"docs/public-claims.json": "e68306b85634d7868ca9697da1e7491fd72abe0ba3eb0706a958b35b06930afb",
"docs/getting-started.md": "61efc6bd618bd6674687d8efac9e1bc425fe5c10e72f87e267461dd2a830736e",
"docs/public-claims.json": "3311b27e29ef81aa25a1503e2407ea12331ba4c626936ea917b9545fba236830",
"docs/public-surface.md": "713f7a050b5f339cf948299103ef3800417dccfecf2cc1a4166397ea6f978907",
"docs/research-and-design.md": "d65c66e323037bda5d45aacef5d48afa6bf93da55901378891d235aca3a5684f",
"docs/safety.md": "7b9b5c515d36e683767ec8d3d9d6d119ac93650b2f629d351deadd4c600ed6a6",
Expand All @@ -88,7 +90,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": "50e07d4290abd9c122a300f7f5aa443d8e829ea5010abbf8ddf0711d2497b576",
"labs/diagram-json/plan.lock.json": "4bdb23a2800a9f826a1298dfb89f63a64ac7004aa15779edeb935075a9fcaaae",
"labs/diagram-json/plan.md": "3cc4f533b8d69386deff16b3a594a3ba09d4c0c3db636cccd8c4380084ce6a51",
"labs/diagram-json/questions.md": "74733b015002c8a6777c558e7e997fa48c94850b9bd39054fe9366c97ecf728d",
"labs/diagram-json/request.md": "0808fc41c36779c404f4a3a121167da6e76cac56df526e70f9ed6d3e0d4c02ed",
Expand All @@ -108,13 +110,14 @@
"release-notes/2026-07-18-host-hook-migrations.md": "1c9f81d9318854214f72802045e8e39c9ca45435af0f9d2c28fcf4ff4c1e0071",
"release-notes/2026-07-18-intelligence-flow-labs.md": "b236dddcf22dab718698b05c5dcf162ffddf9f5b53ea98468fd49b342d75edb9",
"release-notes/2026-07-18-next-stage.md": "42ac8e9e45303fe5609cdd3fde10ca69ed349b2d4948445ed91d0e49d5c769b0",
"release-notes/2026-07-18-run-through-ship.md": "e69d314fe65265eb1f38c933340772d15bbb53b74c33d9d489b8a55849f545c7",
"release-notes/2026-07-18-safety-sql-boundaries.md": "32011ca3d02a371e8f3f2899ffb34df3af0843d18d25e7db95fbca32c2dcf18c",
"release-notes/2026-07-18-stacked-bar-mark.md": "c4d5bd5fb89c280d7fba015384fd795fcb8c31ffe501078aa55a90cbcf66ba7b"
},
"generator": "operatorstack/intelligence-flow:boatstack-distribution",
"schema_version": 1,
"source": {
"commit": "569709dad427c28f7e866a1bd72ca0312d7b2f1b",
"commit": "ae167a3ce7759793d4dfbd710eea7ecbbf577058",
"path": "labs/12-product-engineering-loop",
"repository": "operatorstack/intelligence-flow"
}
Expand Down
7 changes: 7 additions & 0 deletions boatstack/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Map the request to one operation:

- `init`: inspect a repository and create or update `.product-loop/project.json`.
- `next`: report the verified current stage and exactly one next action without changing workflow or repository state.
- `run`: drive the verified feature through every delivery slice and PR publication, pausing at approval, product-decision, and publication boundaries.
- `auto-plan`: refine a saved host Plan-mode file into a reviewable draft feature package; refuse when that file is absent.
- `plan-gate`: validate the Markdown draft, present it for explicit human acceptance, and record that acceptance in Markdown.
- `build`: activate the approved Markdown plan, then implement only the active delivery slice's tasks.
Expand All @@ -30,6 +31,12 @@ For the full state machine, read [workflow.md](references/workflow.md). For arti

Run the project-local helper's read-only `next-status --repo . --json` inspection. Repository artifacts, managed delivery state, and gate receipts are evidence; conversation, terminal, worktree, and process observations are context only. Never run the returned operation automatically. If nothing remains active in an initialized repository, report **Feature complete** with **No action required**. If state is ambiguous or stale, name the blocker instead of choosing by recency.

## Run through ship

For `$boatstack run`, `/boatstack-run`, or natural language such as “run Boatstack through ship,” first run the read-only `next-status --repo . --json`. Return **Feature complete** immediately when nothing remains active, and stop on unverified, ambiguous, or stale state. Before executing a mutating next operation, run `run-preflight --repo . --json`. It fetches `origin` and verifies the current named branch contains the fetched delivery base and is not behind or diverged from its upstream. A failed fetch, missing remote/base, stale base, upstream drift, or constrained branch mismatch blocks before product or workflow mutation. Never repair freshness by merging, rebasing, switching or creating a constrained branch, discarding changes, force-pushing, or broadening permissions.

After preflight, repeatedly run `next-status --repo . --json`, execute only its verified next operation using the canonical semantics below, verify the resulting repository state, and resolve again. Continue across all declared slices. Pause for explicit `a` plan approval, material product questions, and the exact `o` or `u` PR confirmation; a valid answer resumes the foreground run in the current host session. The run invocation itself is never approval or publication authority. Same-intent test/review failures may be recorded and repaired for at most three complete repair-and-gate cycles per active slice in one invocation. Stop on amendments, ambiguity, safety failures, stale evidence, unsupported recovery, branch mismatch, or an exhausted budget. Do not persist autopilot state or use conversation as workflow evidence. Completion means every slice PR is published for review, never merged or deployed.

## Enforce the irreversible-operation boundary

Read [irreversible-operation-boundary.md](references/irreversible-operation-boundary.md). Project hooks hard-deny high-confidence destructive shell and MCP operations on every supported agent call. Never request or invent an in-session bypass. After an external-write failure, preserve state, use read-only diagnosis, retain the immutable target boundary, and choose only proven transactional retry or fix-forward recovery. Source edits may be reviewed, but an executable destructive capability blocks activation and every later gate.
Expand Down
27 changes: 26 additions & 1 deletion boatstack/cmd/boatstack-helper/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,29 @@ func nextStatusCommand(arguments []string) int {
return 0
}

func runPreflightCommand(arguments []string) int {
flags := flag.NewFlagSet("run-preflight", flag.ContinueOnError)
repo := flags.String("repo", ".", "repository whose Git state should be verified before boatstack run")
jsonOutput := flags.Bool("json", false, "print the versioned structured preflight")
if err := flags.Parse(arguments); err != nil {
return 2
}
status := boatstack.CheckRunPreflight(*repo)
if *jsonOutput {
value, err := boatstack.MarshalJSON(status)
if err != nil {
return fail(err)
}
fmt.Print(string(value))
} else {
fmt.Printf("Boatstack run preflight: %s\nReason: %s\n", status.VerificationStatus, status.Reason)
}
if status.VerificationStatus != "VERIFIED" {
return 1
}
return 0
}

func recordChangeCommand(arguments []string) int {
flags := flag.NewFlagSet("record-change", flag.ContinueOnError)
options := boatstack.ChangeObservationOptions{}
Expand Down Expand Up @@ -512,7 +535,7 @@ func publishPRCommand(arguments []string) int {

func run() int {
if len(os.Args) < 2 {
fmt.Fprintln(os.Stderr, "usage: boatstack-helper <init|update|check-update|release-classify|next-patch|export|check-source-plan|planning-write|check-plan|record-approval|activate-plan|delivery-status|next-status|record-change|record-delivery-gate|check-safety|safety-hook|pr-context|check-pr|publish-pr|doctor|version>")
fmt.Fprintln(os.Stderr, "usage: boatstack-helper <init|update|check-update|release-classify|next-patch|export|check-source-plan|planning-write|check-plan|record-approval|activate-plan|delivery-status|next-status|run-preflight|record-change|record-delivery-gate|check-safety|safety-hook|pr-context|check-pr|publish-pr|doctor|version>")
return 2
}
switch os.Args[1] {
Expand Down Expand Up @@ -542,6 +565,8 @@ func run() int {
return deliveryStatusCommand(os.Args[2:])
case "next-status":
return nextStatusCommand(os.Args[2:])
case "run-preflight":
return runPreflightCommand(os.Args[2:])
case "record-change":
return recordChangeCommand(os.Args[2:])
case "record-delivery-gate":
Expand Down
Loading
Loading