mandrel 2.0.0 → 2.1.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 +9 -7
- package/.agents/agents/story-worker.md +41 -46
- package/.agents/audit-checklists/performance.md +1 -1
- package/.agents/docs/SDLC.md +51 -44
- package/.agents/docs/agentrc-reference.json +8 -13
- package/.agents/docs/configuration.md +32 -56
- package/.agents/docs/execution-reference.md +39 -10
- package/.agents/docs/quality-gates.md +14 -16
- package/.agents/docs/workflows.md +6 -6
- package/.agents/instructions.md +64 -79
- package/.agents/rules/ci-remediation.md +3 -3
- package/.agents/rules/git-conventions-reference.md +42 -51
- package/.agents/schemas/agentrc.schema.json +34 -45
- 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 +22 -66
- 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/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 +31 -13
- 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/code-review.js +58 -168
- 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 +114 -24
- package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +11 -22
- package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +3 -7
- 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 -75
- 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/planning/authoring-context.js +41 -40
- 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 +3 -12
- 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 +15 -32
- 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 +6 -5
- package/.agents/scripts/lib/templates/decomposer-prompts.js +7 -3
- 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/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 -6
- 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/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 +79 -4
- 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 +98 -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 +21 -13
- package/.agents/workflows/helpers/code-quality-guardrails.md +7 -7
- package/.agents/workflows/helpers/code-review.md +12 -10
- package/.agents/workflows/helpers/deliver-story-reference.md +73 -32
- package/.agents/workflows/helpers/deliver-story.md +193 -118
- package/.agents/workflows/helpers/parallel-tooling.md +2 -2
- package/.agents/workflows/helpers/worktree-lifecycle.md +28 -32
- package/.agents/workflows/plan.md +184 -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 +40 -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 +12 -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/package.json +1 -1
- 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
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
3
|
"$id": "https://mandrel.dev/schemas/audit-rules.schema.json",
|
|
4
4
|
"title": "AuditRulesManifest",
|
|
5
|
-
"description": "Schema describing the audit-rules.json manifest read by
|
|
5
|
+
"description": "Schema describing the audit-rules.json manifest read by lib/audit-suite/selector.js and lib/audit-suite/runner.js. The manifest enumerates registered audit workflows and the triggers / substitution keys each one accepts, plus the sensitive-path classes that derive review depth from a change set.",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"required": ["version", "audits"],
|
|
8
8
|
"additionalProperties": false,
|
|
@@ -19,9 +19,35 @@
|
|
|
19
19
|
"^[a-z][a-z0-9-]*$": { "$ref": "#/definitions/auditEntry" }
|
|
20
20
|
},
|
|
21
21
|
"additionalProperties": false
|
|
22
|
+
},
|
|
23
|
+
"sensitivePaths": {
|
|
24
|
+
"type": "object",
|
|
25
|
+
"description": "Map of sensitive-path class name to the globs that identify it. A change set touching any registered pattern derives a `high` change level, which resolves review depth to `deep` and the acceptance critic to `fresh` regardless of how narrow the diff is (deriveChangeLevel in lib/orchestration/review-depth.js). This is configuration, not code: an operator extends the classes or their globs here without editing a module, and the globs run through the same picomatch machinery as the audit-lens `filePatterns` triggers above. An absent or empty block means no path is sensitive and depth falls back to diff width alone.",
|
|
26
|
+
"patternProperties": {
|
|
27
|
+
"^[a-z][a-z0-9-]*$": { "$ref": "#/definitions/sensitivePathClass" }
|
|
28
|
+
},
|
|
29
|
+
"additionalProperties": false
|
|
22
30
|
}
|
|
23
31
|
},
|
|
24
32
|
"definitions": {
|
|
33
|
+
"sensitivePathClass": {
|
|
34
|
+
"type": "object",
|
|
35
|
+
"required": ["filePatterns"],
|
|
36
|
+
"additionalProperties": false,
|
|
37
|
+
"properties": {
|
|
38
|
+
"description": {
|
|
39
|
+
"type": "string",
|
|
40
|
+
"description": "What this class covers — why a change here warrants a deeper pass."
|
|
41
|
+
},
|
|
42
|
+
"filePatterns": {
|
|
43
|
+
"type": "array",
|
|
44
|
+
"description": "Glob patterns matched against the changed files of the diff under review.",
|
|
45
|
+
"items": { "type": "string", "minLength": 1 },
|
|
46
|
+
"uniqueItems": true,
|
|
47
|
+
"minItems": 1
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
},
|
|
25
51
|
"auditEntry": {
|
|
26
52
|
"type": "object",
|
|
27
53
|
"required": ["triggers", "scope"],
|
|
@@ -33,6 +59,12 @@
|
|
|
33
59
|
"enum": ["local", "cumulative", "global"],
|
|
34
60
|
"description": "Concern-ownership tier declaring the widest scope at which this lens's concern becomes decidable. `local` — decidable from a single Story's diff (verified at write-time + Story-scope review). `cumulative` — only decidable across the Epic's combined diff (verified at Epic close). `global` — evaluates a whole-product property regardless of the diff (verified at Epic close; exempt from change-set narrowing). All tier routing derives from this one field via resolveLensTier()."
|
|
35
61
|
},
|
|
62
|
+
"target": {
|
|
63
|
+
"type": "string",
|
|
64
|
+
"enum": ["web", "any"],
|
|
65
|
+
"description": "Target-applicability gate: the kind of project this lens can say anything about. `web` — the lens reads a rendered web surface (pages, routes, HTML/CSS, design tokens) and is skipped entirely on a project that has none, however well its keyword or file-pattern triggers match. `any` — always applicable. ABSENT MEANS `any`: omitting the key never changes a lens's behaviour. Applicability is decided by the hasWebSurface() probe in lib/audit-suite/selector.js from observables in the consumer's own checkout — configured navigability routeGlobs, a declared web-framework dependency, or a tracked .html/.css/.jsx/.tsx source file — and NOT from an .agentrc key, so a consumer with a real web surface keeps these lenses with no configuration. The probe fails OPEN: an indeterminate answer treats the project as web-capable, because a wasted lens run is recoverable and silently dropped coverage is not.",
|
|
66
|
+
"default": "any"
|
|
67
|
+
},
|
|
36
68
|
"substitutionKeys": {
|
|
37
69
|
"type": "array",
|
|
38
70
|
"description": "Substitution keys this audit accepts via run-audit-suite --substitution. Empty array means no caller-supplied keys are allowed.",
|
|
@@ -10,8 +10,7 @@ throw.
|
|
|
10
10
|
Each event in the Tech Spec taxonomy has a `<event>.schema.json`
|
|
11
11
|
file. The ledger record (`emitted | completed | failed` union)
|
|
12
12
|
lives in `ledger-record.schema.json` and is consumed by
|
|
13
|
-
`ledger-writer.js
|
|
14
|
-
assertion helpers.
|
|
13
|
+
`ledger-writer.js`.
|
|
15
14
|
|
|
16
15
|
Schemas are intentionally permissive (`additionalProperties: true`)
|
|
17
16
|
on inner objects whose shape is dictated by upstream tooling (e.g.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/ledger-record.schema.json",
|
|
4
4
|
"title": "Lifecycle ledger record (emitted | completed | failed)",
|
|
5
|
-
"description": "Append-only NDJSON record shape for temp/run-<id>/lifecycle.ndjson. Three discriminated kinds; consumers (LedgerWriter,
|
|
5
|
+
"description": "Append-only NDJSON record shape for temp/run-<id>/lifecycle.ndjson. Three discriminated kinds; consumers (LedgerWriter, TraceLogger) discriminate on `kind`.",
|
|
6
6
|
"oneOf": [
|
|
7
7
|
{ "$ref": "#/$defs/emitted" },
|
|
8
8
|
{ "$ref": "#/$defs/completed" },
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/merge.flip-failed.schema.json",
|
|
4
|
+
"title": "merge.flip-failed",
|
|
5
|
+
"description": "Emitted when a delivery run observed a CONFIRMED merge but the agent::closing → agent::done label write itself failed. Deliberately distinct from merge.unlanded (Story #4539): the merge landed, so attributing this to an unlanded merge sends the operator to branch protection and required checks when the real fault is an API failure on the label write, remedied by re-running single-story-confirm-merge.js. scope distinguishes the epic-path (ticketId = epicId) from the standalone story-path (ticketId = storyId).",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": [
|
|
8
|
+
"event",
|
|
9
|
+
"scope",
|
|
10
|
+
"ticketId",
|
|
11
|
+
"prNumber",
|
|
12
|
+
"blockClass",
|
|
13
|
+
"reason",
|
|
14
|
+
"elapsedSeconds"
|
|
15
|
+
],
|
|
16
|
+
"properties": {
|
|
17
|
+
"event": { "type": "string", "const": "merge.flip-failed" },
|
|
18
|
+
"scope": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"enum": ["epic", "story"]
|
|
21
|
+
},
|
|
22
|
+
"ticketId": { "type": "integer", "minimum": 1 },
|
|
23
|
+
"prNumber": { "type": "integer", "minimum": 1 },
|
|
24
|
+
"blockClass": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"enum": ["merged-flip-failed"]
|
|
27
|
+
},
|
|
28
|
+
"reason": { "type": "string", "minLength": 1 },
|
|
29
|
+
"elapsedSeconds": { "type": "number", "minimum": 0 },
|
|
30
|
+
"timestamp": { "type": "string", "format": "date-time" }
|
|
31
|
+
},
|
|
32
|
+
"additionalProperties": false
|
|
33
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/story.merged.schema.json",
|
|
4
4
|
"title": "story.merged",
|
|
5
|
-
"description": "Emitted from the story-close path after a Story branch successfully merges into
|
|
5
|
+
"description": "Emitted from the story-close path after a Story branch successfully merges into main (single-story/confirm-merge.js).",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"required": ["storyId", "sha"],
|
|
8
8
|
"properties": {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
3
|
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/signal-event.schema.json",
|
|
4
4
|
"title": "SignalEvent",
|
|
5
|
-
"description": "One NDJSON line emitted by the signals writer (Epic #1030; canonical envelope cutover Epic #4406 / Story #4413). Runtime events live in append-only NDJSON on local disk under temp/
|
|
5
|
+
"description": "One NDJSON line emitted by the signals writer (Epic #1030; canonical envelope cutover Epic #4406 / Story #4413). Runtime events live in append-only NDJSON on local disk under temp/run-<id>/stories/story-<sid>/signals.ndjson (per-Story) and temp/run-<id>/signals.ndjson (Epic-level wave lifecycle); The stream stays local: Story #4545 deleted the perf-summary / perf-report comment surface that used to roll it up onto tickets, leaving the retro as the consumer. `kind: trace` is the raw tool-call trace; the named kinds are derived signals. This is the ONLY shape — the legacy `timestamp` / `epic` aliases and the `source: { tool }` provenance object were deleted in the same PR that moved every writer (no read-side compatibility branch).",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"additionalProperties": true,
|
|
8
8
|
"required": ["kind", "ts"],
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"source": {
|
|
34
34
|
"type": "string",
|
|
35
35
|
"enum": ["framework", "consumer"],
|
|
36
|
-
"description": "Framework/consumer classification injected by `tagSignalSource` (signals-writer.js) for records appended via appendSignal
|
|
36
|
+
"description": "Framework/consumer classification injected by `tagSignalSource` (signals-writer.js) for records appended via appendSignal. Reserved exclusively for this classifier tag — the originating tool/surface lives in `emitter`."
|
|
37
37
|
},
|
|
38
38
|
"emitter": {
|
|
39
39
|
"type": "object",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"category": {
|
|
58
58
|
"type": "string",
|
|
59
59
|
"minLength": 1,
|
|
60
|
-
"description": "Top-level friction category (e.g. Execution Error, baseline-refresh-regression). Read directly by
|
|
60
|
+
"description": "Top-level friction category (e.g. Execution Error, baseline-refresh-regression). Read directly by the retro routed-proposal extraction — never nested under details."
|
|
61
61
|
},
|
|
62
62
|
"phase": {
|
|
63
63
|
"type": ["string", "null"],
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/story-deliver-terminal.schema.json",
|
|
4
|
+
"title": "story-deliver-terminal",
|
|
5
|
+
"description": "The single terminal envelope every Story close-and-land invocation emits (Story #4543). Before this schema, the delivery tail had two divergent prose return contracts — one in .agents/workflows/helpers/deliver-story.md, a different one in .agents/agents/story-worker.md — and neither was validated by anything, so a caller could not tell a landed Story from a parked one without re-probing GitHub. This is the SSOT both now reference rather than restate. status is exactly one of landed | pending | blocked | failed; phase names where the run ended; tail carries per-step booleans so a partial-tail degradation is visible without failing an otherwise-landed merge; nextCommand names the single command that resumes or remediates the run, drawn from the same vocabulary deliver-recover.js prints.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": [
|
|
8
|
+
"kind",
|
|
9
|
+
"storyId",
|
|
10
|
+
"status",
|
|
11
|
+
"phase",
|
|
12
|
+
"elapsedSeconds",
|
|
13
|
+
"nextCommand"
|
|
14
|
+
],
|
|
15
|
+
"properties": {
|
|
16
|
+
"kind": { "type": "string", "const": "story-deliver-terminal" },
|
|
17
|
+
"storyId": { "type": "integer", "minimum": 1 },
|
|
18
|
+
"status": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"description": "landed — the PR merged, the Story is agent::done, and the post-land tail was attempted. pending — a bounded wait expired with the PR still in flight; NO label was mutated and no merge.unlanded event was emitted, so the run is resumable via nextCommand. blocked — a classified hard block; the Story carries agent::blocked and blocked.blockClass names the class. failed — a phase crashed; phase names which one.",
|
|
21
|
+
"enum": ["landed", "pending", "blocked", "failed"]
|
|
22
|
+
},
|
|
23
|
+
"phase": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"description": "The pipeline phase the run ended in. Mirrors the close pipeline's phase names so a terminal envelope is attributable to one step.",
|
|
26
|
+
"enum": [
|
|
27
|
+
"init",
|
|
28
|
+
"wrong-tree-guard",
|
|
29
|
+
"close-validation",
|
|
30
|
+
"base-sync",
|
|
31
|
+
"push",
|
|
32
|
+
"pull-request",
|
|
33
|
+
"code-review",
|
|
34
|
+
"auto-merge",
|
|
35
|
+
"confirm-merge",
|
|
36
|
+
"post-land",
|
|
37
|
+
"done"
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
"storyBranch": { "type": ["string", "null"] },
|
|
41
|
+
"baseBranch": { "type": ["string", "null"] },
|
|
42
|
+
"pr": {
|
|
43
|
+
"type": ["object", "null"],
|
|
44
|
+
"description": "Live PR facts as observed at terminal time. null before a PR exists (an early-phase failure). `number` is nullable for the real case where `gh pr create` returned a URL the /pull/<n> parser could not read: the PR exists and its url is known, but nothing can address it by number — including auto-merge, which is why that path reports autoMergeReason: pr-number-unparseable.",
|
|
45
|
+
"required": ["number"],
|
|
46
|
+
"properties": {
|
|
47
|
+
"number": { "type": ["integer", "null"], "minimum": 1 },
|
|
48
|
+
"url": { "type": ["string", "null"] },
|
|
49
|
+
"state": {
|
|
50
|
+
"type": ["string", "null"],
|
|
51
|
+
"description": "GitHub PR state as last probed (OPEN | MERGED | CLOSED)."
|
|
52
|
+
},
|
|
53
|
+
"checksStatus": {
|
|
54
|
+
"type": ["string", "null"],
|
|
55
|
+
"description": "Aggregate required-check rollup at terminal time.",
|
|
56
|
+
"enum": [
|
|
57
|
+
"success",
|
|
58
|
+
"pending",
|
|
59
|
+
"still-running",
|
|
60
|
+
"failure",
|
|
61
|
+
"unknown",
|
|
62
|
+
null
|
|
63
|
+
]
|
|
64
|
+
},
|
|
65
|
+
"autoMergeEnabled": { "type": ["boolean", "null"] }
|
|
66
|
+
},
|
|
67
|
+
"additionalProperties": false
|
|
68
|
+
},
|
|
69
|
+
"gates": {
|
|
70
|
+
"type": "object",
|
|
71
|
+
"description": "Outcome of each close gate this invocation was responsible for. A gate the run skipped (--skip-validation, or a phase it never reached) reports \"skipped\" rather than being omitted, so a missing gate is never mistaken for a passing one.",
|
|
72
|
+
"additionalProperties": {
|
|
73
|
+
"type": "string",
|
|
74
|
+
"enum": ["passed", "failed", "skipped"]
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"tail": {
|
|
78
|
+
"type": ["object", "null"],
|
|
79
|
+
"description": "Per-step outcomes of the post-land tail. Deliberately per-step booleans rather than one aggregate success bit: the worktree-reap defect this repo fixed existed precisely because a phase reported an outcome it never checked, and an aggregate invites that class of bug back. A false here degrades the report, never the land.",
|
|
80
|
+
"required": [
|
|
81
|
+
"followUps",
|
|
82
|
+
"statusResync",
|
|
83
|
+
"refCleanup",
|
|
84
|
+
"baseFastForward"
|
|
85
|
+
],
|
|
86
|
+
"properties": {
|
|
87
|
+
"followUps": { "type": "boolean" },
|
|
88
|
+
"statusResync": { "type": "boolean" },
|
|
89
|
+
"refCleanup": { "type": "boolean" },
|
|
90
|
+
"baseFastForward": { "type": "boolean" },
|
|
91
|
+
"details": {
|
|
92
|
+
"type": "object",
|
|
93
|
+
"description": "Per-step diagnostic detail — the reason a false step reported false.",
|
|
94
|
+
"additionalProperties": { "type": ["string", "null"] }
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
"additionalProperties": false
|
|
98
|
+
},
|
|
99
|
+
"blocked": {
|
|
100
|
+
"type": ["object", "null"],
|
|
101
|
+
"description": "Present iff status === \"blocked\". blockClass comes from the shared classifier (merge-block-class.js) or the merged-flip-failed terminal, never an ad hoc string.",
|
|
102
|
+
"required": ["blockClass", "reason"],
|
|
103
|
+
"properties": {
|
|
104
|
+
"blockClass": {
|
|
105
|
+
"type": "string",
|
|
106
|
+
"enum": [
|
|
107
|
+
"checks-pending-timeout",
|
|
108
|
+
"checks-failed",
|
|
109
|
+
"branch-protection-human-required",
|
|
110
|
+
"arm-failure",
|
|
111
|
+
"api-race-other",
|
|
112
|
+
"predicate-refused",
|
|
113
|
+
"merged-flip-failed"
|
|
114
|
+
]
|
|
115
|
+
},
|
|
116
|
+
"reason": { "type": "string", "minLength": 1 },
|
|
117
|
+
"frictionCommentId": {
|
|
118
|
+
"type": ["string", "null"],
|
|
119
|
+
"description": "Pointer to the friction comment carrying the operator-facing remediation."
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
"additionalProperties": false
|
|
123
|
+
},
|
|
124
|
+
"failure": {
|
|
125
|
+
"type": ["object", "null"],
|
|
126
|
+
"description": "Present iff status === \"failed\".",
|
|
127
|
+
"required": ["reason"],
|
|
128
|
+
"properties": {
|
|
129
|
+
"reason": { "type": "string", "minLength": 1 }
|
|
130
|
+
},
|
|
131
|
+
"additionalProperties": false
|
|
132
|
+
},
|
|
133
|
+
"nextCommand": {
|
|
134
|
+
"type": ["string", "null"],
|
|
135
|
+
"description": "The single command that advances this Story from where it stopped, or null when status === \"landed\" and nothing remains. Shares its vocabulary with deliver-recover.js so recovery and normal resumption speak one language."
|
|
136
|
+
},
|
|
137
|
+
"elapsedSeconds": { "type": "number", "minimum": 0 },
|
|
138
|
+
"waitBudget": {
|
|
139
|
+
"type": ["object", "null"],
|
|
140
|
+
"description": "Merge-wait accounting. maxWaitSeconds bounds THIS invocation (defaulting under the host's single-tool-invocation ceiling); cumulativeSeconds is anchored at the PR's createdAt so a resume does not restart the clock, and maxBudgetSeconds bounds that cumulative total.",
|
|
141
|
+
"properties": {
|
|
142
|
+
"maxWaitSeconds": { "type": "integer", "minimum": 1 },
|
|
143
|
+
"waitedSeconds": { "type": "number", "minimum": 0 },
|
|
144
|
+
"cumulativeSeconds": { "type": "number", "minimum": 0 },
|
|
145
|
+
"maxBudgetSeconds": { "type": "integer", "minimum": 1 }
|
|
146
|
+
},
|
|
147
|
+
"additionalProperties": false
|
|
148
|
+
},
|
|
149
|
+
"timestamp": { "type": "string", "format": "date-time" }
|
|
150
|
+
},
|
|
151
|
+
"additionalProperties": false
|
|
152
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "validation-evidence",
|
|
4
4
|
"title": "Validation Evidence",
|
|
5
|
-
"description": "Per-scope record of which validation gates have passed against which commit SHA. Written by lib/validation-evidence.js under the per-Epic temp tree at temp/
|
|
5
|
+
"description": "Per-scope record of which validation gates have passed against which commit SHA. Written by lib/validation-evidence.js under the per-Epic temp tree at temp/run-<id>/validation-evidence.json (Epic-scoped) or temp/run-<id>/stories/story-<storyId>/validation-evidence.json (Story-scoped). Standalone Stories (no parent Epic) use a storyId-anchored keyspace at temp/standalone/stories/story-<storyId>/validation-evidence.json. All paths are gitignored via temp/. Consumed by close-validation, epic-code-review, the acceptance self-eval critic, and /deliver Phase 3 (close-validation) to skip identical re-runs against an already-validated tree. The `storyId` field carries the scope id and equals the epic id for Epic-scoped records.",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"required": ["storyId", "schemaVersion", "records"],
|
|
8
8
|
"properties": {
|
|
@@ -32,26 +32,20 @@
|
|
|
32
32
|
* — this CLI is the decision + signal boundary, mirroring how the existing
|
|
33
33
|
* gates separate decision from ticket mutation.
|
|
34
34
|
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* with NO `--story`. The verdict scores one AC cluster of the Epic's
|
|
40
|
-
* `## Acceptance Table` against the cumulative `main..epic/<id>` diff;
|
|
41
|
-
* round scoping is per cluster off the Epic's `signals.ndjson`. This is
|
|
42
|
-
* the acceptance-dilution guard — `ceil(totalACs / clusterCeiling)`
|
|
43
|
-
* independent maker-blind critic passes, one per cluster.
|
|
35
|
+
* One invocation shape: per-Story. The diff is one Story's; round scoping
|
|
36
|
+
* is per Story off the Story's `signals.ndjson`. (v2.0.0 removed the Epic
|
|
37
|
+
* tier along with the per-AC-cluster `--epic <id> --cluster <id>` mode that
|
|
38
|
+
* scored an Epic `## Acceptance Table` against a `main..epic/<id>` diff.)
|
|
44
39
|
*
|
|
45
40
|
* CLI:
|
|
46
|
-
* --story <id> Story ID (required
|
|
47
|
-
* --epic <id> Parent Epic ID (required with --cluster).
|
|
48
|
-
* --cluster <id> AC-cluster id for the single-delivery critic.
|
|
41
|
+
* --story <id> Story ID (required).
|
|
49
42
|
* --verdict <path> Path to the round's verdict JSON (required).
|
|
50
43
|
* --no-signal Suppress the signal emit (tests).
|
|
51
44
|
*
|
|
52
45
|
* Stdout: a single JSON envelope
|
|
53
46
|
* { storyId, epicId, decision, round, cap, capReached, totalCriteria,
|
|
54
47
|
* metCount, unmetCriteria[], signalEmitted }
|
|
48
|
+
* (`epicId` is retained as a always-null field for envelope stability.)
|
|
55
49
|
*
|
|
56
50
|
* @see .agents/scripts/lib/orchestration/acceptance-eval-decision.js
|
|
57
51
|
* @see .agents/schemas/acceptance-eval-verdict.schema.json
|
|
@@ -68,10 +62,7 @@ import addFormats from 'ajv-formats';
|
|
|
68
62
|
import { runAsCli } from './lib/cli-utils.js';
|
|
69
63
|
import { getAcceptanceEval, resolveConfig } from './lib/config-resolver.js';
|
|
70
64
|
import { Logger } from './lib/Logger.js';
|
|
71
|
-
import {
|
|
72
|
-
appendEpicSignal,
|
|
73
|
-
appendSignal,
|
|
74
|
-
} from './lib/observability/signals-writer.js';
|
|
65
|
+
import { appendSignal } from './lib/observability/signals-writer.js';
|
|
75
66
|
import {
|
|
76
67
|
buildAcceptanceEvalSignal,
|
|
77
68
|
decideAcceptanceEval,
|
|
@@ -139,22 +130,14 @@ function parseCliArgs(argv) {
|
|
|
139
130
|
args: argv,
|
|
140
131
|
options: {
|
|
141
132
|
story: { type: 'string' },
|
|
142
|
-
epic: { type: 'string' },
|
|
143
|
-
cluster: { type: 'string' },
|
|
144
133
|
verdict: { type: 'string' },
|
|
145
134
|
'no-signal': { type: 'boolean', default: false },
|
|
146
135
|
},
|
|
147
136
|
strict: false,
|
|
148
137
|
});
|
|
149
138
|
const storyId = Number.parseInt(values.story ?? '', 10);
|
|
150
|
-
const epicRaw = Number.parseInt(values.epic ?? '', 10);
|
|
151
139
|
return {
|
|
152
140
|
storyId: Number.isInteger(storyId) && storyId > 0 ? storyId : null,
|
|
153
|
-
epicId: Number.isInteger(epicRaw) && epicRaw > 0 ? epicRaw : null,
|
|
154
|
-
clusterId:
|
|
155
|
-
typeof values.cluster === 'string' && values.cluster.length > 0
|
|
156
|
-
? values.cluster
|
|
157
|
-
: null,
|
|
158
141
|
verdictPath: values.verdict ?? null,
|
|
159
142
|
emitSignal: values['no-signal'] !== true,
|
|
160
143
|
};
|
|
@@ -168,7 +151,6 @@ function parseCliArgs(argv) {
|
|
|
168
151
|
*
|
|
169
152
|
* @param {object} args
|
|
170
153
|
* @param {number} args.storyId
|
|
171
|
-
* @param {number | null} args.epicId
|
|
172
154
|
* @param {object} args.verdict — validated verdict object.
|
|
173
155
|
* @param {object} args.config — resolved `.agentrc.json`.
|
|
174
156
|
* @param {boolean} args.emitSignal
|
|
@@ -182,23 +164,18 @@ function parseCliArgs(argv) {
|
|
|
182
164
|
* @returns {Promise<{ envelope: object, exitCode: number }>}
|
|
183
165
|
*/
|
|
184
166
|
export async function runAcceptanceEval(
|
|
185
|
-
{ storyId,
|
|
167
|
+
{ storyId, verdict, config, emitSignal, round },
|
|
186
168
|
deps = {},
|
|
187
169
|
) {
|
|
188
170
|
const {
|
|
189
171
|
appendSignalFn = appendSignal,
|
|
190
|
-
appendEpicSignalFn = appendEpicSignal,
|
|
191
172
|
deriveRoundFn = deriveAcceptanceEvalRound,
|
|
192
173
|
} = deps;
|
|
193
|
-
const clusterMode =
|
|
194
|
-
typeof clusterId === 'string' &&
|
|
195
|
-
clusterId.length > 0 &&
|
|
196
|
-
Number.isInteger(epicId);
|
|
197
174
|
const { maxRounds } = getAcceptanceEval(config);
|
|
198
175
|
const resolvedRound =
|
|
199
176
|
Number.isInteger(round) && round >= 1
|
|
200
177
|
? round
|
|
201
|
-
: deriveRoundFn({ epicId:
|
|
178
|
+
: deriveRoundFn({ epicId: null, storyId, config });
|
|
202
179
|
const outcome = decideAcceptanceEval({
|
|
203
180
|
verdict,
|
|
204
181
|
maxRounds,
|
|
@@ -208,21 +185,16 @@ export async function runAcceptanceEval(
|
|
|
208
185
|
let signalEmitted = false;
|
|
209
186
|
if (emitSignal) {
|
|
210
187
|
const signal = {
|
|
211
|
-
...buildAcceptanceEvalSignal({ storyId, epicId, outcome
|
|
188
|
+
...buildAcceptanceEvalSignal({ storyId, epicId: null, outcome }),
|
|
212
189
|
ts: new Date().toISOString(),
|
|
213
190
|
};
|
|
214
191
|
try {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
epicId,
|
|
222
|
-
storyId,
|
|
223
|
-
signal,
|
|
224
|
-
config,
|
|
225
|
-
});
|
|
192
|
+
signalEmitted = await appendSignalFn({
|
|
193
|
+
epicId: null,
|
|
194
|
+
storyId,
|
|
195
|
+
signal,
|
|
196
|
+
config,
|
|
197
|
+
});
|
|
226
198
|
} catch (err) {
|
|
227
199
|
// Observability is best-effort — a failed signal write must never
|
|
228
200
|
// take down the gate. The decision still stands.
|
|
@@ -236,8 +208,7 @@ export async function runAcceptanceEval(
|
|
|
236
208
|
|
|
237
209
|
const envelope = {
|
|
238
210
|
storyId: storyId ?? null,
|
|
239
|
-
epicId:
|
|
240
|
-
...(clusterMode ? { clusterId } : {}),
|
|
211
|
+
epicId: null,
|
|
241
212
|
decision: outcome.decision,
|
|
242
213
|
round: outcome.round,
|
|
243
214
|
cap: outcome.cap,
|
|
@@ -261,19 +232,11 @@ export async function runAcceptanceEval(
|
|
|
261
232
|
}
|
|
262
233
|
|
|
263
234
|
export async function main(argv = process.argv.slice(2)) {
|
|
264
|
-
const { storyId,
|
|
265
|
-
parseCliArgs(argv);
|
|
235
|
+
const { storyId, verdictPath, emitSignal } = parseCliArgs(argv);
|
|
266
236
|
|
|
267
|
-
|
|
268
|
-
// - Per-Story (fan-out): --story <id> [--epic <id>].
|
|
269
|
-
// - Per-AC-cluster (single delivery): --epic <id> --cluster <id> (no
|
|
270
|
-
// --story); the verdict scores one AC cluster of the Epic's Acceptance
|
|
271
|
-
// Table against the cumulative main..epic/<id> diff.
|
|
272
|
-
const clusterMode = Boolean(clusterId) && Number.isInteger(epicId);
|
|
273
|
-
if (!storyId && !clusterMode) {
|
|
237
|
+
if (!storyId) {
|
|
274
238
|
throw new Error(
|
|
275
|
-
'Usage: node acceptance-eval.js --story <id>
|
|
276
|
-
' or: node acceptance-eval.js --epic <id> --cluster <clusterId> --verdict <path> [--no-signal]',
|
|
239
|
+
'Usage: node acceptance-eval.js --story <id> --verdict <path> [--no-signal]',
|
|
277
240
|
);
|
|
278
241
|
}
|
|
279
242
|
if (!verdictPath) {
|
|
@@ -305,13 +268,8 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
305
268
|
const verdict = validateVerdict(parsed);
|
|
306
269
|
|
|
307
270
|
// A verdict whose embedded storyId disagrees with the CLI flag is a
|
|
308
|
-
// wiring error worth failing on, not a silent mismatch.
|
|
309
|
-
|
|
310
|
-
if (
|
|
311
|
-
!clusterMode &&
|
|
312
|
-
Number.isInteger(verdict.storyId) &&
|
|
313
|
-
verdict.storyId !== storyId
|
|
314
|
-
) {
|
|
271
|
+
// wiring error worth failing on, not a silent mismatch.
|
|
272
|
+
if (Number.isInteger(verdict.storyId) && verdict.storyId !== storyId) {
|
|
315
273
|
throw new Error(
|
|
316
274
|
`acceptance-eval: verdict storyId (${verdict.storyId}) does not match --story ${storyId}.`,
|
|
317
275
|
);
|
|
@@ -320,8 +278,6 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
320
278
|
const config = resolveConfig();
|
|
321
279
|
const { envelope, exitCode } = await runAcceptanceEval({
|
|
322
280
|
storyId,
|
|
323
|
-
epicId,
|
|
324
|
-
clusterId,
|
|
325
281
|
verdict,
|
|
326
282
|
config,
|
|
327
283
|
emitSignal,
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* agents-bootstrap-github — Idempotent Label & Field Setup
|
|
4
4
|
*
|
|
5
5
|
* Creates the required label taxonomy and project board custom fields
|
|
6
|
-
* for the v5
|
|
6
|
+
* for the v5 Story-centric flow on a target GitHub repo. Idempotent —
|
|
7
7
|
* skips resources that already exist.
|
|
8
8
|
*
|
|
9
9
|
* Usage:
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
* and custom fields. Off by default — the project
|
|
46
46
|
* board object is still created when a project
|
|
47
47
|
* name is supplied, but decoration is skipped.
|
|
48
|
-
* --with-issue-forms Opt-in: generate .github/ISSUE_TEMPLATE/story.yml
|
|
49
|
-
*
|
|
48
|
+
* --with-issue-forms Opt-in: generate .github/ISSUE_TEMPLATE/story.yml.
|
|
49
|
+
* Off by default.
|
|
50
50
|
* --reap-conflicting-workflows Delete Projects V2 built-in workflows that
|
|
51
51
|
* race against the orchestrator (destructive)
|
|
52
52
|
* --help Print this help
|
|
@@ -112,7 +112,7 @@ Flags:
|
|
|
112
112
|
--with-project-board Opt-in: provision the Projects V2 Status field
|
|
113
113
|
and custom fields (default: off — prompted y/N).
|
|
114
114
|
--with-issue-forms Opt-in: generate .github/ISSUE_TEMPLATE/story.yml
|
|
115
|
-
|
|
115
|
+
(default: off — prompted y/N).
|
|
116
116
|
--reap-conflicting-workflows Delete Projects V2 built-in workflows that
|
|
117
117
|
race against the orchestrator (destructive)
|
|
118
118
|
--help Print this help
|