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.
- package/CHANGELOG.md +50 -0
- package/LICENSE +21 -0
- package/README.md +559 -0
- package/bin/sdlc.mjs +135 -0
- package/cli/commit.mjs +81 -0
- package/cli/epic-state.mjs +220 -0
- package/cli/gate.mjs +456 -0
- package/cli/lib.mjs +142 -0
- package/cli/manifest.mjs +119 -0
- package/cli/openpr.mjs +65 -0
- package/cli/plan.mjs +127 -0
- package/cli/platform.mjs +151 -0
- package/cli/reconcile.mjs +83 -0
- package/cli/repo.mjs +61 -0
- package/cli/setup.mjs +208 -0
- package/package.json +51 -0
- package/skills/sdlc/config.yaml +156 -0
- package/skills/sdlc/install.sh +51 -0
- package/skills/sdlc/module-help.csv +17 -0
- package/skills/sdlc-author-analysis/SKILL.md +136 -0
- package/skills/sdlc-author-architecture/SKILL.md +180 -0
- package/skills/sdlc-author-architecture/references/contract-format.md +72 -0
- package/skills/sdlc-author-epic/SKILL.md +154 -0
- package/skills/sdlc-author-epic/references/state-schema.md +187 -0
- package/skills/sdlc-author-stories/SKILL.md +109 -0
- package/skills/sdlc-author-stories/references/story-schema.md +46 -0
- package/skills/sdlc-author-ui/SKILL.md +113 -0
- package/skills/sdlc-backfill/SKILL.md +91 -0
- package/skills/sdlc-backfill/references/backfill.md +66 -0
- package/skills/sdlc-backfill/templates/checks/backfill-check.sh +42 -0
- package/skills/sdlc-checks/SKILL.md +138 -0
- package/skills/sdlc-checks/references/check-gates.md +168 -0
- package/skills/sdlc-checks/templates/checks/build-test-lint.sh +14 -0
- package/skills/sdlc-checks/templates/checks/contract-check.sh +62 -0
- package/skills/sdlc-checks/templates/checks/spec-link.sh +38 -0
- package/skills/sdlc-checks/templates/checks/verified-commits.sh +120 -0
- package/skills/sdlc-checks/templates/github/sdlc-checks.yml +45 -0
- package/skills/sdlc-checks/templates/github/sdlc-verified-commits.yml +22 -0
- package/skills/sdlc-checks/templates/gitlab/.gitlab-ci.yml +40 -0
- package/skills/sdlc-checks/templates/gitlab/gitlab-ci.include-root.yml +7 -0
- package/skills/sdlc-checks/templates/gitlab/sdlc-checks.gitlab-ci.yml +47 -0
- package/skills/sdlc-checks/templates/gitlab/sdlc-verified-commits.gitlab-ci.yml +21 -0
- package/skills/sdlc-connect-repos/SKILL.md +159 -0
- package/skills/sdlc-connect-repos/references/code-context.md +92 -0
- package/skills/sdlc-connect-repos/references/hub-config.md +77 -0
- package/skills/sdlc-connect-repos/references/repos-registry.md +62 -0
- package/skills/sdlc-hub-bridge/SKILL.md +119 -0
- package/skills/sdlc-hub-bridge/references/bridge.md +136 -0
- package/skills/sdlc-hub-bridge/references/login-roster.md +42 -0
- package/skills/sdlc-hub-bridge/templates/checks/hub-route.sh +50 -0
- package/skills/sdlc-hub-bridge/templates/github/sdlc-gate-sync.yml +63 -0
- package/skills/sdlc-hub-bridge/templates/gitlab/gitlab-ci.include-root.yml +7 -0
- package/skills/sdlc-hub-bridge/templates/gitlab/sdlc-gate-sync.gitlab-ci.yml +64 -0
- package/skills/sdlc-implement/SKILL.md +143 -0
- package/skills/sdlc-implement/references/implement-conventions.md +103 -0
- package/skills/sdlc-implement/templates/.gitmessage +17 -0
- package/skills/sdlc-pr-template/SKILL.md +86 -0
- package/skills/sdlc-pr-template/references/risk-routing.md +54 -0
- package/skills/sdlc-pr-template/templates/checks/risk-route.sh +44 -0
- package/skills/sdlc-pr-template/templates/github/pull_request_template.md +30 -0
- package/skills/sdlc-pr-template/templates/gitlab/merge_request_templates/Default.md +32 -0
- package/skills/sdlc-pr-template/templates/hub/github/pull_request_template.md +36 -0
- package/skills/sdlc-pr-template/templates/hub/gitlab/merge_request_templates/Default.md +37 -0
- package/skills/sdlc-review-comments/SKILL.md +63 -0
- package/skills/sdlc-review-comments/references/comment-conventions.md +55 -0
- package/skills/sdlc-review-comments/templates/github/REVIEW_COMMENTS.md +49 -0
- package/skills/sdlc-review-comments/templates/gitlab/REVIEW_COMMENTS.md +49 -0
- package/skills/sdlc-review-gate/SKILL.md +196 -0
- package/skills/sdlc-review-gate/references/gating.md +79 -0
- package/skills/sdlc-run/SKILL.md +109 -0
- package/skills/sdlc-run/references/run-loop.md +121 -0
- package/skills/sdlc-ship/SKILL.md +86 -0
- package/skills/sdlc-ship/references/ship-and-record.md +67 -0
- package/skills/sdlc-ship/templates/.coderabbit.yaml +19 -0
- package/skills/sdlc-spec/SKILL.md +119 -0
- package/skills/sdlc-spec/references/spec-handoff.md +101 -0
- 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`.
|