From ca87a9bf073fd5a815dd3e54e9a853a5cdc5c7ab Mon Sep 17 00:00:00 2001 From: "operator-stack-publisher[bot]" Date: Mon, 20 Jul 2026 12:44:24 +0000 Subject: [PATCH] Sync Boatstack from Intelligence Flow Labs @ d27760b57f20 --- CONTRIBUTING.md | 2 +- UPSTREAM.json | 21 ++++++++-------- boatstack/cmd/boatstack-helper/main.go | 7 +++++- boatstack/next.go | 9 ++++++- boatstack/pr.go | 19 +++++++++++---- boatstack/update.go | 7 +++++- boatstack/update_test.go | 2 +- docs/evidence-engineered-coding.md | 2 +- docs/public-claims.json | 24 +++++++++---------- labs/diagram-json/plan.lock.json | 2 +- .../2026-07-20-multi-pr-dx-improvements.md | 3 +++ 11 files changed, 65 insertions(+), 33 deletions(-) create mode 100644 release-notes/2026-07-20-multi-pr-dx-improvements.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1c9fa90..2d7b280 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -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. diff --git a/UPSTREAM.json b/UPSTREAM.json index 745d1d1..546e298 100644 --- a/UPSTREAM.json +++ b/UPSTREAM.json @@ -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", @@ -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", @@ -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", @@ -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", @@ -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", @@ -139,6 +139,7 @@ "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" @@ -146,7 +147,7 @@ "generator": "operatorstack/intelligence-flow:boatstack-distribution", "schema_version": 1, "source": { - "commit": "b90637c6c20526242ed84d4be086e3e609869da4", + "commit": "d27760b57f2026608a939c6fe1712d437bc91442", "path": "labs/12-product-engineering-loop", "repository": "operatorstack/intelligence-flow" } diff --git a/boatstack/cmd/boatstack-helper/main.go b/boatstack/cmd/boatstack-helper/main.go index b21ace4..2ad42ef 100644 --- a/boatstack/cmd/boatstack-helper/main.go +++ b/boatstack/cmd/boatstack-helper/main.go @@ -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 diff --git a/boatstack/next.go b/boatstack/next.go index baff20a..889576d 100644 --- a/boatstack/next.go +++ b/boatstack/next.go @@ -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"` @@ -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": @@ -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 { diff --git a/boatstack/pr.go b/boatstack/pr.go index a2b039e..296e639 100644 --- a/boatstack/pr.go +++ b/boatstack/pr.go @@ -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"` @@ -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) @@ -443,7 +447,7 @@ 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 } @@ -451,6 +455,8 @@ func PreparePRContext(options PRContextOptions) (PRContext, error) { 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 }) @@ -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, @@ -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')"), @@ -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.", "", - "
", "Boatstack provenance", "", "Summarize mode, approval/evidence availability, and coding-host attribution here.", "", "
", "", - }, "\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, "
", "Boatstack provenance", "", "Summarize mode, approval/evidence availability, and coding-host attribution here.", "", "
", "") + return strings.Join(lines, "\n") } func PRContextJSON(context PRContext) ([]byte, error) { diff --git a/boatstack/update.go b/boatstack/update.go index e23d85f..2b3fa52 100644 --- a/boatstack/update.go +++ b/boatstack/update.go @@ -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 diff --git a/boatstack/update_test.go b/boatstack/update_test.go index 91914ef..29cc991 100644 --- a/boatstack/update_test.go +++ b/boatstack/update_test.go @@ -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 { diff --git a/docs/evidence-engineered-coding.md b/docs/evidence-engineered-coding.md index 03a221c..e49a0a7 100644 --- a/docs/evidence-engineered-coding.md +++ b/docs/evidence-engineered-coding.md @@ -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. diff --git a/docs/public-claims.json b/docs/public-claims.json index f1e0f0f..5932818 100644 --- a/docs/public-claims.json +++ b/docs/public-claims.json @@ -1,6 +1,6 @@ { "schema_version": 1, - "source_commit": "b90637c6c20526242ed84d4be086e3e609869da4", + "source_commit": "d27760b57f2026608a939c6fe1712d437bc91442", "statuses": ["verified", "observed", "still_being_evaluated"], "claims": [ { @@ -12,7 +12,7 @@ "readable_evidence": "why-these-steps.md#portable-workflow-and-state", "implementation": ["../boatstack/export.go", "../boatstack/references/artifacts.md", "../boatstack/references/workflow.md"], "verification": ["../boatstack/export_test.go"], - "last_verified_version": "source:b90637c6c20526242ed84d4be086e3e609869da4" + "last_verified_version": "source:d27760b57f2026608a939c6fe1712d437bc91442" }, { "id": "human-decisions", @@ -23,7 +23,7 @@ "readable_evidence": "why-these-steps.md#human-decisions", "implementation": ["../boatstack/references/workflow.md", "../boatstack/plan.go"], "verification": ["../boatstack/plan_test.go", "../boatstack/planning_test.go"], - "last_verified_version": "source:b90637c6c20526242ed84d4be086e3e609869da4" + "last_verified_version": "source:d27760b57f2026608a939c6fe1712d437bc91442" }, { "id": "validation-provenance", @@ -34,7 +34,7 @@ "readable_evidence": "why-these-steps.md#validation-provenance", "implementation": ["validation-and-evidence.md", "../boatstack/plan.go"], "verification": ["../boatstack/plan_test.go"], - "last_verified_version": "source:b90637c6c20526242ed84d4be086e3e609869da4" + "last_verified_version": "source:d27760b57f2026608a939c6fe1712d437bc91442" }, { "id": "irreversible-operations", @@ -46,7 +46,7 @@ "readable_evidence": "why-these-steps.md#irreversible-operations", "implementation": ["safety.md", "../boatstack/safety.go", "../boatstack/hooks.go"], "verification": ["../boatstack/safety_test.go", "../boatstack/hooks_test.go"], - "last_verified_version": "source:b90637c6c20526242ed84d4be086e3e609869da4" + "last_verified_version": "source:d27760b57f2026608a939c6fe1712d437bc91442" }, { "id": "reviewer-ready-pr", @@ -57,7 +57,7 @@ "readable_evidence": "why-these-steps.md#reviewer-ready-pr", "implementation": ["../boatstack/pr.go", "getting-started.md"], "verification": ["../boatstack/pr_test.go"], - "last_verified_version": "source:b90637c6c20526242ed84d4be086e3e609869da4" + "last_verified_version": "source:d27760b57f2026608a939c6fe1712d437bc91442" }, { "id": "phase-scoped-delivery", @@ -68,7 +68,7 @@ "readable_evidence": "why-these-steps.md#phase-scoped-delivery", "implementation": ["../boatstack/delivery.go", "../boatstack/safety.go", "../boatstack/hooks.go", "../boatstack/references/workflow.md"], "verification": ["../boatstack/delivery_test.go", "../boatstack/pr_test.go"], - "last_verified_version": "source:b90637c6c20526242ed84d4be086e3e609869da4" + "last_verified_version": "source:d27760b57f2026608a939c6fe1712d437bc91442" }, { "id": "model-neutral-contract", @@ -79,7 +79,7 @@ "readable_evidence": "why-these-steps.md#model-choice-and-budget", "implementation": ["research-and-design.md", "../boatstack/references/workflow.md"], "verification": ["../boatstack/export_test.go", "../boatstack/planning_test.go"], - "last_verified_version": "source:b90637c6c20526242ed84d4be086e3e609869da4" + "last_verified_version": "source:d27760b57f2026608a939c6fe1712d437bc91442" }, { "id": "cross-model-failures", @@ -90,7 +90,7 @@ "readable_evidence": "why-these-steps.md#model-choice-and-budget", "implementation": ["research-and-design.md"], "verification": ["benchmark-corpus-audit.md", "benchmark-submission-audit.md"], - "last_verified_version": "source:b90637c6c20526242ed84d4be086e3e609869da4" + "last_verified_version": "source:d27760b57f2026608a939c6fe1712d437bc91442" }, { "id": "lower-cost-outcomes", @@ -101,7 +101,7 @@ "readable_evidence": "why-these-steps.md#model-choice-and-budget", "implementation": ["research-and-design.md"], "verification": ["benchmark-corpus-audit.md", "benchmark-submission-audit.md"], - "last_verified_version": "source:b90637c6c20526242ed84d4be086e3e609869da4" + "last_verified_version": "source:d27760b57f2026608a939c6fe1712d437bc91442" }, { "id": "git-worktree-activation", @@ -112,7 +112,7 @@ "readable_evidence": "why-these-steps.md#git-worktree-activation", "implementation": ["../boatstack/runtime_cache.go", "../boatstack/hooks.go"], "verification": ["../boatstack/runtime_cache_test.go", "../boatstack/hooks_test.go"], - "last_verified_version": "source:b90637c6c20526242ed84d4be086e3e609869da4" + "last_verified_version": "source:d27760b57f2026608a939c6fe1712d437bc91442" }, { "id": "visible-updates", @@ -123,7 +123,7 @@ "readable_evidence": "why-these-steps.md#visible-updates", "implementation": ["../boatstack/update.go", "../boatstack/init.go"], "verification": ["../boatstack/update_test.go", "../boatstack/init_test.go", "../boatstack/export_test.go"], - "last_verified_version": "source:b90637c6c20526242ed84d4be086e3e609869da4" + "last_verified_version": "source:d27760b57f2026608a939c6fe1712d437bc91442" } ] } diff --git a/labs/diagram-json/plan.lock.json b/labs/diagram-json/plan.lock.json index 76387fe..944bfd5 100644 --- a/labs/diagram-json/plan.lock.json +++ b/labs/diagram-json/plan.lock.json @@ -6,7 +6,7 @@ "plan_path": "labs/diagram-json/plan.md", "plan_sha256": "3cc4f533b8d69386deff16b3a594a3ba09d4c0c3db636cccd8c4380084ce6a51", "schema_version": 1, - "source_commit": "b90637c6c20526242ed84d4be086e3e609869da4", + "source_commit": "d27760b57f2026608a939c6fe1712d437bc91442", "source_plan_path": "labs/diagram-json/source-plan.md", "source_plan_sha256": "e10593ddaa7522ab80cc991d0a09399257139799e37f737794cd49d68a39985b", "spec_path": "labs/diagram-json/spec.md", diff --git a/release-notes/2026-07-20-multi-pr-dx-improvements.md b/release-notes/2026-07-20-multi-pr-dx-improvements.md new file mode 100644 index 0000000..fe1da26 --- /dev/null +++ b/release-notes/2026-07-20-multi-pr-dx-improvements.md @@ -0,0 +1,3 @@ +### Improve developer experience for multi-PR features + +Boatstack now surfaces slice progression in multi-PR features by indicating the current slice relative to the total slices (e.g., `(PR 1 of 4)`). This context is shown in the terminal when interacting with the feature and is embedded directly within generated PR descriptions. Additionally, Boatstack update notices are suppressed during intermediate slice builds to ensure developers aren't distracted until the final PR of the feature is published.