mandrel 1.92.0 → 1.94.0
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/.agents/agents/acceptance-critic.md +129 -0
- package/.agents/agents/retro.md +42 -0
- package/.agents/agents/story-worker.md +162 -0
- package/.agents/docs/configuration.md +7 -1
- package/.agents/docs/execution-reference.md +27 -2
- package/.agents/instructions.md +43 -33
- package/.agents/personas/engineer.md +26 -112
- package/.agents/personas/security-engineer.md +1 -2
- package/.agents/rules/git-conventions-reference.md +225 -0
- package/.agents/rules/git-conventions.md +25 -200
- package/.agents/rules/security-baseline.md +5 -0
- package/.agents/rules/testing-standards.md +106 -13
- package/.agents/schemas/agentrc.schema.json +31 -1
- package/.agents/schemas/lifecycle/slice.end.schema.json +21 -0
- package/.agents/schemas/lifecycle/slice.heartbeat.schema.json +20 -0
- package/.agents/schemas/lifecycle/slice.start.schema.json +17 -0
- package/.agents/scripts/acceptance-eval.js +62 -18
- package/.agents/scripts/agents-bootstrap-github.js +1 -1
- package/.agents/scripts/bookkeeping-reconcile.js +117 -0
- package/.agents/scripts/check-context-budget.js +62 -5
- package/.agents/scripts/diagnose-friction.js +0 -6
- package/.agents/scripts/epic-deliver-prepare.js +272 -10
- package/.agents/scripts/lib/bootstrap/project-bootstrap.js +56 -18
- package/.agents/scripts/lib/close-validation/gates.js +159 -21
- package/.agents/scripts/lib/config/acceptance-eval.js +52 -5
- package/.agents/scripts/lib/config/delivery-routing.js +87 -0
- package/.agents/scripts/lib/config/explain.js +2 -0
- package/.agents/scripts/lib/config-resolver.js +1 -1
- package/.agents/scripts/lib/config-settings-schema-delivery.js +37 -3
- package/.agents/scripts/lib/config-settings-schema-quality.js +9 -0
- package/.agents/scripts/lib/doc-tiers.js +37 -2
- package/.agents/scripts/lib/observability/active-story-env.js +111 -2
- package/.agents/scripts/lib/observability/hook-heartbeat.js +219 -0
- package/.agents/scripts/lib/observability/tool-trace-hook.js +15 -4
- package/.agents/scripts/lib/orchestration/acceptance-clusters.js +111 -0
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +32 -4
- package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +270 -0
- package/.agents/scripts/lib/orchestration/ceremony-routing.js +141 -0
- package/.agents/scripts/lib/orchestration/context-hydration-engine.js +3 -124
- package/.agents/scripts/lib/orchestration/deliver-route.js +173 -0
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/authoring-context.js +1 -1
- package/.agents/scripts/lib/orchestration/epic-run-state-store.js +233 -0
- package/.agents/scripts/lib/orchestration/file-assumptions.js +68 -7
- package/.agents/scripts/lib/orchestration/lifecycle/emit-slice-lifecycle.js +270 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +83 -2
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/checkpoint-pointer-writer.js +6 -0
- package/.agents/scripts/lib/orchestration/plan-context.js +189 -3
- package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +3 -2
- package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +99 -0
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +38 -1
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +16 -1
- package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +1 -0
- package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +1 -0
- package/.agents/scripts/lib/orchestration/ticket-validator.js +19 -2
- package/.agents/scripts/lib/provider-factory.js +1 -1
- package/.agents/scripts/lib/templates/decomposer-prompts.js +1 -1
- package/.agents/scripts/plan-context.js +28 -10
- package/.agents/scripts/post-structured-comment.js +38 -0
- package/.agents/scripts/slice-phase.js +361 -0
- package/.agents/scripts/sync-claude-agents.js +165 -0
- package/.agents/scripts/update-ticket-state.js +31 -0
- package/.agents/scripts/wave-tick.js +138 -9
- package/.agents/skills/core/api-and-interface-design/SKILL.md +5 -3
- package/.agents/skills/core/code-review-and-quality/SKILL.md +63 -7
- package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +1 -1
- package/.agents/skills/core/epic-plan-consolidate/SKILL.md +5 -5
- package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +8 -8
- package/.agents/skills/core/epic-plan-premortem/SKILL.md +4 -4
- package/.agents/skills/core/epic-plan-spec-author/SKILL.md +26 -56
- package/.agents/skills/core/gates-and-baselines/SKILL.md +149 -0
- package/.agents/skills/core/idea-refinement/SKILL.md +2 -8
- package/.agents/skills/core/qa-coverage-mapping/SKILL.md +7 -7
- package/.agents/skills/skills.index.json +11 -381
- package/.agents/workflows/deliver.md +47 -4
- package/.agents/workflows/helpers/acceptance-self-eval.md +38 -13
- package/.agents/workflows/helpers/deliver-epic-reference.md +18 -5
- package/.agents/workflows/helpers/deliver-epic-single.md +331 -0
- package/.agents/workflows/helpers/deliver-epic.md +51 -8
- package/.agents/workflows/helpers/deliver-stories.md +15 -5
- package/.agents/workflows/helpers/epic-deliver-story.md +12 -3
- package/.agents/workflows/helpers/mandrel-sync-config.md +1 -1
- package/.agents/workflows/helpers/plan-epic-reference.md +19 -8
- package/.agents/workflows/helpers/plan-epic.md +95 -27
- package/.agents/workflows/helpers/scope-triage-gate.md +9 -0
- package/.agents/workflows/mandrel-update.md +1 -1
- package/.agents/workflows/plan.md +16 -4
- package/docs/CHANGELOG.md +23 -0
- package/lib/cli/registry.js +95 -0
- package/package.json +4 -2
- package/.agents/personas/engineer-mobile.md +0 -120
- package/.agents/personas/engineer-web.md +0 -111
- package/.agents/personas/product.md +0 -94
- package/.agents/personas/refactorer.md +0 -113
- package/.agents/personas/sre.md +0 -86
- package/.agents/personas/ux-designer.md +0 -95
- package/.agents/scripts/epic-plan-decompose.js +0 -54
- package/.agents/scripts/epic-plan-spec.js +0 -64
- package/.agents/scripts/lib/orchestration/skill-capsule-loader.js +0 -109
- package/.agents/scripts/plan-critics.js +0 -227
- package/.agents/skills/core/baseline-refresh/SKILL.md +0 -181
- package/.agents/skills/core/ci-cd-and-automation/SKILL.md +0 -274
- package/.agents/skills/core/ci-cd-and-automation/examples.md +0 -211
- package/.agents/skills/core/code-simplification/SKILL.md +0 -389
- package/.agents/skills/core/context-engineering/SKILL.md +0 -309
- package/.agents/skills/core/context-engineering/examples.md +0 -58
- package/.agents/skills/core/deprecation-and-migration/SKILL.md +0 -250
- package/.agents/skills/core/frontend-ui-engineering/SKILL.md +0 -357
- package/.agents/skills/core/hydrate-context/SKILL.md +0 -123
- package/.agents/skills/core/idea-refinement/examples.md +0 -437
- package/.agents/skills/core/idea-refinement/frameworks.md +0 -135
- package/.agents/skills/core/incremental-implementation/SKILL.md +0 -271
- package/.agents/skills/core/introducing-a-baseline-gate/SKILL.md +0 -213
- package/.agents/skills/core/knowledge-transfer/SKILL.md +0 -180
- package/.agents/skills/core/mutation-survivor-remediation/SKILL.md +0 -117
- package/.agents/skills/core/performance-optimization/SKILL.md +0 -314
- package/.agents/skills/core/planning-and-task-breakdown/SKILL.md +0 -277
- package/.agents/skills/core/property-based-testing/SKILL.md +0 -148
- package/.agents/skills/core/refactoring-discipline/SKILL.md +0 -111
- package/.agents/skills/core/shipping-and-launch/SKILL.md +0 -328
- package/.agents/skills/core/spec-driven-development/SKILL.md +0 -252
- package/.agents/skills/core/test-driven-development/SKILL.md +0 -475
- package/.agents/skills/core/using-agent-skills/SKILL.md +0 -232
- package/.agents/skills/stack/architecture/monorepo-path-strategist/SKILL.md +0 -31
- package/.agents/skills/stack/architecture/structured-output-zod/SKILL.md +0 -51
- package/.agents/skills/stack/architecture/subagent-orchestration/SKILL.md +0 -76
- package/.agents/skills/stack/backend/cloudflare-hono-architect/SKILL.md +0 -31
- package/.agents/skills/stack/backend/cloudflare-hono-architect/examples/route-template.ts +0 -33
- package/.agents/skills/stack/backend/cloudflare-queue-manager/SKILL.md +0 -31
- package/.agents/skills/stack/backend/cloudflare-workers/SKILL.md +0 -51
- package/.agents/skills/stack/backend/highlevel-crm/SKILL.md +0 -54
- package/.agents/skills/stack/backend/sqlite-drizzle-expert/SKILL.md +0 -29
- package/.agents/skills/stack/backend/sqlite-drizzle-expert/examples/schema-template.ts +0 -30
- package/.agents/skills/stack/backend/stripe-integration/SKILL.md +0 -57
- package/.agents/skills/stack/backend/stripe-integration/scripts/listen-stripe.sh +0 -9
- package/.agents/skills/stack/backend/turso-sqlite/SKILL.md +0 -48
- package/.agents/skills/stack/frontend/astro/SKILL.md +0 -62
- package/.agents/skills/stack/frontend/astro-react-island-strategist/SKILL.md +0 -30
- package/.agents/skills/stack/frontend/expo-react-native-developer/SKILL.md +0 -29
- package/.agents/skills/stack/frontend/google-analytics-v4/SKILL.md +0 -50
- package/.agents/skills/stack/frontend/tailwind-v4/SKILL.md +0 -58
- package/.agents/skills/stack/frontend/ui-accessibility-engineer/SKILL.md +0 -34
- package/.agents/skills/stack/qa/audit-accessibility/SKILL.md +0 -51
- package/.agents/skills/stack/qa/lighthouse-baseline/SKILL.md +0 -199
- package/.agents/skills/stack/security/backend-security-patterns/SKILL.md +0 -68
|
@@ -3,8 +3,8 @@ name: epic-plan-spec-author
|
|
|
3
3
|
description: >-
|
|
4
4
|
Author the Tech Spec, Acceptance Table markdown, and risk-verdict JSON
|
|
5
5
|
for an Epic from the planner authoring context emitted by
|
|
6
|
-
`
|
|
7
|
-
the host LLM needs to write the three artifacts before `
|
|
6
|
+
`plan-context.js --epic <Epic_ID>`. Use during Phase 7 of `/plan` when
|
|
7
|
+
the host LLM needs to write the three artifacts before `plan-persist.js`
|
|
8
8
|
folds them into the Epic body's managed sections.
|
|
9
9
|
allowed_tools:
|
|
10
10
|
- Read
|
|
@@ -32,7 +32,7 @@ allowed_tools:
|
|
|
32
32
|
|
|
33
33
|
## Policy Capsule
|
|
34
34
|
|
|
35
|
-
- Run only during `/plan` Phase 7, after `
|
|
35
|
+
- Run only during `/plan` Phase 7, after `plan-context.js --epic <Epic_ID>` has written `temp/epic-<Epic_ID>/planner-context.json`; fail loudly if the file is missing rather than fabricating context.
|
|
36
36
|
- Write exactly three artifacts and only inside `temp/epic-<Epic_ID>/`: `techspec.md`, `risk-verdict.json`, `acceptance-spec.md`. All three MUST exist on disk before returning.
|
|
37
37
|
- **Re-emit rule (amend, don't regenerate — Story #4431).** On a re-emit — the Phase 7 persist call rejecting an artifact (e.g. a missing `## Delivery Slicing` heading, a schema-invalid risk verdict) — apply **targeted edits** to the existing `temp/epic-<Epic_ID>/` artifact that fix only what the rejection named; do NOT rewrite an artifact wholesale from a blank draft. `helpers/plan-epic.md` bounds this to **one refinement pass** per invocation (the same shape as the Epic Clarity Gate's own "one refinement pass per invocation" contract) — do not loop.
|
|
38
38
|
- Start each markdown artifact at the correct `##` heading (Tech Spec → `## Delivery Slicing`, Acceptance Spec → `## Acceptance Table` — never the Epic's own `## Acceptance Criteria` heading, which stays the ideation bullets) — never emit a top-level `#` heading. `risk-verdict.json` is raw JSON conforming to `.agents/schemas/risk-verdict.schema.json`.
|
|
@@ -57,7 +57,7 @@ the Tech Spec to produce the Acceptance Spec).
|
|
|
57
57
|
|
|
58
58
|
## When to use
|
|
59
59
|
|
|
60
|
-
`/plan` Phase 7, immediately after `
|
|
60
|
+
`/plan` Phase 7, immediately after `plan-context.js --epic <Epic_ID>`
|
|
61
61
|
writes `temp/epic-<Epic_ID>/planner-context.json`. This Skill replaces the
|
|
62
62
|
inline "Author the Tech Spec" step from the legacy workflow body — the calling
|
|
63
63
|
workflow dispatches this Skill via the `Skill` tool, supplies the Epic ID, and
|
|
@@ -72,7 +72,7 @@ The dispatcher passes the Epic ID as the Skill argument. The Skill itself
|
|
|
72
72
|
reads:
|
|
73
73
|
|
|
74
74
|
- `temp/epic-<Epic_ID>/planner-context.json` — produced by
|
|
75
|
-
`node .agents/scripts/
|
|
75
|
+
`node .agents/scripts/plan-context.js --epic <Epic_ID>`.
|
|
76
76
|
Fields:
|
|
77
77
|
- `epic.id`, `epic.title`, `epic.body` (or `epic.bodySummary` when the
|
|
78
78
|
planning-context budget downgrades the body to a summary)
|
|
@@ -113,10 +113,10 @@ reads:
|
|
|
113
113
|
Treat each as a likely drift signal: confirm the path exists (it may
|
|
114
114
|
have been dropped by truncation) or mark it net-new explicitly in
|
|
115
115
|
the spec so the post-author freshness gate does not flag it.
|
|
116
|
-
- `systemPrompts.techSpec` and
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
116
|
+
- `systemPrompts.techSpec` and `systemPrompts.acceptanceSpec` — the
|
|
117
|
+
**authoritative** rendered system prompts (single-sourced in
|
|
118
|
+
`lib/templates/spec-author-prompts.js`). Apply them verbatim; the
|
|
119
|
+
procedure below describes how to use them, it does not restate them.
|
|
120
120
|
- `bddRunner` — BDD runner pending-tag verification result. Shape:
|
|
121
121
|
`{ runner, pendingTag, supported, fallback, reason? }`. When
|
|
122
122
|
`supported: true`, render the verified `pendingTag` in the
|
|
@@ -151,7 +151,7 @@ reads:
|
|
|
151
151
|
|
|
152
152
|
All three files MUST exist on disk before this Skill returns control. The
|
|
153
153
|
caller will invoke
|
|
154
|
-
`
|
|
154
|
+
`plan-persist.js --epic <Epic_ID> --tech-spec ... --risk-verdict ... --acceptance-table ...`
|
|
155
155
|
next, and the persist half will fail loudly if any file is missing, empty,
|
|
156
156
|
or (for the verdict) schema-invalid.
|
|
157
157
|
|
|
@@ -217,27 +217,13 @@ consolidation and the section the model most often omits when it drafts it last.
|
|
|
217
217
|
> "Independent?" means, why an unjustified `No` slice is a smell, and how the
|
|
218
218
|
> consolidation pass degrades gracefully when the section is absent).
|
|
219
219
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
1. Delivery Slicing — propose how the Epic's enumerated capabilities cluster into shippable Stories. This count is a CEILING, not a target: the Phase 8 consolidation pass may merge below your proposed count when slices form dependent single-consumer chains, but never splits above it. Do NOT coarsen the Epic enumeration to produce this; the grouping recommendation is the granularity lever.
|
|
228
|
-
2. Architecture & Design
|
|
229
|
-
3. Data Models (if any)
|
|
230
|
-
4. API Changes (if any)
|
|
231
|
-
5. Core Components
|
|
232
|
-
6. Security & Privacy Considerations
|
|
233
|
-
|
|
234
|
-
CRITICAL REQUIREMENTS:
|
|
235
|
-
- Respond ONLY with valid Markdown.
|
|
236
|
-
- Do not use top-level <h1> (# ) tags. Open the document with the `## Delivery Slicing` section — it is the primary input to Phase 8 consolidation, so author it first and hang the rest of the spec off it.
|
|
237
|
-
- Do NOT restate the Epic's Context, Goal, or Scope — your output lands as sections of the same Epic body, which travels into every downstream story agent's prompt, so any restatement is pure duplication and a drift risk. If a brief technical orientation is genuinely useful, add an optional `## Technical Overview` of no more than 2–3 sentences that names the *technical approach* only (which subsystems are touched and reused); never re-narrate the problem statement, goals, or scope.
|
|
238
|
-
- Format architectural decisions clearly with bullet points.
|
|
239
|
-
- Author the `## Delivery Slicing` section as a markdown table with columns `Slice | What ships | Independent?`, using noun-phrase slice names (e.g. "Foundation", "Transport seam", "Send helper") that map onto Feature titles. "Independent?" answers: can this slice ship to production and provide value without the next slice landing? A slice you mark "Independent? No" MUST carry a one-line justification (parallelism, risk isolation, or delivery-envelope pressure); an unjustified dependent single-consumer slice folds into its consumer by default rather than shipping as its own Story.
|
|
240
|
-
```
|
|
220
|
+
Apply the `systemPrompts.techSpec` string from the emitted envelope verbatim —
|
|
221
|
+
it is the single source (rendered from `lib/templates/spec-author-prompts.js`).
|
|
222
|
+
It fixes the section order (Delivery Slicing first as the Phase 8 ceiling, then
|
|
223
|
+
Architecture, Data Models, API Changes, Core Components, Security), forbids
|
|
224
|
+
`<h1>` and any restatement of Epic Context/Goal/Scope, and mandates the
|
|
225
|
+
`Slice | What ships | Independent?` table with a justification on every
|
|
226
|
+
`Independent? No` row. Do not re-transcribe it here.
|
|
241
227
|
|
|
242
228
|
### Step 3 — Author the risk verdict (Risk Assessor persona)
|
|
243
229
|
|
|
@@ -359,35 +345,19 @@ MUST:
|
|
|
359
345
|
`Runner Verification: Fallback: dependencies-first ordering (reason: <reason>)`.
|
|
360
346
|
Phase 8 still proceeds; AC reconciliation defers to dependency order.
|
|
361
347
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
2. Stable AC IDs — assign AC-1, AC-2, ... in document order; reuse the same ID across re-plans when an Outcome is materially unchanged so scenario tags (@ac-N) stay aligned
|
|
371
|
-
3. Disposition — tag each row with one of: new | updated | unchanged
|
|
372
|
-
|
|
373
|
-
The Epic body's `## Acceptance Criteria` bullets are the single source of truth for what the spec verifies. Your table does not re-invent criteria — it anchors each one to a specific Epic AC bullet.
|
|
374
|
-
|
|
375
|
-
CRITICAL REQUIREMENTS:
|
|
376
|
-
- Respond ONLY with valid Markdown.
|
|
377
|
-
- Do not use top-level <h1> (# ) tags. Start with ## Acceptance Table — the table lands as a section of the Epic body, so it must NOT reuse the Epic's own ## Acceptance Criteria heading.
|
|
378
|
-
- Every AC row MUST have a stable AC ID of the form AC-<n> (AC-1, AC-2, ...) — do not reorder IDs across re-plans; new ACs get fresh sequential IDs.
|
|
379
|
-
- Every AC row MUST carry a Disposition value from the enum: new | updated | unchanged. (At Epic close, the acceptance reconciler overwrites Disposition with the verification outcome — satisfied | pending | missing — inside this section only; on re-plan, reset each row to the authoring enum.)
|
|
380
|
-
- Each Outcome MUST be a **terse restatement keyed to a specific Epic `## Acceptance Criteria` bullet** — lead the Outcome with the bullet's anchor (its quoted lead phrase or an explicit "Epic AC N" index) and keep the rest to a single user-visible behaviour. Do NOT re-elaborate the Epic bullet in independent words: a free-standing Outcome that paraphrases the criterion without naming the bullet it verifies is forbidden, because it drifts from the Epic silently. No DB assertions, no HTTP status codes, no internal implementation details.
|
|
381
|
-
- Where one Epic AC bullet genuinely expands into several user-visible outcomes, emit one row per outcome and declare the split on each — e.g. lead with "splits Epic AC 3" — so the fan-out is explicit rather than hidden.
|
|
382
|
-
- Anchor coverage MUST be complete and auditable: every Epic AC bullet MUST be covered by at least one row, and every row MUST anchor to an Epic AC bullet. Flag divergence in the authored spec instead of dropping it — if an Epic AC bullet has no corresponding row, or a row has no Epic anchor, call it out explicitly (a note beneath the table) rather than silently omitting the bullet or emitting an unanchored row.
|
|
383
|
-
- Cite proposed feature file paths under tests/features/** so Phase 8 can scaffold matching scenarios.
|
|
384
|
-
- Acceptance Outcomes MUST NOT prescribe a commit subject that begins with a non-Conventional-Commits prefix (allowed leading types: feat|fix|chore|refactor|perf|docs|style|test|build|ci|revert). The legacy `baseline-refresh` token used as a leading subject prescription is forbidden — commitlint will reject it at commit time, and the decompose-time validator (`ticket-validator.js` → `validateAcceptanceSubjectPrefix`) will reject the decompose with `code: 'forbidden-subject-prefix'`. Use a Conventional-Commits subject (e.g. `chore(baselines): refresh ...`) and a body trailer (e.g. `baseline-refresh: true` — trailer with a value, not a subject prefix) when a machine-readable marker is needed. See Epic #2501 for rationale.
|
|
385
|
-
```
|
|
348
|
+
Apply the `systemPrompts.acceptanceSpec` string from the emitted envelope
|
|
349
|
+
verbatim — it is the single source (rendered from
|
|
350
|
+
`lib/templates/spec-author-prompts.js`). It mandates the
|
|
351
|
+
`AC ID | Outcome | Feature File | Scenario | Disposition` table, stable
|
|
352
|
+
`AC-<n>` IDs that survive re-plans, one Outcome per user-visible behaviour
|
|
353
|
+
anchored to a specific Epic `## Acceptance Criteria` bullet, complete and
|
|
354
|
+
auditable anchor coverage, and Conventional-Commits subjects (no
|
|
355
|
+
`baseline-refresh` subject prefix). Do not re-transcribe it here.
|
|
386
356
|
|
|
387
357
|
### Step 5 — Hand back to `/plan`
|
|
388
358
|
|
|
389
359
|
All three files exist; return. The caller will run
|
|
390
|
-
`node .agents/scripts/
|
|
360
|
+
`node .agents/scripts/plan-persist.js --epic <Epic_ID>
|
|
391
361
|
--tech-spec temp/epic-<Epic_ID>/techspec.md
|
|
392
362
|
--risk-verdict temp/epic-<Epic_ID>/risk-verdict.json
|
|
393
363
|
--acceptance-table temp/epic-<Epic_ID>/acceptance-spec.md`, which validates
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gates-and-baselines
|
|
3
|
+
description:
|
|
4
|
+
Governs quality gates and the unified-baseline snapshots. Use when authoring
|
|
5
|
+
a baseline refresh commit (CRAP, maintainability, dead-exports, lighthouse),
|
|
6
|
+
when setting up or modifying CI quality gates, or when introducing a new gate
|
|
7
|
+
that asserts on pre-existing state without turning the integration branch red.
|
|
8
|
+
allowed_tools:
|
|
9
|
+
- Read
|
|
10
|
+
- Write
|
|
11
|
+
- Bash
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Gates and Baselines
|
|
15
|
+
|
|
16
|
+
## Policy Capsule
|
|
17
|
+
|
|
18
|
+
- **No gate may be skipped.** Failing lint means fix lint, not disable the rule; a failing test means fix the code, not `.skip` or delete the test. Gates are ordered shift-left so cheap checks fail first, and CI failure output is fed back verbatim with the directive to reproduce and fix locally before re-pushing.
|
|
19
|
+
- **Introducing a gate that asserts on pre-existing state** (doc-drift, lint-vocabulary, dependency-cycle, missing-coverage) MUST land green at merge: either advisory-first (report-only until the backlog is burned down) or with the populated baseline committed in the same change that turns the gate on. Never wire a gate into `requiredChecks` that lands red on latent findings nobody authored.
|
|
20
|
+
- **Refresh a baseline only when the change is deliberate** — a rename/move, an operator-approved complexity bump, a signed-off perf delta, an intentional API-surface change. Never refresh to paper over an unintentional regression; fix the regression instead.
|
|
21
|
+
- Run the kind-specific update command (`npm run crap:update` / `maintainability:update` / `dead-exports:update` / `lighthouse:update`) on the **Story branch**, not on `main`.
|
|
22
|
+
- Verify the refresh diff is scoped to the relevant `baselines/<kind>.json` (plus cosmetic `package-lock.json` churn only). If unrelated files appear, STOP — the refresh is contaminated. Stage baseline files **explicitly** (`git add baselines/<kind>.json`); never `git add -A` in a refresh commit.
|
|
23
|
+
- Commit-subject contract: a **Conventional-Commits** subject `chore(baselines): refresh <kind> snapshot for <reason>` — never an ad-hoc leading token like `baseline-refresh:` (commitlint and the planner validator reject it). The body is **mandatory** and non-empty: what changed, why the new floor is correct, and the Story/Epic that triggered it.
|
|
24
|
+
- Add the machine-readable trailer `baseline-refresh: true` (git-trailer `Key: value` style) and `Epic: #<epic-id>` to the body whenever observability classification matters. Never pass `--no-verify`; the `commit-msg` hook (commitlint) MUST run and pass.
|
|
25
|
+
- After the refresh lands, re-run `node .agents/scripts/check-baselines.js` to confirm the gate passes against the new snapshot; if it still fails, a sibling kind drifted — refresh that kind too.
|
|
26
|
+
- Keep credentials in GitHub Secrets (or platform equivalent) even for CI-only test databases; treat the security audit (`npm audit` or equivalent) as gating for critical/high vulnerabilities reachable in production code.
|
|
27
|
+
|
|
28
|
+
## The Quality Gate Pipeline
|
|
29
|
+
|
|
30
|
+
Automate quality gates so no change reaches production without passing tests,
|
|
31
|
+
lint, type checking, and build. **Shift left** — a bug caught in linting costs
|
|
32
|
+
minutes; the same bug caught in production costs hours — and prefer many small,
|
|
33
|
+
frequent releases over big-bang merges (a deploy of 3 changes is debuggable, one
|
|
34
|
+
of 30 is not).
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
lint → typecheck → unit tests → build → integration → E2E (optional)
|
|
38
|
+
→ security audit → bundle-size
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**No gate can be skipped.** If lint fails, fix lint. If a test fails, fix the
|
|
42
|
+
code. When CI fails, feed the specific error back into the agent loop with the
|
|
43
|
+
directive to verify locally before re-pushing.
|
|
44
|
+
|
|
45
|
+
### Introducing a gate on pre-existing state
|
|
46
|
+
|
|
47
|
+
A new gate that asserts on latent state (doc-drift, lint-vocabulary,
|
|
48
|
+
dependency-cycle, missing-test-coverage) lands red because of findings nobody
|
|
49
|
+
authored, and every downstream PR is blocked until someone hotfixes the
|
|
50
|
+
integration branch. Before wiring such a gate into `requiredChecks`, land it in
|
|
51
|
+
a shape that is green at merge — **advisory-first** (report-only until the
|
|
52
|
+
backlog is burned down) or by **committing the populated baseline in the same
|
|
53
|
+
change** that turns the gate on.
|
|
54
|
+
|
|
55
|
+
## Baseline Refresh
|
|
56
|
+
|
|
57
|
+
The close-validation chain enforces unified baseline snapshots
|
|
58
|
+
(`baselines/crap.json`, `baselines/maintainability.json`,
|
|
59
|
+
`baselines/dead-exports.json`, `baselines/lighthouse.json`). A refresh is **not**
|
|
60
|
+
a regression entry — it tells the ratchet that the new baseline key is
|
|
61
|
+
intentional, so the gate compares future runs against the refreshed snapshot
|
|
62
|
+
rather than the prior one.
|
|
63
|
+
|
|
64
|
+
**When to refresh:** a file rename/move detached an MI/CRAP key; a method rename
|
|
65
|
+
inside a file produced a phantom new + phantom deleted key (escomplex keys CRAP
|
|
66
|
+
rows on `<file>::<methodName>`); an operator-approved complexity bump or perf
|
|
67
|
+
delta needs to be enshrined as the new floor; a dead-export gate flagged a
|
|
68
|
+
signed-off API-surface change. If the underlying change is an **unintentional**
|
|
69
|
+
regression, do not refresh — remediate first.
|
|
70
|
+
|
|
71
|
+
### Commit-subject contract (authoritative)
|
|
72
|
+
|
|
73
|
+
```text
|
|
74
|
+
chore(baselines): refresh <kind> snapshot for <reason>
|
|
75
|
+
|
|
76
|
+
<non-empty body explaining the refresh — what changed, why the new
|
|
77
|
+
baseline is the correct floor, and any operator sign-off reference>
|
|
78
|
+
|
|
79
|
+
baseline-refresh: true
|
|
80
|
+
Epic: #<epic-id>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The `commit-msg` hook (`commitlint`) rejects any subject whose leading token is
|
|
84
|
+
not one of `feat|fix|chore|refactor|perf|docs|style|test|build|ci|revert`, and
|
|
85
|
+
`--no-verify` is forbidden by
|
|
86
|
+
[`.agents/rules/git-conventions.md`](../../../rules/git-conventions.md), so the
|
|
87
|
+
subject MUST conform. `release-please` consumes the subject on `main`;
|
|
88
|
+
`chore(baselines):` keeps the refresh out of the user-facing changelog (correct —
|
|
89
|
+
it is internal hygiene) while staying machine-parseable. The
|
|
90
|
+
`baseline-refresh: true` **body trailer** is the canonical machine-readable
|
|
91
|
+
marker (what
|
|
92
|
+
[`.agents/scripts/lib/observability/baseline-refresh-rate.js`](../../../scripts/lib/observability/baseline-refresh-rate.js)
|
|
93
|
+
classifies against) — subject-level leading tokens are not, and must not be, used
|
|
94
|
+
for this purpose.
|
|
95
|
+
|
|
96
|
+
### Procedure
|
|
97
|
+
|
|
98
|
+
| Kind | Update command |
|
|
99
|
+
| --------------- | -------------------------------- |
|
|
100
|
+
| CRAP | `npm run crap:update` |
|
|
101
|
+
| Maintainability | `npm run maintainability:update` |
|
|
102
|
+
| Dead-exports | `npm run dead-exports:update` |
|
|
103
|
+
| Lighthouse | `npm run lighthouse:update` |
|
|
104
|
+
|
|
105
|
+
1. **Run the matching update command** on the Story branch (HEAD must already be
|
|
106
|
+
the Story branch, not `main`).
|
|
107
|
+
2. **Verify the diff is scoped** to the relevant `baselines/<kind>.json` (and
|
|
108
|
+
possibly cosmetic `package-lock.json` churn). Unrelated files → STOP, the
|
|
109
|
+
refresh is contaminated.
|
|
110
|
+
3. **Author the commit.** Stage the baseline file(s) explicitly, then commit with
|
|
111
|
+
the Conventional-Commits subject + body trailer above:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
git add baselines/<kind>.json
|
|
115
|
+
git commit -m "$(cat <<'EOF'
|
|
116
|
+
chore(baselines): refresh <kind> snapshot for <reason>
|
|
117
|
+
|
|
118
|
+
<body: what changed, why the new floor is correct, linking the Story/Epic.>
|
|
119
|
+
|
|
120
|
+
baseline-refresh: true
|
|
121
|
+
Epic: #<epic-id>
|
|
122
|
+
EOF
|
|
123
|
+
)"
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Do NOT pass `--no-verify`.
|
|
127
|
+
4. **Re-run the gate** — `node .agents/scripts/check-baselines.js`. If it still
|
|
128
|
+
fails, a sibling kind drifted; repeat from step 1 for that kind.
|
|
129
|
+
|
|
130
|
+
## Red Flags
|
|
131
|
+
|
|
132
|
+
- CI failures ignored or silenced; tests disabled in CI to make the pipeline pass.
|
|
133
|
+
- A new required gate merged red on pre-existing findings, blocking every
|
|
134
|
+
downstream PR.
|
|
135
|
+
- A legacy ad-hoc leading token (`baseline-refresh:`) as the commit subject type.
|
|
136
|
+
- An empty-body refresh — unreviewable, hides the operator decision.
|
|
137
|
+
- A refresh commit whose diff touches unrelated files (contaminated refresh).
|
|
138
|
+
- Refreshing to paper over an unintentional regression.
|
|
139
|
+
- Secrets stored in code or CI config instead of a secrets manager.
|
|
140
|
+
|
|
141
|
+
## Verification
|
|
142
|
+
|
|
143
|
+
- [ ] Every quality gate is present (lint, types, tests, build, audit) and
|
|
144
|
+
failures block merge (branch protection configured).
|
|
145
|
+
- [ ] Any newly introduced gate is green at merge (advisory-first or
|
|
146
|
+
baseline-in-same-change).
|
|
147
|
+
- [ ] A baseline refresh uses the Conventional-Commits subject + non-empty body
|
|
148
|
+
+ `baseline-refresh: true` trailer, staged explicitly, no `--no-verify`.
|
|
149
|
+
- [ ] `check-baselines.js` passes against the refreshed snapshot.
|
|
@@ -124,17 +124,14 @@ conversation, not a template.
|
|
|
124
124
|
wouldn't?"
|
|
125
125
|
|
|
126
126
|
Push beyond what the user initially asked for. Create products people don't
|
|
127
|
-
know they need yet.
|
|
127
|
+
know they need yet. Pick the lens that fits the idea — don't run every one
|
|
128
|
+
mechanically.
|
|
128
129
|
|
|
129
130
|
**If running inside a codebase:** Use `Glob`, `Grep`, and `Read` to scan for
|
|
130
131
|
relevant context — existing architecture, patterns, constraints, prior art.
|
|
131
132
|
Ground your variations in what actually exists. Reference specific files and
|
|
132
133
|
patterns when relevant.
|
|
133
134
|
|
|
134
|
-
Read `frameworks.md` in this skill directory for additional ideation frameworks
|
|
135
|
-
you can draw from. Use them selectively — pick the lens that fits the idea,
|
|
136
|
-
don't run every framework mechanically.
|
|
137
|
-
|
|
138
135
|
#### Phase 2: Evaluate & Converge (Grill)
|
|
139
136
|
|
|
140
137
|
After the user reacts to Phase 1 (indicates which ideas resonate, pushes back,
|
|
@@ -283,9 +280,6 @@ Direct, thoughtful, slightly provocative. You're a sharp thinking partner, not a
|
|
|
283
280
|
facilitator reading from a script. Channel the energy of "that's interesting,
|
|
284
281
|
but what if..." -- always pushing one step further without being exhausting.
|
|
285
282
|
|
|
286
|
-
Read `examples.md` in this skill directory for examples of what great ideation
|
|
287
|
-
sessions look like.
|
|
288
|
-
|
|
289
283
|
## Red Flags
|
|
290
284
|
|
|
291
285
|
- Generating 20+ shallow variations instead of 5-8 considered ones
|
|
@@ -22,7 +22,7 @@ allowed_tools:
|
|
|
22
22
|
- Read the verdict as a `{unit, contract, acceptance}` object: each tier is `{status: 'present'|'absent', note}`. A surface with only a colocated unit test reports `unit: present` and `contract`/`acceptance`: `absent` with explanatory notes.
|
|
23
23
|
- Route remediation by the absent tiers, honoring the assertion-placement rule: wire-shape and status-code gaps become **contract** tests, user-visible journey gaps become **acceptance** scenarios — never push those into unit tests or `.feature` files incorrectly.
|
|
24
24
|
- Treat `absent` as a coverage gap to surface, not an automatic failure: some surfaces legitimately need only one tier (a pure formatter needs no acceptance scenario). Use the notes to justify, not to mandate, the missing tier.
|
|
25
|
-
- This skill is read + classify only: it does not author tests, mutate tickets, or run the suite. Hand the verdict to
|
|
25
|
+
- This skill is read + classify only: it does not author tests, mutate tickets, or run the suite. Hand the verdict to the TDD cycle in `.agents/rules/testing-standards.md` to actually write the missing tier.
|
|
26
26
|
|
|
27
27
|
## Role
|
|
28
28
|
|
|
@@ -45,9 +45,9 @@ missing so remediation is aimed correctly.
|
|
|
45
45
|
- During a test-pyramid audit, to roll up many surfaces into a tier-by-tier
|
|
46
46
|
gap report.
|
|
47
47
|
|
|
48
|
-
**When NOT to use:** for authoring tests (use
|
|
49
|
-
[
|
|
50
|
-
measuring line/branch coverage percentages (that is the unit-tier coverage
|
|
48
|
+
**When NOT to use:** for authoring tests (use the TDD cycle in
|
|
49
|
+
[`.agents/rules/testing-standards.md`](../../../rules/testing-standards.md#applying-the-standards)),
|
|
50
|
+
for measuring line/branch coverage percentages (that is the unit-tier coverage
|
|
51
51
|
config, not this skill), or for anything that requires running the suite.
|
|
52
52
|
|
|
53
53
|
## The verdict shape
|
|
@@ -79,9 +79,9 @@ config, not this skill), or for anything that requires running the suite.
|
|
|
79
79
|
explicit `tier` field when you already know it.
|
|
80
80
|
3. **Read the gaps.** Every `absent` tier is a candidate gap. Apply judgment
|
|
81
81
|
from the Policy Capsule: not every surface needs all three tiers.
|
|
82
|
-
4. **Route remediation.** For real gaps, hand off to
|
|
83
|
-
|
|
84
|
-
assertion-placement rule so each assertion lands in its correct tier.
|
|
82
|
+
4. **Route remediation.** For real gaps, hand off to the TDD cycle in
|
|
83
|
+
`.agents/rules/testing-standards.md` with the missing tier named, honoring
|
|
84
|
+
the assertion-placement rule so each assertion lands in its correct tier.
|
|
85
85
|
|
|
86
86
|
## Example
|
|
87
87
|
|