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/b90637c6c20526242ed84d4be086e3e609869da4/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/d27760b57f2026608a939c6fe1712d437bc91442/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
21 changes: 11 additions & 10 deletions UPSTREAM.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
},
"files": {
".gitignore": "a7079e923a776f14f1bb3a6aa0a11a133a8e1dfb35af020f327623357b7e3957",
"CONTRIBUTING.md": "ab33be7304c410e6f785533eb34bd69cb31c4db10b77354894867820a9413f1d",
"CONTRIBUTING.md": "ee0f065bd50ae659d72482a982ae1b24b7833a787591447c810afca1f0abfe71",
"README.md": "590821a4cf3c4b196d3cfb39c972ccbebef7d4d558df817c1f1e88b4fd7ceb07",
"assets/boatstack-journey.svg": "9f016fbfd2881675551a44dafa282cbc7510a7091131005be490c2dbe5e4e051",
"assets/boatstack-mark.svg": "ec96165583b15cfd446c27049d49217973f3e9b1defa5771cc08eec0c9542ce4",
Expand All @@ -34,7 +34,7 @@
"boatstack/atomic_windows.go": "cefd775cbe7e7c3bd8a3f5673b11cdd784c6d3ebd6de7dcb8f39406b0bee511f",
"boatstack/changelog.go": "c5e1f31440b44d61e6037ad27af0333540af3545d655e35819a0241cbbebd8ec",
"boatstack/changelog_test.go": "ce792f23a7fe1e09fb3096cd1314130a6ab69321d4877b12a8e994027541baf7",
"boatstack/cmd/boatstack-helper/main.go": "3ba7d63640e6e29ab8df1612b05ae7e616b12041b59c44748cfc74f22ba2100b",
"boatstack/cmd/boatstack-helper/main.go": "1d9408c33f6e8f520bb507978f7f7b07fc56a9aedba9469a07a39450c0c0c446",
"boatstack/cmd/boatstack-helper/main_test.go": "ff73003b6a5157202fa09ddf1129fb13c3d79702b2e05a8721ce5a11bf5ab779",
"boatstack/delivery.go": "565bc8465252a798124a29874e1aeffff16e9027d1a86715e11b3e4bc0743bd2",
"boatstack/delivery_test.go": "2545c26389d330a92c11e7b09fb2342101db5d09a825a2a9e81b4ea9eea9407b",
Expand All @@ -50,13 +50,13 @@
"boatstack/integrations.go": "75b39ce2e662fccd66bf4b9bff0e097a4db558f23b3aa1d9bc83a5fc6373444c",
"boatstack/migrate.go": "eaf589e2b266238068e42c6d78e01dc040266d28e342cb24f09e33e8541749b3",
"boatstack/migrate_test.go": "b5c2dad2ab762aa202c5c99a8445774bedd982d280ebbb8dd713e7e9f43299d2",
"boatstack/next.go": "df4164280ecd77a417a02fe4bc3b1f16d7012ea22b6fc8988faf8c71f41bc8e6",
"boatstack/next.go": "d8bb695964ccefc0fc5682230d20b4ab3e7cbb9041ae828fc5103ccd8d83f9d1",
"boatstack/next_test.go": "57828f76257ad7344c383084a97399f6523cbbced28ac2bbe4c14b9da84ccf32",
"boatstack/plan.go": "2497e1d32d88a8e433bc5996b57d175bda4e6ba334cf2510efb7c84fd88a98f3",
"boatstack/plan_test.go": "006cdc6681f77e579c5a0f709e30ede759c337132d4f2f5193b7b79b29bd7149",
"boatstack/planning.go": "4b86ae9dc16393f099ca26812bf3e62909fee42a541b33c33275cc16a80262aa",
"boatstack/planning_test.go": "6b156a64182ed76d4c3d392b4c5a26abe5d8b81cea27ee12ac7c4627c827e186",
"boatstack/pr.go": "d292599ab62eed00b1e1d4d184781719b5e7de66f9f69687a4bb78d393e307f5",
"boatstack/pr.go": "28b9c7bd41c0cbe3ec8d05787d868db36b424ecd3489678524fd0f4878262d78",
"boatstack/pr_test.go": "ae23130d9d96cf214cf272227aa572dd09e2fe3adac22921949f541ba99ecb23",
"boatstack/references/artifacts.md": "8f2e79b8af4bd3ad2e32aa3e8c07f10812555d0a3247e4991db75cc1cda395c3",
"boatstack/references/config-schema.md": "894c001601246ad87411756902aa7b2962314e4395e2075f94d5c7c93c99e013",
Expand All @@ -79,17 +79,17 @@
"boatstack/testdata/reviewer-pr-body.md": "4c64e3788e5d61a377aeb0f797f7fc8d2316ab6e49572d15636eea7ba9e34ac4",
"boatstack/testdata/safety/safe_apply.py.txt": "c9ec7fb932cf21b6aa8df597c4d4c54d6ec65e796240e49118d699f583383975",
"boatstack/testdata/safety/unsafe_apply.py.txt": "42db1751865cc15c4dd69a03146b5deca8f21f916d258e433b27bbef5f884ab1",
"boatstack/update.go": "7a7654e1eccd593a5e1840af06c83098cca8fdf11313f93931258ed011059a95",
"boatstack/update_test.go": "aa0c2ca97038aad661c46321600034e206e88639f89e0216b3c4cf597312cbae",
"boatstack/update.go": "792ba4481503590e1412c0d2ddbfdd912899218a8e3ebcf323e385698b498ab0",
"boatstack/update_test.go": "b7d989c3c74a9e4d80ad14f9f74d94b617798dbcc36359327a4233524677db22",
"boatstack/workspace.go": "91b343400b3506a6f516c28fabc3f1575f22024a5b19f934a020be660a20482e",
"boatstack/workspace_test.go": "d99ee417954f529a333b8330c32104d96b0368c1b07223a42cbf304d5363ad0d",
"docs/account-recovery-walkthrough.md": "676034974594a7d1a559b24dbed31d7ccc429eb81404b203ca07bbdaa19ec3d3",
"docs/benchmark-corpus-audit.md": "f2d206fe8579a514f9da82b2c96c19b343ac004be67617e1bd34f0f8e0e5e6c6",
"docs/benchmark-submission-audit.md": "9518abdd17690729c6423f87cab20418ed47b0915b5faa44b9ef975e9e9c3b79",
"docs/evidence-engineered-coding.md": "6f21f782ea0ae4cee27384c3a4c33af75c28b36fd3fb8d0a6fc67d052a73b853",
"docs/evidence-engineered-coding.md": "32a514ed762e771e342e5a8aca31e1ca414adfcb10bc0e2221bf4af3e3c2e751",
"docs/generated-files.md": "136422baf0c7fc2bd5100cfe0ebdb3d9d0705dfd7e7d54bf745dd1037e63492c",
"docs/getting-started.md": "eacc814fdffdfa3c7d8052b7cd99a79c04da5c75d88d8b44f3fb68d9afec0316",
"docs/public-claims.json": "a52a7fe00d41909fab24a367a6e0d498ecc5983faab1fa0993e24562225ff61b",
"docs/public-claims.json": "cd07d38bd2390a87a9e031c2281eb7ec51c6b0393f41aae309dfe3246a9d0188",
"docs/public-surface.md": "713f7a050b5f339cf948299103ef3800417dccfecf2cc1a4166397ea6f978907",
"docs/research-and-design.md": "d65c66e323037bda5d45aacef5d48afa6bf93da55901378891d235aca3a5684f",
"docs/safety.md": "7b9b5c515d36e683767ec8d3d9d6d119ac93650b2f629d351deadd4c600ed6a6",
Expand All @@ -103,7 +103,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": "417542caeaf38ffd1e9777b5bafff9328890c6697ad5c671bf0e59502213293d",
"labs/diagram-json/plan.lock.json": "e181273a6a0c9b782ed6f5067883d0d4bc836215b8eb00bc968b4ffbf2b277c8",
"labs/diagram-json/plan.md": "3cc4f533b8d69386deff16b3a594a3ba09d4c0c3db636cccd8c4380084ce6a51",
"labs/diagram-json/questions.md": "74733b015002c8a6777c558e7e997fa48c94850b9bd39054fe9366c97ecf728d",
"labs/diagram-json/request.md": "0808fc41c36779c404f4a3a121167da6e76cac56df526e70f9ed6d3e0d4c02ed",
Expand Down Expand Up @@ -139,14 +139,15 @@
"release-notes/2026-07-20-gemini-cli-integration.md": "d829b4fafb3a02dd766e018558b20bf1bc948dd5e337911d6a7c8b54c83c9942",
"release-notes/2026-07-20-generic-execution-mode-dx.md": "e16aa73c4ef8da4acb9f8e24706c7dbaf7d416d27e51d147abee1d0219b6d8e0",
"release-notes/2026-07-20-managed-workspace-lifecycle.md": "e84e9c5a393ca88f9fc14d1f2a99ee9a2a1c525a16d141e9f9981bc9354d8f73",
"release-notes/2026-07-20-multi-pr-dx-improvements.md": "7bbefe56c0b0e7fcddeaaca0dfa6fb1b7a6493828c7a023f4e0387e66fbada4e",
"release-notes/2026-07-20-portability-diagram-dark-theme.md": "b06bebec1361b21ef6deb8c8f43168d189803a32588aeb803ea4b441525a77e2",
"release-notes/2026-07-20-product-focused-pr-titles.md": "ffb8f58fa4978de81f102ca0bbc7fc09b019293aff24e7c661ae635aa46ac839",
"release-notes/2026-07-20-speak-software-standards.md": "a8890ed7eb38868bdf3035572d71785ca89abd3ffc3a314a5dc5315150afe397"
},
"generator": "operatorstack/intelligence-flow:boatstack-distribution",
"schema_version": 1,
"source": {
"commit": "b90637c6c20526242ed84d4be086e3e609869da4",
"commit": "d27760b57f2026608a939c6fe1712d437bc91442",
"path": "labs/12-product-engineering-loop",
"repository": "operatorstack/intelligence-flow"
}
Expand Down
7 changes: 6 additions & 1 deletion boatstack/cmd/boatstack-helper/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,12 @@ func publishPRCommand(arguments []string) int {
verb = "updated"
}
fmt.Printf("PASS: PR %s without merge authorization\nPR_URL=%s\n", verb, url)
if update, ok := boatstack.PostShipUpdateNotice(*repo); ok {

feature := ""
if preview, err := boatstack.ParsePRPreview(*previewPath); err == nil {
feature = preview.Feature
}
if update, ok := boatstack.PostShipUpdateNotice(*repo, feature); ok {
fmt.Printf("UPDATE_AVAILABLE=%s\nUPDATE_RELEASE_URL=%s\n", update.LatestVersion, update.ReleaseURL)
}
return 0
Expand Down
9 changes: 8 additions & 1 deletion boatstack/next.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ type NextStatus struct {
VerificationStatus string `json:"verification_status"`
Feature string `json:"feature,omitempty"`
ActiveSlice string `json:"active_slice,omitempty"`
SliceIndex int `json:"slice_index,omitempty"`
TotalSlices int `json:"total_slices,omitempty"`
ObservedStage string `json:"observed_stage"`
NextOperation string `json:"next_operation"`
Reason string `json:"reason"`
Expand Down Expand Up @@ -136,6 +138,7 @@ func nextForDelivery(repo, feature string) (NextStatus, error) {
status := NextStatus{
SchemaVersion: nextStatusSchemaVersion, VerificationStatus: "VERIFIED",
Feature: feature, ActiveSlice: slice.ID, ObservedStage: slice.Status,
SliceIndex: state.ActiveIndex + 1, TotalSlices: len(state.Slices),
}
switch slice.Status {
case "BUILD":
Expand Down Expand Up @@ -336,7 +339,11 @@ func FormatNextStatus(status NextStatus) string {
parts = append(parts, "Feature: "+status.Feature)
}
if status.ActiveSlice != "" {
parts = append(parts, "Active slice: "+status.ActiveSlice)
if status.TotalSlices > 1 {
parts = append(parts, fmt.Sprintf("Active slice: %s (PR %d of %d)", status.ActiveSlice, status.SliceIndex, status.TotalSlices))
} else {
parts = append(parts, "Active slice: "+status.ActiveSlice)
}
}
parts = append(parts, "Reason: "+status.Reason, "Next: "+status.NextOperation)
if len(status.BlockingAmbiguity) > 0 {
Expand Down
19 changes: 15 additions & 4 deletions boatstack/pr.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ type PRContext struct {
Mode string `json:"mode"`
Feature string `json:"feature,omitempty"`
SliceID string `json:"slice_id,omitempty"`
SliceIndex int `json:"slice_index,omitempty"`
TotalSlices int `json:"total_slices,omitempty"`
BaseBranch string `json:"base_branch"`
HeadBranch string `json:"head_branch"`
BaseCommit string `json:"base_commit"`
Expand Down Expand Up @@ -429,6 +431,8 @@ func PreparePRContext(options PRContextOptions) (PRContext, error) {
sources := []PRSource{configSource}
gateStatus := map[string]string{}
sliceID := ""
sliceIndex := 0
totalSlices := 0
safety, err := CheckRepositorySafety(repo)
if err != nil {
return PRContext{}, fmt.Errorf("cannot establish operational safety evidence: %w", err)
Expand All @@ -443,14 +447,16 @@ func PreparePRContext(options PRContextOptions) (PRContext, error) {
}
sources = append(sources, managedSources...)
gateStatus = statuses
_, slice, gateSources, deliveryErr := CheckDeliveryReadyForShip(repo, options.Feature, base, head, SHA256Bytes(diff), changed)
state, slice, gateSources, deliveryErr := CheckDeliveryReadyForShip(repo, options.Feature, base, head, SHA256Bytes(diff), changed)
if deliveryErr != nil {
return PRContext{}, deliveryErr
}
if options.SliceID != "" && options.SliceID != slice.ID {
return PRContext{}, fmt.Errorf("delivery slice %s is not active; current slice is %s", options.SliceID, slice.ID)
}
sliceID = slice.ID
sliceIndex = state.ActiveIndex + 1
totalSlices = len(state.Slices)
sources = append(sources, gateSources...)
}
sort.Slice(sources, func(i, j int) bool { return sources[i].Path < sources[j].Path })
Expand All @@ -474,6 +480,7 @@ func PreparePRContext(options PRContextOptions) (PRContext, error) {
}
return PRContext{
SchemaVersion: prPreviewSchemaVersion, Mode: mode, Feature: options.Feature, SliceID: sliceID,
SliceIndex: sliceIndex, TotalSlices: totalSlices,
BaseBranch: base, HeadBranch: head, BaseCommit: baseCommit, MergeBaseCommit: mergeBaseCommit, HeadCommit: headCommit,
ProductDiffSHA256: SHA256Bytes(diff), ContextFingerprint: SHA256Bytes(fingerprintPayload),
ChangedFiles: changed, Commits: commits, DiffStat: diffStat,
Expand Down Expand Up @@ -855,7 +862,7 @@ func PRPreviewTemplate(context PRContext) string {
return string(encoded)
}
safetySummary := "Repository safety scan: `" + context.SafetyStatus + "`. Destructive recovery remains operator-only outside Boatstack."
return strings.Join([]string{
lines := []string{
"---",
"boatstack_pr_version: 2",
"title: " + quote("Describe the product or user value of this change (e.g., 'Enable historical data migration')"),
Expand All @@ -873,8 +880,12 @@ func PRPreviewTemplate(context PRContext) string {
"## Operational safety", "", safetySummary, "",
"## Known gaps and risks", "", "List explicit gaps or say that no material gaps are known.", "",
"## Rollout and rollback", "", "Describe deployment impact and the smallest safe rollback.", "",
"<details>", "<summary>Boatstack provenance</summary>", "", "Summarize mode, approval/evidence availability, and coding-host attribution here.", "", "</details>", "",
}, "\n")
}
if context.TotalSlices > 1 {
lines = append(lines, fmt.Sprintf("> *(This is PR %d of %d in the `%s` feature)*", context.SliceIndex, context.TotalSlices, context.Feature), "")
}
lines = append(lines, "<details>", "<summary>Boatstack provenance</summary>", "", "Summarize mode, approval/evidence availability, and coding-host attribution here.", "", "</details>", "")
return strings.Join(lines, "\n")
}

func PRContextJSON(context PRContext) ([]byte, error) {
Expand Down
7 changes: 6 additions & 1 deletion boatstack/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,12 @@ func CachedUpdate(repoPath string) (UpdateCheckResult, bool) {

// PostShipUpdateNotice is deliberately best-effort: release discovery can add
// information after a successful publication, but it cannot change that result.
func PostShipUpdateNotice(repo string) (UpdateCheckResult, bool) {
func PostShipUpdateNotice(repo string, feature string) (UpdateCheckResult, bool) {
if feature != "" {
if state, err := LoadDeliveryState(repo, feature); err == nil && state.ActiveIndex + 1 < len(state.Slices) {
return UpdateCheckResult{}, false
}
}
result, err := CheckForUpdate(UpdateCheckOptions{Repo: repo, Notify: true})
if err != nil || result.Status != "available" || !result.ShouldNotify {
return UpdateCheckResult{}, false
Expand Down
2 changes: 1 addition & 1 deletion boatstack/update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ func TestUpdateCheckCurrentAndFailures(t *testing.T) {
if err := os.Remove(updateStatePath(repo)); err != nil {
t.Fatal(err)
}
if notice, ok := PostShipUpdateNotice(repo); ok {
if notice, ok := PostShipUpdateNotice(repo, ""); ok {
t.Fatalf("release lookup failure changed post-ship behavior: %#v", notice)
}
if cached, ok := CachedUpdate(repo); ok {
Expand Down
2 changes: 1 addition & 1 deletion docs/evidence-engineered-coding.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,6 @@ Delivery and system improvement also remain separate. A failed task may suggest

## What is evidence-backed

The current moves were derived from the Intelligence Flow benchmark corpus and product-repository studies. The generated source commit is [`b90637c6c20526242ed84d4be086e3e609869da4`](https://github.com/operatorstack/intelligence-flow/tree/b90637c6c20526242ed84d4be086e3e609869da4/labs/12-product-engineering-loop).
The current moves were derived from the Intelligence Flow benchmark corpus and product-repository studies. The generated source commit is [`d27760b57f2026608a939c6fe1712d437bc91442`](https://github.com/operatorstack/intelligence-flow/tree/d27760b57f2026608a939c6fe1712d437bc91442/labs/12-product-engineering-loop).

The evidence supports specific failure mechanisms and guardrails. It does not establish that Boatstack is optimal, that control-theory notation proves software quality, or that one workflow dominates every team. Those are evaluation questions, so the distribution preserves measurements, provenance, gaps, and negative results.
Loading
Loading