diff --git a/labs/12-product-engineering-loop/GEMINI.md b/labs/12-product-engineering-loop/GEMINI.md new file mode 100644 index 000000000..dd6aa1e19 --- /dev/null +++ b/labs/12-product-engineering-loop/GEMINI.md @@ -0,0 +1,11 @@ +# Boatstack Lab Development Guidelines + +When modifying files in this lab (`labs/12-product-engineering-loop`), you must adhere to the "speak software" standard. + +## Mandatory Release Notes + +1. **Release Notes Required**: Any change that modifies a published module or lab **requires** a new, dated, append-only release note fragment in `labs/12-product-engineering-loop/boatstack-distribution/release-notes/`. +2. **Format**: The filename should be `YYYY-MM-DD-short-description.md`. The first line must be a level-three Markdown heading (`### `) describing the change. The body should explain the impact. +3. **CI Requirement**: This is programmatically enforced by `release_notes.py check-policy` and preflight checks in CI. + +Do not skip creating a release note when instructed to ship, commit, or build a change in this directory! \ No newline at end of file diff --git a/labs/12-product-engineering-loop/boatstack-distribution/release-notes/2026-07-20-product-focused-pr-titles.md b/labs/12-product-engineering-loop/boatstack-distribution/release-notes/2026-07-20-product-focused-pr-titles.md new file mode 100644 index 000000000..0eb1281c0 --- /dev/null +++ b/labs/12-product-engineering-loop/boatstack-distribution/release-notes/2026-07-20-product-focused-pr-titles.md @@ -0,0 +1,3 @@ +### Enforce product-focused PR titles + +The Boatstack agent instructions for `ship-gate` and the `pr-context` generated template have been updated to enforce product-focused PR titles. The LLM is now explicitly instructed to describe the user value or system outcome rather than listing technical components or using sequence prefixes like 'PR 1'. diff --git a/labs/12-product-engineering-loop/product-engineering-loop/assets/templates/plan.md b/labs/12-product-engineering-loop/product-engineering-loop/assets/templates/plan.md index ab8f9c126..88d8bf56f 100644 --- a/labs/12-product-engineering-loop/product-engineering-loop/assets/templates/plan.md +++ b/labs/12-product-engineering-loop/product-engineering-loop/assets/templates/plan.md @@ -47,7 +47,7 @@ "delivery_slices": [ { "id": "delivery", - "title": "", + "title": "", "task_ids": ["T-1"], "base_branch": "", "head_branch": "" diff --git a/labs/12-product-engineering-loop/product-engineering-loop/export.go b/labs/12-product-engineering-loop/product-engineering-loop/export.go index e97d13548..50aff47fc 100644 --- a/labs/12-product-engineering-loop/product-engineering-loop/export.go +++ b/labs/12-product-engineering-loop/product-engineering-loop/export.go @@ -270,7 +270,7 @@ func BuildExportBundle(configPath string, config ProjectConfig, rawConfig []byte "repair": "First run next-status --repo . --json. Repair requires an active managed delivery and the user's exact free-form requested change. If NOT_STARTED or SOURCE_PLAN_READY, respond No active delivery to repair and make /auto-plan the one next action; do not ask for repair details. If DRAFT_PLAN or APPROVED, route to the returned plan-gate or build operation because no managed delivery exists yet. If FEATURE_COMPLETE and the user supplied an exact correction, preserve the published evidence and plan a linked Boatstack feature with parent_delivery set to the completed feature; otherwise ask for the exact correction. Stop on BLOCKED or INVALID_STATE and preserve all artifacts. For an active delivery, read delivery-status, the current plan lock and acceptance criteria, the actual diff, and current receipts. Compare the exact request with approved intent. Classify it as implementation_repair, verification_repair, review_repair, requirement_amendment, or needs_clarification, then invoke record-change before any product edit. Same-intent repairs may proceed at the returned RESUME_STAGE; requirement amendments and ambiguous intent must stop for a concise plan amendment or one clarifying question. Never edit changes.md or managed delivery state directly. After a repair, reuse the existing /test-gate and /review-gate; do not invent repair-specific gates. If Cursor reports MainThreadShellExec not initialized, make Developer: Reload Window the one recovery action because Boatstack's hook did not start; reserve reinstall guidance for Boatstack runtime integrity errors.", "test-gate": "Read delivery-status and test only the active delivery slice. Run the internal repository safety check, build a requirement-to-evidence matrix, and treat self-authored tests as evidence rather than the sole oracle. External writes require immutable target identity, transactional or fix-forward failure behavior, and an independent safety oracle. Commit the intentional slice product and evidence diff, then record-delivery-gate for the active feature and slice with --gate test and PASS or PASS_WITH_GAPS. Editing evidence Markdown alone never passes the gate. On pass respond Tests passed and make Run /review-gate the one next action. On failure respond Testing found a problem and make the required non-destructive repair the one next action.", "review-gate": "Read delivery-status and review the active slice's actual diff against approved intent, invariants, risks, gaps, and test evidence. Run the internal repository safety check. Executable destructive capability is blocking even when ordinary tests pass. When workflow.maintain_changelog is true, verify the new CHANGELOG.md Unreleased entry accurately describes the actual reader-visible impact rather than commits, PR metadata, artifacts, or test commands. On pass invoke record-delivery-gate for the same feature and slice with --gate review; it must reject a changed or untested diff and a missing or malformed required changelog entry. Then respond Review passed and make Run /ship-gate the one next action. When blocked respond Changes required and make the highest-priority blocking repair the one next action.", - "ship-gate": "Prepare a reviewer-ready PR only; do not merge or deploy without separate authorization. Require the current managed feature approval, lock, test evidence, review evidence, and a passing repository safety scan, and commit the intentional product/artifact diff before projection. Internally run pr-context --repo . --feature in json and template formats, project the approved intent, actual committed diff, decisions, evidence, gaps, rollout, rollback, safety outcome, and operator-only recovery boundary into its required pr.md path, then run check-pr --repo . --preview . 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 the diff makes them relevant. Show the exact title and rendered body before any GitHub mutation. If PR_ACTION is open, respond PR ready and render the one next action as: Reply `o` to open PR. If update, render: Reply `u` to update PR. If manual, preserve the preview and give one manual publication action. Continue accepting the full replies open PR and update PR for compatibility without advertising them. Only after the matching state-scoped shortcut or compatible full reply: commit only the reviewed pr.md, rerun check-pr and require the same preview fingerprint (PREVIEW_FINGERPRINT), then run publish-pr with --action open or update and that fingerprint. The publisher performs a non-force push and rechecks context before GitHub mutation. If the diff or evidence changes, regenerate instead. If a required check fails on the base branch too, record the evidence and recommend a separate repair PR. Never edit unrelated code in this approved feature branch; a policy-approved bypass requires explicit human authorization. After publication respond PR opened with the link and make Review the PR the one next action; never imply merge authorization. If publish-pr returns UPDATE_AVAILABLE, keep Review the PR as the only next action and append a collapsed update notice saying no files changed and /boatstack-update may be run from the clean default branch after this feature PR merges. Do not check for releases before successful publication.", + "ship-gate": "Prepare a reviewer-ready PR only; do not merge or deploy without separate authorization. Require the current managed feature approval, lock, test evidence, review evidence, and a passing repository safety scan, and commit the intentional product/artifact diff before projection. Internally run pr-context --repo . --feature in json and template formats, project the approved intent, actual committed diff, decisions, evidence, gaps, rollout, rollback, safety outcome, and operator-only recovery boundary into its required pr.md path, then run check-pr --repo . --preview . Generate a clear, product-focused PR title that describes the user value or system outcome rather than listing technical components (do not use sequence prefixes like 'PR 1'). 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 the diff makes them relevant. Show the exact title and rendered body before any GitHub mutation. If PR_ACTION is open, respond PR ready and render the one next action as: Reply `o` to open PR. If update, render: Reply `u` to update PR. If manual, preserve the preview and give one manual publication action. Continue accepting the full replies open PR and update PR for compatibility without advertising them. Only after the matching state-scoped shortcut or compatible full reply: commit only the reviewed pr.md, rerun check-pr and require the same preview fingerprint (PREVIEW_FINGERPRINT), then run publish-pr with --action open or update and that fingerprint. The publisher performs a non-force push and rechecks context before GitHub mutation. If the diff or evidence changes, regenerate instead. If a required check fails on the base branch too, record the evidence and recommend a separate repair PR. Never edit unrelated code in this approved feature branch; a policy-approved bypass requires explicit human authorization. After publication respond PR opened with the link and make Review the PR the one next action; never imply merge authorization. If publish-pr returns UPDATE_AVAILABLE, keep Review the PR as the only next action and append a collapsed update notice saying no files changed and /boatstack-update may be run from the clean default branch after this feature PR merges. Do not check for releases before successful publication.", "boatstack-update": "Prepare a visible Boatstack infrastructure update; never mix it into product work or merge it. First run the current helper doctor and force check-update. If current, respond Boatstack is current with No action required. Before mutation fetch the default ref, then require the current clean default branch whose HEAD equals origin/; otherwise respond Update postponed and make finishing the current feature, switching to the clean default branch, and rerunning /boatstack-update the one action. Ensure no update PR or branch already exists, create chore/update-boatstack-v, then run the installer fetched from that exact release tag with BOATSTACK_MODE=update, BOATSTACK_VERSION=, BOATSTACK_REPO=, and BOATSTACK_YES=1. Use install.sh on macOS/Linux and install.ps1 on Windows. The verified update must preserve configuration, adapters, integrations, and user-owned host settings, run doctor, and touch only Boatstack infrastructure. Show the version transition, release notes and link, integration state, exact diff, changed paths, checksums, rollout, and rollback. Respond Boatstack update ready and render the one next action as: Reply `o` to open update PR. Continue accepting the full reply open update PR for compatibility without advertising it. Only the matching state-scoped shortcut or compatible full reply authorizes staging the installer-reported paths, committing chore: update Boatstack to , normal push, and opening a reviewer-ready update PR. If GitHub auth is unavailable, preserve the branch and give one manual publication action. After publication respond Update PR opened with the link and make Review the PR the one next action. On one collision or health failure, respond Update needs attention and make addressing that named problem the one next action. Never merge automatically.", "review": "Alias of review-gate: review the actual diff against approved intent, invariants, risks, gaps, and test evidence. Use Review passed or Changes required and the same single-action routing as review-gate.", "ship": "Alias of ship-gate: prepare and preview the exact reviewer-ready title and body before any GitHub mutation. Require the state-scoped reply o to open or u to update the PR before publication, recheck the preview against current evidence, and never merge or deploy. Keep pre-existing unrelated failures out of the approved feature branch. Use PR ready before confirmation or PR opened after publication.", diff --git a/labs/12-product-engineering-loop/product-engineering-loop/pr.go b/labs/12-product-engineering-loop/product-engineering-loop/pr.go index 2ee5f1888..a2b039e0f 100644 --- a/labs/12-product-engineering-loop/product-engineering-loop/pr.go +++ b/labs/12-product-engineering-loop/product-engineering-loop/pr.go @@ -858,7 +858,7 @@ func PRPreviewTemplate(context PRContext) string { return strings.Join([]string{ "---", "boatstack_pr_version: 2", - "title: " + quote("Describe the reviewer-visible outcome"), + "title: " + quote("Describe the product or user value of this change (e.g., 'Enable historical data migration')"), "mode: " + quote(context.Mode), "feature: " + quote(context.Feature), "slice: " + quote(context.SliceID),