@event4u/agent-config 14.6.0 → 14.8.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 +255 -145
- package/README.md +1 -1
- package/dist/agent-src/commands/analyze/inbox.md +264 -10
- package/dist/agent-src/commands/analyze.md +1 -1
- package/dist/agent-src/commands/evals/git-pr-merge.json +13 -0
- package/dist/agent-src/commands/evals/roadmap.json +17 -1
- package/dist/agent-src/commands/pr/create.md +14 -2
- package/dist/agent-src/commands/pr/merge.md +379 -0
- package/dist/agent-src/commands/roadmap/process-full.md +272 -32
- package/dist/agent-src/commands/roadmap.md +1 -1
- package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +46 -36
- package/dist/agent-src/contexts/execution/autonomy-mechanics.md +37 -2
- package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +95 -2
- package/dist/agent-src/contexts/execution/roadmap-process-loop.md +289 -106
- package/dist/agent-src/rules/artifact-drafting-protocol.md +5 -1
- package/dist/agent-src/rules/context-hygiene.md +2 -0
- package/dist/agent-src/rules/decision-revisit-gate.md +67 -32
- package/dist/agent-src/rules/fix-what-you-see.md +108 -0
- package/dist/agent-src/rules/no-roadmap-references.md +0 -5
- package/dist/agent-src/rules/recurring-criticism.md +110 -0
- package/dist/agent-src/rules/roadmap-progress-sync.md +20 -1
- package/dist/agent-src/rules/rule-type-governance.md +0 -2
- package/dist/agent-src/rules/self-repair-loop.md +17 -0
- package/dist/agent-src/rules/skill-quality.md +0 -2
- package/dist/agent-src/rules/source-confidentiality.md +37 -7
- package/dist/agent-src/scripts/archival_sweep.ts +117 -0
- package/dist/agent-src/scripts/archive_completed_roadmaps.ts +26 -7
- package/dist/agent-src/scripts/dashboard_mode.ts +212 -0
- package/dist/agent-src/scripts/gate_budget.ts +282 -0
- package/dist/agent-src/scripts/gate_execute.ts +72 -31
- package/dist/agent-src/scripts/roadmap_gates.ts +74 -3
- package/dist/agent-src/scripts/update_roadmap_progress.ts +296 -53
- package/dist/agent-src/skills/adr-create/SKILL.md +124 -5
- package/dist/agent-src/skills/ai-council/SKILL.md +48 -807
- package/dist/agent-src/skills/ai-council/references/advanced-modes.md +320 -0
- package/dist/agent-src/skills/ai-council/references/cost-and-redaction.md +99 -0
- package/dist/agent-src/skills/ai-council/references/execution-modes.md +162 -0
- package/dist/agent-src/skills/ai-council/references/output-and-synthesis.md +125 -0
- package/dist/agent-src/skills/ai-council/references/procedure.md +143 -0
- package/dist/agent-src/skills/decision-record/SKILL.md +61 -3
- package/dist/agent-src/skills/decision-review/SKILL.md +65 -0
- package/dist/agent-src/skills/merge-conflicts/SKILL.md +26 -0
- package/dist/agent-src/skills/quality-tools/SKILL.md +34 -326
- package/dist/agent-src/skills/quality-tools/references/js-ts-tools.md +113 -0
- package/dist/agent-src/skills/quality-tools/references/php-tools.md +222 -0
- package/dist/agent-src/skills/roadmap-management/SKILL.md +15 -409
- package/dist/agent-src/skills/roadmap-management/references/archival.md +226 -0
- package/dist/agent-src/skills/roadmap-management/references/authoring.md +107 -0
- package/dist/agent-src/skills/roadmap-management/references/dashboard.md +47 -0
- package/dist/agent-src/skills/roadmap-management/references/lifecycle.md +58 -0
- package/dist/agent-src/skills/security/SKILL.md +8 -0
- package/dist/agent-src/skills/security-audit/SKILL.md +12 -1
- package/dist/agent-src/skills/skill-writing/SKILL.md +34 -570
- package/dist/agent-src/skills/skill-writing/references/procedure.md +275 -0
- package/dist/agent-src/skills/skill-writing/references/read-only-scripts.md +18 -0
- package/dist/agent-src/skills/skill-writing/references/section-patterns.md +298 -0
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/roadmaps.md +65 -4
- package/dist/agent-src/templates/scripts/telemetry/flush_sender.mjs +163 -0
- package/dist/agent-src/templates/scripts/telemetry/remote.ts +160 -7
- package/dist/agent-src/templates/scripts/telemetry/transport.ts +169 -0
- package/dist/cli/registry.js +2 -1
- package/dist/cli/registry.js.map +1 -1
- package/dist/cli-delegate/chunk-2GNWGMAL.js +172 -0
- package/dist/cli-delegate/{chunk-P6LQDIWK.js → chunk-7PRE6ZV2.js} +338 -0
- package/dist/cli-delegate/{chunk-BKO2AZ7Z.js → chunk-B2ERU2VA.js} +1 -1
- package/dist/cli-delegate/chunk-E4XIZDIB.js +402 -0
- package/dist/cli-delegate/{chunk-3UCJWMMP.js → chunk-EEJUMCDZ.js} +16 -16
- package/dist/cli-delegate/{chunk-NXFWFAYV.js → chunk-G23AT6GD.js} +1 -0
- package/dist/cli-delegate/{chunk-XURJ4AQC.js → chunk-H4VIVD4C.js} +385 -284
- package/dist/cli-delegate/chunk-I3EIN2YG.js +36 -0
- package/dist/cli-delegate/{chunk-RLN73PR5.js → chunk-LPPWO5CE.js} +12 -8
- package/dist/cli-delegate/chunk-MWRD5YOH.js +100 -0
- package/dist/cli-delegate/{chunk-UEZ7D35A.js → chunk-N7CDDGI3.js} +4 -23
- package/dist/cli-delegate/{chunk-63WSP6YZ.js → chunk-PMEKGDED.js} +74 -167
- package/dist/cli-delegate/{chunk-GRRPEPRN.js → chunk-T7L2QK3K.js} +24 -5
- package/dist/cli-delegate/{chunk-EVTY7ISR.js → chunk-YM4GZDJG.js} +9 -1
- package/dist/cli-delegate/cmd_adr_effective.js +1162 -0
- package/dist/cli-delegate/cmd_conformance.js +466 -716
- package/dist/cli-delegate/cmd_converge.js +3 -3
- package/dist/cli-delegate/cmd_doctor.js +10 -10
- package/dist/cli-delegate/cmd_explain.js +1 -1
- package/dist/cli-delegate/cmd_export.js +10 -9
- package/dist/cli-delegate/cmd_handoff.js +10 -9
- package/dist/cli-delegate/cmd_memory_get.js +2 -1
- package/dist/cli-delegate/cmd_migrate.js +2 -2
- package/dist/cli-delegate/cmd_packs_active.js +1 -1
- package/dist/cli-delegate/cmd_preflight.js +5 -5
- package/dist/cli-delegate/cmd_prune.js +11 -10
- package/dist/cli-delegate/cmd_route_audit.js +6 -5
- package/dist/cli-delegate/cmd_route_explain.js +3 -3
- package/dist/cli-delegate/cmd_session_recycle.js +840 -30
- package/dist/cli-delegate/cmd_settings_get.js +3 -3
- package/dist/cli-delegate/cmd_settings_migrate.js +10 -9
- package/dist/cli-delegate/cmd_settings_set.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +11 -10
- package/dist/cli-delegate/cmd_uninstall.js +13 -11
- package/dist/cli-delegate/cmd_update.js +4 -4
- package/dist/cli-delegate/cmd_upgrade.js +4 -4
- package/dist/cli-delegate/cmd_validate.js +11 -10
- package/dist/cli-delegate/cmd_versions.js +3 -3
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +111 -37
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +5 -5
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +15 -12
- package/dist/discovery/trust-report.md +3 -3
- package/dist/discovery/workspaces.json +11 -8
- package/dist/hooks/dispatch.js +3165 -2192
- package/dist/install/claudePathsPlan.js +187 -0
- package/dist/install/claudePathsPlan.js.map +1 -0
- package/dist/install/globalRuleLayers.js +169 -0
- package/dist/install/globalRuleLayers.js.map +1 -0
- package/dist/install/hostLayerFingerprint.js +136 -0
- package/dist/install/hostLayerFingerprint.js.map +1 -0
- package/dist/install/install.mjs +553 -425
- package/dist/install/partitionEligibility.js +432 -0
- package/dist/install/partitionEligibility.js.map +1 -0
- package/dist/install/ruleLayerPartition.js +157 -0
- package/dist/install/ruleLayerPartition.js.map +1 -0
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +1863 -1234
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/agent_src.js +41 -0
- package/dist/scripts/_lib/agent_src.js.map +1 -1
- package/dist/scripts/_lib/install_layout.js +83 -0
- package/dist/scripts/_lib/install_layout.js.map +1 -0
- package/dist/scripts/_lib/installed_lock.js +444 -0
- package/dist/scripts/_lib/installed_lock.js.map +1 -0
- package/dist/scripts/_lib/prune_empty_dirs.js +85 -0
- package/dist/scripts/_lib/prune_empty_dirs.js.map +1 -0
- package/dist/scripts/condense.js +63 -251
- package/dist/scripts/condense.js.map +1 -1
- package/dist/server/schemas/settings.js +4 -0
- package/dist/server/schemas/settings.js.map +1 -1
- package/docs/contracts/settings-classes.md +12 -6
- package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +8 -3
- package/docs/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +45 -1
- package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +26 -0
- package/docs/guidelines/agent-infra/false-green.md +47 -1
- package/docs/guidelines/agent-infra/memory-access.md +17 -0
- package/docs/guidelines/agent-infra/recurring-criticism-mechanics.md +96 -0
- package/package.json +1 -1
- package/src/agent-src/scripts/archival_sweep.ts +117 -0
- package/src/agent-src/scripts/archive_completed_roadmaps.ts +26 -7
- package/src/agent-src/scripts/dashboard_mode.ts +212 -0
- package/src/agent-src/scripts/gate_budget.ts +282 -0
- package/src/agent-src/scripts/gate_execute.ts +72 -31
- package/src/agent-src/scripts/roadmap_gates.ts +74 -3
- package/src/agent-src/scripts/update_roadmap_progress.ts +296 -53
- package/src/agent-src/templates/scripts/telemetry/flush_sender.mjs +163 -0
- package/src/agent-src/templates/scripts/telemetry/remote.ts +160 -7
- package/src/agent-src/templates/scripts/telemetry/transport.ts +169 -0
- package/src/config/agent-settings.template.yml +27 -2
- package/src/config/ci-local-parity.yml +39 -0
- package/src/config/estate-count-budget.json +612 -3
- package/src/config/evaluator-budgets.json +3 -3
- package/src/config/gate-coverage.yml +220 -12
- package/src/config/gate-violation-baselines.json +73 -63
- package/src/config/gitignore-block.txt +15 -2
- package/src/config/hook-latency-budget.json +5 -0
- package/src/config/rule-activation-census.json +14 -6
- package/src/config/rule-stub-ceilings.json +34 -7
- package/src/install/claudePathsPlan.ts +196 -0
- package/src/install/globalRuleLayers.ts +197 -0
- package/src/install/hostLayerFingerprint.ts +145 -0
- package/src/install/partitionEligibility.ts +502 -0
- package/src/install/ruleLayerPartition.ts +212 -0
- package/src/scripts/_cli/cmd_adr_effective.ts +484 -0
- package/src/scripts/_cli/cmd_session_recycle.ts +9 -1
- package/src/scripts/_dispatch.bash +17 -1
- package/src/scripts/_lib/ac_heading.ts +30 -0
- package/src/scripts/_lib/adr_frontmatter.test.ts +365 -0
- package/src/scripts/_lib/adr_frontmatter.ts +459 -0
- package/src/scripts/_lib/agent_src.ts +42 -0
- package/src/scripts/_lib/bench_ab_pinned_repo.ts +162 -0
- package/src/scripts/_lib/bench_ab_workspace.ts +10 -1
- package/src/scripts/_lib/envelope_grounding.ts +49 -9
- package/src/scripts/_lib/installed_lock.ts +50 -5
- package/src/scripts/_lib/layer_overlap_notice.ts +11 -2
- package/src/scripts/_lib/md_section.ts +129 -0
- package/src/scripts/_lib/prune_empty_dirs.ts +80 -0
- package/src/scripts/_lib/scope_guard.sh +26 -3
- package/src/scripts/_lib/self_repair.ts +19 -0
- package/src/scripts/_lib/self_repair_class_b.ts +171 -0
- package/src/scripts/adr/evidence_census.ts +899 -0
- package/src/scripts/adr/regenerate_index.ts +12 -32
- package/src/scripts/adr_cite_check.ts +540 -39
- package/src/scripts/ai_council/cli_help.ts +55 -0
- package/src/scripts/audit_adr_coverage.ts +103 -17
- package/src/scripts/before_complete_hook.ts +153 -28
- package/src/scripts/bench_ab_v2_complexity.ts +27 -7
- package/src/scripts/bench_hook_latency.ts +204 -0
- package/src/scripts/build_archive_index.ts +34 -0
- package/src/scripts/check_adr_frontmatter.ts +574 -39
- package/src/scripts/check_hook_bundle_content.ts +219 -0
- package/src/scripts/check_new_adr_evidence.ts +529 -0
- package/src/scripts/check_references.ts +78 -0
- package/src/scripts/check_release_published.ts +32 -11
- package/src/scripts/check_rule_layer_partition.ts +531 -0
- package/src/scripts/check_single_delivery.ts +194 -17
- package/src/scripts/check_standing_rule_delivery.ts +8 -2
- package/src/scripts/ci_settle.ts +170 -0
- package/src/scripts/condense.ts +79 -259
- package/src/scripts/council_cli.ts +3 -3
- package/src/scripts/dispatch_r2_reviewer.ts +6 -14
- package/src/scripts/external_sources_denylist.json +4 -1
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +77 -14
- package/src/scripts/hooks/block_no_verify.ts +61 -10
- package/src/scripts/hooks/block_unauthorized_git.ts +21 -1
- package/src/scripts/hooks/concern_registry.ts +4 -0
- package/src/scripts/hooks/dispatch_hook.ts +154 -187
- package/src/scripts/hooks/dispatch_issues.ts +38 -19
- package/src/scripts/hooks/fallback_yaml.ts +66 -0
- package/src/scripts/hooks/host_semantics.ts +21 -0
- package/src/scripts/hooks/injection_budget.ts +13 -3
- package/src/scripts/hooks/py_json_dumps.ts +103 -0
- package/src/scripts/hooks/rtk_wrap_hook.ts +8 -3
- package/src/scripts/hooks/run_continuation_hook.ts +8 -5
- package/src/scripts/hooks/ship_diff_volume_hook.ts +81 -15
- package/src/scripts/hooks/source_first_gate_hook.ts +464 -0
- package/src/scripts/hooks/state_io.ts +870 -21
- package/src/scripts/hooks/stdin_failure_policy.ts +96 -0
- package/src/scripts/hooks/subagent_ledger_hook.ts +44 -15
- package/src/scripts/hooks/telemetry_flush_hook.ts +139 -0
- package/src/scripts/hooks/telemetry_self_repair.ts +128 -0
- package/src/scripts/hooks/telemetry_usage_hook.ts +22 -4
- package/src/scripts/hooks/turn_end_gate_hook.ts +81 -15
- package/src/scripts/injection_scan_hook.ts +137 -5
- package/src/scripts/install.ts +16 -11
- package/src/scripts/language_mirror_hook.ts +561 -25
- package/src/scripts/lint_framework_leakage_allowlist.json +2 -2
- package/src/scripts/lint_hook_manifest.ts +49 -0
- package/src/scripts/lint_plan_risk_register.ts +4 -3
- package/src/scripts/lint_provenance_vocabulary.ts +472 -4
- package/src/scripts/lint_skill_router_head.ts +4 -4
- package/src/scripts/mcp_server/tools.ts +2 -2
- package/src/scripts/new_roadmap.ts +136 -0
- package/src/scripts/pack_mcp_content.ts +20 -5
- package/src/scripts/release.ts +37 -38
- package/src/scripts/report_layer_overlap.ts +6 -0
- package/src/scripts/routing_doctor.ts +5 -1
- package/src/scripts/self_repair_hook.ts +37 -5
- package/src/scripts/session_register_hook.ts +11 -0
- package/src/scripts/skill_usage_collect.ts +11 -1
- package/src/scripts/skill_usage_report.ts +278 -8
- package/src/scripts/sync_pr_branch.ts +170 -20
- package/src/server/schemas/settings.ts +8 -0
- package/dist/cli-delegate/chunk-EJITJBJX.js +0 -172
- package/dist/cli-delegate/chunk-PZWRPRWP.js +0 -38
- package/dist/cli-delegate/{chunk-PPQO4NGR.js → chunk-6RJA2F5A.js} +3 -3
- package/dist/cli-delegate/{chunk-RYNADUFG.js → chunk-LWTYTX6F.js} +0 -0
- package/dist/cli-delegate/{chunk-FBKL6JWT.js → chunk-MMSGVZKV.js} +3 -3
|
@@ -87,10 +87,54 @@ those artifacts:
|
|
|
87
87
|
to obtain.
|
|
88
88
|
- **Scope is the batch, nothing more.** An artifact NOT declared in the
|
|
89
89
|
roadmap (discovered mid-run) triggers the full interactive protocol —
|
|
90
|
-
or, under the contract, the scope-out-of-roadmap halt.
|
|
90
|
+
or, under the contract, the scope-out-of-roadmap halt. That halt is the
|
|
91
|
+
**default** and stays the default; see § Late artifacts below for the one
|
|
92
|
+
declared value that changes it.
|
|
91
93
|
- Batch mode never skips the Research pass itself — it relocates and
|
|
92
94
|
batches it. `artifact_protocol: skip` does not exist.
|
|
93
95
|
|
|
96
|
+
### Late artifacts — `halt` by default, `auto-research` only when declared
|
|
97
|
+
|
|
98
|
+
The bullet above is the whole rule when the contract says nothing. A contract
|
|
99
|
+
may instead declare `late_artifacts: auto-research`
|
|
100
|
+
([`roadmap-execution-contract § 2a`](../../../src/agent-src/contexts/execution/roadmap-execution-contract.md)),
|
|
101
|
+
and then a mid-run discovery runs **this** procedure rather than halting:
|
|
102
|
+
|
|
103
|
+
1. **Re-run Phase B against current state** — the same overlap scan the batch
|
|
104
|
+
ran at contract time, now over the artifact the run just found. Nothing new
|
|
105
|
+
is invented: this is the accepted-as-non-interactive procedure, later.
|
|
106
|
+
2. **Extend verdict → extend silently.** The nearest match is edited. This is
|
|
107
|
+
the outcome the overlap scan exists to produce and it needs no approval it
|
|
108
|
+
did not already have.
|
|
109
|
+
3. **Create verdict → derive Phase A from what is already on the record.** The
|
|
110
|
+
understand-answers come from the roadmap step text plus the decision-sheet
|
|
111
|
+
answers the user accepted. No new question is opened.
|
|
112
|
+
4. **Genuine overlap conflict → halt.** Two plausible extend targets, or a
|
|
113
|
+
match whose scope contradicts the step, is a real decision and stops the
|
|
114
|
+
run.
|
|
115
|
+
5. **Cap: three per run, then halt regardless of verdict.**
|
|
116
|
+
|
|
117
|
+
`halt` remains the shipped default (`decision 2026-08-20`, AI council 2/2 on
|
|
118
|
+
the `autonomy-defaults-sheet` fork; record
|
|
119
|
+
`agents/evidence/council/drain-blocker-dispositions-a.md`). The reasoning is
|
|
120
|
+
short: the cap bounds how far an unplanned artifact can drift the run, but it
|
|
121
|
+
does not decide whether the drift is wanted, and the conservative side of that
|
|
122
|
+
fork is the behaviour the tree already had. Making `auto-research` a declared
|
|
123
|
+
value rather than an inherited one is also what makes its own kill criterion —
|
|
124
|
+
the late-artifact revisit rate — attributable to the runs that chose it.
|
|
125
|
+
Reverting is one word in each of the two tables; no mechanism depends on the
|
|
126
|
+
default's direction.
|
|
127
|
+
|
|
128
|
+
**Kill criterion for `auto-research`, at the site rather than in a roadmap:**
|
|
129
|
+
a late-artifact revisit rate above 20 % — an auto-authored or auto-extended
|
|
130
|
+
artifact later reworked or reverted — removes the value and returns every
|
|
131
|
+
late discovery to `halt`. **No instrument today:** nothing counts late
|
|
132
|
+
artifacts or their revisits, so the rate is unmeasured rather than low, and
|
|
133
|
+
the cap of three is the only live bound. Recorded here because a criterion
|
|
134
|
+
that lives only in the roadmap that flipped the default becomes unreachable
|
|
135
|
+
the moment that roadmap is archived.
|
|
136
|
+
|
|
137
|
+
|
|
94
138
|
## Complexity budget — the six questions before a new artefact
|
|
95
139
|
|
|
96
140
|
Folded here from the 9.4.0 review (Prio 5), which named the failure mode:
|
|
@@ -88,3 +88,29 @@ Exit code is always 0 — hooks must never block the agent loop.
|
|
|
88
88
|
|
|
89
89
|
- `context-hygiene` (rule) — thresholds, 3-failure rule, tool-loop cap, read-loop Iron Law.
|
|
90
90
|
- `systematic-debugging` § Debug micro-loop — the one-test-one-fix-one-rerun procedure.
|
|
91
|
+
|
|
92
|
+
## The CI waiter — use the helper, never the hand-written loop
|
|
93
|
+
|
|
94
|
+
`./scripts-run src/scripts/ci_settle <pr> [--timeout-min N] [--interval-sec N]`
|
|
95
|
+
|
|
96
|
+
Exit codes: **0** settled green · **1** settled red, with the failing checks
|
|
97
|
+
named · **2** did not settle, or the API could not be read — never a verdict.
|
|
98
|
+
|
|
99
|
+
Four states classify as *not settled*, and each one is a way the hand-written
|
|
100
|
+
form goes wrong: an API error, a non-zero `gh` exit, unparseable output, and
|
|
101
|
+
**zero registered checks** (a run that has not registered its checks yet looks
|
|
102
|
+
exactly like a finished one with nothing to report).
|
|
103
|
+
|
|
104
|
+
**Why it exists.** Measured 2026-08-20:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
until ! gh pr checks 1459 | grep -q "pending"; do sleep 60; done
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
The API then failed. Its error text — `error connecting to api.github.com` —
|
|
111
|
+
contains no `pending`, so the loop exited, the session reported a settle that
|
|
112
|
+
had not happened, and the claim had to be retracted to the user in the next
|
|
113
|
+
reply. The bug is not the sleep or the grep: **absence of the word `pending`
|
|
114
|
+
was treated as evidence of completion**, and an error is neither settled nor
|
|
115
|
+
pending. The exit condition is the part that is easy to get wrong, so it lives
|
|
116
|
+
in one place rather than in every agent's head.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# False Green — the ways a passing result can be wrong here
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Eleven failure modes, each with the detection command that distinguishes "found nothing" from "looked at nothing". Every one is drawn from this repository's own history, not from a generic checklist.
|
|
4
4
|
|
|
5
5
|
_Origin: `road-to-skill-ecosystem-gate-integrity` Phase 3. The recurring shape is not that a gate reports a wrong finding — it is that a gate reports **no** finding for a reason unrelated to the property it guards, and no output distinguishes the two cases._
|
|
6
6
|
|
|
@@ -128,6 +128,52 @@ empty rendered template equals an absent target file. The gate reports
|
|
|
128
128
|
comparing. Two absences are the absence of a comparison, not the presence of a
|
|
129
129
|
match. The estate-wide audit is below.
|
|
130
130
|
|
|
131
|
+
### 10. Hook-bypass override
|
|
132
|
+
|
|
133
|
+
The gate never ran because the hook that runs it was disabled for that
|
|
134
|
+
invocation. `git commit --no-verify` (and its short `-n` form) skips every
|
|
135
|
+
pre-commit hook; `core.hooksPath` repointed at an empty directory skips them
|
|
136
|
+
permanently and silently. Both produce a commit that looks exactly like a
|
|
137
|
+
commit whose hooks passed. The same shape reaches the runtime hook layer: a
|
|
138
|
+
concern bound in the manifest is still inert on a host that does not honour a
|
|
139
|
+
deny, so "the guard is registered" is not "the guard fired".
|
|
140
|
+
|
|
141
|
+
<!-- example-fence-allow: git-no-verify -- the fence teaches how to DETECT the core.hooksPath bypass; the forbidden form has to appear for the diagnostic to be readable, and every line here is a read-only query -->
|
|
142
|
+
```bash
|
|
143
|
+
git config --get core.hooksPath # empty = repo default, good
|
|
144
|
+
./scripts-run src/scripts/hooks/block_no_verify --help # the tool-call guard
|
|
145
|
+
agent-config hooks:status # per-host bindings, not the manifest
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Structural fix:** the bypass is blocked at tool-call time by
|
|
149
|
+
`block-no-verify` on the one host that honours a deny, and the authoritative
|
|
150
|
+
gate is remote CI, which no local override can skip. Never read a local green
|
|
151
|
+
as evidence when the hook path was overridden — re-run in CI, or run the gate
|
|
152
|
+
directly rather than through the hook.
|
|
153
|
+
|
|
154
|
+
### 11. Cached-green reuse
|
|
155
|
+
|
|
156
|
+
The green belongs to a different input than the one being judged. Three real
|
|
157
|
+
shapes here. A gate that reads `dist/agent-src/` passes against a **stale
|
|
158
|
+
projection** while the `src/` change it was meant to judge is not in the tree it
|
|
159
|
+
scanned — the recorded trap is a worktree whose stale `dist` faked generator
|
|
160
|
+
drift, and its mirror, a golden capture reading `dist` where the assertion was
|
|
161
|
+
about `src`. A count ratchet sits inside its limit for so long that "within
|
|
162
|
+
budget" stops meaning anything, which is why a baseline carries an expiry at
|
|
163
|
+
all. And the conversational form: trusting a verification run earlier in the
|
|
164
|
+
same session, after the tree has moved underneath it.
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
bash src/scripts/condense.sh --changed # dist != rewrite(src) => the scan root is stale
|
|
168
|
+
./scripts-run src/scripts/check_condensation --summary # byte-exactness dist vs rewrite(src)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Structural fix:** regenerate before judging (`task sync` then
|
|
172
|
+
`task generate-tools`, in that order), and treat a baseline unchanged past
|
|
173
|
+
`STALE_AFTER_DAYS` (56, `_lib/gate_baseline.ts:39`) as suppression rather than
|
|
174
|
+
as headroom. A completion claim rests on a run made **after** the last edit, not
|
|
175
|
+
on the freshest run you happen to remember.
|
|
176
|
+
|
|
131
177
|
## The audited sync/parity gates
|
|
132
178
|
|
|
133
179
|
Comparison-shaped gates carry entry #9's failure mode by default: `diff a b`
|
|
@@ -8,6 +8,23 @@ abstraction backed by `scripts/memory_lookup.ts` (TypeScript, run via
|
|
|
8
8
|
tsx). It reads curated YAML under `agents/memory/<type>/` and the
|
|
9
9
|
agent-written `agents/memory/intake/*.jsonl` signal log.
|
|
10
10
|
|
|
11
|
+
## Index by the moment, not only by the topic
|
|
12
|
+
|
|
13
|
+
Every entry answers **"what was I about to do when this would have helped"** — a
|
|
14
|
+
verb and its object (`author a roadmap`, `wait on CI`, `push a branch`, `edit a
|
|
15
|
+
markdown section with a script`) — and the index carries a trigger-moment
|
|
16
|
+
section keyed on those verbs beside the topic grouping.
|
|
17
|
+
|
|
18
|
+
A store indexed only by subject is an index for *browsing*, and browsing is not
|
|
19
|
+
the failure mode: an agent does not go looking for a trap it does not know
|
|
20
|
+
exists. Measured 2026-08-20 on one instrumented session — of eleven error
|
|
21
|
+
classes, **nine already had an entry** and all nine were read *after* the
|
|
22
|
+
failure. The deficit was delivery, not knowledge.
|
|
23
|
+
|
|
24
|
+
Writing the trigger key is part of writing the entry. A second index maintained
|
|
25
|
+
separately from the entries rots, and a rotted index is worse than none because
|
|
26
|
+
it still looks authoritative.
|
|
27
|
+
|
|
11
28
|
## The contract
|
|
12
29
|
|
|
13
30
|
Consumers reach it via the CLI (`agent-config memory:lookup`) or the
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Recurring-criticism mechanics
|
|
2
|
+
|
|
3
|
+
> Depth for the `recurring-criticism` rule — the past-disposition store list, the mechanism-is-the-defect classification, the hardening floor, and the failure-mode catalog.
|
|
4
|
+
|
|
5
|
+
_No YAML frontmatter, deliberately: every other guideline under `docs/guidelines/`
|
|
6
|
+
is frontmatter-less, and a `name:` key here makes the two MCP resource loaders
|
|
7
|
+
derive different URIs for the same file — one from the key
|
|
8
|
+
(`guideline://recurring-criticism-mechanics`), one from the path
|
|
9
|
+
(`guideline://agent-infra/recurring-criticism-mechanics`). That is a
|
|
10
|
+
`mcp_parity_smoke` drift, and it only surfaces once `dist/cli/agent-config.js`
|
|
11
|
+
is built, so the local suite passes and CI does not._
|
|
12
|
+
|
|
13
|
+
Depth for [`recurring-criticism`](../../../src/rules/recurring-criticism.md). The
|
|
14
|
+
rule carries the obligation; this carries the lookup addresses and the reasoning
|
|
15
|
+
that would otherwise be paid in every session — that rule is phrase-triggered, and
|
|
16
|
+
a phrase-triggered rule is unconditionally loaded on Claude (the emitter writes no
|
|
17
|
+
`paths:` when any non-path trigger is present), so every line in it is a line every
|
|
18
|
+
session pays for. This file is read on demand.
|
|
19
|
+
|
|
20
|
+
## Look it up before re-deriving it
|
|
21
|
+
|
|
22
|
+
Without a mechanism that forces a reference to the earlier disposition, every
|
|
23
|
+
recurrence becomes a fresh investigation even where the answer already exists
|
|
24
|
+
<!-- harvest:forced-lookup-of-past-root-causes -->. The stores are fragmented and
|
|
25
|
+
only partly queryable, so **name which one you checked**:
|
|
26
|
+
|
|
27
|
+
| Store | Path | Queryable? |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| ADRs + index | `docs/decisions/` + `INDEX.md`, via `adr_cite_check <ADR-NNN>` | yes — status, `review_trigger` state, successors |
|
|
30
|
+
| Estate / activation / low-impact dispositions | `agents/decisions/*.yml`, `agents/decisions/low-impact-decisions.md` | yes, closed vocabularies |
|
|
31
|
+
| Roadmap dispositions | `agents/roadmaps/{archive,skipped,later}/` | `later/` only; `skipped/` carries its reason as header prose |
|
|
32
|
+
| Curated memory | `agents/memory/*.yml` | yes |
|
|
33
|
+
| Analysis documents | `agents/evidence/analysis/` | grep only |
|
|
34
|
+
| Harvest / borrow ledgers | `provenance/*.jsonl` | yes, but `adopt`/`adapt` only |
|
|
35
|
+
|
|
36
|
+
**Rejections are the weak spot, and by design.** `provenance/README.md` states that
|
|
37
|
+
a `reject` verdict lives in the analysis document rather than a ledger, because
|
|
38
|
+
nothing in the tree cites it. So "I found nothing" here means *unstructured prose
|
|
39
|
+
was grepped*, never *nothing was decided*. Say which of the two you mean — the
|
|
40
|
+
difference decides whether the recurrence is new information or a lookup failure.
|
|
41
|
+
|
|
42
|
+
## The mechanism is the candidate defect, not the item
|
|
43
|
+
|
|
44
|
+
Classify what was missing before choosing an artefact — the taxonomy in
|
|
45
|
+
[`skill-improvement-pipeline`](../../../src/skills/skill-improvement-pipeline/SKILL.md)
|
|
46
|
+
§ Classify the missing component (instruction · source-of-truth · tool · validator ·
|
|
47
|
+
permission · sandbox · evaluation · recovery-path) is the one to use, because "add
|
|
48
|
+
another rule" is the answer that feels right and is usually wrong.
|
|
49
|
+
|
|
50
|
+
Then land the learning where it **constrains** the next run, per
|
|
51
|
+
[`learning-to-rule-or-skill`](../../../src/skills/learning-to-rule-or-skill/SKILL.md).
|
|
52
|
+
A lesson that does not narrow the next attempt produces thrashing rather than
|
|
53
|
+
convergence <!-- harvest:unconstraining-lesson-thrashes -->; a learning that lives
|
|
54
|
+
only in a reply is not a learning, it is a note.
|
|
55
|
+
|
|
56
|
+
**Third recurrence of the same class escalates to structure** —
|
|
57
|
+
[`decision-review`](../../../src/skills/decision-review/SKILL.md) § Escalation owns
|
|
58
|
+
the threshold, and its point is worth restating: a louder restatement of a rule the
|
|
59
|
+
agent keeps missing is the one response already known not to work. At that point
|
|
60
|
+
the choice is a deterministic gate or deletion, not more prose.
|
|
61
|
+
|
|
62
|
+
## The hardening floor
|
|
63
|
+
|
|
64
|
+
Self-improvement loops can regress the artefact they improve
|
|
65
|
+
<!-- harvest:self-improvement-can-self-regress -->. Two consequences:
|
|
66
|
+
|
|
67
|
+
- A hardening change carries the **same evidence bar** as any other change. "We
|
|
68
|
+
learned something" is not a licence, and a mechanism proposed in response to a
|
|
69
|
+
recurrence still needs a measured false-positive rate before it becomes CI.
|
|
70
|
+
- It never arrives as a **weakened** gate, a widened allowlist, a lifted Hard
|
|
71
|
+
Floor, or a loosened ratchet. If the only available hardening lowers a floor, the
|
|
72
|
+
recurrence escalates to the owner instead — that transition is owner-reserved per
|
|
73
|
+
[`decision-revisit-gate`](../../../src/rules/decision-revisit-gate.md) § Who
|
|
74
|
+
decides.
|
|
75
|
+
|
|
76
|
+
## Failure modes
|
|
77
|
+
|
|
78
|
+
- **Resolving on the count.** "You have said it three times, so you are right" is
|
|
79
|
+
the sycophancy failure with a procedure attached. The count opens the question.
|
|
80
|
+
- **Resolving on the count, inverted.** "It is only the second time, so the old
|
|
81
|
+
call stands" — the repetition still shifted the burden of proof.
|
|
82
|
+
- **Naming no outcome.** A resolution that does not say which of the three applies
|
|
83
|
+
(decision wrong · never recorded · unreachable) has not resolved anything.
|
|
84
|
+
- **Grepping prose and reporting absence.** See the rejection note above.
|
|
85
|
+
- **Treating a resemblance as a recurrence.** Mechanism-match runs first; a new
|
|
86
|
+
complaint that tests a different mechanism is a new finding.
|
|
87
|
+
- **Hardening the item instead of the mechanism.** Fixing the one instance leaves
|
|
88
|
+
the surface that dismissed it intact, which is what produces the fourth
|
|
89
|
+
recurrence.
|
|
90
|
+
- **Writing the learning into the reply.** It has to land in an artefact.
|
|
91
|
+
|
|
92
|
+
## See also
|
|
93
|
+
|
|
94
|
+
- [`recurring-criticism`](../../../src/rules/recurring-criticism.md) — the obligation.
|
|
95
|
+
- [`decision-revisit-gate`](../../../src/rules/decision-revisit-gate.md) — the other entrance (a lock blocking a change), the five steps, the owner-reserved table.
|
|
96
|
+
- [`self-repair-loop`](../../../src/rules/self-repair-loop.md) — the single-occurrence intake and the `occurrences` counter this rule consumes.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@event4u/agent-config",
|
|
3
3
|
"mcpName": "io.github.event4u-app/agent-config",
|
|
4
|
-
"version": "14.
|
|
4
|
+
"version": "14.8.0",
|
|
5
5
|
"description": "Governed skills, rules and commands for AI coding tools (Claude Code, Cursor, Windsurf, Copilot) — every claim machine-checked, including \"zero runtime daemon\".",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"private": false,
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Archival-sweep spawner for the roadmap dashboard.
|
|
3
|
+
*
|
|
4
|
+
* Split out of `update_roadmap_progress.ts` rather than authored there: that
|
|
5
|
+
* file sits at the 1500-line source ceiling `check_source_size_budget`
|
|
6
|
+
* ratchets, and the sweep plus its contract is the newest and most separable
|
|
7
|
+
* thing in it. The contract below is that text, moved intact.
|
|
8
|
+
*
|
|
9
|
+
* `--archive` (opt-in; wired into `task roadmap-progress` and
|
|
10
|
+
* `agent-config roadmap:progress`) runs the archival sweep before rendering
|
|
11
|
+
* instead of printing "Completed roadmaps not yet archived" and leaving the
|
|
12
|
+
* work to a human who has been ignoring the line for weeks. It is a flag rather
|
|
13
|
+
* than the default because the PostToolUse hook re-runs the WRITE path once per
|
|
14
|
+
* turn on every roadmap edit, and a hook that silently `git mv`s files mid-work
|
|
15
|
+
* is a bigger problem than the warning it would remove. `--check` never
|
|
16
|
+
* archives — see `run_archival_sweep`.
|
|
17
|
+
*
|
|
18
|
+
* WHY the warning existed at all, since this is the one place a reader of the
|
|
19
|
+
* flag will look: the sweep's own default is `--changed-only`, so a PR archives
|
|
20
|
+
* exactly the roadmaps it completed. A roadmap completed by a PR whose sweep did
|
|
21
|
+
* not run is then complete, on the trunk, and OUTSIDE every later branch's
|
|
22
|
+
* history — no `--changed-only` sweep finds it again. Measured 2026-08-20: six
|
|
23
|
+
* such roadmaps, with every regen reprinting the warning at whoever ran it.
|
|
24
|
+
* `/create-pr` § 1c keeps `--changed-only`; repo-wide reconciliation is this
|
|
25
|
+
* flag's job and nothing else's.
|
|
26
|
+
*
|
|
27
|
+
* This layout is deliberate rather than convenient: the prose homes for it are
|
|
28
|
+
* both at their ceilings (`roadmap-progress-mechanics.md` sits 122 chars under
|
|
29
|
+
* the 16,000-char depth ceiling, and `roadmap-management/SKILL.md` tips
|
|
30
|
+
* `skill_too_large` on any prose block), so the contract lives with the code it
|
|
31
|
+
* governs. Moving it out means making room first.
|
|
32
|
+
*
|
|
33
|
+
* AI council 2026-08-20 (anthropic + openai, blind peer review): both seats
|
|
34
|
+
* converged on explicit opt-in + `--all` scope + hook archival-free, and both
|
|
35
|
+
* independently required the `--check` exclusion, the archive-before-render
|
|
36
|
+
* order, and that a failed sweep must not render. RECORDED DISSENT: one seat
|
|
37
|
+
* argued for flipping the sweep's own default to `--all` instead. Rejected —
|
|
38
|
+
* that makes every PR a potential estate-wide cleanup, which is exactly what
|
|
39
|
+
* `--changed-only` exists to prevent.
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
import { spawnSync } from 'node:child_process';
|
|
43
|
+
import * as fs from 'node:fs';
|
|
44
|
+
import * as path from 'node:path';
|
|
45
|
+
import { fileURLToPath } from 'node:url';
|
|
46
|
+
|
|
47
|
+
// Same directory as `update_roadmap_progress.ts`, so the `path.dirname` below
|
|
48
|
+
// resolves the sweep script exactly as it did before the split.
|
|
49
|
+
const _HERE = fileURLToPath(import.meta.url);
|
|
50
|
+
|
|
51
|
+
function _isFile(p: string): boolean {
|
|
52
|
+
try {
|
|
53
|
+
return fs.statSync(p).isFile();
|
|
54
|
+
} catch {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Run the archival sweep for every complete roadmap, in-place.
|
|
61
|
+
*
|
|
62
|
+
* Spawned rather than imported: `archive_completed_roadmaps.ts` imports
|
|
63
|
+
* `collect` from `update_roadmap_progress.ts`, so a static import back would close a cycle, and
|
|
64
|
+
* `main()` is synchronous so a dynamic `await import()` is not available either.
|
|
65
|
+
* The sweep is the same twin `_regen_dashboard` already spawns in the other
|
|
66
|
+
* direction, so the spawn shape is the established one in this pair.
|
|
67
|
+
*
|
|
68
|
+
* No recursion: the sweep re-runs this script with NO flags, so its inner
|
|
69
|
+
* dashboard pass has archival off and terminates at depth 2.
|
|
70
|
+
*
|
|
71
|
+
* `--all`, not the sweep's `--changed-only` default. The default exists so a PR
|
|
72
|
+
* archives exactly the roadmaps it completed; here the caller asked the
|
|
73
|
+
* repo-wide dashboard to reconcile the estate, and the roadmaps that leak are
|
|
74
|
+
* by construction the ones NOT in this branch's history — six had accumulated
|
|
75
|
+
* on the trunk while the warning printed every regen. A roadmap the sweep
|
|
76
|
+
* refuses (open blockers) stays put and is still reported below.
|
|
77
|
+
*/
|
|
78
|
+
export function run_archival_sweep(root: string): SweepResult {
|
|
79
|
+
const script = path.join(path.dirname(_HERE), 'archive_completed_roadmaps.ts');
|
|
80
|
+
if (!_isFile(script)) {
|
|
81
|
+
// A consumer install without the sweep script: nothing to run, and that
|
|
82
|
+
// is a normal state — the warning below still reports the roadmaps.
|
|
83
|
+
return { ran: false, ok: true, stdout: '', stderr: '' };
|
|
84
|
+
}
|
|
85
|
+
const argv = [script, '--all', '--repo-root', root];
|
|
86
|
+
const binName = process.platform === 'win32' ? 'tsx.cmd' : 'tsx';
|
|
87
|
+
let dir = path.dirname(_HERE);
|
|
88
|
+
for (;;) {
|
|
89
|
+
const candidate = path.join(dir, 'node_modules', '.bin', binName);
|
|
90
|
+
if (fs.existsSync(candidate)) {
|
|
91
|
+
return _sweepResult(spawnSync(candidate, argv, { cwd: root, encoding: 'utf-8' }));
|
|
92
|
+
}
|
|
93
|
+
const parent = path.dirname(dir);
|
|
94
|
+
if (parent === dir) {
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
dir = parent;
|
|
98
|
+
}
|
|
99
|
+
return _sweepResult(spawnSync('npx', ['tsx', ...argv], { cwd: root, encoding: 'utf-8' }));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export interface SweepResult {
|
|
103
|
+
ran: boolean;
|
|
104
|
+
ok: boolean;
|
|
105
|
+
stdout: string;
|
|
106
|
+
stderr: string;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function _sweepResult(r: ReturnType<typeof spawnSync>): SweepResult {
|
|
110
|
+
return {
|
|
111
|
+
ran: true,
|
|
112
|
+
ok: r.status === 0,
|
|
113
|
+
stdout: String(r.stdout ?? ''),
|
|
114
|
+
stderr: String(r.stderr ?? ''),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
* ./scripts-run src/scripts/archive_completed_roadmaps # --changed-only (default)
|
|
32
32
|
* ./scripts-run src/scripts/archive_completed_roadmaps --all
|
|
33
33
|
* ./scripts-run src/scripts/archive_completed_roadmaps --base origin/main --dry-run
|
|
34
|
+
* ./scripts-run src/scripts/archive_completed_roadmaps --repo-root /path/to/proj
|
|
34
35
|
*
|
|
35
36
|
* --- Parity notes (ADR-200) ---
|
|
36
37
|
*
|
|
@@ -397,10 +398,13 @@ function _regen_dashboard(root: string, dry_run: boolean): void {
|
|
|
397
398
|
// Python: `_run([sys.executable, str(script)], root)`; the twin spawns the
|
|
398
399
|
// dashboard generator twin through the same `tsx` runtime, cwd=root.
|
|
399
400
|
_runTwin(root, script);
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
401
|
+
// The dashboard is NOT staged. It is gitignored in this repository, and
|
|
402
|
+
// `git add -- <ignored-path>` exits 1 with "The following paths are ignored"
|
|
403
|
+
// -- a code `_run` returns and this call site discarded, so the previous
|
|
404
|
+
// `git add` here was a silent no-op from the moment the file was untracked
|
|
405
|
+
// (2026-08-21) and nothing objected. Regenerating it is still correct; the
|
|
406
|
+
// developer reads it on disk, and `task roadmap-progress-check` compares a
|
|
407
|
+
// present copy against a fresh render.
|
|
404
408
|
}
|
|
405
409
|
|
|
406
410
|
/**
|
|
@@ -462,19 +466,21 @@ function _runTwin(root: string, script: string): void {
|
|
|
462
466
|
const _PROG = 'archive_completed_roadmaps.py';
|
|
463
467
|
|
|
464
468
|
function _usage(): string {
|
|
465
|
-
return `usage: ${_PROG} [-h] [--all] [--base BASE] [--dry-run]\n`;
|
|
469
|
+
return `usage: ${_PROG} [-h] [--all] [--base BASE] [--dry-run] [--repo-root REPO_ROOT]\n`;
|
|
466
470
|
}
|
|
467
471
|
|
|
468
472
|
interface Args {
|
|
469
473
|
all: boolean;
|
|
470
474
|
base: string;
|
|
471
475
|
dry_run: boolean;
|
|
476
|
+
repo_root: string | null;
|
|
472
477
|
}
|
|
473
478
|
|
|
474
479
|
function _parseArgs(argv: readonly string[]): Args {
|
|
475
480
|
let all = false;
|
|
476
481
|
let base = 'origin/main';
|
|
477
482
|
let dry_run = false;
|
|
483
|
+
let repo_root: string | null = null;
|
|
478
484
|
const emitError = (msg: string): never => {
|
|
479
485
|
process.stderr.write(_usage());
|
|
480
486
|
process.stderr.write(`${_PROG}: error: ${msg}\n`);
|
|
@@ -502,17 +508,30 @@ function _parseArgs(argv: readonly string[]): Args {
|
|
|
502
508
|
} else if (tok.startsWith('--base=')) {
|
|
503
509
|
base = tok.slice('--base='.length);
|
|
504
510
|
i += 1;
|
|
511
|
+
} else if (tok === '--repo-root') {
|
|
512
|
+
const val = argv[i + 1];
|
|
513
|
+
if (val === undefined) {
|
|
514
|
+
emitError('argument --repo-root: expected one argument');
|
|
515
|
+
}
|
|
516
|
+
repo_root = val as string;
|
|
517
|
+
i += 2;
|
|
518
|
+
} else if (tok.startsWith('--repo-root=')) {
|
|
519
|
+
repo_root = tok.slice('--repo-root='.length);
|
|
520
|
+
i += 1;
|
|
505
521
|
} else {
|
|
506
522
|
emitError(`unrecognized arguments: ${tok}`);
|
|
507
523
|
}
|
|
508
524
|
}
|
|
509
|
-
return { all, base, dry_run };
|
|
525
|
+
return { all, base, dry_run, repo_root };
|
|
510
526
|
}
|
|
511
527
|
|
|
512
528
|
function main(argv?: readonly string[]): number {
|
|
513
529
|
const ns = _parseArgs(argv ?? process.argv.slice(2));
|
|
514
530
|
|
|
515
|
-
|
|
531
|
+
// An explicit `--repo-root` wins over the `git rev-parse` resolution. The
|
|
532
|
+
// dashboard generator passes it so a monorepo sub-project sweep cannot walk
|
|
533
|
+
// up to the enclosing repo and archive the PARENT's roadmaps.
|
|
534
|
+
const root = ns.repo_root ?? _repo_root();
|
|
516
535
|
const archived = archive_completed(root, {
|
|
517
536
|
changed_only: !ns.all,
|
|
518
537
|
base: ns.base,
|