@event4u/agent-config 14.14.1 → 14.15.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.
@@ -34,10 +34,10 @@
34
34
  "note": "The nine active non-draft roadmaps that predate the `relates:` requirement (road-to-agentic-engineering-assurance, road-to-component-library-lifecycle, road-to-council-evidence-integrity, road-to-frontend-fidelity-calibration, road-to-monorepo-scope-and-detection, road-to-observability-plate, road-to-role-scoped-spawn-profiles, road-to-skill-delivery-over-mcp, road-to-standing-payload-diet). This is a NEW obligation rather than a repaired scan root, and the ratchet is the point: `depends:` shipped in the template with nothing requiring it and measured 0 adoption, so requiring `relates:` retroactively across the estate would be an owner-reserved write with no analysis behind the edges it would have to invent (held as step 4.3, deferred). Clearing an entry here is one roadmap at a time: run `agent-config roadmap:context` on it, write the rows the probe surfaces, and lower the count."
35
35
  },
36
36
  "check_source_size_budget": {
37
- "count": 18205,
37
+ "count": 18193,
38
38
  "landed": "2026-09-03",
39
39
  "note": "Lowered 18,245 -> 18,230 on 2026-09-02 by drain/publication-integrity-option-a. Phase 2 Option A moved the authoring instruction out of the generator: release.ts, which sits ~530 lines PAST the 1500 cap so every line there costs one excess, loses the comment emission, a 16-line HEAD_DEFAULT doc block and its alias const, and gains a shorter writer docstring. The doc block moved to _lib/release_material.ts, which is 289 lines and therefore UNDER the cap, so the same prose now costs nothing. Net -15. The branch first came in at +8 and paid its own way down rather than raising the baseline.",
40
- "reason": "Lowered 18,230 -> 18,209 on 2026-09-03 by drain/artifact-location. `doctor --strict` needed 16 lines of integration wiring in cmd_doctor.ts, which sits ~2,100 lines PAST the 1500 cap so every line there costs one excess. The branch first came in at +137 and paid its own way down rather than raising the baseline: the strict semantics, threshold, kill switch, payload helper and argv fragments moved to _cli/_doctor_strict.ts (~160 lines, under the cap, costs nothing), taking it to +15; then the 37-line drift renderer moved to _cli/_doctor_emit.ts. Net -21. The renderer was chosen deliberately: pure rendering, two dependencies, no argparse involvement and therefore none of the byte-parity risk the parser surface carries against the retired Python implementation; nothing outside cmd_doctor.ts imported it. An AI council on the residual split (a: raise by 15 / d: descope the feature); neither was taken, because a parallel branch demonstrated the same day that paying down is achievable in this codebase, which is the evidence the split lacked. This gate's own test comment prescribes it: a commit that splits a god-file lowers the excess and must carry the lowered baseline. MERGE RECONCILIATION 2026-09-03, 18,209 -> 18,205: drain/wired-instruments and drain/artifact-location each lowered from the SAME 18,230 base in parallel -- the branch to 18,226 (net -4, run_continuation_hook.ts's termination ladder moved to _lib/continuation_ladder.ts and runtime_journal.ts's prose to _lib/outcome_vocabularies.ts, both under the cap) and main to 18,209 (net -21, the doctor --strict split above). Taking either side alone is wrong in a different direction: main's value silently discards the branch's earned -4, and the branch's value RAISES the baseline against main and weakens the gate. The committed number is neither -- it is the gate's own output on the merged tree, where both reductions apply. THIS LOCAL READING IS ADMISSIBLE HERE, and the discriminator matters because this file's ci-parity:local-only entry records a 165 -> 164 lowering that was reverted for exactly the opposite case: that count depends on how the environment resolves the projection surface, whereas this gate walks only SOURCE_ROOTS = ['src'] (check_source_size_budget.ts:88) counting excess lines over the 1500 ceiling, and `git status --porcelain -uall -- src/` reported ZERO untracked files, so a clean CI checkout of this commit measures the same 18,205. If CI reads anything else, CI's number is the correct one and this note is the record of why."
40
+ "reason": "Lowered 18,230 -> 18,209 on 2026-09-03 by drain/artifact-location. `doctor --strict` needed 16 lines of integration wiring in cmd_doctor.ts, which sits ~2,100 lines PAST the 1500 cap so every line there costs one excess. The branch first came in at +137 and paid its own way down rather than raising the baseline: the strict semantics, threshold, kill switch, payload helper and argv fragments moved to _cli/_doctor_strict.ts (~160 lines, under the cap, costs nothing), taking it to +15; then the 37-line drift renderer moved to _cli/_doctor_emit.ts. Net -21. The renderer was chosen deliberately: pure rendering, two dependencies, no argparse involvement and therefore none of the byte-parity risk the parser surface carries against the retired Python implementation; nothing outside cmd_doctor.ts imported it. An AI council on the residual split (a: raise by 15 / d: descope the feature); neither was taken, because a parallel branch demonstrated the same day that paying down is achievable in this codebase, which is the evidence the split lacked. This gate's own test comment prescribes it: a commit that splits a god-file lowers the excess and must carry the lowered baseline. MERGE RECONCILIATION 2026-09-03, 18,209 -> 18,205: drain/wired-instruments and drain/artifact-location each lowered from the SAME 18,230 base in parallel -- the branch to 18,226 (net -4, run_continuation_hook.ts's termination ladder moved to _lib/continuation_ladder.ts and runtime_journal.ts's prose to _lib/outcome_vocabularies.ts, both under the cap) and main to 18,209 (net -21, the doctor --strict split above). Taking either side alone is wrong in a different direction: main's value silently discards the branch's earned -4, and the branch's value RAISES the baseline against main and weakens the gate. The committed number is neither -- it is the gate's own output on the merged tree, where both reductions apply. THIS LOCAL READING IS ADMISSIBLE HERE, and the discriminator matters because this file's ci-parity:local-only entry records a 165 -> 164 lowering that was reverted for exactly the opposite case: that count depends on how the environment resolves the projection surface, whereas this gate walks only SOURCE_ROOTS = ['src'] (check_source_size_budget.ts:88) counting excess lines over the 1500 ceiling, and `git status --porcelain -uall -- src/` reported ZERO untracked files, so a clean CI checkout of this commit measures the same 18,205. If CI reads anything else, CI's number is the correct one and this note is the record of why. LOWERED 18,205 -> 18,193 on 2026-09-03 by fix/release-curation-ask. The change adds a fifth publication guard, and its own additions landed at +10 excess: release.ts 2,008 -> 2,018, every line of which is past the 1500 cap. Paid down rather than baselined, in the two ways this gate's doctrine prescribes. The guard's rationale (~13 lines of docstring, including why prMerged is a parameter rather than a call-site if) lives in release_publication.ts, 915 lines and therefore UNDER the cap, so the prose costs nothing; and the two pure text helpers _splitlines and _rstrip moved out of release.ts into release_env.ts (333 lines, also under the cap), taking release.ts to 1,996 -- 12 BELOW where it started. The branch came in at +10 and leaves at -12. Recorded while moving them: _splitlines is duplicated a third and fourth time at adoption_report.ts:106 and readme_linter.ts:418; collapsing all three onto one definition touches three modules and was left out of this change rather than done silently."
41
41
  },
42
42
  "ci-parity:local-only": {
43
43
  "count": 165,
@@ -11,7 +11,6 @@
11
11
  "brand-source-of-truth.md",
12
12
  "broken-access-control.md",
13
13
  "cli-output-handling.md",
14
- "code-comment-discipline.md",
15
14
  "command-suggestion-policy.md",
16
15
  "commit-conventions.md",
17
16
  "commit-policy.md",
@@ -279,9 +279,57 @@ export function derive_categories(commits: readonly SpanCommit[]): Record<string
279
279
  *
280
280
  * A label with no evidence is omitted, so the caller's `_none_` default still
281
281
  * applies where `_none_` is the true answer. One line per label keeps the
282
- * rendered head inside its cap; SHA citations are capped at `DERIVED_SHA_CAP`
283
- * with an explicit remainder count rather than a silent truncation.
282
+ * rendered head inside its cap; citations are capped at `DERIVED_SHA_CAP` with
283
+ * an explicit remainder count rather than a silent truncation.
284
+ *
285
+ * **PUBLISHABLE BY DEFAULT since 2026-09-03, and this is the third position
286
+ * this line has held.** It shipped `DERIVED_MARKER` plus a CATEGORY
287
+ * DESCRIPTION — "rule/schema diffs, breaking commits or removed public surface
288
+ * in 5a3b7c5". The 2026-09-01 flip then made that marker a hard refusal, and
289
+ * the combination had a consequence nobody priced: every release of this
290
+ * package touches `src/rules/` or `src/scripts/schemas/`, so **Behaviour
291
+ * changes** is always substantiated, so the generator always wrote a line the
292
+ * gate always refused. Every release halted, by construction. That was
293
+ * recorded as "the cadence the flip chose"; the maintainer's instruction of
294
+ * 2026-09-03 — *"fix the bug so this stops happening"* — is the authority for
295
+ * removing it.
296
+ *
297
+ * The fix is not a weaker gate, and it is not the marker moving somewhere
298
+ * cheaper (that was 2026-09-03's first attempt, `guard_release_curation`,
299
+ * which relocated the halt without removing it). It is the writer no longer
300
+ * emitting text that cannot ship. Two changes, and the first is what makes the
301
+ * second honest:
302
+ *
303
+ * 1. The line now states the COMMIT SUBJECTS behind each category, not the
304
+ * name of the category's own detection rule. "hooks:effect reports whether
305
+ * a bound concern fires (b0a03a7)" is a claim a reader can use; "rule/schema
306
+ * diffs in b0a03a7" is a restatement of why the classifier fired.
307
+ * 2. `DERIVED_MARKER` is gone from the emission, so nothing unpublishable is
308
+ * ever written and no release halts on the writer's own output.
309
+ *
310
+ * What is deliberately NOT relaxed: `highlight_contradictions` still refuses a
311
+ * human editing a substantiated line down to `_none_`, which is the failure the
312
+ * false 9.13.0 and 9.14.0 heads actually were; and the marker constant and its
313
+ * four guard sites stay, now covering only a marker somebody writes BY HAND.
314
+ * The honest cost of this change, stated rather than left to be discovered: the
315
+ * head is a categorised view of the span rather than curated prose, and it
316
+ * ships without a human having read it. An operator who wants better prose
317
+ * still edits it — they are no longer STOPPED until they do.
284
318
  */
319
+ /**
320
+ * A commit subject reduced to the claim inside it.
321
+ *
322
+ * Drops the conventional-commit `type(scope):` prefix, because "feat(hooks):"
323
+ * is metadata about the commit and the changelog's own commit lists already
324
+ * carry it — what a highlight line needs is the sentence after the colon. Keeps
325
+ * the subject otherwise verbatim: rewording it here would make the head a
326
+ * paraphrase of the span rather than a citation of it, and the whole point of
327
+ * this module is that the two cannot disagree.
328
+ */
329
+ function _claim_text(subject: string): string {
330
+ return subject.replace(/^[a-z]+(?:\([^)]*\))?!?:\s*/u, '').trim();
331
+ }
332
+
285
333
  export function render_derived_head_values(
286
334
  hits: Readonly<Record<string, readonly CategoryHit[]>>,
287
335
  ): Record<string, string> {
@@ -292,11 +340,19 @@ export function render_derived_head_values(
292
340
  if (!reason || ev.length === 0) {
293
341
  continue;
294
342
  }
295
- const shas = ev.map((h) => h.sha.slice(0, 7));
296
- const shown = shas.slice(0, DERIVED_SHA_CAP);
297
- const remainder = shas.length - shown.length;
298
- const more = remainder > 0 ? ` +${remainder} more` : '';
299
- out[label] = `${DERIVED_MARKER} ${reason} in ${shown.join(', ')}${more}.`;
343
+ const shown = ev.slice(0, DERIVED_SHA_CAP);
344
+ const remainder = ev.length - shown.length;
345
+ const more = remainder > 0 ? `; +${String(remainder)} more` : '';
346
+ const cited = shown
347
+ .map((h) => `${_claim_text(h.text)} (${h.sha.slice(0, 7)})`)
348
+ .join('; ');
349
+ // `reason` still names the classifier that fired, kept as the fallback
350
+ // for a hit whose subject renders empty after trimming — a subject that
351
+ // is nothing but a conventional-commit prefix. Without it the line
352
+ // would read "( b0a03a7)".
353
+ out[label] = cited ? `${cited}${more}.` : `${reason} in ${shown
354
+ .map((h) => h.sha.slice(0, 7))
355
+ .join(', ')}${more}.`;
300
356
  }
301
357
  return out;
302
358
  }