mandrel 1.58.0 → 1.60.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 +100 -98
- package/.agents/docs/SDLC.md +140 -141
- package/.agents/docs/configuration.md +16 -16
- package/.agents/docs/workflows.md +7 -8
- package/.agents/instructions.md +12 -11
- package/.agents/personas/architect.md +1 -1
- package/.agents/personas/product.md +1 -1
- package/.agents/personas/project-manager.md +14 -14
- package/.agents/personas/technical-writer.md +1 -1
- package/.agents/rules/changelog-style.md +5 -5
- package/.agents/rules/git-conventions.md +3 -3
- package/.agents/schemas/agentrc.schema.json +3 -3
- package/.agents/schemas/audit-rules.json +20 -0
- package/.agents/schemas/dispatch-manifest.json +4 -4
- package/.agents/schemas/epic-spec.schema.json +15 -45
- package/.agents/schemas/lifecycle/README.md +1 -1
- package/.agents/schemas/lifecycle/story.dispatch.end.schema.json +1 -1
- package/.agents/schemas/lifecycle/story.dispatch.start.schema.json +1 -1
- package/.agents/schemas/lifecycle/story.heartbeat.schema.json +1 -1
- package/.agents/schemas/validation-evidence.schema.json +1 -1
- package/.agents/scripts/README.md +1 -1
- package/.agents/scripts/acceptance-eval.js +21 -4
- package/.agents/scripts/acceptance-spec-reconciler.js +2 -2
- package/.agents/scripts/analyze-execution.js +2 -2
- package/.agents/scripts/assert-branch.js +1 -3
- package/.agents/scripts/audit-to-stories.js +1 -1
- package/.agents/scripts/bootstrap.js +1 -1
- package/.agents/scripts/check-arch-cycles.js +360 -0
- package/.agents/scripts/check-doc-links.js +2 -3
- package/.agents/scripts/coverage-capture.js +24 -3
- package/.agents/scripts/diagnose-friction.js +1 -1
- package/.agents/scripts/dispatcher.js +2 -2
- package/.agents/scripts/drain-pending-cleanup.js +1 -1
- package/.agents/scripts/epic-audit-prepare.js +3 -3
- package/.agents/scripts/epic-deliver-note-intervention.js +2 -2
- package/.agents/scripts/epic-deliver-preflight.js +11 -9
- package/.agents/scripts/epic-deliver-prepare.js +13 -5
- package/.agents/scripts/epic-execute-record-wave.js +5 -5
- package/.agents/scripts/epic-plan-healthcheck.js +6 -10
- package/.agents/scripts/epic-plan-spec-validate.js +1 -1
- package/.agents/scripts/epic-reconcile.js +11 -29
- package/.agents/scripts/evidence-gate.js +2 -2
- package/.agents/scripts/generate-workflows-doc.js +1 -1
- package/.agents/scripts/git-rebase-and-resolve.js +1 -1
- package/.agents/scripts/hierarchy-gate.js +40 -24
- package/.agents/scripts/lib/ITicketingProvider.js +1 -1
- package/.agents/scripts/lib/audit-suite/selector.js +1 -1
- package/.agents/scripts/lib/audit-to-stories/seed-epic-from-findings.js +2 -2
- package/.agents/scripts/lib/baseline-snapshot.js +7 -7
- package/.agents/scripts/lib/baselines/kinds/coverage.js +33 -149
- package/.agents/scripts/lib/baselines/kinds/duplication.js +27 -116
- package/.agents/scripts/lib/baselines/kinds/kind-factory.js +192 -0
- package/.agents/scripts/lib/baselines/kinds/lighthouse.js +34 -133
- package/.agents/scripts/lib/baselines/kinds/maintainability.js +31 -124
- package/.agents/scripts/lib/baselines/kinds/mutation.js +25 -111
- package/.agents/scripts/lib/baselines/maintainability-baseline-io.js +59 -0
- package/.agents/scripts/lib/baselines/maintainability-baseline-save.js +37 -0
- package/.agents/scripts/lib/baselines/writer.js +1 -1
- package/.agents/scripts/lib/bdd-runner-detect.js +1 -1
- package/.agents/scripts/lib/bdd-scenario-scanner.js +3 -3
- package/.agents/scripts/lib/bootstrap/baselines-layout-migration.js +1 -1
- package/.agents/scripts/lib/bootstrap/branch-protection.js +1 -1
- package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +1 -1
- package/.agents/scripts/lib/bootstrap/commit-push.js +2 -2
- package/.agents/scripts/lib/close-validation/commands.js +188 -0
- package/.agents/scripts/lib/close-validation/gates.js +235 -0
- package/.agents/scripts/lib/close-validation/process.js +101 -0
- package/.agents/scripts/lib/close-validation/projections/maintainability.js +1 -1
- package/.agents/scripts/lib/close-validation/runner.js +325 -0
- package/.agents/scripts/lib/close-validation/telemetry.js +70 -0
- package/.agents/scripts/lib/codebase-snapshot.js +1 -1
- package/.agents/scripts/lib/config/explain.js +1 -1
- package/.agents/scripts/lib/config/quality.js +6 -6
- package/.agents/scripts/lib/config/runners.js +2 -2
- package/.agents/scripts/lib/config/runtime.js +1 -1
- package/.agents/scripts/lib/config/temp-paths.js +2 -2
- package/.agents/scripts/lib/config-resolver.js +2 -5
- package/.agents/scripts/lib/config-settings-schema-delivery.js +2 -2
- package/.agents/scripts/lib/config-settings-schema-quality.js +1 -1
- package/.agents/scripts/lib/config-settings-schema.js +3 -3
- package/.agents/scripts/lib/coverage-capture.js +147 -4
- package/.agents/scripts/lib/cpu-pool.js +14 -0
- package/.agents/scripts/lib/crap-utils.js +6 -11
- package/.agents/scripts/lib/duplicate-search.js +1 -1
- package/.agents/scripts/lib/dynamic-workflow/capability.js +1 -1
- package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +87 -0
- package/.agents/scripts/lib/epic-plan-clarity.js +1 -1
- package/.agents/scripts/lib/epic-plan-ideation.js +1 -1
- package/.agents/scripts/lib/feedback-loop/memory-freshness.js +1 -1
- package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +1 -1
- package/.agents/scripts/lib/findings/classify-finding.js +1 -1
- package/.agents/scripts/lib/findings/promote-finding.js +10 -10
- package/.agents/scripts/lib/git-utils.js +24 -22
- package/.agents/scripts/lib/label-constants.js +3 -4
- package/.agents/scripts/lib/label-taxonomy.js +3 -8
- package/.agents/scripts/lib/maintainability-engine.js +1 -1
- package/.agents/scripts/lib/maintainability-utils.js +4 -187
- package/.agents/scripts/lib/observability/perf-report-readers.js +32 -23
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +81 -7
- package/.agents/scripts/lib/orchestration/code-review.js +95 -82
- package/.agents/scripts/lib/orchestration/context-hydration-engine.js +8 -9
- package/.agents/scripts/lib/orchestration/dependency-analyzer.js +3 -3
- package/.agents/scripts/lib/orchestration/detectors-phase.js +2 -2
- package/.agents/scripts/lib/orchestration/dispatch-engine.js +30 -38
- package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +14 -37
- package/.agents/scripts/lib/orchestration/epic-cleanup.js +1 -1
- package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +22 -22
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +1 -1
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +7 -21
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +3 -3
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +2 -2
- package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +206 -58
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +1 -1
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +27 -3
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/prompts.js +1 -1
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +28 -8
- package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +1 -1
- package/.agents/scripts/lib/orchestration/epic-run-state-store.js +3 -3
- package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +4 -4
- package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +3 -3
- package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +13 -41
- package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +7 -7
- package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +2 -3
- package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +2 -8
- package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +4 -4
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/component-drift.js +103 -0
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +22 -64
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +38 -76
- package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +4 -4
- package/.agents/scripts/lib/orchestration/epic-runner/story-run-progress-writer.js +10 -10
- package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +8 -20
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +7 -15
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +72 -41
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +2 -4
- package/.agents/scripts/lib/orchestration/file-assumptions.js +6 -5
- package/.agents/scripts/lib/orchestration/finalize/close-planning-tickets.js +1 -1
- package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +2 -2
- package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +1 -1
- package/.agents/scripts/lib/orchestration/lease-guard-shared.js +144 -0
- package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +1 -1
- package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +3 -3
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +1 -1
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +1 -1
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +1 -1
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +1 -1
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +1 -1
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +1 -1
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/merge-watcher.js +1 -1
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +1 -1
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js +8 -8
- package/.agents/scripts/lib/orchestration/manifest-builder.js +5 -5
- package/.agents/scripts/lib/orchestration/parked-follow-ons.js +2 -2
- package/.agents/scripts/lib/orchestration/plan-runner/plan-router.js +5 -5
- package/.agents/scripts/lib/orchestration/post-merge/phases/notification.js +3 -3
- package/.agents/scripts/lib/orchestration/post-merge/phases/ticket-closure.js +3 -3
- package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +7 -7
- package/.agents/scripts/lib/orchestration/preflight-cache.js +36 -13
- package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +1 -1
- package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +1 -1
- package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +2 -2
- package/.agents/scripts/lib/orchestration/retro-runner.js +3 -3
- package/.agents/scripts/lib/orchestration/review-depth.js +1 -1
- package/.agents/scripts/lib/orchestration/review-providers/codex.js +5 -60
- package/.agents/scripts/lib/orchestration/review-providers/native.js +7 -6
- package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +105 -0
- package/.agents/scripts/lib/orchestration/review-providers/security-review.js +7 -59
- package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +2 -4
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +1 -1
- package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +1 -1
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +2 -4
- package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +32 -35
- package/.agents/scripts/lib/orchestration/skill-capsule-loader.js +1 -2
- package/.agents/scripts/lib/orchestration/spec-freshness.js +1 -1
- package/.agents/scripts/lib/orchestration/spec-renderer.js +36 -73
- package/.agents/scripts/lib/orchestration/spec-section-validator.js +1 -1
- package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +451 -503
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +8 -2
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +47 -2
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +2 -2
- package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +1 -1
- package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +358 -54
- package/.agents/scripts/lib/orchestration/story-close/phases/close.js +1 -1
- package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +3 -2
- package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +32 -5
- package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +5 -18
- package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +3 -3
- package/.agents/scripts/lib/orchestration/story-close-recovery.js +33 -16
- package/.agents/scripts/lib/orchestration/story-reachability.js +47 -0
- package/.agents/scripts/lib/orchestration/task-body-validator.js +6 -6
- package/.agents/scripts/lib/orchestration/ticket-lease.js +1 -1
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +4 -35
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +1 -10
- package/.agents/scripts/lib/orchestration/ticket-validator.js +25 -70
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +44 -73
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +16 -7
- package/.agents/scripts/lib/orchestration/ticketing/state.js +53 -439
- package/.agents/scripts/lib/orchestration/ticketing/transition.js +471 -0
- package/.agents/scripts/lib/orchestration/ticketing.js +0 -1
- package/.agents/scripts/lib/orchestration/wave-record-notifications.js +3 -3
- package/.agents/scripts/lib/orchestration/wave-record-projection.js +2 -8
- package/.agents/scripts/lib/plan-phase-cleanup.js +1 -1
- package/.agents/scripts/lib/preflight-runner.js +1 -1
- package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +4 -5
- package/.agents/scripts/lib/presentation/manifest-builder.js +28 -34
- package/.agents/scripts/lib/presentation/manifest-formatter.js +3 -4
- package/.agents/scripts/lib/presentation/manifest-helpers.js +1 -1
- package/.agents/scripts/lib/presentation/manifest-procedures.js +4 -4
- package/.agents/scripts/lib/presentation/manifest-render-waves.js +4 -23
- package/.agents/scripts/lib/presentation/manifest-renderer.js +1 -1
- package/.agents/scripts/lib/presentation/manifest-story-views.js +2 -11
- package/.agents/scripts/lib/project-root.js +17 -0
- package/.agents/scripts/lib/signals/schema.js +1 -1
- package/.agents/scripts/lib/spec/index.js +1 -1
- package/.agents/scripts/lib/spec/loader.js +2 -2
- package/.agents/scripts/lib/spec/state.js +7 -16
- package/.agents/scripts/lib/story-adjacency.js +76 -0
- package/.agents/scripts/lib/story-init/context-resolver.js +3 -3
- package/.agents/scripts/lib/story-init/state-transitioner.js +2 -2
- package/.agents/scripts/lib/story-init/task-graph-builder.js +7 -7
- package/.agents/scripts/lib/story-lifecycle.js +9 -9
- package/.agents/scripts/lib/story-plan.js +1 -1
- package/.agents/scripts/lib/templates/decomposer-prompts.js +59 -52
- package/.agents/scripts/lib/transpile.js +93 -0
- package/.agents/scripts/lib/wave-runner/tick.js +4 -153
- package/.agents/scripts/lib/workers/crap-worker.js +1 -1
- package/.agents/scripts/lib/workers/maintainability-report-worker.js +1 -1
- package/.agents/scripts/lib/worktree/lifecycle/creation.js +20 -2
- package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +90 -0
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +26 -8
- package/.agents/scripts/lib/worktree/node-modules-strategy.js +74 -0
- package/.agents/scripts/lifecycle-emit-story-dispatch.js +1 -1
- package/.agents/scripts/lifecycle-emit.js +1 -1
- package/.agents/scripts/providers/github/board-add.js +1 -1
- package/.agents/scripts/providers/github/errors.js +1 -1
- package/.agents/scripts/providers/github/mappers.js +2 -2
- package/.agents/scripts/providers/github/tickets.js +114 -10
- package/.agents/scripts/resync-status-column.js +1 -1
- package/.agents/scripts/retro-run.js +2 -2
- package/.agents/scripts/run-lint.js +10 -1
- package/.agents/scripts/run-tests.js +24 -4
- package/.agents/scripts/single-story-init.js +1 -1
- package/.agents/scripts/stories-wave-tick.js +13 -10
- package/.agents/scripts/story-close.js +1 -1
- package/.agents/scripts/story-init.js +162 -26
- package/.agents/scripts/story-phase.js +5 -5
- package/.agents/scripts/story-plan.js +3 -3
- package/.agents/scripts/sync-branch-from-base.js +2 -2
- package/.agents/scripts/validate-docs-freshness.js +1 -1
- package/.agents/scripts/wave-tick.js +1 -1
- package/.agents/skills/core/analyze-execution/SKILL.md +2 -2
- package/.agents/skills/core/epic-plan-consolidate/SKILL.md +21 -26
- package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +23 -56
- package/.agents/skills/core/epic-plan-spec-author/SKILL.md +4 -4
- package/.agents/skills/core/hydrate-context/SKILL.md +2 -2
- package/.agents/skills/core/idea-refinement/SKILL.md +4 -4
- package/.agents/skills/core/knowledge-transfer/SKILL.md +2 -2
- package/.agents/skills/core/planning-and-task-breakdown/SKILL.md +1 -1
- package/.agents/skills/core/scope-triage/SKILL.md +9 -10
- package/.agents/skills/core/using-agent-skills/SKILL.md +1 -1
- package/.agents/skills/skills.index.json +7 -7
- package/.agents/skills/stack/qa/lighthouse-baseline/SKILL.md +1 -1
- package/.agents/templates/agent-protocol.md +2 -2
- package/.agents/workflows/agents-update.md +2 -2
- package/.agents/workflows/audit-architecture.md +2 -2
- package/.agents/workflows/audit-clean-code.md +2 -2
- package/.agents/workflows/audit-dependencies.md +1 -1
- package/.agents/workflows/audit-devops.md +1 -1
- package/.agents/workflows/audit-documentation.md +226 -0
- package/.agents/workflows/audit-lighthouse.md +1 -1
- package/.agents/workflows/audit-performance.md +2 -2
- package/.agents/workflows/audit-privacy.md +1 -1
- package/.agents/workflows/audit-quality.md +2 -2
- package/.agents/workflows/audit-security.md +2 -2
- package/.agents/workflows/audit-seo.md +1 -1
- package/.agents/workflows/audit-sre.md +1 -1
- package/.agents/workflows/audit-to-stories.md +10 -10
- package/.agents/workflows/audit-ux-ui.md +1 -1
- package/.agents/workflows/deliver.md +85 -0
- package/.agents/workflows/explain.md +3 -3
- package/.agents/workflows/git-merge-pr.md +1 -1
- package/.agents/workflows/git-pr-all.md +13 -10
- package/.agents/workflows/git-push.md +6 -3
- package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
- package/.agents/workflows/helpers/acceptance-self-eval.md +1 -1
- package/.agents/workflows/helpers/code-review.md +5 -5
- package/.agents/workflows/{epic-deliver.md → helpers/deliver-epic.md} +59 -66
- package/.agents/workflows/{story-deliver.md → helpers/deliver-stories.md} +25 -25
- package/.agents/workflows/helpers/diagnose.md +1 -1
- package/.agents/workflows/helpers/epic-audit.md +6 -6
- package/.agents/workflows/helpers/epic-deliver-story.md +28 -39
- package/.agents/workflows/helpers/epic-plan-decompose.md +23 -23
- package/.agents/workflows/helpers/epic-plan-spec.md +6 -6
- package/.agents/workflows/helpers/epic-testing.md +3 -3
- package/.agents/workflows/helpers/parallel-tooling.md +1 -1
- package/.agents/workflows/{epic-plan.md → helpers/plan-epic.md} +84 -84
- package/.agents/workflows/{story-plan.md → helpers/plan-story.md} +43 -43
- package/.agents/workflows/helpers/signals.md +1 -1
- package/.agents/workflows/helpers/single-story-deliver.md +12 -11
- package/.agents/workflows/helpers/worktree-lifecycle.md +18 -18
- package/.agents/workflows/onboard.md +21 -20
- package/.agents/workflows/plan.md +89 -0
- package/.agents/workflows/qa-explore.md +1 -1
- package/.agents/workflows/qa-run-harness.md +1 -1
- package/README.md +17 -20
- package/docs/CHANGELOG.md +1149 -0
- package/lib/cli/__tests__/update-changelog-surface.test.js +357 -0
- package/lib/cli/__tests__/update-reexec.test.js +513 -0
- package/lib/cli/init.js +338 -0
- package/lib/cli/update.js +413 -52
- package/package.json +3 -1
- package/.agents/scripts/lib/auto-refresh-baselines.js +0 -308
- package/.agents/scripts/lib/close-validation.js +0 -897
- package/.agents/scripts/lib/orchestration/cascade-grouping.js +0 -275
- package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter.js +0 -69
- package/.agents/scripts/lib/orchestration/reconciler.js +0 -137
- package/.agents/scripts/lib/orchestration/story-close/format-autofix-scoped.js +0 -221
- package/.agents/scripts/lib/orchestration/story-close/format-autofix-shared.js +0 -123
- package/.agents/scripts/lib/task-utils.js +0 -26
- package/.agents/scripts/story-deliver-prepare.js +0 -267
|
@@ -9,15 +9,22 @@
|
|
|
9
9
|
* MI is computed by the in-repo `escomplex-engine` kernel — same upstream
|
|
10
10
|
* dependency family as CRAP — so the kernel version tracks
|
|
11
11
|
* `typhonjs-escomplex` too.
|
|
12
|
+
*
|
|
13
|
+
* Higher MI = better. New paths land in the `additions` bucket
|
|
14
|
+
* (Story #2012 — new files MUST NOT register as regressions); removed
|
|
15
|
+
* paths count as improvements when their MI was non-perfect — the file is
|
|
16
|
+
* gone, so its prior debt is gone too. Scaffold (sortRows / rollup /
|
|
17
|
+
* compare / applyEpsilon / mergeRows) is generated by `makeBaselineKind`
|
|
18
|
+
* (Story #3983).
|
|
12
19
|
*/
|
|
13
20
|
|
|
14
21
|
import { readBaselineAtRef } from '../../baseline-loader.js';
|
|
15
22
|
import { loadBaseline } from '../../gates/baseline-store.js';
|
|
16
|
-
import { getBaseline } from '
|
|
17
|
-
import { componentMatches } from '../component-matcher.js';
|
|
23
|
+
import { getBaseline } from '../maintainability-baseline-io.js';
|
|
18
24
|
import { canonicalise } from '../path-canon.js';
|
|
19
|
-
import {
|
|
25
|
+
import { percentile } from './_shared-metric.js';
|
|
20
26
|
import { kernelVersion as crapKernelVersion } from './crap.js';
|
|
27
|
+
import { makeBaselineKind } from './kind-factory.js';
|
|
21
28
|
|
|
22
29
|
export const name = 'maintainability';
|
|
23
30
|
export const keyField = 'path';
|
|
@@ -111,12 +118,6 @@ export function filterExcludedRows(rows) {
|
|
|
111
118
|
);
|
|
112
119
|
}
|
|
113
120
|
|
|
114
|
-
export function kernelVersion() {
|
|
115
|
-
// MI and CRAP share the escomplex kernel — pin them together so a drift
|
|
116
|
-
// in either always invalidates both baselines.
|
|
117
|
-
return crapKernelVersion();
|
|
118
|
-
}
|
|
119
|
-
|
|
120
121
|
export function projectRow(row) {
|
|
121
122
|
return {
|
|
122
123
|
path: canonicalise(row.path),
|
|
@@ -124,10 +125,6 @@ export function projectRow(row) {
|
|
|
124
125
|
};
|
|
125
126
|
}
|
|
126
127
|
|
|
127
|
-
export function sortRows(rows) {
|
|
128
|
-
return [...rows].sort((a, b) => a.path.localeCompare(b.path));
|
|
129
|
-
}
|
|
130
|
-
|
|
131
128
|
function aggregate(rows) {
|
|
132
129
|
if (!rows || rows.length === 0) return { min: 0, p50: 0, p95: 0 };
|
|
133
130
|
const sorted = [...rows].map((r) => r.mi).sort((a, b) => a - b);
|
|
@@ -138,117 +135,27 @@ function aggregate(rows) {
|
|
|
138
135
|
};
|
|
139
136
|
}
|
|
140
137
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
* base, improves when it rises, unchanged when equal. New paths (head
|
|
163
|
-
* has a row that base lacks) land in the `additions` bucket; absolute-
|
|
164
|
-
* floor enforcement is the unified `check-baselines` gate's job and runs
|
|
165
|
-
* independently. Removed paths (base has a row that head dropped) count
|
|
166
|
-
* as improvements when their MI was non-perfect; the file is gone, so
|
|
167
|
-
* its prior debt is gone too.
|
|
168
|
-
*
|
|
169
|
-
* Story #2012 — new files MUST NOT register as regressions. The prior
|
|
170
|
-
* behaviour treated missing-in-base as base.mi = 100 and any real-world
|
|
171
|
-
* MI under 100 (i.e., almost every file) flipped to a regression.
|
|
172
|
-
*
|
|
173
|
-
* No I/O. No process exit. No friction emission.
|
|
174
|
-
*/
|
|
175
|
-
export function compare(head, base) {
|
|
176
|
-
const headRows = Array.isArray(head?.rows) ? head.rows : [];
|
|
177
|
-
const baseRows = Array.isArray(base?.rows) ? base.rows : [];
|
|
178
|
-
const baseByKey = new Map();
|
|
179
|
-
for (const r of baseRows) baseByKey.set(r.path, r);
|
|
180
|
-
const seen = new Set();
|
|
181
|
-
const regressions = [];
|
|
182
|
-
const improvements = [];
|
|
183
|
-
const unchanged = [];
|
|
184
|
-
const additions = [];
|
|
185
|
-
for (const h of headRows) {
|
|
186
|
-
seen.add(h.path);
|
|
187
|
-
const b = baseByKey.get(h.path);
|
|
188
|
-
if (!b) {
|
|
189
|
-
additions.push({ key: h.path, head: h, base: null });
|
|
190
|
-
continue;
|
|
191
|
-
}
|
|
192
|
-
const delta = (h.mi ?? 0) - (b.mi ?? 0);
|
|
193
|
-
if (delta < 0) regressions.push({ key: h.path, head: h, base: b });
|
|
194
|
-
else if (delta > 0) improvements.push({ key: h.path, head: h, base: b });
|
|
195
|
-
else unchanged.push({ key: h.path, head: h, base: b });
|
|
196
|
-
}
|
|
197
|
-
for (const b of baseRows) {
|
|
198
|
-
if (seen.has(b.path)) continue;
|
|
199
|
-
if ((b.mi ?? 0) < 100) {
|
|
200
|
-
improvements.push({ key: b.path, head: null, base: b });
|
|
201
|
-
} else {
|
|
202
|
-
unchanged.push({ key: b.path, head: null, base: b });
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
return { regressions, improvements, unchanged, additions };
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Pure stabilizer for s-stability-epsilon (Story #1964). Folds sub-epsilon
|
|
210
|
-
* MI deltas back to the prior bytes so env variance does not rewrite the
|
|
211
|
-
* on-disk baseline. Missing-prior rows fall through to the regenerated
|
|
212
|
-
* row.
|
|
213
|
-
*
|
|
214
|
-
* @param {Array<{path: string, mi: number}>} prior
|
|
215
|
-
* @param {Array<{path: string, mi: number}>} regenerated
|
|
216
|
-
* @param {number} epsilon non-negative absolute tolerance on MI
|
|
217
|
-
* @returns {Array<object>}
|
|
218
|
-
*/
|
|
219
|
-
export function applyEpsilon(prior, regenerated, epsilon) {
|
|
220
|
-
const priorRows = Array.isArray(prior) ? prior : [];
|
|
221
|
-
const regenRows = Array.isArray(regenerated) ? regenerated : [];
|
|
222
|
-
const eps = Number.isFinite(epsilon) && epsilon >= 0 ? epsilon : 0;
|
|
223
|
-
const priorByKey = new Map();
|
|
224
|
-
for (const r of priorRows) priorByKey.set(r.path, r);
|
|
225
|
-
return regenRows.map((row) => {
|
|
226
|
-
const p = priorByKey.get(row.path);
|
|
227
|
-
if (!p) return row;
|
|
228
|
-
return Math.abs((row.mi ?? 0) - (p.mi ?? 0)) <= eps ? p : row;
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Pure scope-aware merge for s-diff-scoped-writes (Story #1974). MI rows
|
|
234
|
-
* match by `path`. In diff mode, rows whose `path` is OUTSIDE
|
|
235
|
-
* `scope.files` are preserved from `prior` verbatim; in-scope rows come
|
|
236
|
-
* from `regenerated`. In full mode (or no scope), regenerated wins
|
|
237
|
-
* everywhere.
|
|
238
|
-
*
|
|
239
|
-
* @param {Array<{path: string, mi: number}>} prior
|
|
240
|
-
* @param {Array<{path: string, mi: number}>} regenerated
|
|
241
|
-
* @param {{mode: 'full'|'diff', files: Set<string>}|null|undefined} scope
|
|
242
|
-
* @returns {Array<object>}
|
|
243
|
-
*/
|
|
244
|
-
export function mergeRows(prior, regenerated, scope) {
|
|
245
|
-
return mergeRowsByScope({
|
|
246
|
-
prior,
|
|
247
|
-
regenerated,
|
|
248
|
-
scope,
|
|
249
|
-
scopeKey: (row) => row.path,
|
|
250
|
-
});
|
|
251
|
-
}
|
|
138
|
+
export const {
|
|
139
|
+
kernelVersion,
|
|
140
|
+
sortRows,
|
|
141
|
+
rollup,
|
|
142
|
+
compare,
|
|
143
|
+
applyEpsilon,
|
|
144
|
+
mergeRows,
|
|
145
|
+
} = makeBaselineKind({
|
|
146
|
+
keyField,
|
|
147
|
+
// MI and CRAP share the escomplex kernel — pin them together so a drift
|
|
148
|
+
// in either always invalidates both baselines.
|
|
149
|
+
kernelVersion: crapKernelVersion,
|
|
150
|
+
axes: ['mi'],
|
|
151
|
+
betterWhen: 'higher',
|
|
152
|
+
aggregate,
|
|
153
|
+
missingBasePolicy: 'addition',
|
|
154
|
+
removedRowPolicy: {
|
|
155
|
+
kind: 'improvement-when',
|
|
156
|
+
when: (b) => (b.mi ?? 0) < 100,
|
|
157
|
+
},
|
|
158
|
+
});
|
|
252
159
|
|
|
253
160
|
// ---------------------------------------------------------------------------
|
|
254
161
|
// CLI-facing pure helpers (Story #1981, Task #1989).
|
|
@@ -4,19 +4,18 @@
|
|
|
4
4
|
* carries score/killed/survived/noCoverage. Stryker is the upstream
|
|
5
5
|
* kernel; we pin a static `1.0.0` until a Mandrel-side retrofit story
|
|
6
6
|
* wires the running Stryker version through (#1908).
|
|
7
|
+
*
|
|
8
|
+
* Higher score = better. New paths land in the `additions` bucket
|
|
9
|
+
* (Story #2012 — any real-world score under 100 must never flip to a
|
|
10
|
+
* regression); removed paths count as improvements when their score was
|
|
11
|
+
* non-perfect. Scaffold is generated by `makeBaselineKind` (Story #3983).
|
|
7
12
|
*/
|
|
8
13
|
|
|
9
|
-
import { componentMatches } from '../component-matcher.js';
|
|
10
14
|
import { canonicalise } from '../path-canon.js';
|
|
11
|
-
import {
|
|
15
|
+
import { makeBaselineKind } from './kind-factory.js';
|
|
12
16
|
|
|
13
17
|
export const name = 'mutation';
|
|
14
18
|
export const keyField = 'path';
|
|
15
|
-
const KERNEL_VERSION = '1.0.0';
|
|
16
|
-
|
|
17
|
-
export function kernelVersion() {
|
|
18
|
-
return KERNEL_VERSION;
|
|
19
|
-
}
|
|
20
19
|
|
|
21
20
|
export function projectRow(row) {
|
|
22
21
|
return {
|
|
@@ -27,10 +26,6 @@ export function projectRow(row) {
|
|
|
27
26
|
};
|
|
28
27
|
}
|
|
29
28
|
|
|
30
|
-
export function sortRows(rows) {
|
|
31
|
-
return [...rows].sort((a, b) => a.path.localeCompare(b.path));
|
|
32
|
-
}
|
|
33
|
-
|
|
34
29
|
function aggregate(rows) {
|
|
35
30
|
if (!rows || rows.length === 0) {
|
|
36
31
|
return { score: 0, killed: 0, survived: 0, noCoverage: 0 };
|
|
@@ -51,103 +46,22 @@ function aggregate(rows) {
|
|
|
51
46
|
};
|
|
52
47
|
}
|
|
53
48
|
|
|
54
|
-
export
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
* behaviour treated missing-in-base as base.score = 100 and any real-
|
|
74
|
-
* world mutation score under 100 flipped to a regression.
|
|
75
|
-
*
|
|
76
|
-
* No I/O. No process exit. No friction emission.
|
|
77
|
-
*/
|
|
78
|
-
export function compare(head, base) {
|
|
79
|
-
const headRows = Array.isArray(head?.rows) ? head.rows : [];
|
|
80
|
-
const baseRows = Array.isArray(base?.rows) ? base.rows : [];
|
|
81
|
-
const baseByKey = new Map();
|
|
82
|
-
for (const r of baseRows) baseByKey.set(r.path, r);
|
|
83
|
-
const seen = new Set();
|
|
84
|
-
const regressions = [];
|
|
85
|
-
const improvements = [];
|
|
86
|
-
const unchanged = [];
|
|
87
|
-
const additions = [];
|
|
88
|
-
for (const h of headRows) {
|
|
89
|
-
seen.add(h.path);
|
|
90
|
-
const b = baseByKey.get(h.path);
|
|
91
|
-
if (!b) {
|
|
92
|
-
additions.push({ key: h.path, head: h, base: null });
|
|
93
|
-
continue;
|
|
94
|
-
}
|
|
95
|
-
const delta = (h.score ?? 0) - (b.score ?? 0);
|
|
96
|
-
if (delta < 0) regressions.push({ key: h.path, head: h, base: b });
|
|
97
|
-
else if (delta > 0) improvements.push({ key: h.path, head: h, base: b });
|
|
98
|
-
else unchanged.push({ key: h.path, head: h, base: b });
|
|
99
|
-
}
|
|
100
|
-
for (const b of baseRows) {
|
|
101
|
-
if (seen.has(b.path)) continue;
|
|
102
|
-
if ((b.score ?? 0) < 100) {
|
|
103
|
-
improvements.push({ key: b.path, head: null, base: b });
|
|
104
|
-
} else {
|
|
105
|
-
unchanged.push({ key: b.path, head: null, base: b });
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
return { regressions, improvements, unchanged, additions };
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Pure stabilizer for s-stability-epsilon (Story #1964). Folds sub-epsilon
|
|
113
|
-
* mutation-score deltas back to the prior bytes. Missing-prior rows fall
|
|
114
|
-
* through to the regenerated row.
|
|
115
|
-
*
|
|
116
|
-
* @param {Array<{path: string, score: number, killed: number, survived: number}>} prior
|
|
117
|
-
* @param {Array<{path: string, score: number, killed: number, survived: number}>} regenerated
|
|
118
|
-
* @param {number} epsilon non-negative absolute tolerance on mutation score
|
|
119
|
-
* @returns {Array<object>}
|
|
120
|
-
*/
|
|
121
|
-
export function applyEpsilon(prior, regenerated, epsilon) {
|
|
122
|
-
const priorRows = Array.isArray(prior) ? prior : [];
|
|
123
|
-
const regenRows = Array.isArray(regenerated) ? regenerated : [];
|
|
124
|
-
const eps = Number.isFinite(epsilon) && epsilon >= 0 ? epsilon : 0;
|
|
125
|
-
const priorByKey = new Map();
|
|
126
|
-
for (const r of priorRows) priorByKey.set(r.path, r);
|
|
127
|
-
return regenRows.map((row) => {
|
|
128
|
-
const p = priorByKey.get(row.path);
|
|
129
|
-
if (!p) return row;
|
|
130
|
-
return Math.abs((row.score ?? 0) - (p.score ?? 0)) <= eps ? p : row;
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Pure scope-aware merge for s-diff-scoped-writes (Story #1974). Mutation
|
|
136
|
-
* rows match by `path`. In diff mode, rows whose `path` is OUTSIDE
|
|
137
|
-
* `scope.files` are preserved from `prior` verbatim; in-scope rows come
|
|
138
|
-
* from `regenerated`. In full mode (or no scope), regenerated wins
|
|
139
|
-
* everywhere.
|
|
140
|
-
*
|
|
141
|
-
* @param {Array<{path: string, score: number, killed: number, survived: number}>} prior
|
|
142
|
-
* @param {Array<{path: string, score: number, killed: number, survived: number}>} regenerated
|
|
143
|
-
* @param {{mode: 'full'|'diff', files: Set<string>}|null|undefined} scope
|
|
144
|
-
* @returns {Array<object>}
|
|
145
|
-
*/
|
|
146
|
-
export function mergeRows(prior, regenerated, scope) {
|
|
147
|
-
return mergeRowsByScope({
|
|
148
|
-
prior,
|
|
149
|
-
regenerated,
|
|
150
|
-
scope,
|
|
151
|
-
scopeKey: (row) => row.path,
|
|
152
|
-
});
|
|
153
|
-
}
|
|
49
|
+
export const {
|
|
50
|
+
kernelVersion,
|
|
51
|
+
sortRows,
|
|
52
|
+
rollup,
|
|
53
|
+
compare,
|
|
54
|
+
applyEpsilon,
|
|
55
|
+
mergeRows,
|
|
56
|
+
} = makeBaselineKind({
|
|
57
|
+
keyField,
|
|
58
|
+
kernelVersion: '1.0.0',
|
|
59
|
+
axes: ['score'],
|
|
60
|
+
betterWhen: 'higher',
|
|
61
|
+
aggregate,
|
|
62
|
+
missingBasePolicy: 'addition',
|
|
63
|
+
removedRowPolicy: {
|
|
64
|
+
kind: 'improvement-when',
|
|
65
|
+
when: (b) => (b.score ?? 0) < 100,
|
|
66
|
+
},
|
|
67
|
+
});
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { Logger } from '../Logger.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Story #1895: project the canonical maintainability envelope back to the
|
|
7
|
+
* legacy flat `{ path: mi }` map so existing gate consumers keep working
|
|
8
|
+
* without churn — Story #1912 will replace this shim with the shared
|
|
9
|
+
* reader. Returns the parsed input unchanged when it doesn't look like an
|
|
10
|
+
* envelope (legacy flat shape stays flat).
|
|
11
|
+
*/
|
|
12
|
+
function projectMaintainabilityEnvelopeToFlat(parsed) {
|
|
13
|
+
if (
|
|
14
|
+
!parsed ||
|
|
15
|
+
typeof parsed !== 'object' ||
|
|
16
|
+
Array.isArray(parsed) ||
|
|
17
|
+
!Array.isArray(parsed.rows) ||
|
|
18
|
+
typeof parsed.$schema !== 'string'
|
|
19
|
+
) {
|
|
20
|
+
return parsed;
|
|
21
|
+
}
|
|
22
|
+
const flat = {};
|
|
23
|
+
for (const row of parsed.rows) {
|
|
24
|
+
if (row && typeof row.path === 'string' && typeof row.mi === 'number') {
|
|
25
|
+
flat[row.path] = row.mi;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return flat;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Loads the current maintainability baseline from disk. The on-disk path is
|
|
33
|
+
* resolved by the caller via {@link getBaselines}; passing it explicitly
|
|
34
|
+
* removes the silent-default behaviour the framework dropped in Epic #730
|
|
35
|
+
* Story 5.5.
|
|
36
|
+
*
|
|
37
|
+
* @param {string} baselinePath Repo-relative or absolute path to the baseline
|
|
38
|
+
* JSON. Required.
|
|
39
|
+
* @returns {Record<string, number>}
|
|
40
|
+
*/
|
|
41
|
+
export function getBaseline(baselinePath) {
|
|
42
|
+
if (typeof baselinePath !== 'string' || baselinePath.length === 0) {
|
|
43
|
+
throw new TypeError(
|
|
44
|
+
'maintainability-utils.getBaseline: baselinePath is required (Epic #730 ' +
|
|
45
|
+
'Story 5.5 — callers resolve the path via getBaselines(config).maintainability.path).',
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
const abs = path.isAbsolute(baselinePath)
|
|
49
|
+
? baselinePath
|
|
50
|
+
: path.resolve(process.cwd(), baselinePath);
|
|
51
|
+
if (!fs.existsSync(abs)) return {};
|
|
52
|
+
try {
|
|
53
|
+
const parsed = JSON.parse(fs.readFileSync(abs, 'utf-8'));
|
|
54
|
+
return projectMaintainabilityEnvelopeToFlat(parsed);
|
|
55
|
+
} catch (err) {
|
|
56
|
+
Logger.warn(`[Maintainability] Failed to parse baseline: ${err.message}`);
|
|
57
|
+
return {};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import {
|
|
3
|
+
write as writeBaselineEnvelope,
|
|
4
|
+
writeFile as writeBaselineFile,
|
|
5
|
+
} from './writer.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Saves a new maintainability baseline to disk at `baselinePath`.
|
|
9
|
+
*
|
|
10
|
+
* Accepts the legacy flat `{ path: mi }` shape for backwards compatibility
|
|
11
|
+
* with existing callers (`regenerateMainFromTree`, refresh helpers). The
|
|
12
|
+
* map is transformed into the canonical envelope shape (`$schema`,
|
|
13
|
+
* `kernelVersion`, `generatedAt`, `rollup`, `rows`) via the shared
|
|
14
|
+
* `lib/baselines/writer.js` pipeline before being persisted, so every
|
|
15
|
+
* write produces a file that round-trips through `lib/baselines/reader.js`
|
|
16
|
+
* without schema errors.
|
|
17
|
+
*
|
|
18
|
+
* @param {Record<string, number>} baseline path→MI flat map.
|
|
19
|
+
* @param {string} baselinePath Required — caller supplies via getBaselines().
|
|
20
|
+
*/
|
|
21
|
+
export function saveBaseline(baseline, baselinePath) {
|
|
22
|
+
if (typeof baselinePath !== 'string' || baselinePath.length === 0) {
|
|
23
|
+
throw new TypeError(
|
|
24
|
+
'maintainability-utils.saveBaseline: baselinePath is required.',
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
const abs = path.isAbsolute(baselinePath)
|
|
28
|
+
? baselinePath
|
|
29
|
+
: path.resolve(process.cwd(), baselinePath);
|
|
30
|
+
|
|
31
|
+
const rows = Object.entries(baseline ?? {}).map(([p, mi]) => ({
|
|
32
|
+
path: p,
|
|
33
|
+
mi,
|
|
34
|
+
}));
|
|
35
|
+
const envelope = writeBaselineEnvelope({ kind: 'maintainability', rows });
|
|
36
|
+
writeBaselineFile(abs, envelope);
|
|
37
|
+
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Every legacy baseline-refresh script (`update-crap-baseline.js`,
|
|
5
5
|
* `update-maintainability-baseline.js`, `lib/coverage-baseline.js`,
|
|
6
|
-
* `
|
|
6
|
+
* the auto-refresh evaluator, now inside `auto-refresh-runner.js`) used to assemble its own envelope and
|
|
7
7
|
* call `fs.writeFileSync`. That meant the path canonicalisation, rollup
|
|
8
8
|
* math, kernel-version stamping, and JSON-serialisation conventions were
|
|
9
9
|
* duplicated five-ish times, each with subtly different rules. The
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* The verification is **static**: we inspect `package.json` for a known BDD
|
|
14
14
|
* runner dependency, and consult a small lookup table of which runners
|
|
15
15
|
* support which pending/skip tag. We do not boot the runner. This keeps
|
|
16
|
-
* `/
|
|
16
|
+
* `/plan` Phase 7 hermetic and offline.
|
|
17
17
|
*
|
|
18
18
|
* **Workspace awareness (Story #2956).** In a pnpm / npm / yarn monorepo the
|
|
19
19
|
* BDD runner is rarely a root devDependency — it lives in the workspace
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* bdd-scenario-scanner.js — Gherkin scenario index for /
|
|
2
|
+
* bdd-scenario-scanner.js — Gherkin scenario index for /plan Phase 7.
|
|
3
3
|
*
|
|
4
4
|
* Story #2637 (sibling to #2634 codebase-snapshot, #2635 spec-freshness,
|
|
5
5
|
* #2636 file-assumption gate). The Acceptance Engineer step of
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* alone — it never inspects the consumer project's existing `.feature`
|
|
8
8
|
* files. Planned ACs frequently duplicate scenarios that already exist or
|
|
9
9
|
* re-specify behaviour the codebase already proves; the duplication is
|
|
10
|
-
* only discovered (at best) during `/
|
|
10
|
+
* only discovered (at best) during `/deliver` or (at worst) after
|
|
11
11
|
* a redundant PR ships.
|
|
12
12
|
*
|
|
13
13
|
* `scanBddScenarios` walks every configured feature root, parses each
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* have a matching scenario.
|
|
21
21
|
*
|
|
22
22
|
* Determinism is load-bearing: the matcher is keyword-based, not
|
|
23
|
-
* embedding-based, so re-running `/
|
|
23
|
+
* embedding-based, so re-running `/plan` against the same
|
|
24
24
|
* acceptance spec produces the same disposition annotations.
|
|
25
25
|
*/
|
|
26
26
|
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*
|
|
16
16
|
* All three shapes are relocated under `<repoRoot>/temp/epic/<id>/baselines/`,
|
|
17
17
|
* where they inherit the existing per-epic temp-tree cleanup contract:
|
|
18
|
-
* `/
|
|
18
|
+
* `/deliver` reaps `temp/epic/<id>/` on merge, so the ratchet snapshots
|
|
19
19
|
* are ephemeral scratch state — never committed, no manual prune.
|
|
20
20
|
*
|
|
21
21
|
* The main-tracked `baselines/{maintainability,crap}.json` files are NOT
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* - `enforce_admins: true` — admins do not bypass the prGate suite.
|
|
8
8
|
* - `required_pull_request_reviews.required_approving_review_count: 0` —
|
|
9
9
|
* CI is the gate; the operator monitors and iterates the open PR
|
|
10
|
-
* to green via `/
|
|
10
|
+
* to green via `/deliver`'s Phase 7 watch loop.
|
|
11
11
|
*
|
|
12
12
|
* Behaviour rules
|
|
13
13
|
* ---------------
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* `--full-scope` so a self-diff doesn't degrade to "no files in diff".
|
|
15
15
|
*
|
|
16
16
|
* 2. **Pass `--epic-ref` where the firing site is Epic-aware.** Inside
|
|
17
|
-
* `/
|
|
17
|
+
* `/deliver` the close-validation chain already threads
|
|
18
18
|
* `--epic-ref epic/<id>`; on CI the equivalent surface is the PR's
|
|
19
19
|
* base branch. The template wires `--epic-ref ${EPIC_REF}` through an
|
|
20
20
|
* env var the workflow computes from `github.head_ref` (story-N
|
|
@@ -112,8 +112,8 @@ export function buildManualInstructions({ stagePaths, baseBranch }) {
|
|
|
112
112
|
` git push -u origin ${baseBranch}`,
|
|
113
113
|
'',
|
|
114
114
|
'Story delivery runs in git worktrees that check out tracked files only,',
|
|
115
|
-
'so the .agents/ wiring MUST be committed before any /
|
|
116
|
-
'/
|
|
115
|
+
'so the .agents/ wiring MUST be committed before any /deliver or',
|
|
116
|
+
'/deliver run — otherwise the worktree has no scripts and breaks.',
|
|
117
117
|
].join('\n');
|
|
118
118
|
}
|
|
119
119
|
|