@event4u/agent-config 10.1.0 → 10.3.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/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +110 -167
- package/README.md +1 -1
- package/dist/agent-src/commands/analyze/reference-repo.md +62 -0
- package/dist/agent-src/commands/roadmap/create.md +4 -1
- package/dist/agent-src/commands/roadmap/next.md +38 -0
- package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +22 -1
- package/dist/agent-src/contexts/contracts/frugality-charter.md +1 -1
- package/dist/agent-src/personas/advisors/first-principles.md +6 -0
- package/dist/agent-src/rules/active-remediation.md +53 -2
- package/dist/agent-src/rules/code-provenance.md +66 -4
- package/dist/agent-src/rules/content-quoting-floor.md +6 -0
- package/dist/agent-src/rules/context-hygiene.md +39 -0
- package/dist/agent-src/rules/design-fidelity.md +49 -3
- package/dist/agent-src/rules/token-budget-discipline.md +3 -2
- package/dist/agent-src/rules/token-efficiency.md +22 -0
- package/dist/agent-src/skills/ai-council/SKILL.md +28 -6
- package/dist/agent-src/skills/condense-memory/SKILL.md +1 -1
- package/dist/agent-src/skills/design-review/references/verification-automation.md +23 -1
- package/dist/agent-src/skills/fe-design/SKILL.md +27 -3
- package/dist/agent-src/skills/judge-synthesis/SKILL.md +30 -0
- package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +11 -0
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +9 -9
- package/dist/agent-src/skills/skill-writing/SKILL.md +4 -0
- package/dist/agent-src/skills/token-optimizer/SKILL.md +5 -1
- package/dist/agent-src/templates/agent-settings.md +12 -28
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +2 -2
- package/dist/agent-src/templates/persona.md +26 -0
- package/dist/agent-src/templates/roadmaps.md +27 -7
- package/dist/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -1
- package/dist/agent-src/templates/skill.md +35 -1
- package/dist/cli/commands/commands.candidates.test.js +257 -0
- package/dist/cli/commands/commands.candidates.test.js.map +1 -0
- package/dist/cli/commands/commands.js +199 -0
- package/dist/cli/commands/commands.js.map +1 -1
- package/dist/cli/main.js +1 -0
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/registry.js +2 -2
- package/dist/cli/registry.js.map +1 -1
- package/dist/cli-delegate/{chunk-3JUTT26I.js → chunk-6ENSXSBW.js} +1 -1
- package/dist/cli-delegate/{chunk-TVGXH7VA.js → chunk-6LOPHJLD.js} +1 -1
- package/dist/cli-delegate/{chunk-XT2YTJCZ.js → chunk-AYKQGIBG.js} +4 -0
- package/dist/cli-delegate/{chunk-HJSKTMIF.js → chunk-BV3WR67D.js} +3 -19
- package/dist/cli-delegate/{chunk-HTIU3W56.js → chunk-BWMXLD4B.js} +6 -2
- package/dist/cli-delegate/{chunk-2H5SE7DU.js → chunk-FV34EGEX.js} +166 -39
- package/dist/cli-delegate/{chunk-XTC5ARB6.js → chunk-IR3IVRVC.js} +7 -2
- package/dist/cli-delegate/{chunk-LRXJK6GN.js → chunk-JMQZ7MM5.js} +1 -1
- package/dist/cli-delegate/{chunk-NX5AXSLD.js → chunk-X3VOARZD.js} +3 -3
- package/dist/cli-delegate/cmd_analyze_session.js +1 -1
- package/dist/cli-delegate/cmd_brand_status.js +1 -1
- package/dist/cli-delegate/cmd_conformance.js +881 -204
- package/dist/cli-delegate/cmd_doctor.js +3 -3
- package/dist/cli-delegate/cmd_explain.js +2 -2
- package/dist/cli-delegate/cmd_export.js +4 -4
- package/dist/cli-delegate/cmd_handoff.js +6 -5
- package/dist/cli-delegate/cmd_mcp_available.js +1 -1
- package/dist/cli-delegate/cmd_migrate.js +2 -2
- package/dist/cli-delegate/cmd_packs_active.js +2 -2
- package/dist/cli-delegate/cmd_prune.js +4 -4
- package/dist/cli-delegate/cmd_route_audit.js +2 -2
- package/dist/cli-delegate/cmd_route_explain.js +1 -1
- package/dist/cli-delegate/cmd_session_recycle.js +44 -9
- package/dist/cli-delegate/cmd_settings_get.js +2 -2
- package/dist/cli-delegate/cmd_settings_migrate.js +4 -4
- package/dist/cli-delegate/cmd_settings_set.js +2 -2
- package/dist/cli-delegate/cmd_sync.js +4 -4
- package/dist/cli-delegate/cmd_uninstall.js +4 -4
- package/dist/cli-delegate/cmd_update.js +1 -1
- package/dist/cli-delegate/cmd_upgrade.js +1 -1
- package/dist/cli-delegate/cmd_validate.js +4 -4
- package/dist/cli-delegate/cmd_versions.js +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +21 -21
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +1 -1
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +2 -2
- package/dist/discovery/trust-report.md +1 -1
- package/dist/discovery/workspaces.json +2 -2
- package/dist/hooks/dispatch.js +204 -44
- package/dist/install/install.mjs +9 -21
- package/dist/mcp/registry-manifest.json +2 -2
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +1337 -490
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/agent_settings.js +25 -2
- package/dist/scripts/_lib/agent_settings.js.map +1 -1
- package/dist/scripts/_lib/compile_time_toggles.js +4 -3
- package/dist/scripts/_lib/compile_time_toggles.js.map +1 -1
- package/dist/server/io/yamlIO.js +0 -2
- package/dist/server/io/yamlIO.js.map +1 -1
- package/dist/server/schemas/settings.js +3 -9
- package/dist/server/schemas/settings.js.map +1 -1
- package/dist/shared/settingsClasses.js +64 -2
- package/dist/shared/settingsClasses.js.map +1 -1
- package/dist/ui/assets/{index-B5qGYOJo.js → index-5fXOHoVh.js} +2 -2
- package/dist/ui/assets/index-5fXOHoVh.js.map +1 -0
- package/dist/ui/index.html +1 -1
- package/docs/contracts/settings-classes.md +307 -145
- package/docs/guidelines/agent-infra/active-remediation-mechanics.md +54 -0
- package/docs/guidelines/agent-infra/layered-settings.md +1 -2
- package/docs/guidelines/agent-infra/symptom-driven-harvest-loop.md +104 -0
- package/docs/guidelines/design-antipatterns.md +79 -10
- package/docs/guidelines/design-fidelity-mechanics.md +120 -2
- package/package.json +1 -1
- package/src/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -1
- package/src/config/agent-settings.template.yml +12 -30
- package/src/config/gate-coverage.yml +42 -8
- package/src/config/gate-violation-baselines.json +15 -3
- package/src/config/profiles/balanced.ini +0 -2
- package/src/config/profiles/full.ini +1 -3
- package/src/config/profiles/minimal.ini +0 -2
- package/src/config/review-prompt-binding-baseline.json +19 -0
- package/src/config/rule-enforcement-baseline.json +0 -1
- package/src/scripts/_cli/cmd_session_recycle.ts +66 -9
- package/src/scripts/_cli/handoff_sessions.ts +3 -2
- package/src/scripts/_dispatch.bash +1 -0
- package/src/scripts/_lib/agent_settings.ts +25 -2
- package/src/scripts/_lib/bench_telegraph.ts +1 -1
- package/src/scripts/_lib/cc_transcript.ts +25 -0
- package/src/scripts/_lib/compile_time_toggles.ts +4 -3
- package/src/scripts/ai_council/clients.ts +243 -34
- package/src/scripts/cache_realization_report.ts +3 -2
- package/src/scripts/check_ci_local_parity.ts +60 -6
- package/src/scripts/check_review_prompt_binding.ts +553 -0
- package/src/scripts/check_rule_projection_integrity.ts +3 -1
- package/src/scripts/check_suppression_hygiene.ts +19 -3
- package/src/scripts/conformance_scan.ts +282 -9
- package/src/scripts/cost/track.mjs +10 -4
- package/src/scripts/council_cli.ts +33 -3
- package/src/scripts/design_slop_rules.test.ts +37 -6
- package/src/scripts/design_slop_rules.ts +150 -22
- package/src/scripts/dispatch_r2_reviewer.ts +15 -1
- package/src/scripts/external_sources_denylist.json +3 -1
- package/src/scripts/hook_manifest.yaml +17 -6
- package/src/scripts/hooks/block_unauthorized_git.ts +54 -8
- package/src/scripts/hooks/delegation_nudge_hook.ts +33 -8
- package/src/scripts/hooks/evidence_independence.ts +61 -9
- package/src/scripts/hooks/session_eol_hook.ts +123 -3
- package/src/scripts/hooks/turn_end_gate_hook.ts +31 -0
- package/src/scripts/hooks/ui_route_nudge_hook.ts +55 -2
- package/src/scripts/lint_design_antipattern_parity.ts +201 -0
- package/src/scripts/lint_harvest_provenance.ts +483 -0
- package/src/scripts/lint_settings_classes.ts +273 -11
- package/src/scripts/lint_skill_router_head.ts +254 -0
- package/src/scripts/lint_symptom_intake.ts +241 -0
- package/src/scripts/report_consultation_rate.ts +128 -2
- package/src/scripts/report_skill_activation.ts +6 -4
- package/src/scripts/report_skill_obligation_violations.ts +2 -1
- package/src/scripts/run_skill_evals.ts +10 -5
- package/src/scripts/schemas/persona.schema.json +8 -0
- package/src/scripts/schemas/provenance-harvest.schema.json +39 -0
- package/src/scripts/sweep_dead_scan_roots.ts +51 -0
- package/src/server/io/yamlIO.ts +0 -2
- package/src/server/schemas/settings.ts +3 -19
- package/src/shared/settingsClasses.ts +93 -2
- package/dist/ui/assets/index-B5qGYOJo.js.map +0 -1
|
@@ -56,6 +56,10 @@ INTENT
|
|
|
56
56
|
│ → cite markitdown (upstream: https://github.com/microsoft/markitdown)
|
|
57
57
|
│ Convert FIRST, then read the markdown — never paste raw binary.
|
|
58
58
|
│
|
|
59
|
+
├── Large file read (source / data / log already in the tree, > 800 lines)
|
|
60
|
+
│ → cite [token-efficiency § Size-gated reads](../../rules/token-efficiency.md)
|
|
61
|
+
│ (size → structural grep → bounded slice; never a full read on spec)
|
|
62
|
+
│
|
|
59
63
|
├── Repeated tool-call across N targets
|
|
60
64
|
│ → cite [token-efficiency](../../rules/token-efficiency.md)
|
|
61
65
|
│ (batch, parallelize, prune; one tool call > many)
|
|
@@ -81,7 +85,7 @@ INTENT
|
|
|
81
85
|
|---|---|---|---|
|
|
82
86
|
| `cli-output-handling` | `src/rules/cli-output-handling.md` | `verbose`, `tail`, `grep`, `CLI` | Wrap-tail-grep contract for any verbose command |
|
|
83
87
|
| `rtk-output-filtering` | `src/skills/rtk-output-filtering/SKILL.md` | `rtk`, `verbose`, `filter`, `wrap` | Project-local rtk filters; wrapper command |
|
|
84
|
-
| `token-efficiency` | `src/rules/token-efficiency.md` | `redirect`, `verbose`, `concise`, `tool` | Batch + parallelize tool calls; brevity floor |
|
|
88
|
+
| `token-efficiency` | `src/rules/token-efficiency.md` | `redirect`, `verbose`, `concise`, `tool`, `large file` | Batch + parallelize tool calls; brevity floor; size-gated reads (probe → grep → slice above 800 lines) |
|
|
85
89
|
| `agent-handoff` | `src/domains/meta/agent-handoff/command.md` | `handoff`, `fresh`, `chat`, `context`, `resume`, `session` | Session picker + generated handoff auto-seeding the next session |
|
|
86
90
|
| `direct-answers` | `src/rules/direct-answers.md` | `brevity`, `flattery`, `severity`, `tiered` | Iron-Law brevity floor (kernel) |
|
|
87
91
|
| `markitdown` | upstream: github.com/microsoft/markitdown | `PDF`, `DOCX`, `HTML`, `convert` | Document → markdown converter (authoritative-link only) |
|
|
@@ -176,12 +176,6 @@ chat_history:
|
|
|
176
176
|
# Logging granularity: per_turn | per_phase | per_tool
|
|
177
177
|
frequency: per_phase
|
|
178
178
|
|
|
179
|
-
# Max file size in KB before overflow handling kicks in
|
|
180
|
-
max_size_kb: 256
|
|
181
|
-
|
|
182
|
-
# Overflow behavior: rotate (drop oldest) | condense (summarize)
|
|
183
|
-
on_overflow: rotate
|
|
184
|
-
|
|
185
179
|
# --- Work-engine hooks ---
|
|
186
180
|
#
|
|
187
181
|
# Lifecycle hook surface of the `work_engine` Python engine
|
|
@@ -288,12 +282,6 @@ quality:
|
|
|
288
282
|
# never claimed as passing.
|
|
289
283
|
local_auto_run: false
|
|
290
284
|
|
|
291
|
-
# Wait for remote CI to finish on the PR / pipeline (true, false)
|
|
292
|
-
# true = poll GitHub check-runs / pipeline after push and report
|
|
293
|
-
# green / red before handing back
|
|
294
|
-
# false = push and hand back immediately (default)
|
|
295
|
-
wait_for_remote_ci: false
|
|
296
|
-
|
|
297
285
|
# --- Subagent orchestration ---
|
|
298
286
|
subagents:
|
|
299
287
|
# Model for implementer subagents (empty = same tier as the session model)
|
|
@@ -485,19 +473,18 @@ verbosity:
|
|
|
485
473
|
# safe task per Phase 10.3.
|
|
486
474
|
taskfile_command_echo: false
|
|
487
475
|
|
|
488
|
-
# --- Telegraph
|
|
476
|
+
# --- Telegraph condensation (output-side) ---
|
|
489
477
|
#
|
|
490
|
-
#
|
|
491
|
-
#
|
|
492
|
-
#
|
|
478
|
+
# One lever, deliberately: whether the telegraph-speak rule ships at all.
|
|
479
|
+
# The rule body states its own grammar scope — which carve-outs (numbered
|
|
480
|
+
# options, Iron-Law literals, code, paths) stay full prose — so there is no
|
|
481
|
+
# separate scope key to pin.
|
|
493
482
|
telegraph:
|
|
494
|
-
#
|
|
495
|
-
#
|
|
496
|
-
#
|
|
497
|
-
#
|
|
498
|
-
|
|
499
|
-
# aggressive = telegraph everywhere except Iron-Law literals
|
|
500
|
-
speak_scope: prose_only
|
|
483
|
+
# speak: false = DORMANT (the shipped default). The rule is omitted from
|
|
484
|
+
# dist/router.json entirely, so its body never reaches a host. That
|
|
485
|
+
# omission is what stops the cost. Set true only after an output-side
|
|
486
|
+
# bench clears the kill-criterion bar.
|
|
487
|
+
speak: false
|
|
501
488
|
|
|
502
489
|
telemetry:
|
|
503
490
|
artifact_engagement:
|
|
@@ -552,7 +539,7 @@ Personal and project-level settings (initial file written by
|
|
|
552
539
|
**Key paths use dot-notation** to denote nesting: `personal.user_name`
|
|
553
540
|
lives under `personal:` in YAML.
|
|
554
541
|
|
|
555
|
-
The `verbosity.*`
|
|
542
|
+
The `verbosity.*` rows are summarized below;
|
|
556
543
|
the canonical narrative lives in
|
|
557
544
|
[`docs/customization.md` § Verbosity](../../docs/customization.md#verbosity).
|
|
558
545
|
|
|
@@ -575,8 +562,6 @@ the canonical narrative lives in
|
|
|
575
562
|
| `code_style.docblocks` | `minimal`, `full` | `minimal` | Consumed by the `code-comment-discipline` rule. `minimal`: no signature-mirroring docblocks; docblocks only for machine-relevant precision (generics, array shapes) or genuine why-context. `full`: exported public library surface may carry one-line summary docblocks; the redundancy ban still holds. |
|
|
576
563
|
| `chat_history.enabled` | `true`, `false` | `true` | Persist chat events to `agents/runtime/.agent-chat-history` (JSONL) for crash recovery. |
|
|
577
564
|
| `chat_history.frequency` | `per_turn`, `per_phase`, `per_tool` | per profile | Logging granularity. Defaults: `minimal`→`per_turn`, `balanced`→`per_phase`, `full`→`per_tool`. |
|
|
578
|
-
| `chat_history.max_size_kb` | integer | per profile | Max file size before overflow handling. Defaults: `minimal`→`128`, `balanced`→`256`, `full`→`512`. |
|
|
579
|
-
| `chat_history.on_overflow` | `rotate`, `condense` | per profile | On overflow: `rotate` drops oldest entries; `condense` marks the file for summarization on the next turn. Defaults: `minimal`/`balanced`→`rotate`, `full`→`condense`. |
|
|
580
565
|
| `chat_history.text_limits.{user,agent,tool,phase}` | integer (chars) | `user=0`, `agent=5000`, `tool=200`, `phase=200` | Per-entry-type text-length cap. `0` = verbatim, no slice. `N > 0` = collapse whitespace, slice to N chars, append `" … [+K chars]"` so the log self-reports truncation. Defaults match `DEFAULT_TEXT_LIMITS` in `scripts/chat_history.ts`. |
|
|
581
566
|
| `hooks.concern_budget.{max_per_event,tier1_concerns,hard_fail}` | integer / list / `true`,`false` | `8` / `[]` / `false` | Concern budget gate for the hook dispatcher (`lint_hook_concern_budget`): caps concerns per (platform, event) cell, restricts `fail_closed: true` to the `tier1_concerns` allowlist, and `hard_fail: false` keeps the gate warn-only. |
|
|
582
567
|
| `hooks.injection_scan.enabled` | `true`, `false` | `false` | PostToolUse prompt-injection scanner: scans tool output for injection signatures and warns in context (exit 2) — never blocks. |
|
|
@@ -587,7 +572,6 @@ the canonical narrative lives in
|
|
|
587
572
|
| `roadmap.skip_pre_run_gate` | `true`, `false` | `true` | When `true` (default): `/roadmap:process-step\|phase\|full` skips the interactive pre-run summary and starts the loop immediately — the resolved roadmap, cadence, and council are surfaced inline so an unwanted pick can still be aborted. When `false`: the loop shows the pre-run summary with numbered options (Go / Different roadmap / Different scope / Toggle council / Abort) and waits. The gate is always shown — regardless of this flag — when the roadmap is ambiguous (multiple active, none named) or a scope / cadence conflict has no sensible default. |
|
|
588
573
|
| `roadmap.quality_cadence` | `end_of_roadmap`, `per_phase`, `per_step` | `end_of_roadmap` | When `/roadmap:process-step|phase|full` runs the project's quality pipeline — only relevant when `quality.local_auto_run` is `true`; when it is `false` (the default) local pipeline runs are suppressed at every cadence and remote CI is the gate. Default skips per-step / per-phase runs and gates only the final archival. `per_phase` runs once after every phase; `per_step` is the legacy verbose mode. Step checkboxes and the dashboard are always updated regardless. |
|
|
589
574
|
| `quality.local_auto_run` | `true`, `false` | `false` | When `false` (default): agent NEVER runs the project's quality pipeline (`task ci`, `make test`, `npm run check`, PHPStan, ECS, Rector, test suites) proactively — and does not ask. The user runs quality tools manually; remote CI is the authoritative gate. The agent runs one only on (1) an explicit ask this turn, (2) a concrete CI failure (run exactly that failing check), or (3) the new-gate carve-out. When `true`: opt-in legacy — agent runs the pipeline autonomously when work is ready for verification. **Carve-out**: NEW CI gates / smoke tests / test files MUST run locally regardless of this flag — without execution the new gate is unverified evidence. Iron Law `verify-before-complete` still applies; suppressed runs are surfaced ("quality gates delegated to remote CI"), never claimed as passing. |
|
|
590
|
-
| `quality.wait_for_remote_ci` | `true`, `false` | `false` | When `true`: after `git push`, the agent polls GitHub check-runs / pipeline status on the PR and reports green / red before handing back. When `false`: agent pushes and hands back immediately; the user inspects CI themselves (default — saves agent runtime and tokens). |
|
|
591
575
|
| `subagents.implementer_model` | model alias or empty | _(empty)_ | Model for implementer subagents. Empty = same tier as session model. See [subagent-configuration](../contexts/subagent-configuration.md). |
|
|
592
576
|
| `subagents.judge_model` | model alias or empty | _(empty)_ | Model for judge subagents. Empty = one tier above implementer (opus if sonnet, sonnet if haiku). |
|
|
593
577
|
| `subagents.max_parallel` | integer | `3` | Maximum parallel subagent invocations. `1` serializes. |
|
|
@@ -613,7 +597,7 @@ the canonical narrative lives in
|
|
|
613
597
|
| `verbosity.offer_council_in_delivery` | `true`, `false` | `false` | Offer "run AI Council on this?" inside delivery commands (`/feature-plan`, `/review-changes`, `/roadmap-create`). Council commands themselves are unaffected. |
|
|
614
598
|
| `verbosity.post_action_reports` | `off`, `minimal`, `full` | `minimal` | Multi-line status / summary blocks after a successful action. `off` = no report; `minimal` = one-line confirmation; `full` = bullet list. |
|
|
615
599
|
| `verbosity.intent_announcements` | `true`, `false` | `false` | Intent announcements ("Let me check…", "Now I will…", "Found it") in skill bodies. `false` = act and emit the result. |
|
|
616
|
-
| `telegraph.
|
|
600
|
+
| `telegraph.speak` | `true`, `false` | `false` | Whether the telegraph-speak rule ships at all. `false` (default) = dormant: the projector omits the rule from `dist/router.json`, so its body never reaches a host. The rule body states its own grammar scope and carve-outs (numbered options, Iron-Law literals, code, paths), so this is the only lever. |
|
|
617
601
|
| `telemetry.artifact_engagement.enabled` | `true`, `false` | `false` | Master switch for the artefact engagement log. Not in the shipped template — a missing `telemetry:` section means disabled (the recording rule no-ops). Default-off; zero file IO and zero token cost when `false`. Maintainer-targeted; consumers leave it off. |
|
|
618
602
|
| `telemetry.artifact_engagement.granularity` | `task`, `phase-step`, `tool-call` | `task` | Boundary at which events are recorded. `tool-call` is expensive — opt-in only. |
|
|
619
603
|
| `telemetry.artifact_engagement.record.consulted` | `true`, `false` | `true` | When `true`: record artefacts loaded into context. |
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
# 1. Package defaults (shipped by event4u/agent-config)
|
|
9
9
|
# 2. ~/.event4u/agent-config/agent-settings.yml — user-global DX-comfort
|
|
10
10
|
# defaults (whitelist: name, ide, rule_loading_tier, personal.bot_icon,
|
|
11
|
-
# personal.autonomy,
|
|
11
|
+
# personal.autonomy, memory.cadence). Created on opt-in via
|
|
12
12
|
# /onboard; project-local files always win. Legacy
|
|
13
13
|
# ~/.config/agent-config/agent-settings.yml is read as a fallback.
|
|
14
14
|
# 3. This file (.agent-project-settings.yml) — team defaults
|
|
@@ -39,7 +39,7 @@ schema_version: 1
|
|
|
39
39
|
# CI guard: a release bump of `package.json` must update this value
|
|
40
40
|
# in lockstep — see scripts/check_template_pin_drift.ts (road-to-
|
|
41
41
|
# portable-runtime-and-update-check P3.3).
|
|
42
|
-
agent_config_version: "10.
|
|
42
|
+
agent_config_version: "10.3.0"
|
|
43
43
|
|
|
44
44
|
# --- Project identity ---
|
|
45
45
|
project:
|
|
@@ -38,6 +38,32 @@ source: package
|
|
|
38
38
|
- mode optional — advisory link to a role-contracts workflow mode
|
|
39
39
|
- version required — semantic version; bump on breaking changes
|
|
40
40
|
- source required — "package" for personas shipped in dist/agent-src/
|
|
41
|
+
- sources optional — harvest_id list this persona may cite as external
|
|
42
|
+
doctrine (provenance/harvests.jsonl). OMIT IT unless you mean
|
|
43
|
+
one of the two scoped states; absent is the normal case and
|
|
44
|
+
the one every existing persona is in.
|
|
45
|
+
-->
|
|
46
|
+
|
|
47
|
+
<!-- SOURCES — an epistemic scope, not a bibliography.
|
|
48
|
+
|
|
49
|
+
A persona declares a voice. `sources:` optionally declares what that voice is
|
|
50
|
+
allowed to assert as *external doctrine* — as opposed to its own reasoning,
|
|
51
|
+
which needs no declaration and is never restricted.
|
|
52
|
+
|
|
53
|
+
| State | Meaning |
|
|
54
|
+
|---|---|
|
|
55
|
+
| field absent | Unscoped. Today's behaviour for every persona; nothing changes. |
|
|
56
|
+
| `sources: []` | Explicitly asserts nothing harvested — its positions are its own. |
|
|
57
|
+
| `sources: [id, …]` | May cite those harvest ids as doctrine. |
|
|
58
|
+
|
|
59
|
+
Every declared id must resolve to a row in `provenance/harvests.jsonl`;
|
|
60
|
+
`lint_harvest_provenance` fails an id that does not. Do NOT invent a row to
|
|
61
|
+
populate the field — an empty ledger and an absent field is the correct
|
|
62
|
+
resting state, and `[]` is for a persona where the distinction is worth
|
|
63
|
+
stating out loud.
|
|
64
|
+
|
|
65
|
+
This does not touch the Unique-Questions heuristic. A scoped persona still
|
|
66
|
+
earns its place by asking what nobody else asks.
|
|
41
67
|
-->
|
|
42
68
|
|
|
43
69
|
# {Role name}
|
|
@@ -197,9 +197,22 @@ Templates for roadmap files stored in `agents/roadmaps/` or `{module_root}/{Modu
|
|
|
197
197
|
"user approves", "looks good", or "sign-off".
|
|
198
198
|
- A **human gate** is allowed only when only a human can **decide or
|
|
199
199
|
authorize**: a Hard-Floor action (deploy, prod data/infra),
|
|
200
|
-
billable spend, or a
|
|
201
|
-
|
|
202
|
-
|
|
200
|
+
billable spend, or a decision bound to the user's own preference,
|
|
201
|
+
risk appetite, or product intent.
|
|
202
|
+
- A **contested technical decision is not a human gate while a
|
|
203
|
+
council is configured.** Which design is sound, whether a contract
|
|
204
|
+
still holds, which of N implementations to pick — these have
|
|
205
|
+
technical answers, and `decision_resolution` already classes a
|
|
206
|
+
contract or architecture change as `medium_impact → council`
|
|
207
|
+
(`docs/contracts/ai-council-config.md`). Authoring them as human
|
|
208
|
+
gates contradicts that classification and spends the user's
|
|
209
|
+
attention on a question the council answers. Run it, record the
|
|
210
|
+
verdict in the phase, and the gate becomes a step.
|
|
211
|
+
`agent-config council:status` says whether one is configured —
|
|
212
|
+
never infer it from the project tree (`council-availability`).
|
|
213
|
+
Record a genuine gate as a structured `## Blockers` entry
|
|
214
|
+
(rule 20) — never as an inline checkbox step scattered through
|
|
215
|
+
phases.
|
|
203
216
|
- An **external dependency is a blocker, not a human gate**, whenever
|
|
204
217
|
the agent can probe its status (CI run finished, package version
|
|
205
218
|
published, upstream PR merged, API reachable, DNS propagated):
|
|
@@ -216,10 +229,17 @@ Templates for roadmap files stored in `agents/roadmaps/` or `{module_root}/{Modu
|
|
|
216
229
|
`security-sensitive-stop`, and `commit-policy` fire at run time on
|
|
217
230
|
their own; an authored "STOP: confirm with user before X" duplicates
|
|
218
231
|
them and only adds interruptions.
|
|
219
|
-
Gate-test before writing any checkpoint
|
|
220
|
-
with a tool or command during the
|
|
221
|
-
|
|
222
|
-
|
|
232
|
+
Gate-test before writing any checkpoint, asked in this order:
|
|
233
|
+
1. *"Could the agent clear this with a tool or command during the
|
|
234
|
+
run?"* Yes → it is a step, not a gate.
|
|
235
|
+
2. *"Does it have a technical answer a council could reach?"* Yes →
|
|
236
|
+
it is a step whose first action runs the council.
|
|
237
|
+
3. Only what survives both — preference, risk appetite, product
|
|
238
|
+
intent, authorization, spend — becomes a structured blocker with
|
|
239
|
+
a decidable `Resolved when:`, owned by a human.
|
|
240
|
+
Stopping at question 1 is the authoring bug this ordering exists to
|
|
241
|
+
prevent: it sends every decision the agent cannot compute straight to
|
|
242
|
+
the user, including the ones the council exists to answer.
|
|
223
243
|
`task lint-roadmap-complexity` warns on human-gate step patterns,
|
|
224
244
|
human-gate phase headings, and human-approval exit criteria.
|
|
225
245
|
|
|
@@ -210,7 +210,6 @@ export const MERGEABLE_KEYS: readonly string[] = [
|
|
|
210
210
|
'memory.cadence',
|
|
211
211
|
'personal.bot_icon',
|
|
212
212
|
'personal.autonomy',
|
|
213
|
-
'telegraph.speak_scope',
|
|
214
213
|
// Knowledge-card global cross-project sharing is a USER-GLOBAL setting
|
|
215
214
|
// (ADR-100 / road-to-structure-grounding-v2). Whitelisted so the
|
|
216
215
|
// ~/.event4u/agent-config/agent-settings.yml values are honoured.
|
|
@@ -207,8 +207,42 @@ Before considering a skill complete, verify it passes all 5 checks:
|
|
|
207
207
|
- [ ] **K3: No obvious content** — doesn't teach the model what it already knows; only project-specific conventions and non-obvious patterns
|
|
208
208
|
- [ ] **K4: Has Gotcha section** — documents real failure patterns, not theoretical advice; seeded with 2-3 entries
|
|
209
209
|
- [ ] **K5: Has Output format** — numbered list with 2-4 deliverables describing what the skill produces
|
|
210
|
-
- [ ] **K6: Under 400 lines** — if larger,
|
|
210
|
+
- [ ] **K6: Under 400 lines** — if larger, restructure as a router head per the contract below (gate: `lint_skill_router_head`)
|
|
211
211
|
- [ ] **English only** — all content in English
|
|
212
212
|
- [ ] **No duplication** — doesn't repeat rules or guidelines that are already enforced elsewhere
|
|
213
213
|
- [ ] **No "Related skills" section for mid-tier / untiered skills** — the agent discovers them via `<available_skills>` descriptions; cross-links waste tokens. Senior-tier skills (`tier: senior`) MUST include the block per `skill-quality.md` § Senior-Tier Required Structure (linter-enforced).
|
|
214
214
|
|
|
215
|
+
## The router-head contract (K6, over the cap)
|
|
216
|
+
|
|
217
|
+
A `SKILL.md` over the 400-line cap restructures instead of growing. The shape:
|
|
218
|
+
|
|
219
|
+
| Part | Holds | Budget |
|
|
220
|
+
|---|---|---|
|
|
221
|
+
| **Entry head** — `SKILL.md` | When-to-use · a mode table · the routing that picks a mode · anything true across *all* modes | the cap |
|
|
222
|
+
| **Mode bodies** — `tasks/*.md` or `references/*.md` in the skill folder | One file per mode: the procedure, its examples, its tables | unbudgeted |
|
|
223
|
+
|
|
224
|
+
One binding constraint on the head: **it never inlines the procedure body for
|
|
225
|
+
more than one mode.** A head that carries mode A in full and points at modes
|
|
226
|
+
B and C has not been restructured — it has been relabelled, and the next edit
|
|
227
|
+
will grow it back.
|
|
228
|
+
|
|
229
|
+
### What this contract does NOT claim
|
|
230
|
+
|
|
231
|
+
It does not claim a token win. The host loads `SKILL.md` whole on trigger, and
|
|
232
|
+
whether it then follows a pointer into `tasks/` is host behaviour **nothing in
|
|
233
|
+
this tree observes**. Anyone proposing a retrofit of an existing oversized skill
|
|
234
|
+
on activation grounds is asserting something currently unmeasurable, and
|
|
235
|
+
ADR-202's lesson binds: an activation claim goes behind a measured instrument or
|
|
236
|
+
it is not made.
|
|
237
|
+
|
|
238
|
+
What the contract does is narrower and real: the 400-line cap was already this
|
|
239
|
+
repo's published position, sitting in a checklist nothing enforced. The gate
|
|
240
|
+
makes an existing contract true for **new** skills. Restructuring the current
|
|
241
|
+
offenders is a separate decision with its own evidence bar.
|
|
242
|
+
|
|
243
|
+
### Grandfathering
|
|
244
|
+
|
|
245
|
+
`lint_skill_router_head` carries a shrink-only allowlist seeded with the skills
|
|
246
|
+
that already exceed the cap. Entries may be removed, never added — a new
|
|
247
|
+
oversized monolith fails the gate rather than joining the list.
|
|
248
|
+
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `commands ls --candidates` — the surface-reduction report of roadmap step 3.4
|
|
3
|
+
* (`road-to-inbox-harvest-2026-08-b-release-integrity`).
|
|
4
|
+
*
|
|
5
|
+
* Every assertion derives its expectation from the synthetic input rather than
|
|
6
|
+
* pinning a literal the implementation happens to emit, so the suite cannot go
|
|
7
|
+
* green for the wrong reason. The report is deliberately built from the
|
|
8
|
+
* discovery manifest ALONE — no census file, no `utilization_report` import —
|
|
9
|
+
* and the tests pin exactly that: the honesty band must survive, and the
|
|
10
|
+
* ownership pointers must not be dropped by a later edit.
|
|
11
|
+
*/
|
|
12
|
+
import { describe, expect, it } from 'vitest';
|
|
13
|
+
import { buildCandidatesReport, renderCandidates, runCommandsLs, CANDIDATES_INCOMPATIBLE, REDUCTION_OWNERS, REPORT_ONLY_NOTICE, TEXT_LIST_CAP, } from './commands.js';
|
|
14
|
+
function cmd(slug, pack, extra = {}) {
|
|
15
|
+
return {
|
|
16
|
+
path: `src/domains/${pack}/${slug}/command.md`,
|
|
17
|
+
category: 'command',
|
|
18
|
+
name: slug,
|
|
19
|
+
slug,
|
|
20
|
+
pack,
|
|
21
|
+
tier: 2,
|
|
22
|
+
workspaces: [],
|
|
23
|
+
packs: [pack],
|
|
24
|
+
lifecycle: 'stable',
|
|
25
|
+
trust: { level: 'core', confidence: 'high', human_review_required: false },
|
|
26
|
+
install: { default: true, removable: false },
|
|
27
|
+
intent: `do ${slug}`,
|
|
28
|
+
...extra,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/** An artefact with NO `intent` key at all — distinct from `intent: ''`, and the
|
|
32
|
+
* shape `exactOptionalPropertyTypes` forces us to build by omission. */
|
|
33
|
+
function cmdWithoutIntent(slug, pack, visibility) {
|
|
34
|
+
const { intent: _omitted, ...rest } = cmd(slug, pack, { visibility });
|
|
35
|
+
return rest;
|
|
36
|
+
}
|
|
37
|
+
/** Mixed fixture: two absorbed-name commands, two undocumented, three packs of
|
|
38
|
+
* unequal weight. */
|
|
39
|
+
const FIXTURE = [
|
|
40
|
+
cmd('alpha', 'engineering-base', { visibility: 'visible' }),
|
|
41
|
+
cmd('bravo', 'engineering-base', { visibility: 'advanced' }),
|
|
42
|
+
cmd('charlie', 'engineering-base', { visibility: 'internal', intent: '' }),
|
|
43
|
+
cmd('delta', 'frontend-design', { visibility: 'visible', replaces: ['old-delta'] }),
|
|
44
|
+
cmd('echo', 'frontend-design', { visibility: 'internal', replaces: ['old-echo', 'older-echo'] }),
|
|
45
|
+
cmdWithoutIntent('foxtrot', 'finance-basic', 'advanced'),
|
|
46
|
+
];
|
|
47
|
+
describe('buildCandidatesReport', () => {
|
|
48
|
+
const report = buildCandidatesReport(FIXTURE);
|
|
49
|
+
it('counts the whole estate it was given', () => {
|
|
50
|
+
expect(report.total).toBe(FIXTURE.length);
|
|
51
|
+
});
|
|
52
|
+
it('partitions visibility exhaustively — the buckets sum to the total', () => {
|
|
53
|
+
const summed = Object.values(report.byVisibility).reduce((a, b) => a + b, 0);
|
|
54
|
+
expect(summed).toBe(FIXTURE.length);
|
|
55
|
+
});
|
|
56
|
+
it('collects the commands that ABSORBED prior names, named explicitly', () => {
|
|
57
|
+
// Named rather than recomputed from the implementation predicate: the
|
|
58
|
+
// first version of this bucket inverted the field's meaning, and a test
|
|
59
|
+
// that re-derives `(replaces ?? []).length > 0` certifies whatever the
|
|
60
|
+
// code does — including the inversion.
|
|
61
|
+
expect(report.absorbedNames.map((r) => r.slug)).toEqual(['delta', 'echo']);
|
|
62
|
+
expect(report.absorbedNames.map((r) => r.slug)).not.toContain('alpha');
|
|
63
|
+
});
|
|
64
|
+
it('carries each absorbed-name list through unchanged', () => {
|
|
65
|
+
for (const row of report.absorbedNames) {
|
|
66
|
+
const source = FIXTURE.find((c) => c.slug === row.slug);
|
|
67
|
+
expect(row.replaces).toEqual(source?.replaces ?? []);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
it('treats an empty-string intent as undocumented, not as documented', () => {
|
|
71
|
+
const expected = FIXTURE
|
|
72
|
+
.filter((c) => (c.intent ?? '').trim() === '')
|
|
73
|
+
.map((c) => c.slug)
|
|
74
|
+
.sort();
|
|
75
|
+
expect(report.noIntent.map((r) => r.slug)).toEqual(expected);
|
|
76
|
+
// Guard the boundary the implementation could get wrong in either
|
|
77
|
+
// direction: '' and undefined both count, a real string never does.
|
|
78
|
+
expect(expected).toContain('charlie');
|
|
79
|
+
expect(expected).toContain('foxtrot');
|
|
80
|
+
expect(expected).not.toContain('alpha');
|
|
81
|
+
});
|
|
82
|
+
it('orders packs by weight descending', () => {
|
|
83
|
+
const counts = report.byPack.map(([, n]) => n);
|
|
84
|
+
expect([...counts]).toEqual([...counts].sort((a, b) => b - a));
|
|
85
|
+
const summed = counts.reduce((a, b) => a + b, 0);
|
|
86
|
+
expect(summed).toBe(FIXTURE.length);
|
|
87
|
+
});
|
|
88
|
+
it('breaks a pack tie by name — exercised on an actual tie', () => {
|
|
89
|
+
// The mixed fixture has counts 3/2/1 and never hits the tie-break, so
|
|
90
|
+
// the previous version of this test asserted a branch it never reached.
|
|
91
|
+
const tied = buildCandidatesReport([
|
|
92
|
+
cmd('one', 'zulu'),
|
|
93
|
+
cmd('two', 'alpha'),
|
|
94
|
+
]);
|
|
95
|
+
expect(tied.byPack.map(([p]) => p)).toEqual(['alpha', 'zulu']);
|
|
96
|
+
});
|
|
97
|
+
it('is byte-stable across input permutations — the report is a set view', () => {
|
|
98
|
+
const shuffled = [...FIXTURE].reverse();
|
|
99
|
+
expect(renderCandidates(buildCandidatesReport(shuffled)))
|
|
100
|
+
.toBe(renderCandidates(buildCandidatesReport(FIXTURE)));
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
describe('buildCandidatesReport — empty estate', () => {
|
|
104
|
+
it('reports a measured zero rather than throwing or omitting sections', () => {
|
|
105
|
+
const empty = buildCandidatesReport([]);
|
|
106
|
+
expect(empty.total).toBe(0);
|
|
107
|
+
expect(empty.absorbedNames).toEqual([]);
|
|
108
|
+
expect(empty.noIntent).toEqual([]);
|
|
109
|
+
expect(empty.byPack).toEqual([]);
|
|
110
|
+
const text = renderCandidates(empty);
|
|
111
|
+
// An absent section would let a real zero read as a missing check.
|
|
112
|
+
expect(text).toContain('measured zero');
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
describe('renderCandidates — the honesty band', () => {
|
|
116
|
+
const text = renderCandidates(buildCandidatesReport(FIXTURE));
|
|
117
|
+
it('states up front that it decides nothing', () => {
|
|
118
|
+
expect(text.split('\n')[0]).toMatch(/report-only/i);
|
|
119
|
+
});
|
|
120
|
+
it('names the usage-evidence owner it deliberately does not import', () => {
|
|
121
|
+
expect(text).toContain('utilization_report');
|
|
122
|
+
});
|
|
123
|
+
it('warns that both census snapshots are dated, not current', () => {
|
|
124
|
+
expect(text).toContain('docs/SKILL_CENSUS.md');
|
|
125
|
+
expect(text).toContain('docs/artefact-census.md');
|
|
126
|
+
expect(text).toMatch(/point-in-time|do not\s+read their numbers as current/i);
|
|
127
|
+
});
|
|
128
|
+
it('hands the reduction targets to their owning roadmaps, all of them', () => {
|
|
129
|
+
for (const owner of REDUCTION_OWNERS)
|
|
130
|
+
expect(text).toContain(owner);
|
|
131
|
+
expect(REDUCTION_OWNERS.length).toBeGreaterThan(0);
|
|
132
|
+
});
|
|
133
|
+
it('never presents itself as a prune instruction', () => {
|
|
134
|
+
// Assert the exported contract, not a hand-copied sentence — a reworded
|
|
135
|
+
// disclaimer stays covered, a DELETED one fails.
|
|
136
|
+
expect(text).toContain(REPORT_ONLY_NOTICE);
|
|
137
|
+
});
|
|
138
|
+
it('states that the absorbed-name bucket is NOT a retirement class', () => {
|
|
139
|
+
// The defect this pins: the bucket was first labelled "deprecation
|
|
140
|
+
// shims", i.e. the exact inverse of what `replaces` means.
|
|
141
|
+
expect(text).not.toMatch(/deprecation shims +\d/);
|
|
142
|
+
expect(text).toMatch(/NOT a retirement class/);
|
|
143
|
+
expect(text).toContain('absorbed prior names');
|
|
144
|
+
});
|
|
145
|
+
it('reports the real shim class as not computable, with its canonical figure', () => {
|
|
146
|
+
expect(text).toMatch(/deprecation shims\s+not computable/);
|
|
147
|
+
expect(text).toContain('superseded_by');
|
|
148
|
+
expect(text).toContain('0 shims of 196');
|
|
149
|
+
});
|
|
150
|
+
it('renders every absorbed-name row it counted, with its absorbed ids', () => {
|
|
151
|
+
const report = buildCandidatesReport(FIXTURE);
|
|
152
|
+
for (const row of report.absorbedNames) {
|
|
153
|
+
expect(text).toContain(row.slug);
|
|
154
|
+
for (const prior of row.replaces)
|
|
155
|
+
expect(text).toContain(prior);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
describe('runCommandsLs — --candidates refuses the narrowing flags', () => {
|
|
160
|
+
// Regression: each of these silently produced a whole-estate report, and a
|
|
161
|
+
// typo'd --profile exited 0 where plain `ls` exits 1.
|
|
162
|
+
for (const flag of CANDIDATES_INCOMPATIBLE) {
|
|
163
|
+
it(`exits 1 when combined with ${flag}`, () => {
|
|
164
|
+
const opts = { candidates: true };
|
|
165
|
+
if (flag === '--pack')
|
|
166
|
+
opts['pack'] = 'git';
|
|
167
|
+
if (flag === '--visible')
|
|
168
|
+
opts['visible'] = true;
|
|
169
|
+
if (flag === '--profile')
|
|
170
|
+
opts['profile'] = 'bogus';
|
|
171
|
+
if (flag === '--expanded')
|
|
172
|
+
opts['expanded'] = true;
|
|
173
|
+
expect(runCommandsLs(opts)).toBe(1);
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
describe('renderCandidates — an unrecognised visibility value cannot vanish', () => {
|
|
178
|
+
// `visibility` is a free string in the manifest (ADR-092 named the field,
|
|
179
|
+
// nothing pins its domain). Rendering only the three known labels made the
|
|
180
|
+
// printed breakdown silently disagree with the total — the exact false-green
|
|
181
|
+
// shape a report must not have.
|
|
182
|
+
const withUnknown = [
|
|
183
|
+
cmd('known', 'engineering-base', { visibility: 'visible' }),
|
|
184
|
+
cmd('odd-one', 'engineering-base', { visibility: 'experimental' }),
|
|
185
|
+
cmd('odd-two', 'engineering-base', { visibility: 'experimental' }),
|
|
186
|
+
];
|
|
187
|
+
const report = buildCandidatesReport(withUnknown);
|
|
188
|
+
const text = renderCandidates(report);
|
|
189
|
+
it('counts the unrecognised value rather than dropping it', () => {
|
|
190
|
+
expect(report.byVisibility['experimental']).toBe(2);
|
|
191
|
+
const summed = Object.values(report.byVisibility).reduce((a, b) => a + b, 0);
|
|
192
|
+
expect(summed).toBe(withUnknown.length);
|
|
193
|
+
});
|
|
194
|
+
it('renders it, so the printed breakdown sums to the printed total', () => {
|
|
195
|
+
expect(text).toContain('experimental');
|
|
196
|
+
// Sum only the visibility block: the run of bucket lines directly
|
|
197
|
+
// following the `surface` line. (A wider filter also matched the
|
|
198
|
+
// owning-packs block, which is why the earlier version of this test
|
|
199
|
+
// carried a variable that did not hold what its name claimed.)
|
|
200
|
+
const rows = text.split('\n');
|
|
201
|
+
const start = rows.findIndex((l) => l.startsWith('surface '));
|
|
202
|
+
const block = [];
|
|
203
|
+
for (const line of rows.slice(start + 1)) {
|
|
204
|
+
const m = line.match(/^ {2}(\S+) +(\d+)$/);
|
|
205
|
+
if (!m)
|
|
206
|
+
break;
|
|
207
|
+
block.push(Number(m[2]));
|
|
208
|
+
}
|
|
209
|
+
expect(block).toHaveLength(4);
|
|
210
|
+
expect(block.reduce((a, b) => a + b, 0)).toBe(report.total);
|
|
211
|
+
});
|
|
212
|
+
it('keeps the JSON record key order deterministic too, not just the render', () => {
|
|
213
|
+
// The fix first sorted unknowns in the renderer only, leaving the record
|
|
214
|
+
// a --json consumer reads in first-seen order.
|
|
215
|
+
const forward = buildCandidatesReport([
|
|
216
|
+
cmd('a', 'p', { visibility: 'zeta' }),
|
|
217
|
+
cmd('b', 'p', { visibility: 'alpha' }),
|
|
218
|
+
]);
|
|
219
|
+
const reversed = buildCandidatesReport([
|
|
220
|
+
cmd('b', 'p', { visibility: 'alpha' }),
|
|
221
|
+
cmd('a', 'p', { visibility: 'zeta' }),
|
|
222
|
+
]);
|
|
223
|
+
expect(Object.keys(forward.byVisibility)).toEqual(Object.keys(reversed.byVisibility));
|
|
224
|
+
expect(Object.keys(forward.byVisibility).slice(-2)).toEqual(['alpha', 'zeta']);
|
|
225
|
+
});
|
|
226
|
+
it('keeps the known labels ahead of the unrecognised one, for byte stability', () => {
|
|
227
|
+
const order = [...text.matchAll(/^ {2}(visible|advanced|internal|experimental) +\d+$/gm)]
|
|
228
|
+
.map((m) => m[1]);
|
|
229
|
+
expect(order[order.length - 1]).toBe('experimental');
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
describe('renderCandidates — the text-mode cap is named, never silent', () => {
|
|
233
|
+
/** One more undocumented command than the cap allows, so truncation bites. */
|
|
234
|
+
const over = Array.from({ length: TEXT_LIST_CAP + 3 }, (_unused, i) => cmd(`undoc-${String(i).padStart(3, '0')}`, 'engineering-base', { intent: '' }));
|
|
235
|
+
const report = buildCandidatesReport(over);
|
|
236
|
+
const text = renderCandidates(report);
|
|
237
|
+
it('keeps the COUNT honest even though the list is truncated', () => {
|
|
238
|
+
expect(report.noIntent.length).toBe(over.length);
|
|
239
|
+
expect(text).toContain(`no stated intent ${over.length}`);
|
|
240
|
+
});
|
|
241
|
+
it('states how many rows it withheld, derived from the input', () => {
|
|
242
|
+
expect(text).toContain(`… and ${over.length - TEXT_LIST_CAP} more`);
|
|
243
|
+
});
|
|
244
|
+
it('caps the enumeration at exactly TEXT_LIST_CAP rows', () => {
|
|
245
|
+
const listed = over.filter((c) => text.includes(` ${c.slug} (`)).length;
|
|
246
|
+
expect(listed).toBe(TEXT_LIST_CAP);
|
|
247
|
+
});
|
|
248
|
+
it('never caps the structured payload', () => {
|
|
249
|
+
// --json consumers get the whole set; the cap is a text-mode concern.
|
|
250
|
+
expect(report.noIntent).toHaveLength(over.length);
|
|
251
|
+
});
|
|
252
|
+
it('adds no truncation notice when the set fits', () => {
|
|
253
|
+
const fits = renderCandidates(buildCandidatesReport(over.slice(0, TEXT_LIST_CAP)));
|
|
254
|
+
expect(fits).not.toContain('more — the full set is in --json');
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
//# sourceMappingURL=commands.candidates.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.candidates.test.js","sourceRoot":"","sources":["../../../src/cli/commands/commands.candidates.test.ts"],"names":[],"mappings":"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"}
|