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,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sdlc-author-stories
|
|
3
|
+
description: 'Front state 7 of the gated SDLC. With the pm, break the approved epic into user stories, each tagged with the repos that must implement it. Assigns zero-padded EP-<slug>-S0N IDs and writes one file per story under stories/. Reads epic + architecture + contract + UI as input. Never auto-advances — hands off to the team review gate (per-repo reviewer routing). Use when the user says "author the stories" or after the UI gate passes.'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SDLC — Author Stories (front state 7)
|
|
7
|
+
|
|
8
|
+
**Goal:** Break an approved epic into human-authored, AI-assisted user stories, each with a stable
|
|
9
|
+
`EP-<slug>-S0N` ID and a `repos` tag listing which repos must implement it. This is a **front state**:
|
|
10
|
+
human-authored with AI assist, **never auto-advances**. When the stories are drafted, control passes
|
|
11
|
+
to `sdlc-review-gate`, which routes **per-repo reviewers** (each repo's engineer reviews the stories
|
|
12
|
+
touching their repo).
|
|
13
|
+
|
|
14
|
+
There is **no `sm` agent** (Phase 0 Deviation 1): the `pm` lens breaks down the epic; the `pm` or
|
|
15
|
+
`architect` lens prepares each story's detail. IDs are engine-assigned and never renamed.
|
|
16
|
+
|
|
17
|
+
## Conventions
|
|
18
|
+
|
|
19
|
+
- `{project-root}` resolves from the project working directory.
|
|
20
|
+
- Stories live under `{project-root}/epics/EP-<slug>/stories/` (build plan §6).
|
|
21
|
+
- Story files are named `EP-<slug>-S0N.md` (zero-padded, e.g. `EP-istifta-inquiries-S01.md`).
|
|
22
|
+
- Speak in the configured `communication_language`; write documents in `document_output_language`.
|
|
23
|
+
|
|
24
|
+
## On Activation
|
|
25
|
+
|
|
26
|
+
### Step 1 — Resolve the epic and check the gate
|
|
27
|
+
Resolve the `EP-<slug>` (ask if not provided). Read `.sdlc/state.json`. Only proceed when
|
|
28
|
+
`currentStep == "stories"` and that step's `status == "in_progress"` (the UI review must already have
|
|
29
|
+
passed). If not, stop and point the user at `sdlc-status` / the gate.
|
|
30
|
+
|
|
31
|
+
### Step 1b — Open the authoring branch
|
|
32
|
+
Open the stories authoring branch `stories/EP-<slug>` per the shared procedure
|
|
33
|
+
(`../sdlc-author-epic/references/state-schema.md` → "Authoring branches"): git-safe (skip with a note
|
|
34
|
+
if `{project-root}` is not a git work tree), check out the branch if it exists, else create it from the
|
|
35
|
+
hub's default branch. Author and commit the story files under `stories/` on it. This is **distinct**
|
|
36
|
+
from the bridge's `review/…` branch.
|
|
37
|
+
|
|
38
|
+
### Step 2 — Read inputs
|
|
39
|
+
Read `epic.md` (scope, acceptance signals, `repos`), `architecture.md` (components by repo, flows),
|
|
40
|
+
`contract.md` (the shared surface stories must honour), and `ui-design.md` (screens/flows). Stories
|
|
41
|
+
must collectively satisfy the epic's acceptance signals and stay within the contract surface.
|
|
42
|
+
|
|
43
|
+
### Step 2b — Load existing-code context (make the brain code-aware)
|
|
44
|
+
Read the registry `{project-root}/.sdlc/repos.json` (`config.yaml` `code_context`). For **each repo in
|
|
45
|
+
`epic.repos`**, load the code-map `{project-root}/.sdlc/code-context/<repo>/code-map.md` so each story's
|
|
46
|
+
**"Notes for build"** can point at the **real existing modules/files** a story extends — giving the
|
|
47
|
+
Phase 3 build (Spec Kit per repo) accurate anchors instead of invented ones.
|
|
48
|
+
|
|
49
|
+
- **Greenfield-safe:** if `repos.json` is absent/empty, note "no repos connected" and proceed.
|
|
50
|
+
- **Staleness:** if a repo's current HEAD ≠ its registry `syncedHead`, warn and suggest
|
|
51
|
+
`sdlc repo refresh <repo>` (a human decision — flag and stop, never auto-refresh); stamp
|
|
52
|
+
`code-context: stale` in the story frontmatter.
|
|
53
|
+
- **Traceability:** record the loaded maps in each story's `code-context:` frontmatter field.
|
|
54
|
+
|
|
55
|
+
### Step 3 — Break down the epic (assist: pm)
|
|
56
|
+
Adopt the **pm** lens (`bmad-agent-pm`, John). Decompose the epic into the smallest set of
|
|
57
|
+
independently reviewable, independently buildable stories. For each story decide which repos it touches
|
|
58
|
+
(must be a subset of the epic's `repos`). Prefer stories scoped to a clear slice of user value.
|
|
59
|
+
|
|
60
|
+
### Step 4 — Assign IDs (engine-assigned, never by hand)
|
|
61
|
+
Scan `stories/` for existing `EP-<slug>-S0N.md`. Assign the next zero-padded numbers continuing from
|
|
62
|
+
the highest existing one (`S01`, `S02`, …). **Never renumber or rename** an existing story — IDs are
|
|
63
|
+
permanent downstream links (build plan §6b).
|
|
64
|
+
|
|
65
|
+
### Step 5 — Prepare each story (assist: pm / architect)
|
|
66
|
+
Write one file per story, `{project-root}/epics/EP-<slug>/stories/EP-<slug>-S0N.md`, using EXACTLY this
|
|
67
|
+
template (see `references/story-schema.md`):
|
|
68
|
+
|
|
69
|
+
```markdown
|
|
70
|
+
---
|
|
71
|
+
id: EP-<slug>-S0N
|
|
72
|
+
epic: EP-<slug>
|
|
73
|
+
status: draft
|
|
74
|
+
owner: <inherit from epic.md owner> # the epic owner carries through; not retyped
|
|
75
|
+
repos: [<subset of epic.repos this story implements>]
|
|
76
|
+
code-context: { repos: [], loaded: <YYYY-MM-DD or none> } # code-maps anchoring "Notes for build" (Step 2b)
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Story
|
|
80
|
+
As a <role>, I want <capability>, so that <outcome>.
|
|
81
|
+
|
|
82
|
+
## Acceptance criteria
|
|
83
|
+
- [ ] <testable criterion>
|
|
84
|
+
- [ ] <testable criterion>
|
|
85
|
+
|
|
86
|
+
## Notes for build
|
|
87
|
+
<!-- contract surface touched, architecture components involved, UI screens -->
|
|
88
|
+
<!-- this is the context the Phase 3 build (Spec Kit per repo) will read -->
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
`repos` is the field the later build phase reads to know where to scaffold specs — set it precisely.
|
|
92
|
+
|
|
93
|
+
### Step 6 — Advance the authoring step (NOT the gate)
|
|
94
|
+
In `state.json`: set `stories.status: "done"`, set `stories-review.status: "in_review"`, and set
|
|
95
|
+
`currentStep: "stories-review"`. Write `state.json`. Do **not** touch `approvals.json`.
|
|
96
|
+
|
|
97
|
+
### Step 7 — Stop at the gate (do NOT advance)
|
|
98
|
+
Report: the story IDs created, the repos each touches, and that the next action is **review** via
|
|
99
|
+
`sdlc-review-gate`. Note that this review routes **per-repo reviewers**: owner + 1 reviewer **plus**, for
|
|
100
|
+
each repo appearing in any story's `repos`, a `domain-owner` approval for that repo. **Never record
|
|
101
|
+
approval here.** Front states do not auto-advance. When the hub has a platform, the gate opens a review
|
|
102
|
+
PR on the hub (via `sdlc-hub-bridge`, with a `domain:<repo>` label per touched repo) and
|
|
103
|
+
`sdlc-review-gate action: sync` pulls platform approvals/comments into the ledger; otherwise the review
|
|
104
|
+
is recorded file-only.
|
|
105
|
+
|
|
106
|
+
## Reference
|
|
107
|
+
- Story frontmatter and body template: `references/story-schema.md`.
|
|
108
|
+
- State schema and field meanings: `../sdlc-author-epic/references/state-schema.md`.
|
|
109
|
+
- Connecting code repos + the code-context the brain reads: `../sdlc-connect-repos/SKILL.md`.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Story schema
|
|
2
|
+
|
|
3
|
+
Each story authored at front state 7 is one Markdown file under `epics/EP-<slug>/stories/`, named
|
|
4
|
+
`EP-<slug>-S0N.md` (zero-padded, never renamed).
|
|
5
|
+
|
|
6
|
+
## Frontmatter
|
|
7
|
+
|
|
8
|
+
| Field | Values | Meaning |
|
|
9
|
+
|-------|--------|---------|
|
|
10
|
+
| `id` | `EP-<slug>-S0N` | Stable story ID. Engine-assigned, zero-padded, never renamed. |
|
|
11
|
+
| `epic` | `EP-<slug>` | Parent epic ID — the unbroken link back to the epic. |
|
|
12
|
+
| `owner` | name | Inherited from `epic.md` `owner` (the single source — not retyped per story). Carries the responsible owner through to the build half. |
|
|
13
|
+
| `status` | `draft` \| `in_review` \| `approved` | Story lifecycle within the stories gate. |
|
|
14
|
+
| `repos` | subset of the epic's `repos` | Which repos must implement this story. **Drives per-repo review routing now and (Phase 3) where specs are scaffolded.** |
|
|
15
|
+
| `code-context` | `{ repos: [<name@sha>], loaded: <date> }` | Optional. Which connected-repo code-maps anchored "Notes for build" (front state 7 Step 2b). The `@sha` (a repo's `syncedHead`) is recommended so freshness is recorded but may be omitted; the SKILL templates show the empty placeholder `{ repos: [], loaded: <date or none> }`. `none` / `[]` when no repos are connected. |
|
|
16
|
+
|
|
17
|
+
## Body
|
|
18
|
+
|
|
19
|
+
```markdown
|
|
20
|
+
## Story
|
|
21
|
+
As a <role>, I want <capability>, so that <outcome>.
|
|
22
|
+
|
|
23
|
+
## Acceptance criteria
|
|
24
|
+
- [ ] <testable criterion>
|
|
25
|
+
- [ ] <testable criterion>
|
|
26
|
+
|
|
27
|
+
## Notes for build
|
|
28
|
+
<!-- contract surface touched, architecture components involved, UI screens -->
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Rules
|
|
32
|
+
|
|
33
|
+
- **IDs are permanent.** Continue numbering from the highest existing `S0N`; never renumber. Renaming
|
|
34
|
+
breaks every downstream link (build plan §6b).
|
|
35
|
+
- **`repos` must be a subset of `epic.repos`.** A story cannot touch a repo the epic does not declare.
|
|
36
|
+
- **Acceptance criteria are testable.** They are what the Phase 3 build (Spec Kit `specify`→`tasks`)
|
|
37
|
+
and the check gates verify against.
|
|
38
|
+
- **Stay within the contract surface.** "Notes for build" should reference the contract elements a
|
|
39
|
+
story touches; a story may not invent cross-repo surface that `contract.md` does not define.
|
|
40
|
+
|
|
41
|
+
## Per-repo review routing (the stories gate)
|
|
42
|
+
|
|
43
|
+
`sdlc-review-gate` treats each repo's engineer as the `domain-owner` for the stories touching that repo.
|
|
44
|
+
The gate passes only when, in addition to the base rule (owner + 1 reviewer), **every repo appearing in
|
|
45
|
+
any story's `repos`** has at least one `domain-owner` approval scoped to that repo (`domain` = repo
|
|
46
|
+
name). The gate's `approved.md` lists which repos still lack sign-off.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sdlc-author-ui
|
|
3
|
+
description: 'Front state 5 of the gated SDLC. With the ux-designer, author ui-design.md and DESIGN.md for an approved architecture, driving Impeccable as harness slash-commands (document/extract/craft) when installed, or authoring directly when not. Reads epic + architecture as input. Never auto-advances — hands off to the team review gate. Use when the user says "author the UI design" or after the architecture gate passes.'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SDLC — Author UI Design (front state 5)
|
|
7
|
+
|
|
8
|
+
**Goal:** Produce a human-authored, AI-assisted `ui-design.md` and `DESIGN.md` for an approved
|
|
9
|
+
architecture. This is a **front state**: human-authored with AI assist, **never auto-advances**. When
|
|
10
|
+
the UI is drafted, control passes to `sdlc-review-gate` (base rule: owner + 1 reviewer).
|
|
11
|
+
|
|
12
|
+
UI work is shaped by **Impeccable**, invoked as **harness slash-commands** (not a subprocess CLI) per
|
|
13
|
+
the Phase 0 deviation. If Impeccable is not installed, the `ux-designer` lens authors the same outputs
|
|
14
|
+
directly — the workflow does not block on the tool.
|
|
15
|
+
|
|
16
|
+
## Conventions
|
|
17
|
+
|
|
18
|
+
- `{project-root}` resolves from the project working directory.
|
|
19
|
+
- Artifacts live under `{project-root}/epics/EP-<slug>/` (build plan §6).
|
|
20
|
+
- `DESIGN.md` is Impeccable's conventional root design-system file (RESEARCH-NOTES §4).
|
|
21
|
+
- Speak in the configured `communication_language`; write documents in `document_output_language`.
|
|
22
|
+
|
|
23
|
+
## On Activation
|
|
24
|
+
|
|
25
|
+
### Step 1 — Resolve the epic and check the gate
|
|
26
|
+
Resolve the `EP-<slug>` (ask if not provided). Read `.sdlc/state.json`. Only proceed when
|
|
27
|
+
`currentStep == "ui-design"` and that step's `status == "in_progress"` (the architecture review must
|
|
28
|
+
already have passed). If not, stop and point the user at `sdlc-status` / the gate.
|
|
29
|
+
|
|
30
|
+
### Step 1b — Open the authoring branch
|
|
31
|
+
Open the UI authoring branch `ui-design/EP-<slug>` per the shared procedure
|
|
32
|
+
(`../sdlc-author-epic/references/state-schema.md` → "Authoring branches"): git-safe (skip with a note
|
|
33
|
+
if `{project-root}` is not a git work tree), check out the branch if it exists, else create it from the
|
|
34
|
+
hub's default branch. Author and commit `ui-design.md` / `DESIGN.md` on it. This is **distinct** from
|
|
35
|
+
the bridge's `review/…` branch.
|
|
36
|
+
|
|
37
|
+
### Step 2 — Read inputs
|
|
38
|
+
Read `epic.md` (user-level acceptance signals, scope) and `architecture.md` (flows, components by
|
|
39
|
+
repo). The UI must cover the user-facing flows the architecture defines.
|
|
40
|
+
|
|
41
|
+
### Step 2b — Load existing-code context (make the brain code-aware)
|
|
42
|
+
Read the registry `{project-root}/.sdlc/repos.json` (`config.yaml` `code_context`). For **each repo in
|
|
43
|
+
`epic.repos`**, load the code-map `{project-root}/.sdlc/code-context/<repo>/code-map.md` so the UI
|
|
44
|
+
**reuses existing components and conventions** rather than inventing parallel ones. This complements
|
|
45
|
+
Impeccable's `/impeccable document` (Step 3), which reads code directly for the design system — when
|
|
46
|
+
Impeccable is absent, the code-map is the brain's view of what UI/components already exist.
|
|
47
|
+
|
|
48
|
+
- **Greenfield-safe:** if `repos.json` is absent/empty, note "no repos connected" and proceed.
|
|
49
|
+
- **Staleness:** if a repo's current HEAD ≠ its registry `syncedHead`, warn and suggest
|
|
50
|
+
`sdlc repo refresh <repo>` (a human decision — flag and stop, never auto-refresh); stamp
|
|
51
|
+
`code-context: stale` in the frontmatter.
|
|
52
|
+
- **Traceability:** record the loaded maps in the `ui-design.md` `code-context:` frontmatter field.
|
|
53
|
+
|
|
54
|
+
### Step 3 — Shape the UI (assist: ux-designer + Impeccable slash-commands)
|
|
55
|
+
Adopt the **ux-designer** lens (`bmad-agent-ux-designer`, Sally). Drive Impeccable as slash-commands:
|
|
56
|
+
|
|
57
|
+
- **Existing project** (a codebase/design system already exists): `/impeccable document` → then
|
|
58
|
+
`/impeccable extract` → then `/impeccable craft`.
|
|
59
|
+
- **New project** (no design system yet): `/impeccable craft` → then `/impeccable extract`.
|
|
60
|
+
|
|
61
|
+
`/impeccable document` generates the root `DESIGN.md` from existing code; `/impeccable extract` pulls
|
|
62
|
+
components/tokens into the design system; `/impeccable craft` is shape-then-build for the new screens.
|
|
63
|
+
|
|
64
|
+
**Graceful degradation:** if Impeccable is not installed (no `/impeccable …` commands available), the
|
|
65
|
+
`ux-designer` lens authors `ui-design.md` and `DESIGN.md` directly, and you **note in `ui-design.md`
|
|
66
|
+
that Impeccable was not used**. Do not run `npx impeccable skills install` as part of this step — tool
|
|
67
|
+
installation is out of scope for the front half.
|
|
68
|
+
|
|
69
|
+
### Step 4 — Write the UI artifacts
|
|
70
|
+
Write `{project-root}/epics/EP-<slug>/ui-design.md` using EXACTLY this template:
|
|
71
|
+
|
|
72
|
+
```markdown
|
|
73
|
+
---
|
|
74
|
+
id: EP-<slug>
|
|
75
|
+
artifact: ui-design
|
|
76
|
+
status: draft
|
|
77
|
+
owner: <inherit from epic.md owner> # the epic owner carries through; not retyped
|
|
78
|
+
repos: [<inherit from epic>]
|
|
79
|
+
impeccable: <used | not-installed>
|
|
80
|
+
code-context: { repos: [], loaded: <YYYY-MM-DD or none> } # code-maps that informed component reuse (Step 2b)
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Screens & states
|
|
84
|
+
<!-- one subsection per screen: purpose, key states (empty/loading/error/success) -->
|
|
85
|
+
|
|
86
|
+
## User flows
|
|
87
|
+
<!-- the click-paths that satisfy the epic's acceptance signals -->
|
|
88
|
+
|
|
89
|
+
## Components & tokens
|
|
90
|
+
<!-- components used; reference DESIGN.md tokens; what is new vs reused -->
|
|
91
|
+
|
|
92
|
+
## Accessibility & responsiveness
|
|
93
|
+
<!-- a11y notes; breakpoints/viewports covered -->
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Also create/update `{project-root}/epics/EP-<slug>/DESIGN.md` (Impeccable's design-system file, or a
|
|
97
|
+
hand-authored equivalent when degraded) capturing the design tokens/components the screens rely on.
|
|
98
|
+
|
|
99
|
+
### Step 5 — Advance the authoring step (NOT the gate)
|
|
100
|
+
In `state.json`: set `ui-design.status: "done"`, set `ui-design-review.status: "in_review"`, and set
|
|
101
|
+
`currentStep: "ui-design-review"`. Write `state.json`. Do **not** touch `approvals.json`.
|
|
102
|
+
|
|
103
|
+
### Step 6 — Stop at the gate (do NOT advance)
|
|
104
|
+
Report: the paths to `ui-design.md` and `DESIGN.md`, whether Impeccable was used, and that the next
|
|
105
|
+
action is **review** via `sdlc-review-gate` (base rule: owner + 1 reviewer). **Never record approval
|
|
106
|
+
here.** Front states do not auto-advance. When the hub has a platform, the gate opens a review PR on the
|
|
107
|
+
hub (via `sdlc-hub-bridge`) and `sdlc-review-gate action: sync` pulls platform approvals/comments into
|
|
108
|
+
the ledger; otherwise the review is recorded file-only.
|
|
109
|
+
|
|
110
|
+
## Reference
|
|
111
|
+
- Impeccable commands and the slash-command-vs-CLI deviation: `RESEARCH-NOTES.md` §4 + Deviation 3.
|
|
112
|
+
- State schema and field meanings: `../sdlc-author-epic/references/state-schema.md`.
|
|
113
|
+
- Connecting code repos + the code-context the brain reads: `../sdlc-connect-repos/SKILL.md`.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sdlc-backfill
|
|
3
|
+
description: 'Build-half Step G of the gated SDLC — backfill: generate specs for already-built features in an existing repo so new work does not break them. Confirm Repomix (the one true CLI subprocess: npx repomix), pack ONE feature at a time (compress + git logs, secret-scan), feed it to AI with a "describe what exists, do not invent" prompt, and write a DRAFT spec marked unverified. Require human approval (reuse sdlc-review-gate) before the spec counts as real. Boundary is auto-proposed from the project convention and human-confirmed. A change is blocked only until the features IT touches have approved specs. Use when the user says "backfill specs", "document an existing feature", or "spec the legacy code".'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SDLC — Backfill (existing-code specs)
|
|
7
|
+
|
|
8
|
+
**Goal:** Bring an existing repo (no specs) under the gated SDLC one **feature** at a time, by
|
|
9
|
+
generating a spec for what is **already built** — so future changes have a contract to check against
|
|
10
|
+
(build plan §G). The generated spec is a **draft, unverified** until a human approves it; only then does
|
|
11
|
+
it count. Gating is **per touched feature**: a new change is blocked only until the features it touches
|
|
12
|
+
have approved specs — never the whole repo at once.
|
|
13
|
+
|
|
14
|
+
## Conventions
|
|
15
|
+
|
|
16
|
+
- `{project-root}` resolves from the project working directory; code repos are separate git repos under
|
|
17
|
+
`{project-root}/demo-repos/<repo>/`.
|
|
18
|
+
- **Repomix is a true CLI subprocess** (Phase 0 / RESEARCH-NOTES §3): `npx repomix@latest [flags]` —
|
|
19
|
+
NOT a slash-command. It secret-scans by default (Secretlint).
|
|
20
|
+
- Backfilled specs live in the code repo at `specs/backfill/<feature>/spec.md`.
|
|
21
|
+
- A **feature** is the project's natural unit from the constitution (e.g. a module / a `src/<feature>/`
|
|
22
|
+
directory). Auto-propose the boundary from the convention; **a human confirms** it where the code
|
|
23
|
+
does not follow it.
|
|
24
|
+
|
|
25
|
+
## Inputs
|
|
26
|
+
|
|
27
|
+
- `repo` — the existing code repo to backfill.
|
|
28
|
+
- `feature` — the feature name (and its file globs, e.g. `src/<feature>/**`).
|
|
29
|
+
- `action` — `pack` | `draft` | `approve` | `gate` (default `pack`).
|
|
30
|
+
|
|
31
|
+
## On Activation
|
|
32
|
+
|
|
33
|
+
### Step 1 — Propose the boundary (auto-propose, human-confirm)
|
|
34
|
+
From the constitution's convention (e.g. module = feature, or `src/<feature>/`), propose the feature's
|
|
35
|
+
file set. Present it and **ask the human to confirm or adjust** the boundary before packing. Never
|
|
36
|
+
guess silently where the code breaks the convention.
|
|
37
|
+
|
|
38
|
+
### Step 2 — `pack` (Repomix, one feature)
|
|
39
|
+
Run, from inside the repo, over **only this feature's files**:
|
|
40
|
+
```
|
|
41
|
+
npx repomix@latest --compress --include "<feature globs>" --include-logs --style markdown -o <out>.md
|
|
42
|
+
```
|
|
43
|
+
`--compress` (Tree-sitter structural compression) keeps it small; `--include-logs` adds the relevant
|
|
44
|
+
git history (default 50; `--include-logs-count N` to change); Secretlint secret-scans by default. If a
|
|
45
|
+
secret is reported, STOP and have it removed/redacted before continuing. (If `npx repomix` is
|
|
46
|
+
unavailable, degrade: hand-assemble the same feature context and record `repomix: unavailable`.)
|
|
47
|
+
|
|
48
|
+
### Step 3 — `draft` (describe what exists — do NOT invent)
|
|
49
|
+
Feed the packed context to the AI with the **"describe what exists, do not invent"** instruction
|
|
50
|
+
(`references/backfill.md`). Write `specs/backfill/<feature>/spec.md` describing the feature's actual
|
|
51
|
+
endpoints/behaviour/data as built, with frontmatter:
|
|
52
|
+
```yaml
|
|
53
|
+
---
|
|
54
|
+
feature: <feature>
|
|
55
|
+
repo: <repo>
|
|
56
|
+
artifact: backfill-spec
|
|
57
|
+
status: draft
|
|
58
|
+
verified: false # not real until a human approves
|
|
59
|
+
source: repomix # or "repomix: unavailable" when degraded
|
|
60
|
+
generated: <YYYY-MM-DD>
|
|
61
|
+
---
|
|
62
|
+
```
|
|
63
|
+
Mark every uncertain item explicitly (`<!-- unverified: ... -->`); do not fill gaps with invented
|
|
64
|
+
behaviour.
|
|
65
|
+
|
|
66
|
+
### Step 4 — `approve` (human approval — reuse the gate)
|
|
67
|
+
A human reads the draft against the real code and approves it with the same `human_approve` discipline
|
|
68
|
+
as `sdlc-review-gate` (owner + 1 reviewer). On approval set the frontmatter `verified: true` and record
|
|
69
|
+
the approver(s) + date. Only a `verified: true` backfill spec counts as real.
|
|
70
|
+
|
|
71
|
+
### Step 5 — `gate` (block changes per touched feature)
|
|
72
|
+
`bash checks/backfill-check.sh <base>` blocks a change that touches a feature being backfilled until
|
|
73
|
+
that feature's spec is `verified: true`. It is **per touched feature** — a change touching feature A is
|
|
74
|
+
not blocked by an unverified feature B. Forward-spec'd features (those with their own `specs/<story>/`)
|
|
75
|
+
are not this gate's concern.
|
|
76
|
+
|
|
77
|
+
### Step 6 — Stop (no auto-advance)
|
|
78
|
+
Report the packed feature, the draft path (or the approval), and what is still unverified. Nothing
|
|
79
|
+
auto-advances; a human owns the approval.
|
|
80
|
+
|
|
81
|
+
## Hard rules (build plan §G, Cross-cutting)
|
|
82
|
+
|
|
83
|
+
- **Describe what exists; never invent.** A backfill spec is a record of built behaviour, not a design.
|
|
84
|
+
- **Draft until human-approved.** `verified: false` specs do not count; approval reuses the gate.
|
|
85
|
+
- **One feature at a time; gate per touched feature.** Never block the whole repo.
|
|
86
|
+
- **Repomix via its real CLI** (Phase 0); secret-scan before any AI sees the code.
|
|
87
|
+
|
|
88
|
+
## Reference
|
|
89
|
+
- The "describe what exists" prompt, the spec shape, and the gate: `references/backfill.md`.
|
|
90
|
+
- The human approval discipline reused: `../sdlc-review-gate/SKILL.md`.
|
|
91
|
+
- Repomix flags: `RESEARCH-NOTES.md` §3.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Backfill — Repomix pack, the "describe what exists" prompt, and the gate
|
|
2
|
+
|
|
3
|
+
Backfill (build plan §G) brings an existing repo under the gated SDLC **one feature at a time**, by
|
|
4
|
+
recording what is already built as a spec a human approves. It never invents behaviour and never blocks
|
|
5
|
+
the whole repo.
|
|
6
|
+
|
|
7
|
+
## Repomix (the one true CLI subprocess)
|
|
8
|
+
|
|
9
|
+
`npx repomix@latest [flags]` (Phase 0 / RESEARCH-NOTES §3). For a single feature:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
npx repomix@latest --compress --include "src/<feature>/**" --include-logs --style markdown -o <out>.md
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
- `--compress` — Tree-sitter structural compression (keeps the pack small and signal-dense).
|
|
16
|
+
- `--include "<glob,glob>"` — restrict to this feature's files (one feature at a time).
|
|
17
|
+
- `--include-logs` — add the relevant git commit history (default 50; `--include-logs-count N`).
|
|
18
|
+
- `--style markdown` — human/AI-readable; default output is `repomix-output.xml`.
|
|
19
|
+
- **Secretlint runs by default** — if a secret is reported, STOP and redact before any AI sees the code.
|
|
20
|
+
|
|
21
|
+
If `npx repomix` is unavailable, degrade: hand-assemble the same feature context (the feature's files +
|
|
22
|
+
recent git log for those paths) and record `repomix: unavailable` in the spec frontmatter.
|
|
23
|
+
|
|
24
|
+
## The "describe what exists, do not invent" prompt
|
|
25
|
+
|
|
26
|
+
> You are documenting an ALREADY-BUILT feature from its packed source + git history. Describe ONLY what
|
|
27
|
+
> the code actually does: its endpoints/inputs/outputs, behaviour, and data as built. Do NOT invent
|
|
28
|
+
> requirements, do NOT propose changes, do NOT fill gaps with assumptions. Where the behaviour is
|
|
29
|
+
> unclear from the code, mark it `<!-- unverified: ... -->` rather than guessing. Output a spec a human
|
|
30
|
+
> can confirm against the code.
|
|
31
|
+
|
|
32
|
+
## The backfill spec
|
|
33
|
+
|
|
34
|
+
`specs/backfill/<feature>/spec.md`:
|
|
35
|
+
|
|
36
|
+
```yaml
|
|
37
|
+
---
|
|
38
|
+
feature: <feature>
|
|
39
|
+
repo: <repo>
|
|
40
|
+
artifact: backfill-spec
|
|
41
|
+
status: draft
|
|
42
|
+
verified: false
|
|
43
|
+
source: repomix
|
|
44
|
+
generated: <YYYY-MM-DD>
|
|
45
|
+
---
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
`verified: false` until a human approves (the `sdlc-review-gate` discipline: owner + 1 reviewer). On
|
|
49
|
+
approval, set `verified: true` and record the approver(s) + date. Only a `verified: true` backfill spec
|
|
50
|
+
counts as real.
|
|
51
|
+
|
|
52
|
+
## Boundary detection (auto-propose, human-confirm)
|
|
53
|
+
|
|
54
|
+
Propose the feature's file set from the project convention (e.g. a module or a `src/<feature>/`
|
|
55
|
+
directory — from the constitution). Present it; a human confirms or adjusts where the code does not
|
|
56
|
+
follow the convention. Never finalise a boundary silently.
|
|
57
|
+
|
|
58
|
+
## The gate — `checks/backfill-check.sh`
|
|
59
|
+
|
|
60
|
+
A change is blocked **only until the features it touches** have approved specs — not the whole repo:
|
|
61
|
+
|
|
62
|
+
- For each `src/<feature>/` the diff touches, if `specs/backfill/<feature>/spec.md` exists it must be
|
|
63
|
+
`verified: true`; otherwise **FAIL** (run backfill + approve for that feature first).
|
|
64
|
+
- A feature with **no** `specs/backfill/<feature>/` is not this gate's concern (it is either
|
|
65
|
+
forward-spec'd via `sdlc-spec`, or not yet being backfilled).
|
|
66
|
+
- Fails closed on an unresolvable base ref, like the other gates.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# backfill gate (Phase 3 build plan §G). A change that touches a feature being backfilled must wait
|
|
3
|
+
# until that feature's backfill spec is human-approved (verified: true). Gated PER touched feature, not
|
|
4
|
+
# the whole repo: touching feature A is never blocked by an unverified feature B. Features that are
|
|
5
|
+
# forward-spec'd (their own specs/<story>/) or not yet being backfilled are not this gate's concern.
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
BASE="${1:-${SDLC_BASE:-origin/main}}"
|
|
9
|
+
if ! git rev-parse --verify --quiet "${BASE}^{commit}" >/dev/null; then
|
|
10
|
+
echo "FAIL [backfill]: base ref '${BASE}' not found — fetch full history / check the base branch."
|
|
11
|
+
exit 1
|
|
12
|
+
fi
|
|
13
|
+
|
|
14
|
+
changed="$(git diff --name-only "${BASE}..HEAD")"
|
|
15
|
+
# Feature = a directory under src/ (src/<feature>/...). Top-level src/*.js files are deliberately NOT
|
|
16
|
+
# gated here (they belong to no single feature); only src/<feature>/ changes are checked.
|
|
17
|
+
feats="$(printf '%s\n' "$changed" | sed -nE 's#^src/([^/]+)/.*#\1#p' | sort -u)"
|
|
18
|
+
|
|
19
|
+
if [ -z "$feats" ]; then
|
|
20
|
+
echo "PASS [backfill]: no src/<feature> changes."
|
|
21
|
+
exit 0
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
rc=0
|
|
25
|
+
while IFS= read -r f; do
|
|
26
|
+
[ -z "$f" ] && continue
|
|
27
|
+
spec="specs/backfill/${f}/spec.md"
|
|
28
|
+
[ -f "$spec" ] || { echo "note [backfill]: ${f} is not being backfilled (no ${spec}) — skipped."; continue; }
|
|
29
|
+
# Read ONLY the YAML frontmatter (between the first two --- lines) so a prose line that merely
|
|
30
|
+
# contains "verified: true" cannot false-pass the gate.
|
|
31
|
+
fm="$(awk 'NR==1 && /^---[[:space:]]*$/ {f=1; next} f && /^---[[:space:]]*$/ {exit} f {print}' "$spec")"
|
|
32
|
+
if printf '%s\n' "$fm" | grep -qiE '^verified:[[:space:]]*true[[:space:]]*$'; then
|
|
33
|
+
echo "PASS [backfill]: ${f} has an approved (verified) backfill spec."
|
|
34
|
+
else
|
|
35
|
+
echo "FAIL [backfill]: ${f} is being backfilled but its spec is not yet human-approved (verified: true)."
|
|
36
|
+
echo " -> run sdlc-backfill approve for ${spec} before changing this feature."
|
|
37
|
+
rc=1
|
|
38
|
+
fi
|
|
39
|
+
done <<EOF
|
|
40
|
+
$feats
|
|
41
|
+
EOF
|
|
42
|
+
exit "$rc"
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sdlc-checks
|
|
3
|
+
description: 'Build-half Step C of the gated SDLC — the production-safety check gates. Wire and run the CI gates on a code repo: spec-link (every change links a real story/spec via its Task trailer), contract-check (a diff that changes the contract surface without a Contract-Change + an updated, re-locked contract FAILS and routes back to the architecture gate), build/test/lint, and verified-commits (no unverified commits from unverified users — platform-Verified signature + roster-allowlisted author, on the hub and every repo). The gates are CI-agnostic bash, invoked by GitHub Actions and GitLab CI. Use when the user says "wire the check gates", "run the gates", "require signed commits", or "set up CI checks" for a repo.'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SDLC — Check Gates (build-half Step C)
|
|
7
|
+
|
|
8
|
+
**Goal:** Install and run the **check gates** that protect production for a code repo. They run
|
|
9
|
+
in CI on every PR/MR and must pass before merge (build plan §C). Each is a small, separate check:
|
|
10
|
+
|
|
11
|
+
1. **spec-link** — the change links a real story/spec: its commits carry a `Task: <story>-<task>`
|
|
12
|
+
trailer (the convention `sdlc-implement` writes) whose `<story>` resolves to `specs/<story>/link.md`.
|
|
13
|
+
No unlinked code reaches merge.
|
|
14
|
+
2. **contract-check** — if the diff changes the **contract surface** (the repo's quoted slice under
|
|
15
|
+
`specs/<story>/contracts/`) without a `Contract-Change: yes` trailer **and** an updated, re-locked
|
|
16
|
+
contract upstream, it **FAILS and routes back to the architecture gate**. The shared surface is
|
|
17
|
+
never widened from inside a code repo (Phase 2 contract representation: delimited block + SHA-256 lock).
|
|
18
|
+
3. **build/test/lint** — standard quality stage; tests must actually exercise new behavior, not just pass.
|
|
19
|
+
4. **verified-commits** — no unverified commits from unverified users: every commit in the range must
|
|
20
|
+
carry a signature the platform marks **Verified** AND be authored by a known identity
|
|
21
|
+
(`.sdlc/verified-authors`, generated from the hub roster's `email` fields). Enforced on the
|
|
22
|
+
**product hub and every connected repo**; runs on PRs/MRs only, so the gate-sync bot's direct
|
|
23
|
+
ledger pushes are unaffected (never replace it with a default-branch push rule — see
|
|
24
|
+
`references/check-gates.md` §4).
|
|
25
|
+
|
|
26
|
+
The gates are **CI-agnostic bash** in `checks/`; thin pipeline configs invoke them on GitHub Actions
|
|
27
|
+
and GitLab CI. This step is **by hand** in Phase 3 — run the gates with the skill or let CI run them;
|
|
28
|
+
**nothing auto-advances**. The gates are blocking in CI, but the human still owns the merge (Step E).
|
|
29
|
+
|
|
30
|
+
## Conventions
|
|
31
|
+
|
|
32
|
+
- `{project-root}` resolves from the project working directory — the **product** repo (holds the
|
|
33
|
+
canonical templates under this skill).
|
|
34
|
+
- Code repos are separate git repos under `{project-root}/demo-repos/<repo>/`
|
|
35
|
+
(`config.yaml` `build.code_repos_root`).
|
|
36
|
+
- Canonical gate sources live in this skill's `templates/` (the source of truth that gets installed
|
|
37
|
+
into each code repo):
|
|
38
|
+
- `templates/checks/{spec-link,contract-check,build-test-lint,verified-commits}.sh`
|
|
39
|
+
- `templates/github/sdlc-verified-commits.yml` + `templates/gitlab/sdlc-verified-commits.gitlab-ci.yml`
|
|
40
|
+
→ the standalone hub-side verified-commits CI (installed by `sdlc check --fix` with the hub wiring)
|
|
41
|
+
- `templates/github/sdlc-checks.yml` → installs to `.github/workflows/sdlc-checks.yml` (marked `# sdlc-managed: sdlc-checks`)
|
|
42
|
+
- `templates/gitlab/sdlc-checks.gitlab-ci.yml` → includable fragment, installs to `.gitlab/ci/sdlc-checks.yml`
|
|
43
|
+
- `templates/gitlab/gitlab-ci.include-root.yml` → minimal root written only when no root `.gitlab-ci.yml` exists
|
|
44
|
+
- `templates/gitlab/.gitlab-ci.yml` → legacy standalone root (greenfield single-file option)
|
|
45
|
+
- The gates depend on the conventions from earlier steps: the `Task:`/`Contract-Change:` commit
|
|
46
|
+
trailers (`sdlc-implement`), the `specs/<story>/link.md` + `contracts/` slice (`sdlc-spec`), and the
|
|
47
|
+
locked `contract.md` (`sdlc-author-architecture`).
|
|
48
|
+
|
|
49
|
+
## Inputs
|
|
50
|
+
|
|
51
|
+
- `repo` — the code repo to wire/run gates for (one of an epic's repos), or `hub` to wire the product hub itself.
|
|
52
|
+
- `action` — `wire` (install the gates into the repo) | `run` (run the three gates now). Default `run`.
|
|
53
|
+
- `base` — for `run`: the base ref to diff against (the PR/MR target; default the repo's default branch).
|
|
54
|
+
|
|
55
|
+
## On Activation
|
|
56
|
+
|
|
57
|
+
### Step 1 — Resolve the code repo
|
|
58
|
+
Map `repo` → `{project-root}/demo-repos/<repo>/` (or the registry `path` in `.sdlc/repos.json`); confirm
|
|
59
|
+
it is its own git repo. Operate inside it with absolute paths. For `repo: hub`, the target is
|
|
60
|
+
`{project-root}` itself and the platform comes from `.sdlc/hub.json` — see "Wiring the hub" in
|
|
61
|
+
`references/check-gates.md`.
|
|
62
|
+
|
|
63
|
+
### Step 2 — `wire` (install the gates, syncing with any existing CI)
|
|
64
|
+
Copy from this skill's `templates/`:
|
|
65
|
+
- `templates/checks/*.sh` → `<repo>/checks/` (and `chmod +x`).
|
|
66
|
+
- Detect the platform and **merge — never clobber — the matching** CI config. Inspect what is already
|
|
67
|
+
there first; the principle is **additive: never edit a foreign CI file**.
|
|
68
|
+
|
|
69
|
+
**GitHub** (detect by any `.github/workflows/*.y*ml`): our gates live in their own
|
|
70
|
+
`.github/workflows/sdlc-checks.yml`, which GitHub runs independently of every other workflow, so
|
|
71
|
+
"merge" reduces to "do not collide on the path".
|
|
72
|
+
- No file at our path → copy `templates/github/sdlc-checks.yml` verbatim.
|
|
73
|
+
- A file at our path whose **first line is `# sdlc-managed: sdlc-checks`** → it is ours; refresh it
|
|
74
|
+
(no-op if unchanged).
|
|
75
|
+
- A **foreign** file occupies that path/name → write to a non-colliding filename
|
|
76
|
+
(`sdlc-checks.gen.yml`) and ensure its `name:` does not clash. Never merge jobs into a foreign
|
|
77
|
+
workflow; never edit one.
|
|
78
|
+
|
|
79
|
+
**GitLab** (detect by a root `.gitlab-ci.yml` and/or `.gitlab/ci/*.yml`): install the includable
|
|
80
|
+
fragment `templates/gitlab/sdlc-checks.gitlab-ci.yml` → `<repo>/.gitlab/ci/sdlc-checks.yml` (its jobs
|
|
81
|
+
carry `needs: []` and no `stage:`, so a foreign root `stages:` cannot break or reorder them).
|
|
82
|
+
- No root `.gitlab-ci.yml` → write `templates/gitlab/gitlab-ci.include-root.yml` to
|
|
83
|
+
`<repo>/.gitlab-ci.yml` (a minimal root that only `include:`s our fragment).
|
|
84
|
+
- Root exists → read its top-level `include:`. Add the `include:` key if absent; append
|
|
85
|
+
`- local: '.gitlab/ci/sdlc-checks.yml'` if the key exists but the entry is missing; **no-op** if it
|
|
86
|
+
is already listed. Touch nothing else in the root.
|
|
87
|
+
- If the existing YAML cannot be parsed safely → **STOP** and print the exact include snippet for the
|
|
88
|
+
human to paste (graceful degradation — never guess-edit a pipeline you cannot parse).
|
|
89
|
+
- The legacy standalone `templates/gitlab/.gitlab-ci.yml` is retained only for a clean greenfield repo
|
|
90
|
+
that prefers a single self-contained file; the include path above is the default.
|
|
91
|
+
|
|
92
|
+
- Ensure `<repo>/package.json` defines `lint`, `build`, `test` scripts (see `references/check-gates.md`
|
|
93
|
+
for the canonical scripts). **Only ADD a missing script; never overwrite an existing one.**
|
|
94
|
+
|
|
95
|
+
Re-running `wire` is **idempotent** — markers (`# sdlc-managed: sdlc-checks`,
|
|
96
|
+
`# sdlc-managed-include: sdlc-checks`) and the include-entry check make a second run a no-op.
|
|
97
|
+
Commit the wiring on the repo's default branch (it is shared infrastructure, not a task diff).
|
|
98
|
+
|
|
99
|
+
**The hub is wired the same way.** `repo: hub` wires the hub repo itself (platform from `.sdlc/hub.json`)
|
|
100
|
+
with a hub-flavored gate set — see "Wiring the hub" in `references/check-gates.md`.
|
|
101
|
+
|
|
102
|
+
### Step 3 — `run` (run the gates now)
|
|
103
|
+
From inside the repo, run each gate against `base` and report PASS/FAIL per gate:
|
|
104
|
+
```
|
|
105
|
+
bash checks/spec-link.sh "<base>"
|
|
106
|
+
bash checks/contract-check.sh "<base>"
|
|
107
|
+
bash checks/build-test-lint.sh
|
|
108
|
+
```
|
|
109
|
+
A non-zero exit is a FAIL. Summarize which gates passed and, for any failure, the exact remediation
|
|
110
|
+
(spec-link: add the `Task:` trailer / spec; contract-check: route back to the architecture gate and
|
|
111
|
+
re-lock the contract; build/test/lint: fix the failing lint/test).
|
|
112
|
+
|
|
113
|
+
### Step 4 — Report; the advance decision belongs to the dial (Phase 4)
|
|
114
|
+
Report the gate results. Passing gates do **not** merge anything — the AI review (Step D/E) and the
|
|
115
|
+
human engineer review (Step E) still own the merge. This skill never edits the epic's `.sdlc/` state.
|
|
116
|
+
|
|
117
|
+
- **Run standalone** (the Phase 3 default): **stop** here. A clean pass does not advance anything; a
|
|
118
|
+
human takes the next step.
|
|
119
|
+
- **Run by the orchestrator** (`sdlc-run`, Phase 4): this skill still just reports PASS/FAIL — the
|
|
120
|
+
*advance decision* is the orchestrator's, read from the `checks` step's `automation` dial. On a clean
|
|
121
|
+
pass with `checks` earned to `machine_advance`, `sdlc-run` advances to `engineer-review` on its own;
|
|
122
|
+
on any FAIL it halts and pulls in a human (build plan §B). **What the gates check is unchanged** —
|
|
123
|
+
only who decides to proceed after a clean pass.
|
|
124
|
+
|
|
125
|
+
## Hard rules (build plan §C, Cross-cutting)
|
|
126
|
+
|
|
127
|
+
- **The gates are blocking in CI, advisory to no one.** A FAIL stops the merge; a PASS does not grant it.
|
|
128
|
+
- **Contract surface is never widened from a code repo.** contract-check routes surface changes back
|
|
129
|
+
to the architecture gate; only an updated, re-locked contract + `Contract-Change: yes` may pass.
|
|
130
|
+
- **Tests must exercise behavior.** build/test/lint is not satisfied by empty or trivial tests.
|
|
131
|
+
- **The gate never advances itself.** A FAIL always halts. A clean PASS advances only when the
|
|
132
|
+
orchestrator's `checks` dial is `machine_advance` (earned) — and only as far as the engineer review,
|
|
133
|
+
which is always human. Standalone, the gate still stops and the human owns the merge.
|
|
134
|
+
|
|
135
|
+
## Reference
|
|
136
|
+
- Gate definitions, the canonical scripts, CI wiring, and the convention map: `references/check-gates.md`.
|
|
137
|
+
- Commit-trailer conventions the gates read: `../sdlc-implement/references/implement-conventions.md`.
|
|
138
|
+
- Contract surface + hash recipe: `../sdlc-author-architecture/references/contract-format.md`.
|