mandrel 2.0.0 → 2.2.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/README.md +59 -28
- package/.agents/agents/acceptance-critic.md +20 -9
- package/.agents/agents/story-worker.md +45 -48
- package/.agents/audit-checklists/performance.md +1 -1
- package/.agents/docs/SDLC.md +60 -46
- package/.agents/docs/agentrc-reference.json +8 -13
- package/.agents/docs/configuration.md +33 -57
- package/.agents/docs/execution-reference.md +39 -10
- package/.agents/docs/quality-gates.md +17 -19
- package/.agents/docs/workflows.md +6 -6
- package/.agents/instructions.md +64 -79
- package/.agents/rules/ci-remediation.md +3 -3
- package/.agents/rules/gherkin-standards.md +10 -0
- package/.agents/rules/git-conventions-reference.md +42 -51
- package/.agents/schemas/acceptance-eval-verdict.schema.json +2 -2
- package/.agents/schemas/agentrc.schema.json +35 -46
- package/.agents/schemas/audit-rules.json +59 -1
- package/.agents/schemas/audit-rules.schema.json +33 -1
- package/.agents/schemas/lifecycle/README.md +1 -2
- package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
- package/.agents/schemas/lifecycle/merge.flip-failed.schema.json +33 -0
- package/.agents/schemas/lifecycle/merge.unlanded.schema.json +1 -0
- package/.agents/schemas/lifecycle/story.merged.schema.json +1 -1
- package/.agents/schemas/signal-event.schema.json +3 -3
- package/.agents/schemas/story-deliver-terminal.schema.json +152 -0
- package/.agents/schemas/validation-evidence.schema.json +1 -1
- package/.agents/scripts/acceptance-eval.js +24 -68
- package/.agents/scripts/agents-bootstrap-github.js +1 -1
- package/.agents/scripts/bootstrap.js +3 -3
- package/.agents/scripts/check-dead-exports.js +43 -104
- package/.agents/scripts/check-doc-links.js +2 -2
- package/.agents/scripts/check-lifecycle-lint.js +1 -1
- package/.agents/scripts/check-workflow-cli-lint.js +91 -0
- package/.agents/scripts/deliver-recover.js +122 -0
- package/.agents/scripts/drain-pending-cleanup.js +1 -1
- package/.agents/scripts/evidence-gate.js +20 -50
- package/.agents/scripts/generate-skills-index.js +17 -1
- package/.agents/scripts/generate-workflows-doc.js +4 -4
- package/.agents/scripts/lib/ITicketingProvider.js +1 -19
- package/.agents/scripts/lib/audit-suite/selector.js +323 -23
- package/.agents/scripts/lib/baselines/kinds/maintainability.js +0 -11
- package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +28 -33
- package/.agents/scripts/lib/bootstrap/manifest.js +8 -11
- package/.agents/scripts/lib/bootstrap/project-bootstrap.js +30 -53
- package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +0 -2
- package/.agents/scripts/lib/checks/core-bare-clean.js +4 -1
- package/.agents/scripts/lib/checks/index.js +1 -1
- package/.agents/scripts/lib/checks/loop-health.js +12 -11
- package/.agents/scripts/lib/checks/state.js +17 -248
- package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +3 -3
- package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +3 -4
- package/.agents/scripts/lib/checks/worktree-bootstrap-env.js +2 -2
- package/.agents/scripts/lib/checks/worktree-residue-biome.js +3 -3
- package/.agents/scripts/lib/cli-args.js +23 -2
- package/.agents/scripts/lib/close-validation/gates.js +13 -13
- package/.agents/scripts/lib/close-validation/projections/inputs.js +7 -7
- package/.agents/scripts/lib/close-validation/projections/maintainability.js +12 -12
- package/.agents/scripts/lib/close-validation/runner.js +13 -21
- package/.agents/scripts/lib/close-validation/telemetry.js +17 -8
- package/.agents/scripts/lib/config/acceptance-eval.js +2 -2
- package/.agents/scripts/lib/config/delivery-routing.js +7 -6
- package/.agents/scripts/lib/config/explain.js +10 -16
- package/.agents/scripts/lib/config/github.js +7 -5
- package/.agents/scripts/lib/config/limits.js +15 -25
- package/.agents/scripts/lib/config/quality.js +11 -14
- package/.agents/scripts/lib/config/runners.js +8 -21
- package/.agents/scripts/lib/config/temp-paths.js +18 -56
- package/.agents/scripts/lib/config-settings-schema-delivery.js +34 -16
- package/.agents/scripts/lib/config-settings-schema-quality.js +9 -2
- package/.agents/scripts/lib/config-settings-schema.js +48 -22
- package/.agents/scripts/lib/dead-exports-knip.js +105 -0
- package/.agents/scripts/lib/dead-exports-mode.js +51 -0
- package/.agents/scripts/lib/duplicate-search.js +38 -7
- package/.agents/scripts/lib/findings/promote-finding.js +23 -14
- package/.agents/scripts/lib/format-generated-json.js +97 -0
- package/.agents/scripts/lib/framework-version.js +19 -189
- package/.agents/scripts/lib/gh-exec.js +8 -0
- package/.agents/scripts/lib/git-branch-lifecycle.js +0 -158
- package/.agents/scripts/lib/git-utils.js +0 -14
- package/.agents/scripts/lib/json-utils.js +1 -2
- package/.agents/scripts/lib/label-constants.js +0 -15
- package/.agents/scripts/lib/label-taxonomy.js +1 -12
- package/.agents/scripts/lib/observability/active-story-env.js +42 -163
- package/.agents/scripts/lib/observability/runtime-friction.js +243 -0
- package/.agents/scripts/lib/observability/signal-validator.js +4 -4
- package/.agents/scripts/lib/observability/signals-writer.js +6 -82
- package/.agents/scripts/lib/observability/source-classifier.js +2 -2
- package/.agents/scripts/lib/observability/tool-trace-hook.js +2 -12
- package/.agents/scripts/lib/orchestration/acceptance-clusters.js +1 -1
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +2 -2
- package/.agents/scripts/lib/orchestration/ceremony-routing.js +43 -45
- package/.agents/scripts/lib/orchestration/change-set.js +103 -0
- package/.agents/scripts/lib/orchestration/code-review.js +70 -191
- package/.agents/scripts/lib/orchestration/consolidation-precondition.js +3 -3
- package/.agents/scripts/lib/orchestration/deliver-recover.js +328 -0
- package/.agents/scripts/lib/orchestration/detectors-phase.js +12 -6
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +34 -0
- package/.agents/scripts/lib/orchestration/lease-guard-shared.js +3 -2
- package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +142 -0
- package/.agents/scripts/lib/orchestration/lifecycle/emit-loop-tick.js +9 -11
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +86 -0
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +37 -103
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +7 -3
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js +50 -85
- package/.agents/scripts/lib/orchestration/lifecycle/trace-logger.js +3 -14
- package/.agents/scripts/lib/orchestration/merge-block-class.js +76 -20
- package/.agents/scripts/lib/orchestration/merge-poll.js +104 -0
- package/.agents/scripts/lib/orchestration/plan-context.js +116 -33
- package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +26 -36
- package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +31 -22
- package/.agents/scripts/lib/orchestration/plan-metrics.js +38 -6
- package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +16 -6
- package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +173 -25
- package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +116 -0
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +280 -100
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +472 -55
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +21 -16
- package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +509 -0
- package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +230 -0
- package/.agents/scripts/lib/orchestration/planning/authoring-context.js +41 -40
- package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +1 -2
- package/.agents/scripts/lib/orchestration/planning/spec-authoring-grounding.js +1 -1
- package/.agents/scripts/lib/orchestration/resolve-stories.js +344 -0
- package/.agents/scripts/lib/orchestration/retro-proposals.js +7 -7
- package/.agents/scripts/lib/orchestration/review-depth.js +105 -40
- package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +3 -13
- package/.agents/scripts/lib/orchestration/review-providers/native.js +1 -154
- package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +3 -2
- package/.agents/scripts/lib/orchestration/review-providers/security-review.js +1 -1
- package/.agents/scripts/lib/orchestration/review-providers/types.js +5 -4
- package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +1 -1
- package/.agents/scripts/lib/orchestration/run-epilogue.js +374 -16
- package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +24 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +11 -9
- package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +4 -4
- package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +4 -13
- package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +608 -152
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +72 -30
- package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +305 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +1 -1
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +12 -8
- package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +37 -4
- package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +2 -2
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +264 -43
- package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +1 -1
- package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +10 -10
- package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +104 -279
- package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +191 -0
- package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +120 -0
- package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +360 -0
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +75 -14
- package/.agents/scripts/lib/orchestration/story-init-remote.js +12 -8
- package/.agents/scripts/lib/orchestration/story-plan-state.js +14 -29
- package/.agents/scripts/lib/orchestration/task-body-validator.js +52 -7
- package/.agents/scripts/lib/orchestration/ticket-lease.js +27 -74
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +119 -14
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +3 -4
- package/.agents/scripts/lib/orchestration/ticket-validator.js +121 -18
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +14 -47
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +19 -32
- package/.agents/scripts/lib/orchestration/ticketing/transition.js +61 -1
- package/.agents/scripts/lib/orchestration/ticketing.js +0 -1
- package/.agents/scripts/lib/plan-phase-cleanup.js +12 -14
- package/.agents/scripts/lib/planning-corpus.js +12 -286
- package/.agents/scripts/lib/preflight-runner.js +2 -2
- package/.agents/scripts/lib/qa/qa-context-hydrator.js +5 -5
- package/.agents/scripts/lib/signals/index.js +4 -17
- package/.agents/scripts/lib/signals/read.js +35 -35
- package/.agents/scripts/lib/signals/schema.js +8 -11
- package/.agents/scripts/lib/signals/span-tree.js +7 -7
- package/.agents/scripts/lib/signals/write.js +0 -1
- package/.agents/scripts/lib/single-story/story-merged-notify.js +13 -2
- package/.agents/scripts/lib/skills/parse-skill.js +16 -3
- package/.agents/scripts/lib/story-adjacency.js +8 -7
- package/.agents/scripts/lib/story-body/story-body.js +81 -13
- package/.agents/scripts/lib/templates/decomposer-prompts.js +15 -16
- package/.agents/scripts/lib/test-env.js +14 -1
- package/.agents/scripts/lib/test-tiers.js +0 -3
- package/.agents/scripts/lib/ticket-body-sections.js +0 -14
- package/.agents/scripts/lib/validation-evidence.js +31 -59
- package/.agents/scripts/lib/wave-runner/live-probe.js +315 -0
- package/.agents/scripts/lib/wave-runner/ready-set.js +32 -6
- package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +1 -1
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +68 -19
- package/.agents/scripts/lib/worktree/lifecycle-manager.js +1 -2
- package/.agents/scripts/plan-context.js +38 -7
- package/.agents/scripts/plan-critics.js +203 -0
- package/.agents/scripts/plan-persist.js +145 -35
- package/.agents/scripts/plan-run-epilogue.js +83 -38
- package/.agents/scripts/post-structured-comment.js +0 -38
- package/.agents/scripts/pr-watch-with-update.js +43 -22
- package/.agents/scripts/providers/github/compose.js +0 -1
- package/.agents/scripts/providers/github/errors.js +0 -19
- package/.agents/scripts/providers/github/issues.js +1 -11
- package/.agents/scripts/providers/github/mappers.js +5 -0
- package/.agents/scripts/providers/github/sub-issues.js +0 -47
- package/.agents/scripts/providers/github/tickets.js +33 -153
- package/.agents/scripts/providers/github.js +17 -6
- package/.agents/scripts/quality-preview.js +13 -6
- package/.agents/scripts/resolve-stories.js +236 -0
- package/.agents/scripts/run-coverage.js +4 -1
- package/.agents/scripts/run-lint.js +2 -2
- package/.agents/scripts/run-verify.js +31 -2
- package/.agents/scripts/signals-view.js +9 -10
- package/.agents/scripts/single-story-close.js +173 -18
- package/.agents/scripts/single-story-confirm-merge.js +288 -15
- package/.agents/scripts/single-story-init.js +6 -10
- package/.agents/scripts/stories-wave-tick.js +380 -53
- package/.agents/scripts/story-plan.js +3 -3
- package/.agents/scripts/update-ticket-state.js +8 -50
- package/.agents/skills/core/code-review-and-quality/SKILL.md +28 -450
- package/.agents/skills/core/code-review-and-quality/reference.md +458 -0
- package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +22 -315
- package/.agents/skills/core/debugging-and-error-recovery/reference.md +323 -0
- package/.agents/skills/core/diagnose-friction/SKILL.md +14 -18
- package/.agents/skills/core/documentation-and-adrs/SKILL.md +25 -397
- package/.agents/skills/core/documentation-and-adrs/reference.md +403 -0
- package/.agents/skills/core/gates-and-baselines/SKILL.md +12 -12
- package/.agents/skills/core/idea-refinement/SKILL.md +3 -3
- package/.agents/skills/core/scope-triage/SKILL.md +3 -0
- package/.agents/skills/core/security-and-hardening/SKILL.md +22 -367
- package/.agents/skills/core/security-and-hardening/reference.md +375 -0
- package/.agents/skills/skills.index.json +2 -12
- package/.agents/skills/stack/qa/playwright-bdd/SKILL.md +2 -4
- package/.agents/skills/stack/qa/qa-explore-driving/SKILL.md +1 -1
- package/.agents/skills/stack/qa/qa-harness/SKILL.md +1 -3
- package/.agents/workflows/audit-architecture.md +3 -4
- package/.agents/workflows/audit-clean-code.md +4 -4
- package/.agents/workflows/audit-documentation.md +4 -5
- package/.agents/workflows/audit-lighthouse.md +8 -0
- package/.agents/workflows/audit-navigability.md +10 -0
- package/.agents/workflows/audit-performance.md +2 -3
- package/.agents/workflows/audit-quality.md +8 -9
- package/.agents/workflows/audit-security.md +1 -2
- package/.agents/workflows/audit-seo.md +10 -0
- package/.agents/workflows/audit-ux-ui.md +7 -0
- package/.agents/workflows/deliver.md +133 -45
- package/.agents/workflows/git-cleanup.md +2 -2
- package/.agents/workflows/git-deliver.md +1 -1
- package/.agents/workflows/helpers/acceptance-self-eval.md +34 -17
- package/.agents/workflows/helpers/code-quality-guardrails.md +15 -12
- package/.agents/workflows/helpers/code-review.md +14 -12
- package/.agents/workflows/helpers/deliver-story-reference.md +73 -32
- package/.agents/workflows/helpers/deliver-story.md +209 -118
- package/.agents/workflows/helpers/parallel-tooling.md +2 -2
- package/.agents/workflows/helpers/worktree-lifecycle.md +28 -32
- package/.agents/workflows/plan.md +239 -19
- package/.agents/workflows/qa-assist.md +6 -6
- package/.agents/workflows/qa-explore.md +3 -3
- package/.agents/workflows/qa-run.md +1 -5
- package/bin/mandrel.js +12 -1
- package/docs/CHANGELOG.md +62 -0
- package/lib/cli/registry.js +262 -19
- package/lib/cli/sync-agents.js +157 -0
- package/lib/cli/sync-commands.js +115 -6
- package/lib/cli/sync.js +168 -6
- package/lib/cli/update.js +105 -8
- package/lib/cli/version-helpers.js +131 -0
- package/lib/migrations/README.md +7 -5
- package/lib/migrations/index.js +17 -9
- package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +100 -0
- package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +101 -0
- package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +154 -0
- package/package.json +2 -2
- package/.agents/schemas/epic-perf-report.schema.json +0 -89
- package/.agents/schemas/lifecycle/acceptance.reconcile.failed.schema.json +0 -13
- package/.agents/schemas/lifecycle/acceptance.reconcile.ok.schema.json +0 -13
- package/.agents/schemas/lifecycle/acceptance.reconcile.skipped.schema.json +0 -13
- package/.agents/schemas/lifecycle/acceptance.reconcile.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/acceptance.reconcile.waived.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.automerge.end.schema.json +0 -15
- package/.agents/schemas/lifecycle/epic.automerge.start.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.blocked.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.cleanup.end.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.cleanup.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.close.end.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.complete.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.finalize.end.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.finalize.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.merge.armed.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.merge.blocked.schema.json +0 -14
- package/.agents/schemas/lifecycle/epic.merge.confirmed.schema.json +0 -17
- package/.agents/schemas/lifecycle/epic.merge.ready.schema.json +0 -15
- package/.agents/schemas/lifecycle/epic.plan.end.schema.json +0 -18
- package/.agents/schemas/lifecycle/epic.plan.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.snapshot.end.schema.json +0 -16
- package/.agents/schemas/lifecycle/epic.snapshot.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.watch.end.schema.json +0 -29
- package/.agents/schemas/lifecycle/epic.watch.start.schema.json +0 -16
- package/.agents/schemas/lifecycle/story.heartbeat.schema.json +0 -20
- package/.agents/schemas/risk-verdict.schema.json +0 -53
- package/.agents/schemas/story-perf-summary.schema.json +0 -73
- package/.agents/scripts/analyze-execution.js +0 -444
- package/.agents/scripts/check-prepush-recovery.js +0 -90
- package/.agents/scripts/lib/git-merge-orchestrator.js +0 -261
- package/.agents/scripts/lib/observability/baseline-refresh-rate.js +0 -221
- package/.agents/scripts/lib/observability/hook-heartbeat.js +0 -187
- package/.agents/scripts/lib/observability/perf-aggregator.js +0 -813
- package/.agents/scripts/lib/observability/perf-report-readers.js +0 -328
- package/.agents/scripts/lib/observability/perf-report-render.js +0 -182
- package/.agents/scripts/lib/orchestration/audit-lens-routing.js +0 -128
- package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +0 -273
- package/.agents/scripts/lib/orchestration/error-journal.js +0 -139
- package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +0 -155
- package/.agents/scripts/lib/orchestration/lifecycle/ledger-diff.js +0 -140
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/merge-watcher.js +0 -665
- package/.agents/scripts/lib/orchestration/plan-review-routing.js +0 -63
- package/.agents/scripts/lib/orchestration/planning/risk-verdict.js +0 -104
- package/.agents/scripts/lib/orchestration/planning-context-budget.js +0 -213
- package/.agents/scripts/lib/orchestration/planning-risk.js +0 -194
- package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +0 -56
- package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +0 -21
- package/.agents/scripts/lib/orchestration/post-merge/phases/notification.js +0 -78
- package/.agents/scripts/lib/orchestration/post-merge/phases/temp-cleanup.js +0 -68
- package/.agents/scripts/lib/orchestration/post-merge/phases/ticket-closure.js +0 -118
- package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +0 -397
- package/.agents/scripts/lib/orchestration/preflight-cache.js +0 -187
- package/.agents/scripts/lib/orchestration/resolve-plan-run.js +0 -155
- package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +0 -275
- package/.agents/scripts/lib/orchestration/story-progress/story-run-progress-writer.js +0 -400
- package/.agents/scripts/lib/single-story/confirm-merge-follow-ups.js +0 -36
- package/.agents/scripts/resolve-plan-run.js +0 -117
- package/.agents/skills/core/analyze-execution/SKILL.md +0 -101
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js
|
|
2
|
+
/**
|
|
3
|
+
* Story #4531 — the first real step in the migration registry.
|
|
4
|
+
*
|
|
5
|
+
* `delivery.quality.codingGuardrails.miDropMustRefactor` and
|
|
6
|
+
* `delivery.quality.autoRefresh.miDropCap` were schema-validated, defaulted,
|
|
7
|
+
* and seeded by `apply-quality-bootstrap.js` into a consumer's
|
|
8
|
+
* `.agentrc.json` — but never consumed by the gate they were named for
|
|
9
|
+
* (`maintainability.tolerance` is the knob actually in force; see the
|
|
10
|
+
* Story body for the full diagnosis). Both retired keys lived under
|
|
11
|
+
* sub-schemas with `additionalProperties: false`, so a consumer whose
|
|
12
|
+
* config still carries either key hits a hard AJV validation failure on
|
|
13
|
+
* upgrade, not a warning. This step strips them before that check runs.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import nodeFs from 'node:fs';
|
|
17
|
+
import path from 'node:path';
|
|
18
|
+
|
|
19
|
+
const AGENTRC_FILENAME = '.agentrc.json';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @param {unknown} ctx
|
|
23
|
+
* @returns {string}
|
|
24
|
+
*/
|
|
25
|
+
function resolveAgentrcPath(ctx) {
|
|
26
|
+
const projectRoot = ctx?.projectRoot ?? process.cwd();
|
|
27
|
+
return path.join(projectRoot, AGENTRC_FILENAME);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @param {unknown} ctx
|
|
32
|
+
* @param {typeof nodeFs} fsImpl
|
|
33
|
+
* @returns {object | null}
|
|
34
|
+
*/
|
|
35
|
+
function readAgentrcConfig(ctx, fsImpl) {
|
|
36
|
+
try {
|
|
37
|
+
const raw = fsImpl.readFileSync(resolveAgentrcPath(ctx), 'utf8');
|
|
38
|
+
return JSON.parse(raw);
|
|
39
|
+
} catch {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @param {object | null} config
|
|
46
|
+
* @returns {boolean}
|
|
47
|
+
*/
|
|
48
|
+
function hasRetiredKey(config) {
|
|
49
|
+
const guardrails = config?.delivery?.quality?.codingGuardrails;
|
|
50
|
+
const autoRefresh = config?.delivery?.quality?.autoRefresh;
|
|
51
|
+
return (
|
|
52
|
+
(Boolean(guardrails) && Object.hasOwn(guardrails, 'miDropMustRefactor')) ||
|
|
53
|
+
(Boolean(autoRefresh) && Object.hasOwn(autoRefresh, 'miDropCap'))
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export const retireMiDropKnobs = {
|
|
58
|
+
version: '2.1.0',
|
|
59
|
+
description:
|
|
60
|
+
'strip retired delivery.quality.codingGuardrails.miDropMustRefactor ' +
|
|
61
|
+
'and delivery.quality.autoRefresh.miDropCap from .agentrc.json',
|
|
62
|
+
/**
|
|
63
|
+
* @param {{ projectRoot?: string, fs?: typeof nodeFs }} [ctx]
|
|
64
|
+
* @returns {boolean}
|
|
65
|
+
*/
|
|
66
|
+
detect(ctx) {
|
|
67
|
+
const fsImpl = ctx?.fs ?? nodeFs;
|
|
68
|
+
return hasRetiredKey(readAgentrcConfig(ctx, fsImpl));
|
|
69
|
+
},
|
|
70
|
+
/**
|
|
71
|
+
* @param {{ projectRoot?: string, fs?: typeof nodeFs }} [ctx]
|
|
72
|
+
* @returns {void}
|
|
73
|
+
*/
|
|
74
|
+
apply(ctx) {
|
|
75
|
+
const fsImpl = ctx?.fs ?? nodeFs;
|
|
76
|
+
const config = readAgentrcConfig(ctx, fsImpl);
|
|
77
|
+
if (!config) return;
|
|
78
|
+
|
|
79
|
+
const guardrails = config.delivery?.quality?.codingGuardrails;
|
|
80
|
+
if (guardrails && Object.hasOwn(guardrails, 'miDropMustRefactor')) {
|
|
81
|
+
delete guardrails.miDropMustRefactor;
|
|
82
|
+
if (Object.keys(guardrails).length === 0) {
|
|
83
|
+
delete config.delivery.quality.codingGuardrails;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const autoRefresh = config.delivery?.quality?.autoRefresh;
|
|
88
|
+
if (autoRefresh && Object.hasOwn(autoRefresh, 'miDropCap')) {
|
|
89
|
+
delete autoRefresh.miDropCap;
|
|
90
|
+
if (Object.keys(autoRefresh).length === 0) {
|
|
91
|
+
delete config.delivery.quality.autoRefresh;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
fsImpl.writeFileSync(
|
|
96
|
+
resolveAgentrcPath(ctx),
|
|
97
|
+
`${JSON.stringify(config, null, 2)}\n`,
|
|
98
|
+
);
|
|
99
|
+
},
|
|
100
|
+
};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js
|
|
2
|
+
/**
|
|
3
|
+
* Story #4545 — retire `delivery.deliverRunner.verifyConcurrencyCap`.
|
|
4
|
+
*
|
|
5
|
+
* The knob was schema-validated, defaulted to 4, resolved by `getRunners`,
|
|
6
|
+
* and documented as bounding "the per-wave verifyWaveResults loop" — a loop
|
|
7
|
+
* that does not exist anywhere in the tree. Its only reader was
|
|
8
|
+
* `analyze-execution.js`, which echoed the number into a perf report rather
|
|
9
|
+
* than bounding anything; that CLI is deleted in the same Story. Setting the
|
|
10
|
+
* knob to any value only ever changed a number printed in a report.
|
|
11
|
+
*
|
|
12
|
+
* `delivery.deliverRunner` declares `additionalProperties: false`, so a
|
|
13
|
+
* consumer whose config still carries the key hits a hard AJV validation
|
|
14
|
+
* failure on upgrade — every script that resolves config, not just the one
|
|
15
|
+
* that read it. This step strips it before that check runs.
|
|
16
|
+
*
|
|
17
|
+
* Unlike the 2.1.0 mi-drop step, this one also sweeps `.agentrc.local.json`:
|
|
18
|
+
* the resolver deep-merges the local override over `.agentrc.json` and
|
|
19
|
+
* validates the *merged* result, so a key left in the local file fails the
|
|
20
|
+
* same way a key in the committed file does.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import nodeFs from 'node:fs';
|
|
24
|
+
import path from 'node:path';
|
|
25
|
+
|
|
26
|
+
const AGENTRC_FILENAMES = ['.agentrc.json', '.agentrc.local.json'];
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @param {unknown} ctx
|
|
30
|
+
* @param {string} filename
|
|
31
|
+
* @returns {string}
|
|
32
|
+
*/
|
|
33
|
+
function resolveAgentrcPath(ctx, filename) {
|
|
34
|
+
const projectRoot = ctx?.projectRoot ?? process.cwd();
|
|
35
|
+
return path.join(projectRoot, filename);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @param {unknown} ctx
|
|
40
|
+
* @param {string} filename
|
|
41
|
+
* @param {typeof nodeFs} fsImpl
|
|
42
|
+
* @returns {object | null}
|
|
43
|
+
*/
|
|
44
|
+
function readAgentrcConfig(ctx, filename, fsImpl) {
|
|
45
|
+
try {
|
|
46
|
+
const raw = fsImpl.readFileSync(resolveAgentrcPath(ctx, filename), 'utf8');
|
|
47
|
+
return JSON.parse(raw);
|
|
48
|
+
} catch {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @param {object | null} config
|
|
55
|
+
* @returns {boolean}
|
|
56
|
+
*/
|
|
57
|
+
function hasRetiredKey(config) {
|
|
58
|
+
const deliverRunner = config?.delivery?.deliverRunner;
|
|
59
|
+
return (
|
|
60
|
+
Boolean(deliverRunner) &&
|
|
61
|
+
Object.hasOwn(deliverRunner, 'verifyConcurrencyCap')
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export const retireVerifyConcurrencyCap = {
|
|
66
|
+
version: '2.1.0',
|
|
67
|
+
description:
|
|
68
|
+
'strip retired delivery.deliverRunner.verifyConcurrencyCap from ' +
|
|
69
|
+
'.agentrc.json and .agentrc.local.json',
|
|
70
|
+
/**
|
|
71
|
+
* @param {{ projectRoot?: string, fs?: typeof nodeFs }} [ctx]
|
|
72
|
+
* @returns {boolean}
|
|
73
|
+
*/
|
|
74
|
+
detect(ctx) {
|
|
75
|
+
const fsImpl = ctx?.fs ?? nodeFs;
|
|
76
|
+
return AGENTRC_FILENAMES.some((filename) =>
|
|
77
|
+
hasRetiredKey(readAgentrcConfig(ctx, filename, fsImpl)),
|
|
78
|
+
);
|
|
79
|
+
},
|
|
80
|
+
/**
|
|
81
|
+
* @param {{ projectRoot?: string, fs?: typeof nodeFs }} [ctx]
|
|
82
|
+
* @returns {void}
|
|
83
|
+
*/
|
|
84
|
+
apply(ctx) {
|
|
85
|
+
const fsImpl = ctx?.fs ?? nodeFs;
|
|
86
|
+
for (const filename of AGENTRC_FILENAMES) {
|
|
87
|
+
const config = readAgentrcConfig(ctx, filename, fsImpl);
|
|
88
|
+
if (!hasRetiredKey(config)) continue;
|
|
89
|
+
|
|
90
|
+
delete config.delivery.deliverRunner.verifyConcurrencyCap;
|
|
91
|
+
if (Object.keys(config.delivery.deliverRunner).length === 0) {
|
|
92
|
+
delete config.delivery.deliverRunner;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
fsImpl.writeFileSync(
|
|
96
|
+
resolveAgentrcPath(ctx, filename),
|
|
97
|
+
`${JSON.stringify(config, null, 2)}\n`,
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
};
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// lib/migrations/steps/2.2.0-retire-epic-ac-tags.js
|
|
2
|
+
/**
|
|
3
|
+
* Story #4604 — strip the retired `@epic-<id>-ac-N` Gherkin AC tag namespace
|
|
4
|
+
* from consumer feature files.
|
|
5
|
+
*
|
|
6
|
+
* The v2 Epic removal deleted `acceptance-spec-reconciler.js`, the only
|
|
7
|
+
* consumer of the namespaced per-Epic AC tags, and the `/plan` authoring
|
|
8
|
+
* prompt no longer mandates them. Surviving tags in consumer `.feature`
|
|
9
|
+
* files are inert and violate the gherkin-standards tag taxonomy's
|
|
10
|
+
* no-ad-hoc-tags rule, so this step removes them: each `@epic-<digits>-ac-<digits>`
|
|
11
|
+
* token is deleted from tag lines, a tag line left with no tags is dropped
|
|
12
|
+
* entirely, and every other tag and line is preserved byte-for-byte. Files
|
|
13
|
+
* with no stale tags are never rewritten.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import nodeFs from 'node:fs';
|
|
17
|
+
import path from 'node:path';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Mirror of `CANONICAL_FEATURE_ROOTS` in
|
|
21
|
+
* `.agents/scripts/lib/bdd-runner-detect.js`. Duplicated deliberately:
|
|
22
|
+
* `lib/` runs from the installed npm package inside a consumer project and
|
|
23
|
+
* must not import from the materialized `.agents/` payload.
|
|
24
|
+
*/
|
|
25
|
+
const CANONICAL_FEATURE_ROOTS = Object.freeze([
|
|
26
|
+
'tests/features',
|
|
27
|
+
'features',
|
|
28
|
+
'test/features',
|
|
29
|
+
]);
|
|
30
|
+
|
|
31
|
+
const EPIC_AC_TAG_RE = /@epic-\d+-ac-\d+/;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* A Gherkin tag line: optional indentation followed by one or more
|
|
35
|
+
* whitespace-separated `@tag` tokens and nothing else.
|
|
36
|
+
*/
|
|
37
|
+
const TAG_LINE_RE = /^(\s*)(@\S+(?:\s+@\S+)*)\s*$/;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Recursively collect `.feature` file paths under `root`.
|
|
41
|
+
*
|
|
42
|
+
* @param {string} root
|
|
43
|
+
* @param {typeof nodeFs} fsImpl
|
|
44
|
+
* @returns {string[]}
|
|
45
|
+
*/
|
|
46
|
+
function collectFeatureFiles(root, fsImpl) {
|
|
47
|
+
/** @type {string[]} */
|
|
48
|
+
const found = [];
|
|
49
|
+
/** @type {string[]} */
|
|
50
|
+
const queue = [root];
|
|
51
|
+
while (queue.length > 0) {
|
|
52
|
+
const dir = queue.pop();
|
|
53
|
+
/** @type {import('node:fs').Dirent[]} */
|
|
54
|
+
let entries;
|
|
55
|
+
try {
|
|
56
|
+
entries = fsImpl.readdirSync(dir, { withFileTypes: true });
|
|
57
|
+
} catch {
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
for (const entry of entries) {
|
|
61
|
+
const full = path.join(dir, entry.name);
|
|
62
|
+
if (entry.isDirectory()) {
|
|
63
|
+
queue.push(full);
|
|
64
|
+
} else if (entry.isFile() && entry.name.endsWith('.feature')) {
|
|
65
|
+
found.push(full);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return found.sort();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @param {unknown} ctx
|
|
74
|
+
* @param {typeof nodeFs} fsImpl
|
|
75
|
+
* @returns {string[]} Absolute paths of every `.feature` file under the
|
|
76
|
+
* canonical feature roots that exist in the consumer tree.
|
|
77
|
+
*/
|
|
78
|
+
function resolveFeatureFiles(ctx, fsImpl) {
|
|
79
|
+
const projectRoot = ctx?.projectRoot ?? process.cwd();
|
|
80
|
+
return CANONICAL_FEATURE_ROOTS.flatMap((root) =>
|
|
81
|
+
collectFeatureFiles(path.join(projectRoot, root), fsImpl),
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Strip retired `@epic-<id>-ac-<n>` tokens from one file's content.
|
|
87
|
+
* Only tag lines are touched; a tag line whose every tag was retired is
|
|
88
|
+
* dropped. Returns the original string when nothing matched.
|
|
89
|
+
*
|
|
90
|
+
* @param {string} content
|
|
91
|
+
* @returns {string}
|
|
92
|
+
*/
|
|
93
|
+
function stripEpicAcTags(content) {
|
|
94
|
+
if (!EPIC_AC_TAG_RE.test(content)) return content;
|
|
95
|
+
const newline = content.includes('\r\n') ? '\r\n' : '\n';
|
|
96
|
+
const lines = content.split(newline);
|
|
97
|
+
/** @type {string[]} */
|
|
98
|
+
const out = [];
|
|
99
|
+
for (const line of lines) {
|
|
100
|
+
const match = line.match(TAG_LINE_RE);
|
|
101
|
+
if (!match || !EPIC_AC_TAG_RE.test(line)) {
|
|
102
|
+
out.push(line);
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
const [, indent, tagBlock] = match;
|
|
106
|
+
const kept = tagBlock
|
|
107
|
+
.split(/\s+/)
|
|
108
|
+
.filter((tag) => !EPIC_AC_TAG_RE.test(tag));
|
|
109
|
+
if (kept.length === 0) continue;
|
|
110
|
+
out.push(`${indent}${kept.join(' ')}`);
|
|
111
|
+
}
|
|
112
|
+
return out.join(newline);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export const retireEpicAcTags = {
|
|
116
|
+
version: '2.2.0',
|
|
117
|
+
description:
|
|
118
|
+
'strip retired @epic-<id>-ac-N Gherkin AC tags from feature files ' +
|
|
119
|
+
'(their reconciler consumer was deleted in the v2 Epic removal)',
|
|
120
|
+
/**
|
|
121
|
+
* @param {{ projectRoot?: string, fs?: typeof nodeFs }} [ctx]
|
|
122
|
+
* @returns {boolean}
|
|
123
|
+
*/
|
|
124
|
+
detect(ctx) {
|
|
125
|
+
const fsImpl = ctx?.fs ?? nodeFs;
|
|
126
|
+
return resolveFeatureFiles(ctx, fsImpl).some((file) => {
|
|
127
|
+
try {
|
|
128
|
+
return EPIC_AC_TAG_RE.test(fsImpl.readFileSync(file, 'utf8'));
|
|
129
|
+
} catch {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
},
|
|
134
|
+
/**
|
|
135
|
+
* @param {{ projectRoot?: string, fs?: typeof nodeFs }} [ctx]
|
|
136
|
+
* @returns {void}
|
|
137
|
+
*/
|
|
138
|
+
apply(ctx) {
|
|
139
|
+
const fsImpl = ctx?.fs ?? nodeFs;
|
|
140
|
+
for (const file of resolveFeatureFiles(ctx, fsImpl)) {
|
|
141
|
+
/** @type {string} */
|
|
142
|
+
let content;
|
|
143
|
+
try {
|
|
144
|
+
content = fsImpl.readFileSync(file, 'utf8');
|
|
145
|
+
} catch {
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
const stripped = stripEpicAcTags(content);
|
|
149
|
+
if (stripped !== content) {
|
|
150
|
+
fsImpl.writeFileSync(file, stripped);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mandrel",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Claude Code-first opinionated workflow framework: instructions, skills, rules, and SDLC workflows that govern AI coding assistants.",
|
|
5
5
|
"files": [
|
|
6
6
|
".agents/",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"crap:update": "node .agents/scripts/update-crap-baseline.js",
|
|
46
46
|
"duplication:check": "node .agents/scripts/check-baselines.js --gate duplication",
|
|
47
47
|
"duplication:update": "node .agents/scripts/update-duplication-baseline.js",
|
|
48
|
-
"quality:preview": "node .agents/scripts/
|
|
48
|
+
"quality:preview": "node .agents/scripts/check-dead-exports.js && node .agents/scripts/quality-preview.js",
|
|
49
49
|
"quality:watch": "node .agents/scripts/quality-watch.js",
|
|
50
50
|
"sync:commands": "node bin/mandrel.js sync-commands",
|
|
51
51
|
"sync:agents": "node .agents/scripts/sync-claude-agents.js",
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/epic-perf-report.schema.json",
|
|
4
|
-
"title": "EpicPerfReport",
|
|
5
|
-
"description": "Payload of the <!-- structured:epic-perf-report --> comment posted once per Epic at close, alongside the retro (Epic #1030; waveParallelism utilisation rows added under Epic #3019 / Story #3025).",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"additionalProperties": false,
|
|
8
|
-
"required": [
|
|
9
|
-
"kind",
|
|
10
|
-
"epicId",
|
|
11
|
-
"generatedAt",
|
|
12
|
-
"signalCounts",
|
|
13
|
-
"waveParallelism",
|
|
14
|
-
"topHotspots",
|
|
15
|
-
"mostFrictionStories"
|
|
16
|
-
],
|
|
17
|
-
"properties": {
|
|
18
|
-
"kind": { "type": "string", "const": "epic-perf-report" },
|
|
19
|
-
"epicId": { "type": "integer", "minimum": 1 },
|
|
20
|
-
"generatedAt": { "type": "string", "format": "date-time" },
|
|
21
|
-
"signalCounts": {
|
|
22
|
-
"type": "object",
|
|
23
|
-
"description": "Rolled-up signal counts by kind for the entire Epic.",
|
|
24
|
-
"additionalProperties": false,
|
|
25
|
-
"properties": {
|
|
26
|
-
"friction": { "type": "integer", "minimum": 0 },
|
|
27
|
-
"hotspot": { "type": "integer", "minimum": 0 },
|
|
28
|
-
"rework": { "type": "integer", "minimum": 0 },
|
|
29
|
-
"churn": { "type": "integer", "minimum": 0 },
|
|
30
|
-
"idle": { "type": "integer", "minimum": 0 },
|
|
31
|
-
"retry": { "type": "integer", "minimum": 0 }
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
"waveParallelism": {
|
|
35
|
-
"type": "array",
|
|
36
|
-
"description": "Per-wave parallelism utilisation. utilisation = summedStoryMs / (wallClockMs * min(storyCount, concurrencyCap)), clamped to [0,1] (Epic #3019 / Story #3025; effective-cap denominator Story #3850).",
|
|
37
|
-
"items": {
|
|
38
|
-
"type": "object",
|
|
39
|
-
"additionalProperties": false,
|
|
40
|
-
"required": [
|
|
41
|
-
"waveIndex",
|
|
42
|
-
"wallClockMs",
|
|
43
|
-
"summedStoryMs",
|
|
44
|
-
"utilisation",
|
|
45
|
-
"capBinding",
|
|
46
|
-
"verifyConcurrencyCap"
|
|
47
|
-
],
|
|
48
|
-
"properties": {
|
|
49
|
-
"waveIndex": { "type": "integer", "minimum": 0 },
|
|
50
|
-
"storyCount": {
|
|
51
|
-
"type": "integer",
|
|
52
|
-
"minimum": 0,
|
|
53
|
-
"description": "Number of Stories in the wave (from wave-start.stories). Added Story #3850."
|
|
54
|
-
},
|
|
55
|
-
"wallClockMs": { "type": "integer", "minimum": 0 },
|
|
56
|
-
"summedStoryMs": { "type": "integer", "minimum": 0 },
|
|
57
|
-
"utilisation": { "type": "number", "minimum": 0, "maximum": 1 },
|
|
58
|
-
"capBinding": { "type": "boolean" },
|
|
59
|
-
"verifyConcurrencyCap": { "type": "integer", "minimum": 1 }
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
},
|
|
63
|
-
"topHotspots": {
|
|
64
|
-
"type": "array",
|
|
65
|
-
"items": {
|
|
66
|
-
"type": "object",
|
|
67
|
-
"additionalProperties": false,
|
|
68
|
-
"required": ["phase", "occurrences", "avgRatio"],
|
|
69
|
-
"properties": {
|
|
70
|
-
"phase": { "type": "string", "minLength": 1 },
|
|
71
|
-
"occurrences": { "type": "integer", "minimum": 0 },
|
|
72
|
-
"avgRatio": { "type": "number", "minimum": 0 }
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
},
|
|
76
|
-
"mostFrictionStories": {
|
|
77
|
-
"type": "array",
|
|
78
|
-
"items": {
|
|
79
|
-
"type": "object",
|
|
80
|
-
"additionalProperties": false,
|
|
81
|
-
"required": ["storyId", "frictionCount"],
|
|
82
|
-
"properties": {
|
|
83
|
-
"storyId": { "type": "integer", "minimum": 1 },
|
|
84
|
-
"frictionCount": { "type": "integer", "minimum": 0 }
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/acceptance.reconcile.failed.schema.json",
|
|
4
|
-
"title": "acceptance.reconcile.failed",
|
|
5
|
-
"description": "Emitted by AcceptanceReconciler when reconciliation fails. Routes to epic.blocked; no PR is created.",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"required": ["baseRead", "reason"],
|
|
8
|
-
"properties": {
|
|
9
|
-
"baseRead": { "type": "boolean" },
|
|
10
|
-
"reason": { "type": "string", "minLength": 1 }
|
|
11
|
-
},
|
|
12
|
-
"additionalProperties": false
|
|
13
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/acceptance.reconcile.ok.schema.json",
|
|
4
|
-
"title": "acceptance.reconcile.ok",
|
|
5
|
-
"description": "Emitted by AcceptanceReconciler when reconciliation passes. Finalizer subscribes only to this event to gate the push and PR create.",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"required": ["baseRead"],
|
|
8
|
-
"properties": {
|
|
9
|
-
"baseRead": { "type": "boolean" },
|
|
10
|
-
"reason": { "type": "string" }
|
|
11
|
-
},
|
|
12
|
-
"additionalProperties": false
|
|
13
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/acceptance.reconcile.skipped.schema.json",
|
|
4
|
-
"title": "acceptance.reconcile.skipped",
|
|
5
|
-
"description": "Emitted by AcceptanceReconciler when reconciliation is skipped because the linked Acceptance Spec declares zero AC IDs ('empty-spec'). Story #2893 split the `acceptance::n-a` waiver path out to `acceptance.reconcile.waived` so the Finalizer can route waived Epics through to PR creation while empty-spec Epics still terminate without a PR. The reason field is required so the listener never silently no-ops.",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"required": ["baseRead", "reason"],
|
|
8
|
-
"properties": {
|
|
9
|
-
"baseRead": { "type": "boolean" },
|
|
10
|
-
"reason": { "type": "string", "minLength": 1 }
|
|
11
|
-
},
|
|
12
|
-
"additionalProperties": false
|
|
13
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/acceptance.reconcile.start.schema.json",
|
|
4
|
-
"title": "acceptance.reconcile.start",
|
|
5
|
-
"description": "Emitted by AcceptanceReconciler at the start of acceptance-spec reconciliation. Must precede pr.created in every healthy run (reconciliation ordering invariant).",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"required": ["epicId"],
|
|
8
|
-
"properties": {
|
|
9
|
-
"epicId": { "type": "integer", "minimum": 1 }
|
|
10
|
-
},
|
|
11
|
-
"additionalProperties": false
|
|
12
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/acceptance.reconcile.waived.schema.json",
|
|
4
|
-
"title": "acceptance.reconcile.waived",
|
|
5
|
-
"description": "Emitted by AcceptanceReconciler when reconciliation is waived by the acceptance::n-a label. Distinct from acceptance.reconcile.skipped (which now means 'empty-spec' only) so the Finalizer can subscribe to .waived and route waived Epics through to PR creation while empty-spec Epics still terminate without a PR. The reason field is required and pinned to 'waiver'.",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"required": ["baseRead", "reason"],
|
|
8
|
-
"properties": {
|
|
9
|
-
"baseRead": { "type": "boolean" },
|
|
10
|
-
"reason": { "type": "string", "const": "waiver" }
|
|
11
|
-
},
|
|
12
|
-
"additionalProperties": false
|
|
13
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/epic.automerge.end.schema.json",
|
|
4
|
-
"title": "epic.automerge.end",
|
|
5
|
-
"description": "Emitted at the end of the automerge phase wrapper. merged=true means GitHub completed the squash; merged=false with a reason captures predicate-blocked or armed-but-pending outcomes.",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"required": ["prUrl", "merged"],
|
|
8
|
-
"properties": {
|
|
9
|
-
"prUrl": { "type": "string", "format": "uri", "minLength": 1 },
|
|
10
|
-
"merged": { "type": "boolean" },
|
|
11
|
-
"reason": { "type": "string" },
|
|
12
|
-
"epicId": { "type": "integer", "minimum": 1 }
|
|
13
|
-
},
|
|
14
|
-
"additionalProperties": false
|
|
15
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/epic.automerge.start.schema.json",
|
|
4
|
-
"title": "epic.automerge.start",
|
|
5
|
-
"description": "Emitted at the start of the automerge phase wrapper (Phase 8.5, via lifecycle-emit.js). AutomergePredicate subscribes to this event (Story #3901) and evaluates the structured-signal verdict; it carries no checkOutcomes because Phase 8 already polled CI to green. Distinct from epic.merge.ready (predicate outcome) and epic.merge.armed (arm outcome).",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"required": ["prUrl"],
|
|
8
|
-
"properties": {
|
|
9
|
-
"prUrl": { "type": "string", "format": "uri", "minLength": 1 },
|
|
10
|
-
"epicId": { "type": "integer", "minimum": 1 }
|
|
11
|
-
},
|
|
12
|
-
"additionalProperties": false
|
|
13
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/epic.blocked.schema.json",
|
|
4
|
-
"title": "epic.blocked",
|
|
5
|
-
"description": "Emitted by AcceptanceReconciler (on a failed acceptance reconciliation), MergeWatcher (on a merge-watch timeout), and — in headless runs (Story #4472) — AutomergePredicate (on a predicate refusal that would otherwise silently park) and AutomergeArmer (on a genuine arm failure) when the Epic transitions to agent::blocked. Subscribed by NotifyDispatcher, which fans the blocker out to the curated webhook channel. The reason field carries either a typed marker (timeout:<event>, merge-predicate:refused, merge-arm:failed, waiver, …) or a free-form summary; sourceStoryId scopes the blocker to a child Story when applicable.",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"required": ["reason"],
|
|
8
|
-
"properties": {
|
|
9
|
-
"reason": { "type": "string", "minLength": 1 },
|
|
10
|
-
"sourceStoryId": { "type": "integer", "minimum": 1 }
|
|
11
|
-
},
|
|
12
|
-
"additionalProperties": false
|
|
13
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/epic.cleanup.end.schema.json",
|
|
4
|
-
"title": "epic.cleanup.end",
|
|
5
|
-
"description": "Emitted by Cleaner when branch cleanup and temp archive complete.",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"required": ["epicId"],
|
|
8
|
-
"properties": {
|
|
9
|
-
"epicId": { "type": "integer", "minimum": 1 }
|
|
10
|
-
},
|
|
11
|
-
"additionalProperties": false
|
|
12
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/epic.cleanup.start.schema.json",
|
|
4
|
-
"title": "epic.cleanup.start",
|
|
5
|
-
"description": "Emitted by Cleaner at the start of branch cleanup + temp archive.",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"required": ["epicId"],
|
|
8
|
-
"properties": {
|
|
9
|
-
"epicId": { "type": "integer", "minimum": 1 }
|
|
10
|
-
},
|
|
11
|
-
"additionalProperties": false
|
|
12
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/epic.close.end.schema.json",
|
|
4
|
-
"title": "epic.close.end",
|
|
5
|
-
"description": "Emitted when the close-tail phase finishes; AcceptanceReconciler subscribes to this event to gate finalize.",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"required": ["epicId"],
|
|
8
|
-
"properties": {
|
|
9
|
-
"epicId": { "type": "integer", "minimum": 1 }
|
|
10
|
-
},
|
|
11
|
-
"additionalProperties": false
|
|
12
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/epic.complete.schema.json",
|
|
4
|
-
"title": "epic.complete",
|
|
5
|
-
"description": "Terminal event for a successful Epic run, emitted by Cleaner once the temp archive + branch reap complete. NotifyDispatcher subscribes to this event to fan the completion out to the curated webhook channel; the agent::done label flip is driven by the post-merge close path.",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"required": ["epicId", "prUrl"],
|
|
8
|
-
"properties": {
|
|
9
|
-
"epicId": { "type": "integer", "minimum": 1 },
|
|
10
|
-
"prUrl": { "type": "string", "format": "uri", "minLength": 1 }
|
|
11
|
-
},
|
|
12
|
-
"additionalProperties": false
|
|
13
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/epic.finalize.end.schema.json",
|
|
4
|
-
"title": "epic.finalize.end",
|
|
5
|
-
"description": "Emitted by Finalizer after the PR is opened (or short-circuited by gh pr list --head idempotency check).",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"required": ["epicId", "prUrl"],
|
|
8
|
-
"properties": {
|
|
9
|
-
"epicId": { "type": "integer", "minimum": 1 },
|
|
10
|
-
"prUrl": { "type": "string", "format": "uri", "minLength": 1 }
|
|
11
|
-
},
|
|
12
|
-
"additionalProperties": false
|
|
13
|
-
}
|