mandrel 2.56.0 → 2.58.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.
Files changed (114) hide show
  1. package/.agents/agents/plan-critic.md +13 -18
  2. package/.agents/agents/story-worker.md +25 -33
  3. package/.agents/docs/agentrc-reference.json +0 -30
  4. package/.agents/docs/configuration.md +8 -28
  5. package/.agents/docs/execution-reference.md +5 -5
  6. package/.agents/docs/quality-gates.md +8 -7
  7. package/.agents/instructions.md +9 -10
  8. package/.agents/schemas/agentrc.schema.json +9 -185
  9. package/.agents/schemas/story-deliver-terminal.schema.json +1 -1
  10. package/.agents/scripts/acceptance-eval.js +107 -17
  11. package/.agents/scripts/ceremony-derive.js +191 -0
  12. package/.agents/scripts/check-context-budget.js +28 -33
  13. package/.agents/scripts/check-cyclomatic.js +4 -3
  14. package/.agents/scripts/deliver-light.js +31 -94
  15. package/.agents/scripts/evidence-gate.js +17 -1
  16. package/.agents/scripts/lib/audit-suite/checklist-threading.js +15 -2
  17. package/.agents/scripts/lib/baselines/coverage-updater-cli.js +110 -0
  18. package/.agents/scripts/lib/baselines/crap-preview-scan.js +25 -0
  19. package/.agents/scripts/lib/baselines/crap-updater-cli.js +223 -0
  20. package/.agents/scripts/lib/bdd-scenario-budget.js +21 -3
  21. package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +0 -1
  22. package/.agents/scripts/lib/close-validation/gates.js +52 -1
  23. package/.agents/scripts/lib/config/acceptance-eval.js +25 -57
  24. package/.agents/scripts/lib/config/delivery-routing.js +7 -33
  25. package/.agents/scripts/lib/config/explain.js +0 -19
  26. package/.agents/scripts/lib/config/limits.js +18 -78
  27. package/.agents/scripts/lib/config/quality.js +6 -3
  28. package/.agents/scripts/lib/config/runners.js +3 -2
  29. package/.agents/scripts/lib/config-settings-schema-delivery.js +15 -68
  30. package/.agents/scripts/lib/config-settings-schema-quality.js +0 -14
  31. package/.agents/scripts/lib/config-settings-schema.js +16 -143
  32. package/.agents/scripts/lib/crap-engine.js +35 -4
  33. package/.agents/scripts/lib/crap-utils.js +17 -1
  34. package/.agents/scripts/lib/cyclomatic-ceiling.js +19 -7
  35. package/.agents/scripts/lib/generated/agentrc-validator.js +1 -1
  36. package/.agents/scripts/lib/observability/runtime-friction.js +1 -1
  37. package/.agents/scripts/lib/observability/source-classifier.js +1 -0
  38. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +5 -4
  39. package/.agents/scripts/lib/orchestration/ceremony-routing.js +19 -73
  40. package/.agents/scripts/lib/orchestration/code-review.js +7 -3
  41. package/.agents/scripts/lib/orchestration/complexity-gate.js +46 -212
  42. package/.agents/scripts/lib/orchestration/file-assumptions.js +32 -17
  43. package/.agents/scripts/lib/orchestration/light-escalation.js +3 -3
  44. package/.agents/scripts/lib/orchestration/light-suitability.js +66 -233
  45. package/.agents/scripts/lib/orchestration/pinned-identifier-lint.js +137 -0
  46. package/.agents/scripts/lib/orchestration/plan-context.js +189 -387
  47. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +42 -153
  48. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +14 -70
  49. package/.agents/scripts/lib/orchestration/plan-persist/acceptance-handle-repair.js +107 -0
  50. package/.agents/scripts/lib/orchestration/plan-persist/changes-repair.js +305 -0
  51. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +138 -170
  52. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +128 -297
  53. package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +55 -0
  54. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +16 -65
  55. package/.agents/scripts/lib/orchestration/plan-persist/wave-serialisation.js +22 -35
  56. package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +36 -135
  57. package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +61 -223
  58. package/.agents/scripts/lib/orchestration/review-base-ref.js +138 -0
  59. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +5 -0
  60. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +37 -5
  61. package/.agents/scripts/lib/orchestration/single-story-close/phases/pre-gate-steps.js +46 -16
  62. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +6 -1
  63. package/.agents/scripts/lib/orchestration/story-close/context-budget-writeback.js +213 -0
  64. package/.agents/scripts/lib/orchestration/task-body-validator.js +10 -63
  65. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +33 -539
  66. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +21 -414
  67. package/.agents/scripts/lib/orchestration/ticket-validator.js +54 -118
  68. package/.agents/scripts/lib/orchestration/verify-credit.js +69 -24
  69. package/.agents/scripts/lib/story-body/body-format-lints.js +15 -85
  70. package/.agents/scripts/lib/story-body/story-body.js +54 -240
  71. package/.agents/scripts/lib/templates/decomposer-prompts.js +133 -121
  72. package/.agents/scripts/lib/test-isolate/cli-options.js +93 -0
  73. package/.agents/scripts/lib/test-isolate/progress-log.js +45 -0
  74. package/.agents/scripts/lib/test-isolate/render-report.js +97 -0
  75. package/.agents/scripts/lib/test-isolate/run-isolate.js +87 -0
  76. package/.agents/scripts/lib/test-run-credit.js +277 -0
  77. package/.agents/scripts/lib/wave-runner/footprint.js +48 -358
  78. package/.agents/scripts/lib/wave-runner/ready-set.js +6 -5
  79. package/.agents/scripts/lib/workers/crap-worker.js +32 -41
  80. package/.agents/scripts/plan-context.js +7 -9
  81. package/.agents/scripts/plan-critics.js +28 -54
  82. package/.agents/scripts/plan-persist.js +25 -68
  83. package/.agents/scripts/quality-preview.js +51 -0
  84. package/.agents/scripts/run-tests.js +12 -0
  85. package/.agents/scripts/stories-wave-tick.js +23 -45
  86. package/.agents/scripts/test-isolate.js +13 -180
  87. package/.agents/scripts/update-coverage-baseline.js +25 -70
  88. package/.agents/scripts/update-crap-baseline.js +19 -123
  89. package/.agents/skills/core/scope-triage/SKILL.md +3 -3
  90. package/.agents/workflows/audit-clean-code.md +4 -3
  91. package/.agents/workflows/helpers/acceptance-self-eval.md +41 -41
  92. package/.agents/workflows/helpers/code-quality-guardrails.md +4 -4
  93. package/.agents/workflows/helpers/code-review.md +2 -3
  94. package/.agents/workflows/helpers/deliver-digest.md +46 -55
  95. package/.agents/workflows/helpers/deliver-light.md +40 -105
  96. package/.agents/workflows/helpers/deliver-reference.md +1 -1
  97. package/.agents/workflows/helpers/deliver-story-reference.md +54 -55
  98. package/.agents/workflows/helpers/deliver-story.md +10 -13
  99. package/.agents/workflows/helpers/plan-reference.md +163 -221
  100. package/.agents/workflows/mandrel-plan.md +31 -40
  101. package/.agents/workflows/memory-consolidate.md +9 -13
  102. package/docs/CHANGELOG.md +36 -0
  103. package/lib/cli/registry.js +98 -2
  104. package/lib/migrations/index.js +4 -0
  105. package/lib/migrations/steps/2.57.0-retire-delivery-limit-knobs.js +45 -0
  106. package/lib/migrations/steps/2.57.0-retire-planning-limit-knobs.js +59 -0
  107. package/package.json +1 -1
  108. package/.agents/scripts/lib/framework-version.js +0 -39
  109. package/.agents/scripts/lib/orchestration/consolidation-precondition.js +0 -223
  110. package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +0 -97
  111. package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +0 -26
  112. package/.agents/scripts/lib/orchestration/spec-budget.js +0 -89
  113. package/.agents/scripts/lib/orchestration/spec-spill.js +0 -74
  114. package/.agents/scripts/lib/orchestration/verify-tier-repair.js +0 -107
@@ -0,0 +1,137 @@
1
+ /**
2
+ * pinned-identifier-lint.js — the `pinned-identifier` advisory lint over a
3
+ * draft Story's `acceptance[]` (Story #5323).
4
+ *
5
+ * `acceptance[]` is the Story's **binding** contract and `changes[]` only an
6
+ * advisory sketch the deliverer may revise, so an acceptance item naming an
7
+ * internal symbol pins something the executor is free to rename out from
8
+ * under it. The story-author prompt has always said so; nothing surfaced a
9
+ * violation, which left the rule enforced only by the authoring model
10
+ * remembering it.
11
+ *
12
+ * The classifier lives in its own module because its vocabulary is its own:
13
+ * four token grammars and a call-suffix strip that the sibling prose lint in
14
+ * `plan-text-hygiene.js` shares nothing with.
15
+ *
16
+ * Advisory by contract: findings are deterministic text for the persist
17
+ * dry-run's warning list. They never gate persist and spawn nothing.
18
+ *
19
+ * Pure, synchronous, no I/O.
20
+ *
21
+ * @module lib/orchestration/pinned-identifier-lint
22
+ */
23
+
24
+ /**
25
+ * An inline code span carrying one of these is naming something other than a
26
+ * source identifier, and is never a pinned identifier:
27
+ *
28
+ * - `/` — a file path or a glob (`src/app.js`, `tests/x/*.spec.ts`);
29
+ * - `.` — a dotted path, a filename, or a config key
30
+ * (`delivery.routing.closeAndLand`, `story-body.js`);
31
+ * - `:` — a label (`agent::ready`, `type::story`);
32
+ * - `-` — a kebab token: a `data-testid` value, a slug, a package name, or
33
+ * a CLI flag (`--dry-run`);
34
+ * - whitespace — an argv shape, so a command (`npm run lint`);
35
+ * - `[` / `]` — a field reference (`acceptance[]`).
36
+ */
37
+ const NON_IDENTIFIER_MARKERS = /[/.:\-\s[\]]/;
38
+
39
+ /** A bare source identifier, with an optional call suffix stripped. */
40
+ const BARE_IDENTIFIER_RE = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
41
+
42
+ /**
43
+ * An UPPER_SNAKE token. Exempt by contract: an environment variable and an
44
+ * internal constant are the same shape, and warning on every `DATABASE_URL`
45
+ * to catch the occasional pinned constant trades a real class of false
46
+ * positives for a marginal gain.
47
+ */
48
+ const UPPER_SNAKE_RE = /^[A-Z0-9_$]+$/;
49
+
50
+ /**
51
+ * A case transition (`staffCan`, `MyCalendarBoard`, `TimeGrid`) — the
52
+ * signature that separates a source identifier from a prose word a criterion
53
+ * legitimately quotes (`landed`, `pending`, `main`).
54
+ */
55
+ const CASE_TRANSITION_RE = /[a-z][A-Z]/;
56
+
57
+ /** The remedy, either side of the identifiers a finding names. */
58
+ const MESSAGE_HEAD = 'Acceptance item pins the internal identifier(s) ';
59
+ const MESSAGE_TAIL =
60
+ '; `changes[]` is an advisory sketch the deliverer may reshape, so assert ' +
61
+ 'the observable behaviour instead of the symbol that implements it.';
62
+
63
+ /**
64
+ * Collect the inline code spans of one acceptance item.
65
+ *
66
+ * @param {string} item
67
+ * @returns {string[]}
68
+ */
69
+ function codeSpans(item) {
70
+ return [...String(item ?? '').matchAll(/`([^`\n]+)`/g)].map((m) => m[1]);
71
+ }
72
+
73
+ /**
74
+ * Decide whether one code span pins a source identifier: a bare token
75
+ * carrying a case transition, with no separator that would make it a path, a
76
+ * label, a kebab token, a flag or a command, and not an UPPER_SNAKE name.
77
+ *
78
+ * Deliberately conservative in one direction only: a false positive costs a
79
+ * warning line the author dismisses, while a false negative on a path, a
80
+ * testid or a command would train the author to ignore the lint.
81
+ *
82
+ * @param {string} span
83
+ * @returns {boolean}
84
+ */
85
+ function isPinnedIdentifier(span) {
86
+ const token = span.trim().replace(/\(\s*\)$/, '');
87
+ return (
88
+ !NON_IDENTIFIER_MARKERS.test(token) &&
89
+ BARE_IDENTIFIER_RE.test(token) &&
90
+ !UPPER_SNAKE_RE.test(token) &&
91
+ CASE_TRANSITION_RE.test(token)
92
+ );
93
+ }
94
+
95
+ /**
96
+ * The authored `acceptance[]` of one draft Story.
97
+ *
98
+ * It is authored at the ticket's top level — the machine contract the
99
+ * validators read — and synced into the body only at assembly, so the top
100
+ * level wins; the parsed body covers a draft that carries it inline.
101
+ *
102
+ * @param {object} story The raw draft ticket.
103
+ * @param {object} body Its parsed body.
104
+ * @returns {string[]}
105
+ */
106
+ function resolveAcceptance(story, body) {
107
+ if (Array.isArray(story?.acceptance)) return story.acceptance;
108
+ return Array.isArray(body?.acceptance) ? body.acceptance : [];
109
+ }
110
+
111
+ /**
112
+ * Evaluate the lint over one draft Story — one finding per offending
113
+ * acceptance item, naming every identifier it pinned.
114
+ *
115
+ * @param {object} story The raw draft ticket.
116
+ * @param {object} body Its parsed body.
117
+ * @param {string} slug
118
+ * @param {(text: string) => string} excerpt Evidence truncator, shared with
119
+ * the sibling lints so every finding excerpts alike.
120
+ * @returns {Array<{ kind: 'pinned-identifier', slug: string, evidence: string, message: string }>}
121
+ */
122
+ export function findPinnedIdentifiers(story, body, slug, excerpt) {
123
+ const acceptance = resolveAcceptance(story, body);
124
+ const findings = [];
125
+ for (const item of acceptance) {
126
+ const pinned = codeSpans(item).filter(isPinnedIdentifier);
127
+ if (pinned.length === 0) continue;
128
+ const named = pinned.map((name) => `\`${name}\``).join(', ');
129
+ findings.push({
130
+ kind: 'pinned-identifier',
131
+ slug,
132
+ evidence: excerpt(String(item ?? '')),
133
+ message: `${MESSAGE_HEAD}${named}${MESSAGE_TAIL}`,
134
+ });
135
+ }
136
+ return findings;
137
+ }