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/9749f1b5397c73f6ea9077719a85f60ae7eee1d6/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/9668feb5b9ba3b816d470dde2cc87c70811a7f9a/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
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,17 @@ Install Boatstack in its own infrastructure PR and merge it before starting a fe
## Start with two moves

1. Create and save a plan in your coding tool's Plan mode.
2. Run `/auto-plan`.
2. Start Boatstack with the entry point for your host.

| Host | Start command |
|---|---|
| Claude Code | `/auto-plan` |
| Cursor | `/auto-plan` |
| Codex | `$boatstack auto-plan` |

That is all you need to learn up front. Boatstack shows one next action at a time through approval, building, tests, review, and PR preparation.

When you are ready, that guidance moves through `/plan-gate` → `/build` → `/test-gate` → `/review-gate` → `/ship-gate`.
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
29 changes: 15 additions & 14 deletions UPSTREAM.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
},
"files": {
".gitignore": "a7079e923a776f14f1bb3a6aa0a11a133a8e1dfb35af020f327623357b7e3957",
"CONTRIBUTING.md": "e1a9752e2aa9f716579096a2ed8f1d0025673ad7775a7eb3a106dc238285420a",
"README.md": "83ea436685782c5c2d2d375ceae21cb95c72a5f6608eb8187a5efc817350e081",
"CONTRIBUTING.md": "d79729327266363a2fbc47cca778245c619d874a74c7c4ae7ff6ecee1f9ba6b2",
"README.md": "d52c9be1a91165e3bb22318e3014278eb5326d10a45da6311f677d704e5c086d",
"assets/boatstack-journey.svg": "c1f7fe2741f5e9ca66bb3fe9b103e6364ba5acbca8b7a8054768ffd85cf325ea",
"assets/boatstack-mark.svg": "ec96165583b15cfd446c27049d49217973f3e9b1defa5771cc08eec0c9542ce4",
"assets/boatstack-portability.svg": "ce648f5581d16586d25824d3a8132ef1b3d88b73329179173120129d4f74fd24",
Expand All @@ -34,18 +34,18 @@
"boatstack/cmd/boatstack-helper/main.go": "dbb8cb4bb403aa36a47bd9317e9a34845cabfa5b8e4152a7fb57ded1591d8957",
"boatstack/delivery.go": "bfdce7dd3bc1357a614bd458f2f6b4b8570015c117d1f7638c7a1bf3110e1a48",
"boatstack/delivery_test.go": "a8a5a7e6e8dcfee1538367d49c76c531e04211876c1685265884cff26ae04497",
"boatstack/export.go": "faf905a8d45a73a03792fb000e56cba351f86caf3b3c261ff8d324e612e48377",
"boatstack/export_test.go": "9961313036b8ca8681d804193921357f29d6acd30a9532aa522986d48a9894ef",
"boatstack/export.go": "5a2002ba99b1b0c22f503f378072902393edb9d70dba06a090fe25e5ac734612",
"boatstack/export_test.go": "1cbed87e24f1b81d20fbdd64eaef0b5b713abda06518b144d5aed5726247d183",
"boatstack/go.mod": "57c377eccea51372d6664de4169e2ca45806b046f7e8a98a1e35a9eb454b4b8d",
"boatstack/hooks.go": "718161de45165e450369577e5ef1e9fdc76a484d61fa56a36eb6a117b2e63249",
"boatstack/hooks_test.go": "c3f359416ea53f258d8747d0247381e8946efd4d4a5bcf072c4147f885475ad3",
"boatstack/init.go": "ddee0cfd8ab9f3416fb895afd99d1682ca09550d2d9b2ad3cd11f5e06438c585",
"boatstack/init_test.go": "b761ada1f5a04c0a27225a6f1eb99baf5477a424c5a9748a3267f07ba5a84605",
"boatstack/init.go": "a9740a401bf4b0b5a700b02fe8f15d80757ed2c697fa6ebce38d3c03f6c7ba75",
"boatstack/init_test.go": "ea5898df01d4fa5e039749df83f9190fd8fe95b2fe9b7e2526e0d0ecba8a7f03",
"boatstack/integrations.go": "75b39ce2e662fccd66bf4b9bff0e097a4db558f23b3aa1d9bc83a5fc6373444c",
"boatstack/plan.go": "d83037a9f06f927427a59ea936bbee4041ea9276dd84992599c16ef6259b2d4f",
"boatstack/plan_test.go": "006cdc6681f77e579c5a0f709e30ede759c337132d4f2f5193b7b79b29bd7149",
"boatstack/planning.go": "3a26417a295e5dfc2b6dcac702287c04b6053e7b74215858a4ea11cf9f9dadfe",
"boatstack/planning_test.go": "4662908c1ec063aa8ef6f91db52247864303d9b91ef2363a8f68b41082fe383f",
"boatstack/planning_test.go": "6b156a64182ed76d4c3d392b4c5a26abe5d8b81cea27ee12ac7c4627c827e186",
"boatstack/pr.go": "2af70c81108288cd9cd319f7100d1abd957e7e84f8db1474afa51a8b74e9d442",
"boatstack/pr_test.go": "74afb1a9be3c4a95a426515be415149ae24b077454b486d8e69b7118c42f2916",
"boatstack/references/artifacts.md": "3a87b8f8d835329191bedb20c94e6056fe2251b3e9d510656909eb9d276069dc",
Expand All @@ -68,14 +68,14 @@
"docs/account-recovery-walkthrough.md": "676034974594a7d1a559b24dbed31d7ccc429eb81404b203ca07bbdaa19ec3d3",
"docs/benchmark-corpus-audit.md": "f2d206fe8579a514f9da82b2c96c19b343ac004be67617e1bd34f0f8e0e5e6c6",
"docs/benchmark-submission-audit.md": "9518abdd17690729c6423f87cab20418ed47b0915b5faa44b9ef975e9e9c3b79",
"docs/evidence-engineered-coding.md": "2368d5fba09ad6f24f8317fcc40f6d2208c01d1dc6d4a673d0f2477f5cca6757",
"docs/generated-files.md": "7b2e8c10a35aa351fb87753492ed3cadb05011002d2fd6ffeb1951c356f6b286",
"docs/getting-started.md": "6d98555b9d7a27091169a6a8c1efb64c84791c73a72f814e2a4dbdc149ac58a6",
"docs/public-claims.json": "b9080efb0c1d995aef961345e7dc2343cc7c83715a822af5d0ed89bca979227a",
"docs/evidence-engineered-coding.md": "027e20dc9faad84dfa533f365514ad70195cad945bf46ca17a67e3d2dcbaedbb",
"docs/generated-files.md": "136422baf0c7fc2bd5100cfe0ebdb3d9d0705dfd7e7d54bf745dd1037e63492c",
"docs/getting-started.md": "4ef77719a01a2dbe98c5154d58fc03f51797ae0ef39a09d8804fe0708b8cc920",
"docs/public-claims.json": "915db0f39b14208ea083f9567dcedc5d19b973577c5c448136d6ca7baee94623",
"docs/public-surface.md": "713f7a050b5f339cf948299103ef3800417dccfecf2cc1a4166397ea6f978907",
"docs/research-and-design.md": "d65c66e323037bda5d45aacef5d48afa6bf93da55901378891d235aca3a5684f",
"docs/safety.md": "7b9b5c515d36e683767ec8d3d9d6d119ac93650b2f629d351deadd4c600ed6a6",
"docs/troubleshooting.md": "a3314d0eb97643534415f3c19f1763fd80ff6bb5e98c53b646e447e0b31c4829",
"docs/troubleshooting.md": "5233172deea20a962a3557e96f864113c3f6242a835e207e108817f8051ff237",
"docs/validation-and-evidence.md": "e7d91ad49c6adb44784ebe7d94feceb6abd445857f9a0716f0758bf6b55296c5",
"docs/why-these-steps.md": "80957af13979070e8b2f2a8db78ce06d20d152bbc8ec41c3a8003f28393f6369",
"install.ps1": "960b2b20b406bb2878a560e9ace53fe7226bc510be6ee8466ce4e608beb5625a",
Expand All @@ -85,7 +85,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": "86398343fb6a7cc35a97099753ec3118ee03985b3869fd225a13b18c6b16d86c",
"labs/diagram-json/plan.lock.json": "d3b39300d7dba9b5b863826b7dc14b582963daa123fa8dda605a353043d2ad7b",
"labs/diagram-json/plan.md": "3cc4f533b8d69386deff16b3a594a3ba09d4c0c3db636cccd8c4380084ce6a51",
"labs/diagram-json/questions.md": "74733b015002c8a6777c558e7e997fa48c94850b9bd39054fe9366c97ecf728d",
"labs/diagram-json/request.md": "0808fc41c36779c404f4a3a121167da6e76cac56df526e70f9ed6d3e0d4c02ed",
Expand All @@ -97,6 +97,7 @@
"release-notes/2026-07-17-visible-release-messages.md": "c93e8c812528a983502263e35d66c86a265d6ccba8203f393788c069b3fa6606",
"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-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 @@ -107,7 +108,7 @@
"generator": "operatorstack/intelligence-flow:boatstack-distribution",
"schema_version": 1,
"source": {
"commit": "9749f1b5397c73f6ea9077719a85f60ae7eee1d6",
"commit": "9668feb5b9ba3b816d470dde2cc87c70811a7f9a",
"path": "labs/12-product-engineering-loop",
"repository": "operatorstack/intelligence-flow"
}
Expand Down
80 changes: 77 additions & 3 deletions boatstack/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,44 @@ type ExportBundle struct {
Config ProjectConfig
}

type claudeSkillSpec struct {
Name string
Description string
ArgumentHint string
}

var claudeVisibleSkills = []claudeSkillSpec{
{
Name: "auto-plan",
Description: "Refine one saved Plan-mode proposal into a reviewable Boatstack feature plan.",
ArgumentHint: "[plan-file]",
},
{
Name: "plan-gate",
Description: "Review and explicitly approve a Boatstack feature plan before implementation.",
},
{
Name: "build",
Description: "Implement the currently approved Boatstack delivery slice.",
},
{
Name: "test-gate",
Description: "Validate the active Boatstack delivery slice and record current test evidence.",
},
{
Name: "review-gate",
Description: "Review the active Boatstack delivery slice against approved intent and evidence.",
},
{
Name: "ship-gate",
Description: "Prepare and, after confirmation, publish the active Boatstack delivery slice as a pull request.",
},
{
Name: "boatstack-update",
Description: "Prepare a separate reviewed update of Boatstack's repository infrastructure.",
},
}

func LoadConfig(path string) (ProjectConfig, []byte, error) {
raw, err := os.ReadFile(path)
if err != nil {
Expand Down Expand Up @@ -95,6 +133,23 @@ Follow the User-facing response contract in @.product-loop/workflow.md. Lead wit
`, operation, operation, preflight, extra)
}

func claudeOperationSkill(spec claudeSkillSpec, operationBody string) string {
argumentHint := ""
arguments := ""
if spec.ArgumentHint != "" {
argumentHint = fmt.Sprintf("argument-hint: %q\n", spec.ArgumentHint)
arguments = "\n\nUser arguments: $ARGUMENTS"
}
return fmt.Sprintf(`---
name: %s
description: %s
%sdisable-model-invocation: true
---

%s%s
`, spec.Name, spec.Description, argumentHint, strings.TrimSpace(operationBody), arguments)
}

func BuildExportBundle(configPath string, config ProjectConfig, rawConfig []byte, adapterName string) (ExportBundle, error) {
if !adapterNamePattern.MatchString(adapterName) {
return ExportBundle{}, fmt.Errorf("adapter name must be a lowercase kebab-case slug")
Expand Down Expand Up @@ -202,7 +257,7 @@ Boatstack's repository hooks deny high-confidence irreversible operations across

adapterSkill := fmt.Sprintf(`---
name: %s
description: Run Boatstack's evidence-engineered coding node for question-led planning, explicit approval, open implementation, evidence gates, and PR preparation.
description: Use when the user asks Boatstack to auto-plan, approve a plan, build, test, review, ship, update Boatstack, or run a retrospective.
---

# Boatstack adapter
Expand Down Expand Up @@ -232,12 +287,31 @@ When the user asks to update Boatstack, run the boatstack-update operation. Neve
For a managed ship, use the internal pr-context operation with --feature to project the feature spec, accepted decisions, actual committed diff, evidence ledger, review findings, gaps, rollout, and rollback into the required pr.md artifact. Inspect the returned changed files, diff stat, high-risk matches, and the actual diff before writing claims; commits alone are not authoritative. Always include why, what changed, review order, evidence, gaps/risks, rollout/rollback, and collapsed provenance. Add UI evidence, security/privacy, migration, or operations sections only when relevant. For a natural-language request to improve an existing or ad-hoc PR, run pr-context without --feature and use the same reviewer-first format from observed branch facts, but mark unavailable approval or gate evidence as NOT_VERIFIED. Never create or advertise a /pr-brief command. Validate with check-pr and always show the exact title and rendered body before publication. Ask for state-scoped o to open or u to update the PR. Only after the matching shortcut or compatible full reply, commit only pr.md, revalidate the unchanged preview fingerprint, and invoke the internal publish-pr operation with the selected action. It may perform a normal push but never force-push. Any intervening product diff or evidence change invalidates the preview. Keep model attribution inside collapsed provenance. Internal helper names and hashes stay out of the primary response.

If gstack is enabled, use only its namespaced /gstack-* specialist lenses inside Boatstack operations. If Spec Kit is enabled, use it to generate or cross-check artifacts; never invoke speckit.implement to bypass Boatstack's plan approval and build gate.
`, adapterName)
`, adapterName)
if contains(adapters, "claude") {
files[fmt.Sprintf(".claude/skills/%s/SKILL.md", adapterName)], err = GeneratedFrontmatter(adapterSkill)
claudeAdapterSkill := strings.Replace(
adapterSkill,
"\n---\n\n# Boatstack adapter",
"\nuser-invocable: false\n---\n\n# Boatstack adapter",
1,
)
files[fmt.Sprintf(".claude/skills/%s/SKILL.md", adapterName)], err = GeneratedFrontmatter(claudeAdapterSkill)
if err != nil {
return ExportBundle{}, err
}
for _, spec := range claudeVisibleSkills {
extra, ok := operations[spec.Name]
if !ok {
return ExportBundle{}, fmt.Errorf("missing operation instructions for Claude skill %s", spec.Name)
}
path := fmt.Sprintf(".claude/skills/%s/SKILL.md", spec.Name)
files[path], err = GeneratedFrontmatter(
claudeOperationSkill(spec, commandBody(spec.Name, extra)),
)
if err != nil {
return ExportBundle{}, err
}
}
}
if contains(adapters, "codex") {
files[fmt.Sprintf(".agents/skills/%s/SKILL.md", adapterName)], err = GeneratedFrontmatter(adapterSkill)
Expand Down
Loading
Loading