yadflow 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/LICENSE +21 -0
  3. package/README.md +559 -0
  4. package/bin/sdlc.mjs +135 -0
  5. package/cli/commit.mjs +81 -0
  6. package/cli/epic-state.mjs +220 -0
  7. package/cli/gate.mjs +456 -0
  8. package/cli/lib.mjs +142 -0
  9. package/cli/manifest.mjs +119 -0
  10. package/cli/openpr.mjs +65 -0
  11. package/cli/plan.mjs +127 -0
  12. package/cli/platform.mjs +151 -0
  13. package/cli/reconcile.mjs +83 -0
  14. package/cli/repo.mjs +61 -0
  15. package/cli/setup.mjs +208 -0
  16. package/package.json +51 -0
  17. package/skills/sdlc/config.yaml +156 -0
  18. package/skills/sdlc/install.sh +51 -0
  19. package/skills/sdlc/module-help.csv +17 -0
  20. package/skills/sdlc-author-analysis/SKILL.md +136 -0
  21. package/skills/sdlc-author-architecture/SKILL.md +180 -0
  22. package/skills/sdlc-author-architecture/references/contract-format.md +72 -0
  23. package/skills/sdlc-author-epic/SKILL.md +154 -0
  24. package/skills/sdlc-author-epic/references/state-schema.md +187 -0
  25. package/skills/sdlc-author-stories/SKILL.md +109 -0
  26. package/skills/sdlc-author-stories/references/story-schema.md +46 -0
  27. package/skills/sdlc-author-ui/SKILL.md +113 -0
  28. package/skills/sdlc-backfill/SKILL.md +91 -0
  29. package/skills/sdlc-backfill/references/backfill.md +66 -0
  30. package/skills/sdlc-backfill/templates/checks/backfill-check.sh +42 -0
  31. package/skills/sdlc-checks/SKILL.md +138 -0
  32. package/skills/sdlc-checks/references/check-gates.md +168 -0
  33. package/skills/sdlc-checks/templates/checks/build-test-lint.sh +14 -0
  34. package/skills/sdlc-checks/templates/checks/contract-check.sh +62 -0
  35. package/skills/sdlc-checks/templates/checks/spec-link.sh +38 -0
  36. package/skills/sdlc-checks/templates/checks/verified-commits.sh +120 -0
  37. package/skills/sdlc-checks/templates/github/sdlc-checks.yml +45 -0
  38. package/skills/sdlc-checks/templates/github/sdlc-verified-commits.yml +22 -0
  39. package/skills/sdlc-checks/templates/gitlab/.gitlab-ci.yml +40 -0
  40. package/skills/sdlc-checks/templates/gitlab/gitlab-ci.include-root.yml +7 -0
  41. package/skills/sdlc-checks/templates/gitlab/sdlc-checks.gitlab-ci.yml +47 -0
  42. package/skills/sdlc-checks/templates/gitlab/sdlc-verified-commits.gitlab-ci.yml +21 -0
  43. package/skills/sdlc-connect-repos/SKILL.md +159 -0
  44. package/skills/sdlc-connect-repos/references/code-context.md +92 -0
  45. package/skills/sdlc-connect-repos/references/hub-config.md +77 -0
  46. package/skills/sdlc-connect-repos/references/repos-registry.md +62 -0
  47. package/skills/sdlc-hub-bridge/SKILL.md +119 -0
  48. package/skills/sdlc-hub-bridge/references/bridge.md +136 -0
  49. package/skills/sdlc-hub-bridge/references/login-roster.md +42 -0
  50. package/skills/sdlc-hub-bridge/templates/checks/hub-route.sh +50 -0
  51. package/skills/sdlc-hub-bridge/templates/github/sdlc-gate-sync.yml +63 -0
  52. package/skills/sdlc-hub-bridge/templates/gitlab/gitlab-ci.include-root.yml +7 -0
  53. package/skills/sdlc-hub-bridge/templates/gitlab/sdlc-gate-sync.gitlab-ci.yml +64 -0
  54. package/skills/sdlc-implement/SKILL.md +143 -0
  55. package/skills/sdlc-implement/references/implement-conventions.md +103 -0
  56. package/skills/sdlc-implement/templates/.gitmessage +17 -0
  57. package/skills/sdlc-pr-template/SKILL.md +86 -0
  58. package/skills/sdlc-pr-template/references/risk-routing.md +54 -0
  59. package/skills/sdlc-pr-template/templates/checks/risk-route.sh +44 -0
  60. package/skills/sdlc-pr-template/templates/github/pull_request_template.md +30 -0
  61. package/skills/sdlc-pr-template/templates/gitlab/merge_request_templates/Default.md +32 -0
  62. package/skills/sdlc-pr-template/templates/hub/github/pull_request_template.md +36 -0
  63. package/skills/sdlc-pr-template/templates/hub/gitlab/merge_request_templates/Default.md +37 -0
  64. package/skills/sdlc-review-comments/SKILL.md +63 -0
  65. package/skills/sdlc-review-comments/references/comment-conventions.md +55 -0
  66. package/skills/sdlc-review-comments/templates/github/REVIEW_COMMENTS.md +49 -0
  67. package/skills/sdlc-review-comments/templates/gitlab/REVIEW_COMMENTS.md +49 -0
  68. package/skills/sdlc-review-gate/SKILL.md +196 -0
  69. package/skills/sdlc-review-gate/references/gating.md +79 -0
  70. package/skills/sdlc-run/SKILL.md +109 -0
  71. package/skills/sdlc-run/references/run-loop.md +121 -0
  72. package/skills/sdlc-ship/SKILL.md +86 -0
  73. package/skills/sdlc-ship/references/ship-and-record.md +67 -0
  74. package/skills/sdlc-ship/templates/.coderabbit.yaml +19 -0
  75. package/skills/sdlc-spec/SKILL.md +119 -0
  76. package/skills/sdlc-spec/references/spec-handoff.md +101 -0
  77. package/skills/sdlc-status/SKILL.md +92 -0
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env bash
2
+ # Risk routing (Phase 3 build plan §D). Reads a PR/MR description's Impact & Risk block and prints the
3
+ # required reviewers, reusing sdlc-review-gate's escalation: a `high` risk level — or a touched
4
+ # contract/auth/payments surface — requires a domain-owner approval per touched domain, on top of the
5
+ # base rule (owner + 1 reviewer). Advisory: it ROUTES the human review; it does not approve or merge.
6
+ set -euo pipefail
7
+
8
+ BODY="${1:?usage: risk-route.sh <pr-description-file>}"
9
+ [ -f "$BODY" ] || { echo "risk-route: file not found: $BODY" >&2; exit 2; }
10
+
11
+ # Value side of the FIRST line matching a label regex, with any HTML comment + markdown markers
12
+ # stripped. Tolerant: a missing label yields empty (never aborts) — an advisory helper must still
13
+ # produce output for a half-filled body. Anchor on the real label so the right line is read.
14
+ value_of() {
15
+ grep -iE "$1" "$BODY" 2>/dev/null | head -1 \
16
+ | sed -E 's/<!--.*$//; s/^[^:]*://; s/[*`]//g; s/^[[:space:]]*//; s/[[:space:]]*$//' || true
17
+ }
18
+
19
+ risk="$(printf '%s' "$(value_of 'Risk level:')" | tr 'A-Z' 'a-z' | grep -oE 'low|medium|high' | head -1 || true)"
20
+ contract="$(printf '%s' "$(value_of 'Contract surface touched:')" | tr 'A-Z' 'a-z' | grep -oE 'yes|no' | head -1 || true)"
21
+ domains="$(value_of 'Domains.*touched:')"
22
+
23
+ echo "Risk level: ${risk:-unspecified}"
24
+ echo "Contract surface touched: ${contract:-unspecified}"
25
+ echo "Domains touched: ${domains:-unspecified}"
26
+
27
+ if [ "$risk" = "high" ] || [ "$contract" = "yes" ]; then
28
+ why=""
29
+ [ "$risk" = "high" ] && why="risk: high"
30
+ [ "$contract" = "yes" ] && why="${why:+$why, }contract surface touched"
31
+ echo "ROUTE: ESCALATED (${why}) -> owner + 1 reviewer PLUS one domain-owner approval per touched domain"
32
+ echo " (same escalation as sdlc-review-gate). Required domain owners:"
33
+ case "$domains" in
34
+ ""|*"<"*|*"…"*|*"|"*)
35
+ echo " (Domains line not filled in — list each touched domain to route the owners.)" ;;
36
+ *)
37
+ printf '%s\n' "$domains" | tr ',' '\n' | while IFS= read -r d; do
38
+ d="$(printf '%s' "$d" | sed -E 's/^[[:space:]]*//; s/[[:space:]]*$//')"
39
+ [ -n "$d" ] && echo " - domain-owner: $d"
40
+ done ;;
41
+ esac
42
+ else
43
+ echo "ROUTE: base rule -> owner + 1 reviewer (no domain-owner escalation)."
44
+ fi
@@ -0,0 +1,30 @@
1
+ <!-- SDLC PR template (Phase 3 build plan §D). One atomic task per PR. -->
2
+
3
+ ## Summary
4
+ <!-- What this PR does, in one or two sentences. -->
5
+
6
+ ## Story / task
7
+ <!-- The commits MUST carry a `Task: <story>-<task>` trailer (the spec-link gate checks this). -->
8
+ - Story / task: `EP-<slug>-S0N-T0N`
9
+ - Spec: `specs/EP-<slug>-S0N/` (link.md points back to the product repo)
10
+
11
+ ## Impact & Risk
12
+ <!-- Fill every field. risk-route.sh + the engineer review read this block. -->
13
+ - **Domains / repos touched:** <backend | mobile | …>
14
+ - **Contract surface touched:** no <!-- yes => needs Contract-Change + a re-locked contract (contract-check) -->
15
+ - **Risk level:** low <!-- low | medium | high — high (or a contract/auth/payments surface) routes to domain owners -->
16
+ - **Rollback plan:** <how to revert if this misbehaves>
17
+
18
+ > **Routing:** `low`/`medium` → base rule (owner + 1 reviewer). `high` (or a touched
19
+ > contract/auth/payments surface) → **plus one domain-owner approval per touched domain**, the same
20
+ > escalation `sdlc-review-gate` applies. Run `bash checks/risk-route.sh <this-description>` to list them.
21
+
22
+ ## Testing
23
+ <!-- How the acceptance criteria were exercised. Tests must exercise behavior, not just pass. -->
24
+
25
+ ## Checklist
26
+ - [ ] Commits carry a `Task: <story>-<task>` trailer (spec-link gate)
27
+ - [ ] No contract-surface change without `Contract-Change: yes` + a re-locked contract (contract-check gate)
28
+ - [ ] Lint, build, and tests pass (build/test/lint gate)
29
+ - [ ] Diff stays inside the files the task's spec declared (≤3 where possible)
30
+ - [ ] Impact & Risk filled; `high` risk adds the required domain-owner reviewers
@@ -0,0 +1,32 @@
1
+ <!-- SDLC MR template (Phase 3 build plan §D). One atomic task per MR. -->
2
+
3
+ ## Summary
4
+ <!-- What this MR does, in one or two sentences. -->
5
+
6
+ ## Story / task
7
+ <!-- The commits MUST carry a `Task: <story>-<task>` trailer (the spec-link gate checks this). -->
8
+ - Story / task: `EP-<slug>-S0N-T0N`
9
+ - Spec: `specs/EP-<slug>-S0N/` (link.md points back to the product repo)
10
+
11
+ ## Impact & Risk
12
+ <!-- Fill every field. risk-route.sh + the engineer review read this block. -->
13
+ - **Domains / repos touched:** <backend | mobile | …>
14
+ - **Contract surface touched:** no <!-- yes => needs Contract-Change + a re-locked contract (contract-check) -->
15
+ - **Risk level:** low <!-- low | medium | high — high (or a contract/auth/payments surface) routes to domain owners -->
16
+ - **Rollback plan:** <how to revert if this misbehaves>
17
+
18
+ > **Routing:** `low`/`medium` → base rule (owner + 1 reviewer). `high` (or a touched
19
+ > contract/auth/payments surface) → **plus one domain-owner approval per touched domain**, the same
20
+ > escalation `sdlc-review-gate` applies. Run `bash checks/risk-route.sh <this-description>` to list them.
21
+
22
+ ## Testing
23
+ <!-- How the acceptance criteria were exercised. Tests must exercise behavior, not just pass. -->
24
+
25
+ ## Checklist
26
+ - [ ] Commits carry a `Task: <story>-<task>` trailer (spec-link gate)
27
+ - [ ] No contract-surface change without `Contract-Change: yes` + a re-locked contract (contract-check gate)
28
+ - [ ] Lint, build, and tests pass (build/test/lint gate)
29
+ - [ ] Diff stays inside the files the task's spec declared (≤3 where possible)
30
+ - [ ] Impact & Risk filled; `high` risk adds the required domain-owner reviewers
31
+
32
+ /assign me
@@ -0,0 +1,36 @@
1
+ <!-- SDLC HUB PR template — front-half artifact review (epic / architecture+contract / ui-design / stories). -->
2
+ <!-- This PR is a REVIEW VEHICLE on the product hub, not a code merge. The file gate (sdlc-review-gate)
3
+ advances the step; do NOT rely on merging this PR to advance. Reviewers approve/comment here, then a
4
+ `sdlc-review-gate action: sync` pulls that into the file ledger. -->
5
+
6
+ ## Artifact under review
7
+ - Epic: `EP-<slug>`
8
+ - Artifact: `epic.md | architecture.md (+contract.md) | ui-design.md | stories/`
9
+ - Gate step: `<epic-review | architecture-review | ui-design-review | stories-review>`
10
+ - Owner: `<epic.md owner>`
11
+
12
+ ## What changed
13
+ <!-- One or two sentences on what this artifact says / what changed since the last review round. -->
14
+
15
+ ## Impact & Risk (front-half)
16
+ - **Domains / repos touched:** <epic.repos, e.g. backend, mobile>
17
+ - **Risk tags:** <none | contract | auth | payments> <!-- contract/auth/payments => escalates to domain owners -->
18
+ - **Contract surface:** <n/a | locked @ sha256:…> <!-- architecture only; a re-lock invalidates prior approvals -->
19
+
20
+ ## Required approvals (sdlc-review-gate rule)
21
+ - Base: **owner + 1 reviewer**.
22
+ - Escalated (risk tag set, or a stories PR): **plus one domain-owner per touched repo** — see the
23
+ requested reviewers / `domain:<repo>` labels on this PR. Run `bash checks/hub-route.sh <this-description>`
24
+ to list them.
25
+
26
+ ## How to review (this drives the gate)
27
+ - **Approve** this PR to record an `owner` / `reviewer` / `domain-owner` approval in the file ledger
28
+ (your platform login maps to your SDLC name + role via `.sdlc/hub.json`'s roster).
29
+ - **Comment / request changes** to record review comments (synced into `reviews/<artifact>--<date>--comments.md`).
30
+ - **Do NOT merge to advance** — `sdlc-review-gate action: sync` + `action: advance` move the step.
31
+
32
+ ## Checklist
33
+ - [ ] `owner` set in the artifact frontmatter (inherited from `epic.md`)
34
+ - [ ] Contract re-locked (`.sdlc/contract-lock.json`) if the surface changed (architecture only)
35
+ - [ ] Risk tags reflect the real surface touched (contract/auth/payments escalate)
36
+ - [ ] No secrets or tokens in the artifact or this description
@@ -0,0 +1,37 @@
1
+ <!-- SDLC HUB MR template — front-half artifact review (epic / architecture+contract / ui-design / stories). -->
2
+ <!-- This MR is a REVIEW VEHICLE on the product hub, not a code merge. The file gate (sdlc-review-gate)
3
+ advances the step; do NOT rely on merging this MR to advance. Reviewers approve/comment here, then a
4
+ `sdlc-review-gate action: sync` pulls that into the file ledger. -->
5
+
6
+ ## Artifact under review
7
+ - Epic: `EP-<slug>`
8
+ - Artifact: `epic.md | architecture.md (+contract.md) | ui-design.md | stories/`
9
+ - Gate step: `<epic-review | architecture-review | ui-design-review | stories-review>`
10
+ - Owner: `<epic.md owner>`
11
+
12
+ ## What changed
13
+ <!-- One or two sentences on what this artifact says / what changed since the last review round. -->
14
+
15
+ ## Impact & Risk (front-half)
16
+ - **Domains / repos touched:** <epic.repos, e.g. backend, mobile>
17
+ - **Risk tags:** <none | contract | auth | payments> <!-- contract/auth/payments => escalates to domain owners -->
18
+ - **Contract surface:** <n/a | locked @ sha256:…> <!-- architecture only; a re-lock invalidates prior approvals -->
19
+
20
+ ## Required approvals (sdlc-review-gate rule)
21
+ - Base: **owner + 1 reviewer**.
22
+ - Escalated (risk tag set, or a stories MR): **plus one domain-owner per touched repo** — see the
23
+ reviewers / `domain:<repo>` labels on this MR. Run `bash checks/hub-route.sh <this-description>` to list them.
24
+
25
+ ## How to review (this drives the gate)
26
+ - **Approve** this MR to record an `owner` / `reviewer` / `domain-owner` approval in the file ledger
27
+ (your platform login maps to your SDLC name + role via `.sdlc/hub.json`'s roster).
28
+ - **Comment** to record review comments (synced into `reviews/<artifact>--<date>--comments.md`).
29
+ - **Do NOT merge to advance** — `sdlc-review-gate action: sync` + `action: advance` move the step.
30
+
31
+ ## Checklist
32
+ - [ ] `owner` set in the artifact frontmatter (inherited from `epic.md`)
33
+ - [ ] Contract re-locked (`.sdlc/contract-lock.json`) if the surface changed (architecture only)
34
+ - [ ] Risk tags reflect the real surface touched (contract/auth/payments escalate)
35
+ - [ ] No secrets or tokens in the artifact or this description
36
+
37
+ /assign me
@@ -0,0 +1,63 @@
1
+ ---
2
+ name: sdlc-review-comments
3
+ description: 'Installs platform-matched PR/MR review-comment scaffolds into a repo so reviewers leave structured, attributable feedback that maps cleanly into the SDLC file ledger. Works for code repos and the product hub. GitHub has no repo-level multi-comment template, so the scaffold is a committed REVIEW_COMMENTS.md reviewers copy from (saved as Saved Replies on GitHub / comment templates on GitLab). Each canned comment carries an attributable `**<name> (<role>)**` header that matches the `## <name> (<role>)` headings sdlc-review-gate writes. Use when the user says "add the comment templates" or "set up review comments" for a repo.'
4
+ ---
5
+
6
+ # SDLC — Review Comment Templates
7
+
8
+ **Goal:** Give reviewers a consistent, **attributable** set of canned PR/MR comments so review feedback
9
+ reads the same across repos and **maps cleanly into the file ledger** the gate keeps. The headers match
10
+ the `## <name> (<role>)` shape `sdlc-review-gate` writes into `reviews/<artifact>--<date>--comments.md`
11
+ and the per-commenter record in `comments.json`, so a synced or copy-pasted comment lands without
12
+ reformatting.
13
+
14
+ ## Platform reality (why this is a committed doc, not a config file)
15
+
16
+ Neither GitHub nor GitLab has a **repo-level** multi-comment template convention: GitHub *Saved Replies*
17
+ are per-account and GitLab *comment templates* are per-user/group, both set in the UI — there is no
18
+ `.github/comment_templates/` or `.gitlab/comment_templates/` the repo can ship. The pragmatic mechanism
19
+ on **both** is a single committed doc reviewers copy from (and optionally paste once into their personal
20
+ Saved Replies / comment templates). This skill ships that doc.
21
+
22
+ ## Conventions
23
+
24
+ - `{project-root}` resolves from the project working directory — the **product** repo (holds the
25
+ canonical templates under this skill).
26
+ - Canonical sources live in this skill's `templates/`:
27
+ - `templates/github/REVIEW_COMMENTS.md` → installs to `<repo>/.github/REVIEW_COMMENTS.md`
28
+ - `templates/gitlab/REVIEW_COMMENTS.md` → installs to `<repo>/.gitlab/REVIEW_COMMENTS.md`
29
+ - The two variants are identical except a footer line (GitHub: "save these as Saved Replies"; GitLab:
30
+ "save these as comment templates").
31
+
32
+ ## Inputs
33
+
34
+ - `repo` — the repo to add the scaffold to (one of an epic's repos), or `hub` for the product hub.
35
+ - `action` — `wire` (install the matching scaffold). Default `wire`.
36
+
37
+ ## On Activation
38
+
39
+ ### Step 1 — Resolve the repo and detect the platform
40
+ Map `repo` → its path (`{project-root}/demo-repos/<repo>/` or the registry `path`); for `repo: hub` the
41
+ target is `{project-root}` and the platform comes from `.sdlc/hub.json`. Detect the platform: a GitHub
42
+ remote or `.github/` → GitHub; a GitLab remote or `.gitlab/` → GitLab. If ambiguous, ask.
43
+
44
+ ### Step 2 — `wire` (drop only the matching scaffold)
45
+ Copy the matching `templates/<platform>/REVIEW_COMMENTS.md` into the repo's `.github/` or `.gitlab/`.
46
+ Do not clobber an existing non-SDLC file of the same name — back it up / ask. Commit on the repo's
47
+ default branch (shared infrastructure, not a task diff). Idempotent — re-running refreshes in place.
48
+
49
+ ### Step 3 — Stop (no auto-advance)
50
+ Report what was committed. The scaffold is an aid to human review; it approves nothing and touches no
51
+ `.sdlc/` state.
52
+
53
+ ## Hard rules
54
+
55
+ - **Drop only the matching scaffold** for the detected platform.
56
+ - **Attributable headers** — every canned comment keeps the `**<name> (<role>)**` form so the gate's
57
+ ledger and the PR thread agree.
58
+ - **Nothing auto-advances.** Comments feed the human review and (via the bridge) `sdlc-review-gate`.
59
+
60
+ ## Reference
61
+ - Comment conventions + the full scaffold contents: `references/comment-conventions.md`.
62
+ - The ledger headings these match: `../sdlc-review-gate/SKILL.md` (comment action) and `references/gating.md`.
63
+ - The review bridge that syncs platform comments into the ledger: `../sdlc-hub-bridge/SKILL.md`.
@@ -0,0 +1,55 @@
1
+ # Review comment conventions
2
+
3
+ The scaffold (`REVIEW_COMMENTS.md`) groups canned comments into **blocking** (a gate would fail / must
4
+ be fixed before merge) and **non-blocking** (suggestions, nits, questions). Every comment starts with an
5
+ attributable header:
6
+
7
+ ```
8
+ **<name> (<role>)**
9
+ ```
10
+
11
+ `<role>` is one of `owner | reviewer | domain-owner` — the same roles `sdlc-review-gate` records. This
12
+ header matches the `## <name> (<role>)` headings the gate writes into
13
+ `reviews/<artifact>--<date>--comments.md`, so a comment copied from the PR thread (or synced by
14
+ `sdlc-hub-bridge`) needs no reformatting to land in the ledger.
15
+
16
+ ## Blocking comments (a gate or rule says stop)
17
+
18
+ These map to the code-repo check gates (`sdlc-checks`) and the file-boundary / contract rules:
19
+
20
+ - **spec-link** — "This commit has no `Task: <story>-<task>` trailer; the spec-link gate will fail. Add
21
+ the trailer (and ensure `specs/<story>/link.md` exists)."
22
+ - **contract-check** — "This diff changes the contract surface without `Contract-Change: yes` + a
23
+ re-locked contract. Route back to the architecture gate and re-lock before this can merge."
24
+ - **build-test-lint** — "Lint/build/test is red (or the test doesn't exercise the new behavior). The
25
+ build-test-lint gate must pass with a test that actually exercises the acceptance criterion."
26
+ - **file-boundary** — "This diff touches files the task's `Files:` list didn't declare. Re-scope the
27
+ task (re-run `sdlc-spec`) rather than widening the diff silently."
28
+
29
+ ## Escalation / routing comment
30
+
31
+ - **routing** — "Risk is `high` / a contract|auth|payments surface is touched — this needs a
32
+ domain-owner approval per touched repo (the same escalation `sdlc-review-gate` applies). Run
33
+ `bash checks/risk-route.sh <body>` (code repo) or `bash checks/hub-route.sh <body>` (hub)."
34
+
35
+ ## Non-blocking comments
36
+
37
+ - **suggestion** — "Suggestion (non-blocking): …"
38
+ - **nit** — "Nit: …"
39
+ - **question** — "Question: … (not blocking — just want to understand)."
40
+
41
+ ## Approval note
42
+
43
+ - **approve** — "Approving as `<role>`. Recorded in `approvals.json` (code-repo ship: `build-log.json`).
44
+ On the hub, your approval here is pulled in by `sdlc-review-gate action: sync`."
45
+
46
+ ## Hub front-artifact review
47
+
48
+ The hub scaffold adds a **Front-artifact review** section whose headers mirror the gate's comment file
49
+ exactly, so reviewing an `epic.md` / `architecture.md` / `ui-design.md` / `stories/` PR produces comments
50
+ that drop straight into `reviews/<artifact>--<date>--comments.md`:
51
+
52
+ ```
53
+ **<name> (<role>)**
54
+ - <comment about scope / contract surface / acceptance signals / story split>
55
+ ```
@@ -0,0 +1,49 @@
1
+ # Review comments — canned replies
2
+
3
+ Copy a block below into a PR review comment. Keep the `**<name> (<role>)**` header — it matches the
4
+ SDLC review ledger (`reviews/<artifact>--<date>--comments.md`) so feedback stays attributable.
5
+ `<role>` is one of `owner | reviewer | domain-owner`.
6
+
7
+ ## Blocking (a gate or rule says stop — must be fixed before merge)
8
+
9
+ **<name> (<role>)**
10
+ - spec-link: this range has no `Task: <story>-<task>` trailer — the spec-link gate will fail. Add the
11
+ trailer and make sure `specs/<story>/link.md` exists.
12
+
13
+ **<name> (<role>)**
14
+ - contract-check: this diff changes the contract surface without `Contract-Change: yes` + a re-locked
15
+ contract. Route back to the architecture gate and re-lock before merge.
16
+
17
+ **<name> (<role>)**
18
+ - build-test-lint: lint/build/test is red, or the test doesn't exercise the new behavior. The gate must
19
+ pass with a test that actually exercises the acceptance criterion.
20
+
21
+ **<name> (<role>)**
22
+ - file-boundary: this touches files the task's `Files:` list didn't declare. Re-scope the task (re-run
23
+ `sdlc-spec`) instead of widening the diff.
24
+
25
+ ## Routing / escalation
26
+
27
+ **<name> (<role>)**
28
+ - routing: risk is `high` / a contract|auth|payments surface is touched — needs a domain-owner approval
29
+ per touched repo (same escalation as `sdlc-review-gate`). Run `bash checks/risk-route.sh <body>`.
30
+
31
+ ## Non-blocking
32
+
33
+ **<name> (<role>)**
34
+ - Suggestion (non-blocking): …
35
+
36
+ **<name> (<role>)**
37
+ - Nit: …
38
+
39
+ **<name> (<role>)**
40
+ - Question: … (not blocking — just want to understand).
41
+
42
+ ## Approval
43
+
44
+ **<name> (<role>)**
45
+ - Approving as `<role>`. Recorded in `approvals.json` (ship: `build-log.json`).
46
+
47
+ ---
48
+ > Tip (GitHub): paste the blocks you use most into your personal **Saved Replies**
49
+ > (Settings → Saved replies) so they are one click away in any PR.
@@ -0,0 +1,49 @@
1
+ # Review comments — canned replies
2
+
3
+ Copy a block below into an MR review comment. Keep the `**<name> (<role>)**` header — it matches the
4
+ SDLC review ledger (`reviews/<artifact>--<date>--comments.md`) so feedback stays attributable.
5
+ `<role>` is one of `owner | reviewer | domain-owner`.
6
+
7
+ ## Blocking (a gate or rule says stop — must be fixed before merge)
8
+
9
+ **<name> (<role>)**
10
+ - spec-link: this range has no `Task: <story>-<task>` trailer — the spec-link gate will fail. Add the
11
+ trailer and make sure `specs/<story>/link.md` exists.
12
+
13
+ **<name> (<role>)**
14
+ - contract-check: this diff changes the contract surface without `Contract-Change: yes` + a re-locked
15
+ contract. Route back to the architecture gate and re-lock before merge.
16
+
17
+ **<name> (<role>)**
18
+ - build-test-lint: lint/build/test is red, or the test doesn't exercise the new behavior. The gate must
19
+ pass with a test that actually exercises the acceptance criterion.
20
+
21
+ **<name> (<role>)**
22
+ - file-boundary: this touches files the task's `Files:` list didn't declare. Re-scope the task (re-run
23
+ `sdlc-spec`) instead of widening the diff.
24
+
25
+ ## Routing / escalation
26
+
27
+ **<name> (<role>)**
28
+ - routing: risk is `high` / a contract|auth|payments surface is touched — needs a domain-owner approval
29
+ per touched repo (same escalation as `sdlc-review-gate`). Run `bash checks/risk-route.sh <body>`.
30
+
31
+ ## Non-blocking
32
+
33
+ **<name> (<role>)**
34
+ - Suggestion (non-blocking): …
35
+
36
+ **<name> (<role>)**
37
+ - Nit: …
38
+
39
+ **<name> (<role>)**
40
+ - Question: … (not blocking — just want to understand).
41
+
42
+ ## Approval
43
+
44
+ **<name> (<role>)**
45
+ - Approving as `<role>`. Recorded in `approvals.json` (ship: `build-log.json`).
46
+
47
+ ---
48
+ > Tip (GitLab): paste the blocks you use most into your personal/group **Comment templates**
49
+ > (Preferences → Comment templates) so they are one click away in any MR.
@@ -0,0 +1,196 @@
1
+ ---
2
+ name: sdlc-review-gate
3
+ description: 'The reusable team review + approve gate for the SDLC. Shares an authored artifact for review, records reviewer comments and approvals as files, enforces the owner + 1 reviewer rule (escalating to domain owners on contract/auth/payments), and advances the epic state ONLY when approval is recorded. Use when the user says "review the analysis/epic/architecture/UI/stories", "comment", "approve", or "advance the gate".'
4
+ ---
5
+
6
+ # SDLC — Team Review Gate (build plan §3 piece 2, §4, §5)
7
+
8
+ **Goal:** One reusable step type that turns any authored artifact into a gated, human-approved
9
+ review. Every `review+approve` step in the workflow (the optional analysis, epic, architecture+contract,
10
+ UI, stories) uses this exact gate. **No step advances until its review is approved** and recorded as a
11
+ file. The `analysis-review` and `epic`/`ui-design` reviews use the **base** rule (owner + 1 reviewer);
12
+ escalation applies only where `risk_tags` or per-repo routing call for it.
13
+
14
+ This gate is **swappable and file-driven**: it talks only through files. A front step advances only on a
15
+ human act — recording an approval and `advance`, or (with the bridge) **merging the approved,
16
+ fully-resolved review PR/MR**. It works the same whether a human or the `sdlc gate` CLI triggers it — the
17
+ trigger is a parameter, not a hardcoded human.
18
+
19
+ ## Conventions
20
+ - `{project-root}` resolves from the project working directory.
21
+ - Operate on one epic: `{project-root}/epics/EP-<slug>/`.
22
+ - State files: `.sdlc/state.json`, `.sdlc/approvals.json`, `.sdlc/comments.json`, and (when the bridge is
23
+ used) `.sdlc/hub-prs.json`. Review records: `reviews/`.
24
+ - The artifact base name drops the extension (`epic.md` → `epic`; story `stories/...S01.md` → `stories-S01`).
25
+
26
+ ## Inputs
27
+ - `epic`: the `EP-<slug>` to operate on.
28
+ - `artifact`: the file under the epic being reviewed (e.g. `epic.md`).
29
+ - `action`: one of `open` | `comment` | `approve` | `sync` | `advance` (default: `open`).
30
+ - For `comment` / `approve`: the reviewer name and role (`owner` | `reviewer` | `domain-owner`),
31
+ and for domain owners the `domain` (repo/area). Ask if not provided.
32
+ - `sync` needs no reviewer input — it reads the platform PR/MR review state (via `sdlc-hub-bridge`).
33
+
34
+ ## On Activation
35
+
36
+ ### Step 1 — Load state
37
+ Read `.sdlc/state.json`. Find the `review+approve` step whose `artifact` matches the input (or the
38
+ step named `currentStep` if it is a review step). Read `.sdlc/approvals.json`. Read `epic.md` for the
39
+ epic's `repos` (the **touched domains**). Determine the **reviewer rule** for this step:
40
+ - **Base rule:** `owner + 1 reviewer` — at least one `owner` approval AND at least one distinct
41
+ non-owner `reviewer` approval.
42
+ - **Escalation option (risk-driven):** if the step's `risk_tags` intersect `{contract, auth,
43
+ payments}`, ALSO require at least one `domain-owner` approval **per touched domain** (build plan §4,
44
+ §5). For the **architecture+contract** review (`risk_tags: ["contract"]`), the touched domains are
45
+ the epic's `repos` — each repo's owner must sign off on the shared surface, so it escalates by
46
+ default.
47
+ - **Per-repo routing option (stories):** for the **stories** review, the relevant domain engineer
48
+ reviews the stories touching their repo: treat each repo's engineer as a `domain-owner` for that
49
+ repo's stories. The touched domains are the **union of every story's `repos`** under `stories/`
50
+ (build plan §4 step 8). The `domain` field on each approval is the repo name.
51
+
52
+ Escalation and per-repo routing are **options of this one gate**, selected by `risk_tags` and the
53
+ touched `repos` — never a forked or copied gate.
54
+
55
+ ### Step 2 — Dispatch on `action`
56
+
57
+ **`open`** — Present the artifact for review. Summarise what changed, list the required reviewers per
58
+ the rule above, and tell reviewers how to comment/approve. Set the step `status` to `in_review` and
59
+ `currentStep` to this step in `state.json` if not already. Do not advance.
60
+
61
+ If `.sdlc/hub.json` has a non-null `platform`, `bridge_enabled: true`, `config.yaml` `hub.bridge: true`,
62
+ and `gh`/`glab` is authenticated, **also open a review PR/MR on the hub** by invoking
63
+ `sdlc-hub-bridge action: open` (epic + artifact). Record the PR in `epics/<epic>/.sdlc/hub-prs.json`
64
+ (`{step, artifact, platform, number, url, branch, lastSyncedAt}`) and report the URL + required
65
+ reviewers. Otherwise (no platform / disabled / no CLI) proceed **file-only** exactly as before — no
66
+ error. Opening the PR records no approvals and never advances.
67
+
68
+ **`comment`** — Capture reviewer feedback. Append/create a review file
69
+ `reviews/<artifact-base>--<YYYY-MM-DD>--comments.md` with a heading per reviewer:
70
+
71
+ ```markdown
72
+ # Review comments — <artifact> — <YYYY-MM-DD>
73
+
74
+ ## <reviewer> (<role>)
75
+ - <comment>
76
+ - <comment>
77
+ ```
78
+
79
+ Also append a **machine-readable** participation record to `.sdlc/comments.json` (create as `[]` if
80
+ absent — the markdown stays the human-readable record, this makes commenter names queryable, the
81
+ counterpart to `approvals.json`):
82
+ ```json
83
+ { "artifact": "<artifact>", "step": "<step id>", "commenter": "<name>", "role": "<owner|reviewer|domain-owner>", "domain": "<optional>", "round": <n>, "count": <comments this round>, "date": "<YYYY-MM-DD>" }
84
+ ```
85
+ `round` increments each comment→address cycle for the artifact; upsert by `(step, commenter, round)`.
86
+
87
+ Then help the **owner address the comments** using the agent lens listed for this step
88
+ (analysis → `analyst`; epic → `pm`; architecture → `architect`; ui-design → `ux-designer`;
89
+ stories → `pm`, with `architect` for technical detail — there is **no `sm` agent**, Phase 0
90
+ Deviation 1). Update the authored artifact in place.
91
+ Repeat comment→address rounds until reviewers are satisfied. **Commenting never advances the gate.**
92
+
93
+ **`approve`** — Record an approval. Append to `.sdlc/approvals.json`:
94
+ ```json
95
+ { "artifact": "<artifact>", "step": "<step id>", "approver": "<name>", "role": "<owner|reviewer|domain-owner>", "domain": "<optional>", "status": "approved", "date": "<YYYY-MM-DD>" }
96
+ ```
97
+ Also write/refresh `reviews/<artifact-base>--<YYYY-MM-DD>--approved.md` as a **named roster** with three
98
+ sections, so every participant is attributable in one place:
99
+
100
+ ```markdown
101
+ # Approval record — <artifact> — <YYYY-MM-DD>
102
+
103
+ Reviewer rule in force: **<base | escalated | per-repo>** (<why — e.g. risk_tags / touched repos>).
104
+
105
+ ## Approved by
106
+ - <name> — <role>[ (<domain>)] — approved <date>
107
+
108
+ ## Reviewed / commented by (participation, from comments.json)
109
+ - <name> — <role> — <n> comment(s) across <r> round(s)
110
+
111
+ ## Still required to pass the gate
112
+ - <missing owner/reviewer/domain-owner, or "none">
113
+
114
+ Gate status: **<PASSED | BLOCKED>** — <reason>.
115
+ ```
116
+
117
+ Then **re-evaluate the rule** (Step 3). Recording an approval does NOT itself advance — advancement is
118
+ a separate, explicit check.
119
+
120
+ **`sync`** — (the platform bridge input path) Pull the hub review PR/MR's review state into the ledger,
121
+ then re-evaluate the rule (Step 3). Read the PR for this step from `.sdlc/hub-prs.json` and use
122
+ `sdlc-hub-bridge`'s read recipes (`../sdlc-hub-bridge/references/bridge.md`) to fetch reviews + comments
123
+ via the local user's `gh`/`glab`. For each:
124
+ - map the platform `login` → SDLC `name` + `role` via `.sdlc/hub.json`'s roster (a roster `name` equal
125
+ to a repo's `domain_owner` in `repos.json` becomes that repo's `domain-owner` for a touched domain;
126
+ an unmapped login is a plain `reviewer`, flagged, never promoted);
127
+ - an `APPROVED` review / MR approval → append an `approved` record to `approvals.json` tagged
128
+ `"source": "bridge"`; a `COMMENTED`/`CHANGES_REQUESTED`/note → write to
129
+ `reviews/<artifact-base>--<YYYY-MM-DD>--comments.md` + `comments.json` (never an approval).
130
+ **Idempotent:** upsert bridge approvals by `(step, approver, role, domain)`, supersede revoked ones, and
131
+ key comments on the platform comment id (re-running `sync` does not duplicate). **Manual approvals (no
132
+ `source` tag) are never touched.** For the architecture+contract step, discard bridge approvals dated
133
+ before a new contract lock (re-lock invalidates platform approvals too). Then refresh the `approved.md`
134
+ roster, set `hub-prs.json` `lastSyncedAt`, and **re-evaluate Step 3**. Under the PR-driven CLI (`sdlc
135
+ gate sync`), `sync` advances the step when Step 3 passes on a **merged**, fully-resolved, approved PR
136
+ (the merge is the human act); otherwise it records state and holds the step `in_review`.
137
+
138
+ **`advance`** — Run the gate predicate (Step 3). Only advance if it passes.
139
+
140
+ ### Step 3 — Gate predicate (the only path that advances)
141
+ The step may advance **iff ALL hold**:
142
+ 1. `automation` is `human_approve` (it always is for front steps) and the required approvals exist:
143
+ ≥1 `owner` AND ≥`review_gate.default_reviewers` (1) distinct non-owner `reviewer`, AND — if the
144
+ step is escalated — ≥1 `domain-owner` for each touched domain.
145
+ 2. The artifact has not changed since the latest approval round (no newer authored edit than the
146
+ newest `approved` record). If it changed, approvals are stale → return to `comment`. For the
147
+ **architecture+contract** review, also recompute the contract-surface hash (see
148
+ `../sdlc-author-architecture/references/contract-format.md`): if it no longer matches
149
+ `.sdlc/contract-lock.json`, the surface changed → approvals stale → return to `comment` and re-lock.
150
+
151
+ If the predicate **fails**: report exactly which approvals are still missing and STOP. Do not modify
152
+ `currentStep`.
153
+
154
+ If the predicate **passes**:
155
+ - Mark this review step `status: "done"`.
156
+ - If there **is** a next step in `steps[]`: set it `status` from `blocked` to `in_progress`
157
+ (authoring) or `in_review`, and set `currentStep` to that next step.
158
+ - If this is the **last** step (`stories-review`, the final review): there is no further front step —
159
+ set `currentStep: "ready-for-build"` (the Phase 3 handoff sentinel; it is intentionally not a
160
+ `steps[]` entry). The front half is complete.
161
+ - Write `state.json`. Report the advance and what the next authored artifact is (or that the epic is
162
+ now `ready-for-build`).
163
+
164
+ ### PR-driven automation (the `sdlc gate` CLI)
165
+ When the hub has a platform, the mechanical `open`/`sync`/`advance` is performed deterministically by the
166
+ **`sdlc gate` CLI** (`sdlc gate open|sync|comments|status`), which writes the same `.sdlc/` + `reviews/`
167
+ records this skill describes. The skill's job is then the human half: presenting the artifact, helping the
168
+ owner address comments, and narrating the gate. The CLI is the single implementation of the gh/glab
169
+ mechanics — do not hand-run gh/glab recipes when it is installed.
170
+
171
+ Under that CLI the gate **advances on merge**: a review PR/MR whose reviewer rule is satisfied, whose
172
+ comment threads are **all resolved**, and which has been **merged** auto-marks the step `done` and
173
+ unblocks the next step. (Until those three hold, the step stays `in_review`.)
174
+
175
+ `sync` can also be **event-driven**: when the hub is wired with the gate-sync CI (`sdlc-hub-bridge`
176
+ `wire` action), every approval / change request / dismissal / merge on the review PR/MR triggers
177
+ `sdlc gate ci` on the hub, which runs the same sync and commits the ledger updates directly to the
178
+ hub's default branch (pull to see them locally). The predicate, the human merge, and manual
179
+ `sdlc gate sync` are all unchanged — CI never approves and never merges.
180
+
181
+ ### Hard rules (build plan §1, §5)
182
+ - **The merge click is the human approval act.** A front step advances only when a human merges the
183
+ approved, fully-resolved review PR — there is no machine-driven advance. A step `locked: true` may not
184
+ be switched to `machine_advance`; refuse such a request.
185
+ - **Approvals are revoked when the reviewed artifact changes.** `sync` re-hashes the artifact (the locked
186
+ contract surface for architecture) and drops any approval bound to a stale hash, so a reviewer must
187
+ re-approve the new content. Unresolved comments / `CHANGES_REQUESTED` hold the gate `in_review`.
188
+ - The gate talks only through `.sdlc/` and `reviews/` files — never hidden state.
189
+ - **The platform is an input path only.** `open`/`sync` use the local user's own `gh`/`glab` (no stored
190
+ tokens), and the **file ledger remains the source of truth** — the Step 3 predicate is unchanged
191
+ whether approvals arrive manually or via `sync`. With no hub platform / no CLI, the gate runs file-only
192
+ with no error (record approvals manually and `advance`).
193
+
194
+ ## Reference
195
+ - Gating details and worked example: `references/gating.md`.
196
+ - The platform PR/MR bridge (`open`/`sync` mechanics, read recipes, roster): `../sdlc-hub-bridge/SKILL.md`.