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 1c9fa90b..2d7b2809 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 745d1d12..546e298a 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 b21ace45..2ad42ef0 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 baff20a3..889576d3 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 a2b039e0..296e6395 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 e23d85f6..2b3fa52b 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 91914efc..29cc991c 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 03a221c9..e49a0a7f 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 f1e0f0f9..5932818d 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 76387fed..944bfd58 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 00000000..fe1da260 --- /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.