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,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`.