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/697ce2f7d98eb3bfb249b33d3556efbd7e9365b1/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/bbed9588e74016250e3cf8968e70bdd375afb863/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
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,24 @@ In Claude Code and Cursor, that guidance moves through `/plan-gate` → `/build`
<img src="assets/boatstack-journey.svg" width="960" alt="One feature moves from idea through planning, approval, building, tests, review, and pull request; its retained plans, decisions, gaps, evidence, and code state combine with the next idea to create the next plan">
</p>

## Change course without losing the delivery

After Build, describe changes normally. Boatstack records them, preserves valid work, and resumes at the earliest boundary.

```text
“This is wrong” → record → repair → test → review
↘ changed intent → approve delta
```

Receipts remain as history; published corrections become linked deliveries.

## Features

- **A guided path from idea to PR.** Start with `/auto-plan`; Boatstack presents one next action at a time through planning, approval, build, validation, review, and PR preparation.
- **Human decisions stay human.** Material product questions remain open until a person answers them, and implementation waits for explicit approval.
- **Evidence tied to the promise.** Tests and checks map to the outcomes the change claims to deliver instead of treating one green command as proof of everything.
- **Context that survives the feature.** Plans, decisions, accepted gaps, evidence, review findings, and code state can inform the next feature rather than disappearing with the chat.
- **Conversational repair after Build.** Describe what changed; Boatstack preserves valid work and reruns only affected boundaries.
- **Safer agent execution.** High-confidence destructive recovery is stopped before execution; phased work is gated and published one approved delivery slice at a time.
- **Reviewer-ready pull requests.** Boatstack carries the reason, actual changes, validation, risks, gaps, rollout, and rollback into a focused PR brief.
- **Portable across your AI stack.** Cursor, Codex, Claude Code, different model tiers, and specialist skills use the same repository-owned delivery contract.
Expand Down
33 changes: 17 additions & 16 deletions UPSTREAM.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"canonical_context": {
"characters": 38485,
"estimated_tokens": 9622,
"characters": 39803,
"estimated_tokens": 9951,
"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": "ca94e9856aab321b125ddeb9f9845c9a26f957585ba46e5547525875b34aa64b",
"README.md": "d52c9be1a91165e3bb22318e3014278eb5326d10a45da6311f677d704e5c086d",
"CONTRIBUTING.md": "6c29c112507af7f6661d7d3485da1f7974462b85f54b1075a014fdb5b9a4e546",
"README.md": "7d1473b75566901899b49a9f98cd5446ac40d2fceee3f168c5e6869c742e0b4a",
"assets/boatstack-journey.svg": "c1f7fe2741f5e9ca66bb3fe9b103e6364ba5acbca8b7a8054768ffd85cf325ea",
"assets/boatstack-mark.svg": "ec96165583b15cfd446c27049d49217973f3e9b1defa5771cc08eec0c9542ce4",
"assets/boatstack-portability.svg": "ce648f5581d16586d25824d3a8132ef1b3d88b73329179173120129d4f74fd24",
"boatstack/SKILL.md": "3fde100e855b968cfca3bfebf324955a6440a1b7a14b1bd2ec21ad8e4b9613d8",
"boatstack/SKILL.md": "9443685e255a59de2f5e58928051b4f7385f7401831300b78376d48e41024ba1",
"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": "dbb8cb4bb403aa36a47bd9317e9a34845cabfa5b8e4152a7fb57ded1591d8957",
"boatstack/delivery.go": "d092ac67116d651938ed1e2912bb845c3b273d650cf88049304888be9683c59c",
"boatstack/delivery_test.go": "a8a5a7e6e8dcfee1538367d49c76c531e04211876c1685265884cff26ae04497",
"boatstack/export.go": "3f086d8615769f857ba704678fea78ec63bdf28c15acd4a7bf0c1414f132e285",
"boatstack/export_test.go": "87fc1aef65f3e437d3ca9660e31b9fa77bbb6d80f9b131adff1dbd422a71fdfe",
"boatstack/cmd/boatstack-helper/main.go": "fc979a21007107f6a2f52a2c1eb82c35be5dbe97a775a908e0d1ebc25864f040",
"boatstack/delivery.go": "907a0ff8dc3e6120387eef3c7d97cdadb0b9dd8f788cb39e149aa7a6c4a6260a",
"boatstack/delivery_test.go": "744d166757deafe5b9fc4f66b79b324de43dcc36a26a317572eaec73a8b21044",
"boatstack/export.go": "72ed801fcf52fc93e8446dd3b7d205d7ef8a0530b33f4e02891f7290bc243343",
"boatstack/export_test.go": "8f04947a5e1723df21f068b14ba295b0281a04b5037d251be0315100bdce65e8",
"boatstack/go.mod": "57c377eccea51372d6664de4169e2ca45806b046f7e8a98a1e35a9eb454b4b8d",
"boatstack/hooks.go": "1d5d8c4bf7e6e867c8bf07e391d86158347269f856647a5d256f345bbb8d3c96",
"boatstack/hooks_test.go": "c3f359416ea53f258d8747d0247381e8946efd4d4a5bcf072c4147f885475ad3",
Expand All @@ -49,11 +49,11 @@
"boatstack/planning_test.go": "6b156a64182ed76d4c3d392b4c5a26abe5d8b81cea27ee12ac7c4627c827e186",
"boatstack/pr.go": "2e0ea90a991fe4504e54972506cb306f48124c8b34be8577d96f6c97079bdf0c",
"boatstack/pr_test.go": "74afb1a9be3c4a95a426515be415149ae24b077454b486d8e69b7118c42f2916",
"boatstack/references/artifacts.md": "3a87b8f8d835329191bedb20c94e6056fe2251b3e9d510656909eb9d276069dc",
"boatstack/references/artifacts.md": "8f2e79b8af4bd3ad2e32aa3e8c07f10812555d0a3247e4991db75cc1cda395c3",
"boatstack/references/failure-moves.md": "1d35126348d0b681976e8819665e16fd745fd65eca271492603cb80aab75bf49",
"boatstack/references/irreversible-operation-boundary.md": "2a695f2d7de95cfc8750f107bef9c86581712aa1f02e7233b69b850d8c2af42e",
"boatstack/references/portability.md": "fb683095991bb0cb06ec56fb8884c49038b283172a7d2f8b203483b7cacb4bae",
"boatstack/references/workflow.md": "6a7d146c2ad072c513324ad058d4b6c38ea967f2b9c199e055cfc528f4b826ad",
"boatstack/references/workflow.md": "6794ef2899e3cde7f8cdf182b65def8e371ae3ec3d38cc3cbe2009adb4321512",
"boatstack/release.go": "fa2ac926df89c90c5844e938a2e02d4b8dbbaefbf85bb7a1a89fc51690bea520",
"boatstack/release_test.go": "5cf2d76fe9b836a91ca68eba53d5585e2c4be5b9421aaf939ea0723063a24690",
"boatstack/runtime.go": "f393745950e8ba2da7e25d5539ad536a6239a10c17109224bad20cf48445c380",
Expand All @@ -69,10 +69,10 @@
"docs/account-recovery-walkthrough.md": "676034974594a7d1a559b24dbed31d7ccc429eb81404b203ca07bbdaa19ec3d3",
"docs/benchmark-corpus-audit.md": "f2d206fe8579a514f9da82b2c96c19b343ac004be67617e1bd34f0f8e0e5e6c6",
"docs/benchmark-submission-audit.md": "9518abdd17690729c6423f87cab20418ed47b0915b5faa44b9ef975e9e9c3b79",
"docs/evidence-engineered-coding.md": "8c79f43e67c6fa9dbd4f5eb84595ef7846b14a35d21c6be1403182f20551ab4c",
"docs/evidence-engineered-coding.md": "d9397b0ddb7ede2080a1a4d703b3272dcf31080cfc0f7b1cc732c847145386ee",
"docs/generated-files.md": "136422baf0c7fc2bd5100cfe0ebdb3d9d0705dfd7e7d54bf745dd1037e63492c",
"docs/getting-started.md": "4ef77719a01a2dbe98c5154d58fc03f51797ae0ef39a09d8804fe0708b8cc920",
"docs/public-claims.json": "0bcb69c56b2e6edd97d21b5b6d0f3ac3eb8554c46e9ea2324b46166c1814f180",
"docs/public-claims.json": "67f2b7c4a288ba11338b11e5db2cb7efa7e498c42dcc3264da641ecbadd59f2a",
"docs/public-surface.md": "713f7a050b5f339cf948299103ef3800417dccfecf2cc1a4166397ea6f978907",
"docs/research-and-design.md": "d65c66e323037bda5d45aacef5d48afa6bf93da55901378891d235aca3a5684f",
"docs/safety.md": "7b9b5c515d36e683767ec8d3d9d6d119ac93650b2f629d351deadd4c600ed6a6",
Expand All @@ -86,7 +86,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": "de95c999eb36de930d3a0fcca0d5751c1087ae49bb26b8347ec90432291457d6",
"labs/diagram-json/plan.lock.json": "4fc2cba6a3a4bbe37d6e3591b583c023dccc8fff778ec00fd2c8ef789d6a6b0e",
"labs/diagram-json/plan.md": "3cc4f533b8d69386deff16b3a594a3ba09d4c0c3db636cccd8c4380084ce6a51",
"labs/diagram-json/questions.md": "74733b015002c8a6777c558e7e997fa48c94850b9bd39054fe9366c97ecf728d",
"labs/diagram-json/request.md": "0808fc41c36779c404f4a3a121167da6e76cac56df526e70f9ed6d3e0d4c02ed",
Expand All @@ -100,6 +100,7 @@
"release-notes/2026-07-18-automated-releases.md": "6571eec442a27bd1a55667567f0659993c516171ef10ae71046cce80f7fd29fa",
"release-notes/2026-07-18-base-aware-release-preflight.md": "cdface46ccd959a5299de4c363c9e4057e7257820dab77dcf0e587daef5d3d99",
"release-notes/2026-07-18-claude-command-discovery.md": "bb42c23041916dee21e502449143620a8dcbd0dec4aad01162293499547f1114",
"release-notes/2026-07-18-conversational-delivery-repair.md": "3d1a13b4e2e423f923df6aec29947070b5fef39af15d07437523580fad82622a",
"release-notes/2026-07-18-global-reply-shortcuts.md": "329d6fd104079bc5f66e7c3d477f4ff2a6bb264d429485c6f42f9c203d17fa29",
"release-notes/2026-07-18-harbor-lab-namespace.md": "6419c049e5a3024c5a8604e4d9fb241c27ceb80bf1d4cc62f66d1a0eaf09ea21",
"release-notes/2026-07-18-host-hook-migrations.md": "1c9f81d9318854214f72802045e8e39c9ca45435af0f9d2c28fcf4ff4c1e0071",
Expand All @@ -110,7 +111,7 @@
"generator": "operatorstack/intelligence-flow:boatstack-distribution",
"schema_version": 1,
"source": {
"commit": "697ce2f7d98eb3bfb249b33d3556efbd7e9365b1",
"commit": "bbed9588e74016250e3cf8968e70bdd375afb863",
"path": "labs/12-product-engineering-loop",
"repository": "operatorstack/intelligence-flow"
}
Expand Down
9 changes: 9 additions & 0 deletions boatstack/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Map the request to one operation:
- `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.
- `repair`: classify a free-form post-build change, record it durably, and resume from the earliest affected stage without silently changing approved intent.
- `test-gate`: test requirements and relevant regressions using independent evidence.
- `review-gate`: review the diff against the spec, project invariants, risks, and known gaps.
- `ship-gate`: preview, then explicitly open or update, a reviewer-ready PR grounded in the approved diff and evidence.
Expand Down Expand Up @@ -132,6 +133,14 @@ All files created or updated by `auto-plan` and `plan-gate` must be Markdown. gs

Do not branch the workflow on model brand, price, or a guessed capability tier. Branch only on observable work state: unresolved ambiguity, risk, convergence, repeated tactics, tool results, test fidelity, and gate evidence. A repository may choose any implementation model; the contract and gates stay the same.

## Repair from ordinary conversation

Before any product edit, read managed delivery status. If a delivery is active and the user reports a problem or requests a modification, use `repair` even when they do not name Boatstack or a slash command. Compare the exact request with the current lock, acceptance criteria, diff, evidence, and receipts. Classify it as `implementation_repair`, `verification_repair`, `review_repair`, `requirement_amendment`, or `needs_clarification`, then invoke `record-change` before editing.

Same-intent repair resumes at the helper-reported stage and reuses the existing gates. A requirement amendment or ambiguous expected behavior blocks product edits and returns to a concise Plan Gate delta. Never edit `changes.md`, ignored delivery state, or receipts directly; those are emitted by controlled transitions. Conversation history is never workflow authority.

A published delivery is immutable. Record the observation against it, then plan the correction under a new feature id whose structured plan sets `parent_delivery` to the published feature. Activation refuses to reset published slices; the corrective child receives its own lock and full gates.

## Enforce the gates

### Test gate
Expand Down
29 changes: 28 additions & 1 deletion boatstack/cmd/boatstack-helper/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,31 @@ func deliveryStatusCommand(arguments []string) int {
return 0
}

func recordChangeCommand(arguments []string) int {
flags := flag.NewFlagSet("record-change", flag.ContinueOnError)
options := boatstack.ChangeObservationOptions{}
flags.StringVar(&options.Repo, "repo", ".", "repository containing the managed delivery")
flags.StringVar(&options.Feature, "feature", "", "managed Boatstack feature slug")
flags.StringVar(&options.Message, "message", "", "exact user change request")
flags.StringVar(&options.SourceStage, "source-stage", "", "stage where the change was observed")
flags.StringVar(&options.Expected, "expected", "", "approved or requested expected behavior")
flags.StringVar(&options.Actual, "actual", "", "observed behavior")
flags.StringVar(&options.Evidence, "evidence", "", "bounded evidence or reproduction reference")
flags.StringVar(&options.Classification, "classification", "", "implementation_repair, verification_repair, review_repair, requirement_amendment, or needs_clarification")
if err := flags.Parse(arguments); err != nil {
return 2
}
if options.Feature == "" || options.Message == "" || options.SourceStage == "" || options.Classification == "" {
return fail(fmt.Errorf("record-change requires --feature, --message, --source-stage, and --classification"))
}
observation, state, err := boatstack.RecordChangeObservation(options)
if err != nil {
return fail(err)
}
fmt.Printf("PASS: change observation recorded\nOBSERVATION_ID=%s\nCLASSIFICATION=%s\nMODE=%s\nRESUME_STAGE=%s\n", observation.ID, observation.Classification, state.Mode, state.ResumeStage)
return 0
}

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 @@ -464,7 +489,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|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|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 @@ -492,6 +517,8 @@ func run() int {
return activatePlanCommand(os.Args[2:])
case "delivery-status":
return deliveryStatusCommand(os.Args[2:])
case "record-change":
return recordChangeCommand(os.Args[2:])
case "record-delivery-gate":
return recordDeliveryGateCommand(os.Args[2:])
case "pr-context":
Expand Down
Loading
Loading