@event4u/agent-config 14.21.0 → 14.23.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/.augment-plugin/marketplace.json +3 -3
- package/.augment-plugin/plugin.json +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +164 -187
- package/CREDITS.md +37 -0
- package/README.md +1 -1
- package/dist/agent-src/commands/analyze/inbox.md +380 -5
- package/dist/agent-src/commands/analyze/repo.md +4 -2
- package/dist/agent-src/commands/pr/merge.md +47 -38
- package/dist/agent-src/commands/roadmap/next.md +8 -0
- package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +69 -0
- package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +5 -5
- package/dist/agent-src/contexts/execution/autonomy-mechanics.md +12 -0
- package/dist/agent-src/rules/external-code-graph-interop.md +19 -14
- package/dist/agent-src/rules/notes-first-reasoning.md +36 -25
- package/dist/agent-src/rules/token-efficiency.md +26 -3
- package/dist/agent-src/scripts/_cli_entry.ts +51 -0
- package/dist/agent-src/scripts/archive_completed_roadmaps.ts +120 -27
- package/dist/agent-src/scripts/roadmap_gates.ts +4 -20
- package/dist/agent-src/scripts/roadmap_set_step.ts +5 -2
- package/dist/agent-src/scripts/stubs_due.ts +4 -18
- package/dist/agent-src/scripts/update_roadmap_progress.ts +7 -24
- package/dist/agent-src/skills/code-intelligence/SKILL.md +82 -1
- package/dist/agent-src/skills/git-workflow/references/push-closes-its-loop.md +9 -0
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +17 -0
- package/dist/agent-src/skills/tailwind-engineer/SKILL.md +52 -2
- package/dist/agent-src/templates/agent-settings.md +0 -1
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/cli/registry.js +1 -1
- package/dist/cli-delegate/_cli_entry.js +8 -0
- package/dist/cli-delegate/_lib/pin_resolver.js +170 -0
- package/dist/cli-delegate/archival_sweep.js +8 -0
- package/dist/cli-delegate/archive_completed_roadmaps.js +542 -0
- package/dist/cli-delegate/check_update_banner.js +923 -0
- package/dist/cli-delegate/{chunk-ZVBOHSVF.js → chunk-2KKXJW25.js} +23 -9
- package/dist/cli-delegate/chunk-5EK5WQN6.js +28 -0
- package/dist/cli-delegate/chunk-7XGD2OEU.js +96 -0
- package/dist/cli-delegate/chunk-DBH4AHDK.js +155 -0
- package/dist/cli-delegate/{chunk-4FS4WRXP.js → chunk-IAI3XL43.js} +15 -3
- package/dist/cli-delegate/chunk-JO25G5H7.js +20 -0
- package/dist/cli-delegate/{chunk-643Z7FIC.js → chunk-KCNTUSPI.js} +7 -1
- package/dist/cli-delegate/chunk-LTYVIY76.js +7961 -0
- package/dist/cli-delegate/chunk-QAJS5YWY.js +999 -0
- package/dist/cli-delegate/{chunk-YS6XTLEK.js → chunk-TYSY33MD.js} +56 -6
- package/dist/cli-delegate/chunk-ULET4BYS.js +328 -0
- package/dist/cli-delegate/chunk-YDQSHTD7.js +187 -0
- package/dist/cli-delegate/chunk-YWVXLR44.js +48 -0
- package/dist/cli-delegate/chunk-ZZQBUHFK.js +273 -0
- package/dist/cli-delegate/cmd_conformance.js +2 -2
- package/dist/cli-delegate/cmd_export.js +2 -2
- package/dist/cli-delegate/cmd_handoff.js +45 -13
- package/dist/cli-delegate/cmd_prune.js +2 -2
- package/dist/cli-delegate/cmd_session_recycle.js +4 -14
- package/dist/cli-delegate/cmd_settings_migrate.js +2 -2
- package/dist/cli-delegate/cmd_settings_set.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +2 -2
- package/dist/cli-delegate/cmd_uninstall.js +2 -2
- package/dist/cli-delegate/cmd_validate.js +2 -2
- package/dist/cli-delegate/dashboard_mode.js +16 -0
- package/dist/cli-delegate/gate_budget.js +24 -0
- package/dist/cli-delegate/gate_execute.js +25 -0
- package/dist/cli-delegate/guarded_baseline.js +18 -0
- package/dist/cli-delegate/resume_probe.js +22 -0
- package/dist/cli-delegate/roadmap_gates.js +638 -0
- package/dist/cli-delegate/roadmap_set_step.js +173 -0
- package/dist/cli-delegate/stub_queue.js +47 -0
- package/dist/cli-delegate/stubs_due.js +38 -0
- package/dist/cli-delegate/ticket_bundles.js +59 -0
- package/dist/cli-delegate/update_roadmap_progress.js +60 -0
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +13 -13
- 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 +1813 -946
- package/dist/install/claudeLayerCarriage.js +237 -0
- package/dist/install/claudePathsPlan.js +79 -0
- package/dist/install/hostLayerFingerprint.js +1 -1
- package/dist/install/install.mjs +21 -3
- package/dist/install/partitionEligibility.js +231 -117
- package/dist/install/ruleLayerPartition.js +10 -7
- package/dist/mcp/registry-manifest.json +2 -2
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +10870 -7641
- package/dist/scripts/_lib/lean_projection_mode.js +108 -0
- package/dist/scripts/_lib/router_match.js +243 -0
- package/dist/scripts/_lib/rule_injection.js +216 -0
- package/dist/scripts/condense.js +52 -45
- package/dist/scripts/project_thin_rules.js +139 -19
- package/dist/server/schemas/settings.js +16 -3
- package/docs/MIGRATION.md +105 -1
- package/docs/contracts/settings-classes.md +40 -8
- package/docs/guidelines/agent-infra/minimal-safe-diff-mechanics.md +73 -0
- package/docs/guidelines/agent-infra/notes-horizon-mechanics.md +90 -0
- package/llms.txt +1 -1
- package/package.json +7 -4
- package/src/agent-src/scripts/_cli_entry.ts +51 -0
- package/src/agent-src/scripts/archive_completed_roadmaps.ts +120 -27
- package/src/agent-src/scripts/roadmap_gates.ts +4 -20
- package/src/agent-src/scripts/roadmap_set_step.ts +5 -2
- package/src/agent-src/scripts/stubs_due.ts +4 -18
- package/src/agent-src/scripts/update_roadmap_progress.ts +7 -24
- package/src/config/agent-settings.template.yml +47 -1
- package/src/config/continuity-surface.json +516 -0
- package/src/config/estate-count-budget.json +1 -1
- package/src/config/evaluator-budgets.json +4 -4
- package/src/config/gate-coverage.yml +29 -8
- package/src/config/gate-violation-baselines.json +8 -8
- package/src/config/gitignore-block.txt +19 -0
- package/src/config/hook-token-budget.json +7 -6
- package/src/config/host-injection-effect.json +73 -0
- package/src/config/packed-binary-manifest.json +33 -0
- package/src/config/preamble-payload-budget.json +112 -105
- package/src/config/publish-surface.json +4 -2
- package/src/config/routing-coverage-seed.json +9 -2
- package/src/install/claudeLayerCarriage.ts +273 -0
- package/src/install/claudePathsPlan.ts +76 -0
- package/src/install/hostLayerFingerprint.ts +1 -1
- package/src/install/partitionEligibility.ts +261 -127
- package/src/install/ruleLayerPartition.ts +19 -23
- package/src/scripts/_cli/cmd_session_recycle.ts +2 -25
- package/src/scripts/_cli/handoff_sessions.ts +14 -44
- package/src/scripts/_dispatch.bash +77 -27
- package/src/scripts/_lib/auto_dispatch.ts +2 -2
- package/src/scripts/_lib/catalogue_layer_parity.ts +146 -0
- package/src/scripts/_lib/continuity_slot.ts +295 -0
- package/src/scripts/_lib/continuity_surface.ts +296 -0
- package/src/scripts/_lib/continuity_writer.ts +253 -0
- package/src/scripts/_lib/corpus_manifest.ts +26 -9
- package/src/scripts/_lib/hook_settings.ts +86 -1
- package/src/scripts/_lib/injection_effect.ts +151 -0
- package/src/scripts/_lib/layer_overlap_notice.ts +50 -6
- package/src/scripts/_lib/lean_projection_mode.ts +127 -0
- package/src/scripts/_lib/packed_binary_predicate.ts +262 -0
- package/src/scripts/_lib/pin_resolver.ts +13 -0
- package/src/scripts/_lib/recycle_envelope_paths.ts +109 -21
- package/src/scripts/_lib/regression_neighbourhood.ts +159 -22
- package/src/scripts/_lib/retired_status.ts +74 -0
- package/src/scripts/_lib/session_eol.ts +44 -0
- package/src/scripts/_lib/session_index_trust.ts +346 -0
- package/src/scripts/_lib/skill_catalogue.ts +156 -21
- package/src/scripts/_lib/standing_bound_ratchet.ts +154 -0
- package/src/scripts/_lib/subagent_capsule.ts +117 -8
- package/src/scripts/_lib/vendored_grammar_upstream.ts +280 -0
- package/src/scripts/ai_council/api_transport.ts +5 -0
- package/src/scripts/ai_council/deliberation_metrics.ts +353 -0
- package/src/scripts/ai_council/prompts.ts +9 -0
- package/src/scripts/ai_council/synthesis_disagreement.ts +206 -0
- package/src/scripts/audit_mcp_tools.ts +69 -25
- package/src/scripts/build_mcp_catalog.ts +24 -1
- package/src/scripts/capture_skill_catalogue.ts +24 -11
- package/src/scripts/check_candidate_lines.ts +499 -0
- package/src/scripts/check_continuity_surface.ts +475 -0
- package/src/scripts/check_dependency_floors.ts +13 -6
- package/src/scripts/check_estate_count.ts +40 -79
- package/src/scripts/check_host_tree_parity.ts +291 -0
- package/src/scripts/check_pack_size.ts +262 -23
- package/src/scripts/check_preamble_payload_budget.ts +136 -7
- package/src/scripts/check_roadmap_trackable.ts +19 -16
- package/src/scripts/check_rule_layer_partition.ts +54 -34
- package/src/scripts/check_rule_projection_integrity.ts +102 -2
- package/src/scripts/check_single_delivery.ts +97 -31
- package/src/scripts/check_update_banner.ts +13 -0
- package/src/scripts/ci_settle.ts +205 -5
- package/src/scripts/code_graph/build.ts +217 -15
- package/src/scripts/code_graph/cli.ts +334 -15
- package/src/scripts/code_graph/detect.ts +38 -0
- package/src/scripts/code_graph/extract.ts +11 -0
- package/src/scripts/code_graph/grammar_probe.ts +43 -0
- package/src/scripts/code_graph/loader.ts +88 -14
- package/src/scripts/code_graph/query.ts +144 -11
- package/src/scripts/code_graph/resolution_tiers.ts +238 -0
- package/src/scripts/code_graph/sqlite_store.ts +262 -6
- package/src/scripts/code_graph/types.ts +117 -3
- package/src/scripts/code_graph/validate.ts +26 -1
- package/src/scripts/code_graph/verbs.ts +590 -0
- package/src/scripts/condense.ts +54 -42
- package/src/scripts/corpus_manifest.ts +5 -5
- package/src/scripts/council_cli.ts +11 -12
- package/src/scripts/count_intent_disagreement.ts +426 -0
- package/src/scripts/handoff_context_hook.ts +118 -1
- package/src/scripts/hook_effect_doctor.ts +82 -1
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +87 -12
- package/src/scripts/hooks/block_speaking_inbox_dir.ts +182 -16
- package/src/scripts/hooks/chain_nudge_hook.ts +282 -0
- package/src/scripts/hooks/code_graph_context_hook.ts +201 -0
- package/src/scripts/hooks/concern_registry.ts +4 -2
- package/src/scripts/hooks/host_semantics.ts +1 -1
- package/src/scripts/hooks/orchestration_record_hook.ts +2 -2
- package/src/scripts/hooks/push_settle_hook.ts +3 -2
- package/src/scripts/hooks/rule_inject_hook.ts +108 -21
- package/src/scripts/hooks/session_eol_hook.ts +120 -2
- package/src/scripts/hooks/skill_route_hook.ts +11 -4
- package/src/scripts/hot_context_hook.ts +62 -7
- package/src/scripts/inbox_source_census.ts +322 -0
- package/src/scripts/install-hooks.sh +82 -0
- package/src/scripts/{lint_carrier_integrity.ts → lint_deferral_integrity.ts} +60 -214
- package/src/scripts/lint_plan_risk_register.ts +13 -17
- package/src/scripts/lint_roadmap_blockers.ts +164 -1
- package/src/scripts/mcp_server/consumer_tool_catalog.json +152 -2
- package/src/scripts/mcp_server/graph_tools.ts +294 -0
- package/src/scripts/mcp_server/path_util.ts +31 -0
- package/src/scripts/mcp_server/suggest_skill.ts +72 -0
- package/src/scripts/mcp_server/tool_catalog_source.ts +7 -1
- package/src/scripts/mcp_server/tools.ts +5 -69
- package/src/scripts/media/lib/adapter-contract.md +7 -2
- package/src/scripts/media/lib/fixtures/flux/asset-0001.png +0 -0
- package/src/scripts/media/lib/fixtures/gemini-image/asset-0001.png +0 -0
- package/src/scripts/media/lib/fixtures/ideogram/asset-0001.png +0 -0
- package/src/scripts/model_rule_injection.ts +61 -4
- package/src/scripts/project_thin_rules.ts +149 -16
- package/src/scripts/rdp_candidates_delta.ts +276 -0
- package/src/scripts/rdp_quality_eval.ts +217 -19
- package/src/scripts/release_mix_taxonomy.json +3 -2
- package/src/scripts/report_host_injection_effect.ts +189 -0
- package/src/scripts/report_layer_overlap.ts +41 -0
- package/src/scripts/report_skill_menu_census.ts +341 -0
- package/src/scripts/report_standing_payload_by_host.ts +650 -0
- package/src/scripts/schemas/agent-settings.schema.json +7 -1
- package/src/scripts/session_memory_index.ts +81 -8
- package/src/scripts/skill_tools/score_skill_relevance.ts +70 -6
- package/src/scripts/skill_tools/suggest_skill_for_task.ts +37 -3
- package/src/server/schemas/settings.ts +23 -4
- package/src/vendor/grammars/README.md +86 -0
- package/src/vendor/grammars/tree-sitter-javascript.wasm +0 -0
- package/src/vendor/grammars/tree-sitter-php.wasm +0 -0
- package/src/vendor/grammars/tree-sitter-typescript.wasm +0 -0
- package/src/scripts/_lib/carrier_status.ts +0 -118
- package/src/scripts/_lib/estate_carrier_cases.ts +0 -72
- package/src/scripts/hooks/code_graph_nudge_hook.ts +0 -191
|
@@ -155,3 +155,72 @@ could have shared. `probe_turnaround` reports the rate afterwards and refuses to
|
|
|
155
155
|
gate on a store CI does not have. This paragraph is the whole mechanism, and the
|
|
156
156
|
roadmap that added it pre-committed to recording a null if the rate does not
|
|
157
157
|
move rather than repeating the reminder more loudly.
|
|
158
|
+
|
|
159
|
+
## One command per Bash call — the detail
|
|
160
|
+
|
|
161
|
+
Migrated from `token-efficiency` § One command per Bash call on 2026-09-08,
|
|
162
|
+
because that rule's body is re-written on every subagent spawn while this file
|
|
163
|
+
is loaded on demand. The Iron Law stays in the rule; everything below is
|
|
164
|
+
lookup material.
|
|
165
|
+
|
|
166
|
+
### Why chaining costs more, not less
|
|
167
|
+
|
|
168
|
+
The host splits a compound command on `&&`, `||`, `;`, `|`, `|&`, `&` and
|
|
169
|
+
newlines and requires **each segment to match the allowlist independently**.
|
|
170
|
+
A single unmatched segment sends the whole call down the permission path even
|
|
171
|
+
when every other segment was already allowed. So chaining does not save a
|
|
172
|
+
round-trip — it converts N cheap authorizations into one expensive one.
|
|
173
|
+
|
|
174
|
+
### The measurement
|
|
175
|
+
|
|
176
|
+
Over 40,268 real Bash calls from one maintainer's transcripts:
|
|
177
|
+
|
|
178
|
+
- **97.7 %** carry a shell metacharacter. The package's own category-A
|
|
179
|
+
classifier (`permission_gate` + `category_a.ts`) is therefore reachable on
|
|
180
|
+
**2.3 %** of real calls; the host allowlist decides the rest.
|
|
181
|
+
- **17.9 %** have a head token matching no allowlist pattern. Distribution:
|
|
182
|
+
a leading `VAR=…` assignment 5,215×, `./scripts-run` 520×, `python3` 518×,
|
|
183
|
+
shell loop keywords 460×, `sleep` 155×, `mkdir` 71×, `cp` 49×.
|
|
184
|
+
- Of those 5,215 assignments, **5,037 are genuinely standalone** (`F=/path; …`)
|
|
185
|
+
and only 178 are env prefixes (`VAR=v cmd`). The distinction was checked
|
|
186
|
+
rather than assumed, because a review had claimed the whole class was a
|
|
187
|
+
measurement artifact. It is not: that shape cannot be written as an
|
|
188
|
+
allowlist pattern at all, so it shrinks only by not being written.
|
|
189
|
+
|
|
190
|
+
### The substitutions
|
|
191
|
+
|
|
192
|
+
| Instead of | Write |
|
|
193
|
+
|---|---|
|
|
194
|
+
| `D=/repo; cd $D && git status` | `git -C /repo status` |
|
|
195
|
+
| `V=$(git rev-parse HEAD); echo $V` | two calls, the second using the printed value |
|
|
196
|
+
| `mkdir -p x && cp a x/` | two calls in the same block |
|
|
197
|
+
| `cd sub && <cmd>` | the directory flag the tool already has (`-C`, `--cwd`, `--prefix`) |
|
|
198
|
+
|
|
199
|
+
A loop that genuinely cannot be expressed without the shell stays a loop —
|
|
200
|
+
prefer a script file over an inline `for` when it recurs.
|
|
201
|
+
|
|
202
|
+
### What the carrier does and does not do
|
|
203
|
+
|
|
204
|
+
`chain-nudge` (`src/scripts/hooks/chain_nudge_hook.ts`) is a `pre_tool_use`
|
|
205
|
+
concern bound on the three hook-capable platforms. It reads
|
|
206
|
+
`tool_input.command`, strips quoted spans and heredoc bodies so an operator
|
|
207
|
+
inside a string literal cannot be misread, and injects one advisory line the
|
|
208
|
+
first time a session chains work. It is ON by default with
|
|
209
|
+
`hooks.chain_nudge.enabled: false` as the opt-out — inverting
|
|
210
|
+
`code-graph-nudge`, which gates on a project capability that may be absent,
|
|
211
|
+
because the fact this one carries is a property of the host's permission
|
|
212
|
+
matcher and holds in every consumer.
|
|
213
|
+
|
|
214
|
+
**It never blocks, and it fires once.** So it changes what the agent knows,
|
|
215
|
+
not what the agent may do: compliance stays model-carried, and the concern's
|
|
216
|
+
tests establish detector behavior, not adherence. On a host with no
|
|
217
|
+
`pre_tool_use` slot nothing fires at all and the rule is model-carried end to
|
|
218
|
+
end — `agent-config hooks:status` reports which slots are bound where you are.
|
|
219
|
+
|
|
220
|
+
### The sentence this replaced
|
|
221
|
+
|
|
222
|
+
Until 2026-09-08 the batching paragraph in the rule ended "NOT write shorter
|
|
223
|
+
commands: the long commands are already the batching." That was written about
|
|
224
|
+
token cost, where it holds, and it is wrong about the permission layer below —
|
|
225
|
+
a batch is N tool calls in ONE block, never N shell commands in ONE call. The
|
|
226
|
+
old wording collapsed the two and so encouraged the most expensive shape.
|
|
@@ -232,11 +232,11 @@ NEVER A SILENTLY DEGRADED ANSWER. NO LLM CLASSIFIER FALLBACK (CUT C3).
|
|
|
232
232
|
**Why rg-first** (council 2026-07-28, 2 rounds): the pre-registered benchmark
|
|
233
233
|
behind the `code-graph-retrieval-null` claim (`docs/CLAIMS.md`) measured
|
|
234
234
|
native-graph recall 0.365 vs grep 0.797 on graph-shaped questions — an
|
|
235
|
-
indexing gap that
|
|
236
|
-
permanently: the 2026-08-15 withdrawal retracted
|
|
237
|
-
the 2026-08-22 extractor repair. The accelerant
|
|
238
|
-
|
|
239
|
-
|
|
235
|
+
indexing gap that kept `code_graph.enabled` false BY DEFAULT until that flag
|
|
236
|
+
was retired (2026-09-07) — not permanently: the 2026-08-15 withdrawal retracted
|
|
237
|
+
that, and the figures predate the 2026-08-22 extractor repair. The accelerant
|
|
238
|
+
clause above is that bound's escape hatch, reached only when a caller passes a
|
|
239
|
+
usable graph, which no production caller yet does.
|
|
240
240
|
|
|
241
241
|
**Escalation, not degradation:** a primitive that returns nothing (index miss,
|
|
242
242
|
pattern too ambiguous, report script absent) — **or an unusable result**
|
|
@@ -193,6 +193,18 @@ decision. Engage per [`rdp-gate`](rdp-gate.md).
|
|
|
193
193
|
The suite states three retry numbers; they are **stages of one escalation
|
|
194
194
|
ladder on the same failing target**, not competing budgets:
|
|
195
195
|
|
|
196
|
+
0. **Attempt 1 fails → read the candidate list, if one exists, BEFORE retry 1.**
|
|
197
|
+
Where the run recorded a candidate set for this work
|
|
198
|
+
([`notes-first-reasoning`](../../rules/notes-first-reasoning.md)
|
|
199
|
+
§ Reopening), the first failure reads it first: a failure is evidence about
|
|
200
|
+
the CHOSEN FORM, and retrying the same approach spends the budget without
|
|
201
|
+
ever reaching the second-best candidate — which is how the mechanism that
|
|
202
|
+
discovers a form was wrong never routes back to the form. Where no candidate
|
|
203
|
+
list exists the ladder is unchanged and stage 1 runs immediately.
|
|
204
|
+
**This adds a branch; it does not move the budget.** Reading the list is not
|
|
205
|
+
an attempt and is not counted, and the reopen is capped at one per candidate:
|
|
206
|
+
the second contradiction on the same candidate continues down this ladder
|
|
207
|
+
rather than reopening again.
|
|
196
208
|
1. **Attempt 1 fails → up to 2 retries of the same approach**
|
|
197
209
|
([`think-before-action`](../../rules/think-before-action.md) "MAX 2
|
|
198
210
|
RETRIES PER APPROACH") — the soft, agent-side stage: rethink between
|
|
@@ -25,11 +25,10 @@ obligation_frequency: "per-turn"
|
|
|
25
25
|
|
|
26
26
|
Some repos commit a pre-built code-intelligence index — a `graph.json`-shaped
|
|
27
27
|
artifact or a SCIP index (`index.scip`, `*.scip`). One that exists is already
|
|
28
|
-
built
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
benchmark-gated) covers the gap.
|
|
28
|
+
built, so it is the cheap first question for "who calls X", "where is Y used",
|
|
29
|
+
"what does this import". This suite is an **orchestrator first, owner where it
|
|
30
|
+
wins** (ADR-124): query a shipped index when present and fresh; otherwise the
|
|
31
|
+
native engine covers the gap (shipped since ADR-259 — no manual install).
|
|
33
32
|
|
|
34
33
|
## The rule
|
|
35
34
|
|
|
@@ -41,6 +40,17 @@ NO FRESH INDEX SHIPPED → THE NATIVE ENGINE MAY BUILD ONE (ADR-124); STILL
|
|
|
41
40
|
GREP-FALLBACK FOR WHAT THE GRAPH DOES NOT ANSWER, AND SAY WHICH SOURCE ANSWERED.
|
|
42
41
|
```
|
|
43
42
|
|
|
43
|
+
## Staleness is part of the answer
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
AN ANSWER FROM AN INDEX N COMMITS BEHIND IS WORTH LESS THAN THE SAME ANSWER
|
|
47
|
+
FROM A FRESH ONE. NEVER REPORT A GRAPH ANSWER WITHOUT KNOWING WHICH IT WAS.
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`behind:N` → refresh first, or grep and say so. Silence is not freshness.
|
|
51
|
+
Delivery per host: [`code-intelligence`](../skills/code-intelligence/SKILL.md)
|
|
52
|
+
§ Staleness delivery.
|
|
53
|
+
|
|
44
54
|
## When it fires
|
|
45
55
|
|
|
46
56
|
A codebase-structure question (call graph, references, usages, import graph)
|
|
@@ -58,9 +68,8 @@ AND the repo contains a detectable index:
|
|
|
58
68
|
3. **Fall back to `grep`/read** only for what the index does not cover, and say
|
|
59
69
|
so ("the index has no entry for X, so I grepped").
|
|
60
70
|
|
|
61
|
-
Query-first is an **ordering** heuristic, never a claim the index answers better
|
|
62
|
-
|
|
63
|
-
is graph-first. Routing changes; permission does not. Figures:
|
|
71
|
+
Query-first is an **ordering** heuristic, never a claim the index answers better
|
|
72
|
+
— no measured class beat `grep`. Figures:
|
|
64
73
|
[`code-intelligence`](../skills/code-intelligence/SKILL.md) § Measured.
|
|
65
74
|
|
|
66
75
|
## When NOT to fire
|
|
@@ -71,11 +80,7 @@ is graph-first. Routing changes; permission does not. Figures:
|
|
|
71
80
|
## See also
|
|
72
81
|
|
|
73
82
|
- [`code-intelligence`](../skills/code-intelligence/SKILL.md) — the executable
|
|
74
|
-
routing skill
|
|
75
|
-
|
|
76
|
-
(`agent-config hooks:status`, never a guess from the host name).
|
|
77
|
-
- [`discovery_graph`](../scripts/discovery_graph.ts) — this suite's OWN artefact
|
|
78
|
-
relation-graph (`affected`/`explain`); the external code-graph is the
|
|
79
|
-
*source-code* analogue this rule defers to for code questions.
|
|
83
|
+
routing skill, the measured figures, staleness delivery per host, and the
|
|
84
|
+
pointer to this suite's OWN artifact relation-graph (`discovery_graph`).
|
|
80
85
|
- [`think-before-action`](think-before-action.md) — analyze with the best
|
|
81
86
|
available tool before grepping blind.
|
|
@@ -24,11 +24,8 @@ obligation_frequency: "per-turn"
|
|
|
24
24
|
# Notes-First Reasoning
|
|
25
25
|
|
|
26
26
|
Part of the Reasoning Discipline Protocol. Engage per
|
|
27
|
-
[`rdp-gate`](../contexts/execution/rdp-gate.md)
|
|
28
|
-
|
|
29
|
-
host. The notes file is grounded in the documented cross-run lessons memory
|
|
30
|
-
(consolidated via [`memory-consolidation`](../skills/memory-consolidation/SKILL.md));
|
|
31
|
-
the in-task sections below are a local derivation for within-task scope.
|
|
27
|
+
[`rdp-gate`](../contexts/execution/rdp-gate.md) — skip on trivial tasks, apply
|
|
28
|
+
lightly on a strong-reasoning host.
|
|
32
29
|
|
|
33
30
|
## The Iron Law
|
|
34
31
|
|
|
@@ -38,36 +35,50 @@ NOTES FILE — NEVER ECHOED INTO THE RESPONSE.
|
|
|
38
35
|
THE RESPONSE CARRIES CONCLUSIONS + EVIDENCE ONLY.
|
|
39
36
|
```
|
|
40
37
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
This is not "show your work in the reply" — it is the opposite. Why, and what
|
|
39
|
+
grounds the notes file:
|
|
40
|
+
[`notes-horizon-mechanics`](../docs/guidelines/agent-infra/notes-horizon-mechanics.md).
|
|
44
41
|
|
|
45
42
|
## Notes file structure (the file, not the response)
|
|
46
43
|
|
|
47
|
-
Use the sections that apply
|
|
48
|
-
no "write N hypotheses" instruction — record what the work actually surfaced.
|
|
44
|
+
Use the sections that apply — record what the work actually surfaced.
|
|
49
45
|
|
|
50
46
|
- `## In-Task Hypothesis Log` — competing explanations under consideration.
|
|
51
|
-
- `## Killed beliefs` — each discarded hypothesis + the
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
- `## Decisions` — decision · alternatives · reason · revisit-if
|
|
55
|
-
|
|
56
|
-
[`decision-record`](../skills/decision-record/SKILL.md)/ADR** when
|
|
57
|
-
|
|
58
|
-
next month need this context?).
|
|
47
|
+
- `## Killed beliefs` — each discarded hypothesis + the `killed-if` that killed
|
|
48
|
+
it.
|
|
49
|
+
- `## Predictions` — **chosen form** · prediction · confidence · result · lesson.
|
|
50
|
+
- `## Decisions` — decision · alternatives · reason · revisit-if ·
|
|
51
|
+
**next-commitment**. Tactical decisions stay here; **escalate to
|
|
52
|
+
[`decision-record`](../skills/decision-record/SKILL.md)/ADR** when cross-task
|
|
53
|
+
or architectural.
|
|
59
54
|
- `## Uncertainty` — per-dimension score (e.g. architecture/implementation/
|
|
60
55
|
requirements: high/medium/low); feeds the adaptive-effort decision.
|
|
61
56
|
|
|
57
|
+
### The horizon — where `next-commitment` ends
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
A CHOICE AUTHORISES WORK UP TO THE NEXT EVIDENCE-PRODUCING BOUNDARY.
|
|
61
|
+
NAME THE BOUNDARY FROM THE LIST. NEVER "THE WORK THE EVIDENCE SUPPORTS" —
|
|
62
|
+
THAT IS A JUDGEMENT, AND A JUDGEMENT IS NOT A HORIZON.
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Reopening — once, on contradiction, never on a schedule
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
AN OBSERVATION THAT CONTRADICTS THE PREDICTION REOPENS THE CHOICE BEFORE THE
|
|
69
|
+
NEXT STEP — FROM THE CANDIDATE LIST THAT ALREADY EXISTS, NEVER A FRESH
|
|
70
|
+
ENUMERATION. ONE REOPEN PER CANDIDATE. THE SECOND CONTRADICTION HANDS OVER TO
|
|
71
|
+
THE RETRY-BUDGET LADDER RATHER THAN REOPENING AGAIN.
|
|
72
|
+
```
|
|
73
|
+
|
|
62
74
|
## What stays out of notes
|
|
63
75
|
|
|
64
|
-
User-attribute facts, transient TODOs, and durable cross-run lessons
|
|
65
|
-
|
|
76
|
+
User-attribute facts, transient TODOs, and durable cross-run lessons go to the
|
|
77
|
+
memory system (`memory-consolidation`), not the in-task notes.
|
|
66
78
|
|
|
67
79
|
## See also
|
|
68
80
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
response carries comes from real tool results.
|
|
81
|
+
[`notes-horizon-mechanics`](../docs/guidelines/agent-infra/notes-horizon-mechanics.md)
|
|
82
|
+
— every mechanic this rule points at. Also
|
|
83
|
+
[`rdp-gate`](../contexts/execution/rdp-gate.md) and
|
|
84
|
+
[`verify-before-complete`](verify-before-complete.md).
|
|
@@ -37,9 +37,32 @@ A CALL THAT DOES NOT READ THE PREVIOUS RESULT IS NOT A SECOND TURN.
|
|
|
37
37
|
|
|
38
38
|
The ceiling above forbids repetition; this forbids splitting work that had no
|
|
39
39
|
reason to be split — measured mean batch size **1.01**, i.e. fully serial. The
|
|
40
|
-
discriminator is the dependency, never the count.
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
discriminator is the dependency, never the count. `instruction-only` — nothing
|
|
41
|
+
can observe a call that was not batched. Evidence + the absent-cause finding:
|
|
42
|
+
[`token-efficiency-mechanics`](../contexts/communication/rules-auto/token-efficiency-mechanics.md).
|
|
43
|
+
|
|
44
|
+
## One command per Bash call
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
ONE COMMAND PER BASH CALL. NEVER CHAIN WORK STEPS WITH `;`, `&&` OR `||`,
|
|
48
|
+
AND NEVER CARRY STATE FORWARD IN A LEADING `VAR=…` ASSIGNMENT.
|
|
49
|
+
N COMMANDS GO IN N CALLS IN ONE BLOCK — THAT IS WHAT A BATCH IS.
|
|
50
|
+
A CHAINED CALL IS AUTHORIZED ONLY AS STRONGLY AS ITS WEAKEST SEGMENT.
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
A permission rule, not a token one — which is why it is not folded into the
|
|
54
|
+
section above. The host splits a compound command on the shell operators and
|
|
55
|
+
requires **each segment to match the allowlist independently**, so one
|
|
56
|
+
unmatched segment sends the whole call down the permission path even when
|
|
57
|
+
every other segment was already allowed. Chaining converts N cheap
|
|
58
|
+
authorizations into one expensive one. `D=/repo; cd $D && git status` is
|
|
59
|
+
`git -C /repo status`.
|
|
60
|
+
|
|
61
|
+
**Not forbidden:** a pipe of ordinary filters, a redirect, a heredoc — one
|
|
62
|
+
command with a filter or with input, not two work steps. Carried at tool-call
|
|
63
|
+
time by the `chain-nudge` `pre_tool_use` concern, which is advisory and never
|
|
64
|
+
blocks, so compliance stays model-carried. Measured numbers, the substitution
|
|
65
|
+
table and the carrier's limits:
|
|
43
66
|
[`token-efficiency-mechanics`](../contexts/communication/rules-auto/token-efficiency-mechanics.md).
|
|
44
67
|
|
|
45
68
|
## Enumerated file sets are ONE operation, not N repetitions
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Was this module invoked as the command?" — one definition for the scripts
|
|
3
|
+
* under `agents/scripts` that both run directly and are imported by siblings.
|
|
4
|
+
*
|
|
5
|
+
* Five of them carried a byte-identical copy of this logic, and the copies were
|
|
6
|
+
* about to gain a sixth clause each. The interesting part is why the obvious
|
|
7
|
+
* one-liner is not enough:
|
|
8
|
+
*
|
|
9
|
+
* - `--splitting` in `build:agent-src-delegate` can move a module body into a
|
|
10
|
+
* shared chunk, where `import.meta.url` names the CHUNK. The URL comparison
|
|
11
|
+
* then never matches and the command exits 0 having done nothing — measured
|
|
12
|
+
* on `update_roadmap_progress` before this guard existed. Inside the bundle
|
|
13
|
+
* the invoked file name is the reliable signal, so the delegate branch runs
|
|
14
|
+
* first and a miss falls through rather than returning false.
|
|
15
|
+
* - A symlinked invocation (`.augment/scripts` → `dist/agent-src/scripts`, or
|
|
16
|
+
* macOS `/var` → `/private/var`) makes the raw URLs differ: `import.meta.url`
|
|
17
|
+
* is the resolved real path while `argv[1]` keeps the symlink. Hence the
|
|
18
|
+
* realpath comparison last.
|
|
19
|
+
*
|
|
20
|
+
* `moduleUrl` is the caller's own `import.meta.url` — it cannot be read from
|
|
21
|
+
* here, which is why it is a parameter rather than a lookup.
|
|
22
|
+
*/
|
|
23
|
+
import * as fs from 'node:fs';
|
|
24
|
+
import * as path from 'node:path';
|
|
25
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
26
|
+
|
|
27
|
+
/** Defined only by the esbuild delegate builds; `undefined` under tsx and node. */
|
|
28
|
+
declare const __AGENT_CONFIG_CLI_DELEGATE__: boolean | undefined;
|
|
29
|
+
|
|
30
|
+
export function isCliEntry(moduleUrl: string, name: string): boolean {
|
|
31
|
+
const argv1 = process.argv[1];
|
|
32
|
+
if (argv1 === undefined) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
if (
|
|
36
|
+
typeof __AGENT_CONFIG_CLI_DELEGATE__ !== 'undefined' &&
|
|
37
|
+
__AGENT_CONFIG_CLI_DELEGATE__ &&
|
|
38
|
+
path.basename(argv1, '.js') === name
|
|
39
|
+
) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
const argvPath = path.resolve(argv1);
|
|
43
|
+
if (moduleUrl === pathToFileURL(argvPath).href) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
return fs.realpathSync(fileURLToPath(moduleUrl)) === fs.realpathSync(argvPath);
|
|
48
|
+
} catch {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -56,11 +56,17 @@ import { spawnSync } from 'node:child_process';
|
|
|
56
56
|
import * as fs from 'node:fs';
|
|
57
57
|
import * as path from 'node:path';
|
|
58
58
|
import process from 'node:process';
|
|
59
|
-
import { fileURLToPath
|
|
59
|
+
import { fileURLToPath } from 'node:url';
|
|
60
60
|
|
|
61
|
-
import {
|
|
61
|
+
import {
|
|
62
|
+
blocker_is_resolved,
|
|
63
|
+
collect,
|
|
64
|
+
parse_blockers,
|
|
65
|
+
} from './update_roadmap_progress.js';
|
|
62
66
|
import { guardedBaselineProblems, parseGuardedBaselines } from './guarded_baseline.js';
|
|
63
67
|
|
|
68
|
+
import { isCliEntry } from './_cli_entry.js';
|
|
69
|
+
|
|
64
70
|
const _HERE = fileURLToPath(import.meta.url);
|
|
65
71
|
|
|
66
72
|
interface CompletedProcess {
|
|
@@ -263,6 +269,80 @@ function _git_mv(root: string, src_rel: string, dst_rel: string, dry_run: boolea
|
|
|
263
269
|
}
|
|
264
270
|
}
|
|
265
271
|
|
|
272
|
+
// ---------------------------------------------------------------------
|
|
273
|
+
// The index/working-tree blocker divergence check (1b) + staging (1a)
|
|
274
|
+
// ---------------------------------------------------------------------
|
|
275
|
+
//
|
|
276
|
+
// The open-blocker refusal below reads the file with `fs.readFileSync`, i.e.
|
|
277
|
+
// the WORKING TREE. `git mv` then moves the INDEX ENTRY, which still carries
|
|
278
|
+
// whatever was staged. When the two disagree the commit ships the index
|
|
279
|
+
// content — content this gate never read.
|
|
280
|
+
//
|
|
281
|
+
// Measured, once, at full cost (2026-09-08): an edit removing a roadmap's
|
|
282
|
+
// blocker was made and never staged; `git mv` moved the stale index entry; the
|
|
283
|
+
// archived file shipped a blocker declared `Status: open` that had already been
|
|
284
|
+
// relocated to an active roadmap. The same blocker was open in two files at
|
|
285
|
+
// once, one of them archived, and it was caught by a human reading
|
|
286
|
+
// `git status` rather than by any gate.
|
|
287
|
+
//
|
|
288
|
+
// The check is scoped to blocker id → status and deliberately NOT to whole-file
|
|
289
|
+
// equality. An unstaged typo fix in a roadmap title has nothing to do with the
|
|
290
|
+
// defect, and refusing archival for it trains `git add -A`, which destroys the
|
|
291
|
+
// staging discipline this check depends on. AI council 2026-09-08, 2/2 present
|
|
292
|
+
// (anthropic/claude-sonnet-4-5 + openai/gpt-4o), on that scoping specifically:
|
|
293
|
+
// broad scoping is "user-hostile, trains developers to `git add -A`
|
|
294
|
+
// reflexively, defeating staging discipline".
|
|
295
|
+
|
|
296
|
+
/** Blocker id → status, as the archive-transition check compares them. */
|
|
297
|
+
function _blockerStatuses(text: string): Map<string, string> {
|
|
298
|
+
const out = new Map<string, string>();
|
|
299
|
+
for (const b of parse_blockers(text)) {
|
|
300
|
+
out.set(b.id, blocker_is_resolved(b) ? 'resolved' : 'open');
|
|
301
|
+
}
|
|
302
|
+
return out;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* `git show :<rel>` — the STAGED content of a path, or null when the path has
|
|
307
|
+
* no index entry.
|
|
308
|
+
*
|
|
309
|
+
* Null is the untracked / pre-first-commit case, which `_git_mv` already
|
|
310
|
+
* handles by falling back to a plain rename. There is no index entry to
|
|
311
|
+
* disagree with, so the divergence check has nothing to assert and says so by
|
|
312
|
+
* returning null rather than by guessing at an empty string — an empty staged
|
|
313
|
+
* file and an absent one differ, and only the second is legitimate here.
|
|
314
|
+
*/
|
|
315
|
+
function _indexContent(root: string, rel: string): string | null {
|
|
316
|
+
const cp = _run(['git', 'show', `:${rel}`], root);
|
|
317
|
+
return cp.returncode === 0 ? cp.stdout : null;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Human-readable disagreements between the staged and working-tree blocker
|
|
322
|
+
* maps of one path. Empty array = the two agree, or there is no index entry.
|
|
323
|
+
*/
|
|
324
|
+
function _blockerDivergence(root: string, rel: string, workTreeText: string): string[] {
|
|
325
|
+
const staged = _indexContent(root, rel);
|
|
326
|
+
if (staged === null) {
|
|
327
|
+
return [];
|
|
328
|
+
}
|
|
329
|
+
const wt = _blockerStatuses(workTreeText);
|
|
330
|
+
const idx = _blockerStatuses(staged);
|
|
331
|
+
const ids = [...new Set([...wt.keys(), ...idx.keys()])].sort();
|
|
332
|
+
const out: string[] = [];
|
|
333
|
+
for (const id of ids) {
|
|
334
|
+
const a = idx.get(id);
|
|
335
|
+
const b = wt.get(id);
|
|
336
|
+
if (a === b) {
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
out.push(
|
|
340
|
+
`blocker '${id}': staged=${a ?? 'absent'} vs working tree=${b ?? 'absent'}`,
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
return out;
|
|
344
|
+
}
|
|
345
|
+
|
|
266
346
|
/**
|
|
267
347
|
* Repo-relative paths of files containing `needle`, by walking the filesystem.
|
|
268
348
|
*
|
|
@@ -545,9 +625,8 @@ function archive_completed(
|
|
|
545
625
|
// and invisible in a sweep that only reports what it moved; a MALFORMED
|
|
546
626
|
// one on `[x]` would otherwise archive with an annotation claiming the
|
|
547
627
|
// opposite. Both are named here instead.
|
|
548
|
-
const
|
|
549
|
-
|
|
550
|
-
);
|
|
628
|
+
const roadmapText = fs.readFileSync(path.join(roadmap_root, stats.rel), 'utf-8');
|
|
629
|
+
const guarded = parseGuardedBaselines(roadmapText);
|
|
551
630
|
if (guarded.length > 0) {
|
|
552
631
|
process.stderr.write(
|
|
553
632
|
` ⚠️ ${stats.rel}: ${guarded.length} guarded-baseline step(s) — ` +
|
|
@@ -601,12 +680,37 @@ function archive_completed(
|
|
|
601
680
|
if (changed_only && !(touched as Set<string>).has(old_rel)) {
|
|
602
681
|
continue; // complete, but not this branch's work
|
|
603
682
|
}
|
|
683
|
+
// The gate above validated the WORKING TREE; `git mv` ships the INDEX.
|
|
684
|
+
// When they disagree about a blocker, the validated content is not the
|
|
685
|
+
// content that gets committed — see § the index/working-tree blocker
|
|
686
|
+
// divergence check above for the measured failure.
|
|
687
|
+
const divergence = _blockerDivergence(root, old_rel, roadmapText);
|
|
688
|
+
if (divergence.length > 0) {
|
|
689
|
+
process.stderr.write(
|
|
690
|
+
` ⚠️ ${stats.rel}: staged and working-tree blockers disagree ` +
|
|
691
|
+
`(${divergence.length}) — not archived. \`git mv\` would commit ` +
|
|
692
|
+
'the staged content, which this sweep never validated. Stage or ' +
|
|
693
|
+
'discard the change, then re-run.\n',
|
|
694
|
+
);
|
|
695
|
+
for (const d of divergence) {
|
|
696
|
+
process.stderr.write(` · ${d}\n`);
|
|
697
|
+
}
|
|
698
|
+
continue;
|
|
699
|
+
}
|
|
604
700
|
const new_rel = `agents/roadmaps/archive/${stats.rel}`;
|
|
605
701
|
const mv = _git_mv(root, old_rel, new_rel, dry_run);
|
|
606
702
|
if (!mv.ok) {
|
|
607
703
|
process.stderr.write(` ⚠️ could not archive ${old_rel} (mv failed)\n`);
|
|
608
704
|
continue;
|
|
609
705
|
}
|
|
706
|
+
// `git mv` moved the index ENTRY, not the working-tree content. Staging
|
|
707
|
+
// the destination makes what gets committed identical to what the checks
|
|
708
|
+
// above read — the divergence check refuses a disagreement that exists
|
|
709
|
+
// BEFORE the move, and this closes one created by an edit between the
|
|
710
|
+
// move and the commit.
|
|
711
|
+
if (!dry_run && mv.tracked) {
|
|
712
|
+
_run(['git', 'add', '--', new_rel], root);
|
|
713
|
+
}
|
|
610
714
|
const refs = _inbound_ref_rewrite(root, old_rel, new_rel, dry_run, mv.tracked);
|
|
611
715
|
// Stage rewritten refs only in a tracked repo; an untracked consumer's
|
|
612
716
|
// files are not in the index, so the filesystem rewrite is the whole job.
|
|
@@ -638,6 +742,16 @@ function _regen_dashboard(root: string, dry_run: boolean): void {
|
|
|
638
742
|
if (dry_run) {
|
|
639
743
|
return;
|
|
640
744
|
}
|
|
745
|
+
// Inside `dist/cli-delegate/` the twin sits next to us as a precompiled
|
|
746
|
+
// bundle, and plain `node` runs it — the tsx walk below would otherwise
|
|
747
|
+
// reach `npx tsx`, which resolves against the CONSUMER's npm config and
|
|
748
|
+
// hard-fails on a mismatched `engines`/`devEngines` pin (the very class
|
|
749
|
+
// ADR-204 removed from the dispatcher and left standing here).
|
|
750
|
+
const bundledTwin = path.join(path.dirname(_HERE), 'update_roadmap_progress.js');
|
|
751
|
+
if (_isFile(bundledTwin)) {
|
|
752
|
+
spawnSync(process.execPath, [bundledTwin], { cwd: root, encoding: 'utf-8' });
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
641
755
|
const script = path.join(path.dirname(_HERE), 'update_roadmap_progress.ts');
|
|
642
756
|
// Python: `_run([sys.executable, str(script)], root)`; the twin spawns the
|
|
643
757
|
// dashboard generator twin through the same `tsx` runtime, cwd=root.
|
|
@@ -800,28 +914,7 @@ function main(argv?: readonly string[]): number {
|
|
|
800
914
|
return 0;
|
|
801
915
|
}
|
|
802
916
|
|
|
803
|
-
|
|
804
|
-
if (process.argv[1] === undefined) {
|
|
805
|
-
return false;
|
|
806
|
-
}
|
|
807
|
-
const argvUrl = pathToFileURL(path.resolve(process.argv[1])).href;
|
|
808
|
-
if (import.meta.url === argvUrl) {
|
|
809
|
-
return true;
|
|
810
|
-
}
|
|
811
|
-
// A symlinked invocation (e.g. via `.augment/scripts` → `dist/agent-src/scripts`,
|
|
812
|
-
// or macOS /var → /private/var temp dirs) makes the raw URLs differ:
|
|
813
|
-
// import.meta.url is the resolved real path while argv[1] keeps the symlink
|
|
814
|
-
// path. Compare realpaths so the entry guard still fires (without this the
|
|
815
|
-
// archival sweep silently no-ops when run through the symlink).
|
|
816
|
-
try {
|
|
817
|
-
const here = fs.realpathSync(fileURLToPath(import.meta.url));
|
|
818
|
-
const argv = fs.realpathSync(path.resolve(process.argv[1]));
|
|
819
|
-
return here === argv;
|
|
820
|
-
} catch {
|
|
821
|
-
return false;
|
|
822
|
-
}
|
|
823
|
-
}
|
|
824
|
-
if (_isCliEntry() || process.argv[1] === _HERE) {
|
|
917
|
+
if (isCliEntry(import.meta.url, 'archive_completed_roadmaps')) {
|
|
825
918
|
try {
|
|
826
919
|
process.exitCode = main();
|
|
827
920
|
} catch (exc) {
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
*/
|
|
66
66
|
|
|
67
67
|
import * as path from 'node:path';
|
|
68
|
-
import { fileURLToPath
|
|
68
|
+
import { fileURLToPath } from 'node:url';
|
|
69
69
|
import * as fs from 'node:fs';
|
|
70
70
|
import { spawnSync } from 'node:child_process';
|
|
71
71
|
|
|
@@ -80,6 +80,8 @@ import { execute } from './gate_execute.js';
|
|
|
80
80
|
import { listPending } from '../templates/scripts/work_engine/hooks/builtin/staged_confirmation_store.js';
|
|
81
81
|
import type { StagedAction } from '../templates/scripts/work_engine/hooks/builtin/staged_confirmation.js';
|
|
82
82
|
|
|
83
|
+
import { isCliEntry } from './_cli_entry.js';
|
|
84
|
+
|
|
83
85
|
const _HERE = fileURLToPath(import.meta.url);
|
|
84
86
|
|
|
85
87
|
/** Hard wrap for the rendered body — keeps output readable in a narrow pane. */
|
|
@@ -928,26 +930,8 @@ function main(argv?: readonly string[]): number {
|
|
|
928
930
|
return 0;
|
|
929
931
|
}
|
|
930
932
|
|
|
931
|
-
function _isCliEntry(): boolean {
|
|
932
|
-
if (process.argv[1] === undefined) {
|
|
933
|
-
return false;
|
|
934
|
-
}
|
|
935
|
-
const argvPath = path.resolve(process.argv[1]);
|
|
936
|
-
if (import.meta.url === pathToFileURL(argvPath).href) {
|
|
937
|
-
return true;
|
|
938
|
-
}
|
|
939
|
-
// A symlinked invocation (`.augment/scripts` → `dist/agent-src/scripts`, or
|
|
940
|
-
// macOS /var → /private/var) makes the raw URLs differ: import.meta.url is
|
|
941
|
-
// the resolved real path while argv[1] keeps the symlink. Compare realpaths
|
|
942
|
-
// so the entry guard still fires through the projection.
|
|
943
|
-
try {
|
|
944
|
-
return fs.realpathSync(_HERE) === fs.realpathSync(argvPath);
|
|
945
|
-
} catch {
|
|
946
|
-
return false;
|
|
947
|
-
}
|
|
948
|
-
}
|
|
949
933
|
|
|
950
|
-
if (
|
|
934
|
+
if (isCliEntry(import.meta.url, 'roadmap_gates')) {
|
|
951
935
|
process.exitCode = main();
|
|
952
936
|
}
|
|
953
937
|
|
|
@@ -30,7 +30,9 @@
|
|
|
30
30
|
import * as fs from 'node:fs';
|
|
31
31
|
import * as path from 'node:path';
|
|
32
32
|
import process from 'node:process';
|
|
33
|
-
import { fileURLToPath
|
|
33
|
+
import { fileURLToPath } from 'node:url';
|
|
34
|
+
|
|
35
|
+
import { isCliEntry } from './_cli_entry.js';
|
|
34
36
|
|
|
35
37
|
const _HERE = fileURLToPath(import.meta.url);
|
|
36
38
|
|
|
@@ -246,8 +248,9 @@ export function main(argv: string[] = process.argv.slice(2)): number {
|
|
|
246
248
|
}
|
|
247
249
|
}
|
|
248
250
|
|
|
251
|
+
|
|
249
252
|
/* c8 ignore start */
|
|
250
|
-
if (
|
|
253
|
+
if (isCliEntry(import.meta.url, 'roadmap_set_step')) {
|
|
251
254
|
process.exit(main());
|
|
252
255
|
}
|
|
253
256
|
/* c8 ignore stop */
|
|
@@ -42,7 +42,9 @@
|
|
|
42
42
|
*/
|
|
43
43
|
import * as fs from 'node:fs';
|
|
44
44
|
import * as path from 'node:path';
|
|
45
|
-
import { fileURLToPath
|
|
45
|
+
import { fileURLToPath } from 'node:url';
|
|
46
|
+
|
|
47
|
+
import { isCliEntry } from './_cli_entry.js';
|
|
46
48
|
|
|
47
49
|
const STUB_DIR = path.join('agents', 'roadmaps', 'stubs');
|
|
48
50
|
|
|
@@ -459,24 +461,8 @@ export function main(argv: readonly string[] = process.argv.slice(2)): number {
|
|
|
459
461
|
return 0;
|
|
460
462
|
}
|
|
461
463
|
|
|
462
|
-
function _isCliEntry(): boolean {
|
|
463
|
-
if (process.argv[1] === undefined) {
|
|
464
|
-
return false;
|
|
465
|
-
}
|
|
466
|
-
const argvUrl = pathToFileURL(path.resolve(process.argv[1])).href;
|
|
467
|
-
if (import.meta.url === argvUrl) {
|
|
468
|
-
return true;
|
|
469
|
-
}
|
|
470
|
-
try {
|
|
471
|
-
const here = fs.realpathSync(fileURLToPath(import.meta.url));
|
|
472
|
-
const argv = fs.realpathSync(path.resolve(process.argv[1]));
|
|
473
|
-
return here === argv;
|
|
474
|
-
} catch {
|
|
475
|
-
return false;
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
464
|
|
|
479
|
-
if (
|
|
465
|
+
if (isCliEntry(import.meta.url, 'stubs_due')) {
|
|
480
466
|
process.exitCode = main();
|
|
481
467
|
}
|
|
482
468
|
|