@event4u/agent-config 17.0.0 → 17.2.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 +157 -468
- package/README.md +4 -3
- package/dist/agent-src/commands/project/analyze.md +9 -6
- package/dist/agent-src/commands/project/map.md +58 -0
- package/dist/agent-src/commands/project.md +5 -3
- package/dist/agent-src/contexts/execution/host-capability-manifest.md +5 -3
- package/dist/agent-src/skills/code-intelligence/SKILL.md +6 -0
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/roadmaps.md +5 -1
- package/dist/cli/registry.js +1 -1
- package/dist/cli-delegate/{chunk-IROAQ77A.js → chunk-3PK3VZHB.js} +107 -9
- package/dist/cli-delegate/{chunk-2SFOOFJJ.js → chunk-BZJ4Y3CI.js} +1 -1
- package/dist/cli-delegate/{chunk-CAL76ADI.js → chunk-CMZEKSNN.js} +52 -10
- package/dist/cli-delegate/{chunk-ESUNQ5XR.js → chunk-E3CFULNX.js} +22 -4
- package/dist/cli-delegate/{chunk-GOMILC3O.js → chunk-QBHEI5N4.js} +4 -3
- package/dist/cli-delegate/{chunk-SIOMDAKL.js → chunk-VYZGJLCA.js} +29 -39
- package/dist/cli-delegate/chunk-W5JXMF2T.js +77 -0
- package/dist/cli-delegate/{chunk-4SHNERBL.js → chunk-XIAPY44N.js} +1 -1
- package/dist/cli-delegate/{chunk-JHMMWNJ2.js → chunk-YHAPONWV.js} +1 -1
- package/dist/cli-delegate/cmd_conformance.js +32 -47
- package/dist/cli-delegate/cmd_doctor.js +4 -4
- package/dist/cli-delegate/cmd_doctor_neighbours.js +2 -2
- package/dist/cli-delegate/cmd_explain.js +1 -1
- package/dist/cli-delegate/cmd_export.js +6 -6
- package/dist/cli-delegate/cmd_fleet.js +3 -3
- package/dist/cli-delegate/cmd_preflight.js +3 -3
- package/dist/cli-delegate/cmd_prune.js +6 -6
- package/dist/cli-delegate/cmd_settings_migrate.js +6 -6
- package/dist/cli-delegate/cmd_settings_set.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +6 -6
- package/dist/cli-delegate/cmd_uninstall.js +6 -6
- package/dist/cli-delegate/cmd_update.js +9 -13
- package/dist/cli-delegate/cmd_validate.js +6 -6
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +41 -15
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +3 -3
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +6 -5
- package/dist/discovery/trust-report.md +2 -2
- package/dist/discovery/workspaces.json +5 -4
- package/dist/hooks/dispatch.js +163 -148
- package/dist/hooks/dispatch.sha256 +1 -1
- package/dist/hooks/instructions_observer.chunk.cjs +301 -0
- package/dist/hooks/instructions_observer.chunk.cjs.sha256 +1 -0
- package/dist/install/claudeRuleRewrite.js +10 -3
- package/dist/install/conflict.js +24 -2
- package/dist/install/conflictTracker.js +14 -3
- package/dist/install/install.mjs +222 -117
- package/dist/install/installThinLayer.js +1 -0
- package/dist/install/loggedWrites.js +142 -0
- package/dist/install/paths.js +12 -2
- package/dist/install/preserve.js +25 -4
- package/dist/install/txlog.js +10 -6
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +33595 -22916
- package/dist/scripts/_lib/egress_rules.js +4 -1
- package/dist/scripts/_lib/identifier_redaction.js +35 -2
- package/dist/scripts/ai_council/seat_policy.js +7 -1
- package/dist/server/schemas/settings.js +1 -1
- package/package.json +4 -1
- package/src/config/ci-local-parity.yml +1 -1
- package/src/config/continuity-surface.json +7 -0
- package/src/config/evaluator-budgets.json +4 -4
- package/src/config/gate-coverage.yml +27 -7
- package/src/config/gate-violation-baselines.json +9 -3
- package/src/config/gitignore-block.txt +6 -0
- package/src/config/hook-bundle-budget.json +19 -4
- package/src/config/hook-token-budget.json +1 -1
- package/src/config/packed-binary-manifest.json +27 -0
- package/src/config/production-entries.json +18 -0
- package/src/config/release-gate-locality.yml +0 -7
- package/src/config/skill-body-budget.json +7 -1
- package/src/install/claudeRuleRewrite.ts +10 -1
- package/src/install/conflict.ts +24 -1
- package/src/install/conflictTracker.ts +18 -2
- package/src/install/installThinLayer.ts +6 -0
- package/src/install/loggedWrites.ts +148 -0
- package/src/install/paths.ts +11 -2
- package/src/install/preserve.ts +40 -4
- package/src/install/txlog.ts +10 -6
- package/src/scripts/_cli/cmd_conformance.ts +3 -2
- package/src/scripts/_cli/cmd_update.ts +15 -17
- package/src/scripts/_lib/bench_ab_complexity.ts +14 -2
- package/src/scripts/_lib/collector_record.ts +1 -0
- package/src/scripts/_lib/council_settings_block.ts +9 -2
- package/src/scripts/_lib/egress_rules.ts +4 -1
- package/src/scripts/_lib/host_capability.ts +10 -5
- package/src/scripts/_lib/identifier_redaction.ts +38 -2
- package/src/scripts/_lib/price_freshness.ts +112 -0
- package/src/scripts/_lib/production_reach.ts +194 -0
- package/src/scripts/_lib/quota_parked.ts +17 -28
- package/src/scripts/_lib/release_findings_ingest.ts +13 -335
- package/src/scripts/_lib/runtime_journal.ts +7 -7
- package/src/scripts/_lib/tier_downshift_verdict.ts +81 -35
- package/src/scripts/ai_council/chairman.ts +5 -2
- package/src/scripts/ai_council/clients.ts +4 -3
- package/src/scripts/ai_council/free_hand_shadow.ts +24 -12
- package/src/scripts/ai_council/free_route_catalog.ts +142 -5
- package/src/scripts/ai_council/free_route_client.ts +4 -0
- package/src/scripts/ai_council/hand_payload.ts +115 -7
- package/src/scripts/ai_council/orchestrator.ts +7 -10
- package/src/scripts/ai_council/route_chooser.ts +1 -1
- package/src/scripts/ai_council/route_member.ts +66 -4
- package/src/scripts/ai_council/seat_policy.ts +8 -1
- package/src/scripts/ai_council/self_hosted_probe.ts +327 -0
- package/src/scripts/ai_council/status_surface.ts +2 -0
- package/src/scripts/ask_transport.ts +137 -15
- package/src/scripts/check_finding_dispositions.ts +25 -71
- package/src/scripts/check_release_pr_shape.ts +3 -3
- package/src/scripts/check_step_production_reach.ts +257 -0
- package/src/scripts/code_graph/build.ts +210 -10
- package/src/scripts/code_graph/cli.ts +168 -46
- package/src/scripts/code_graph/detect.ts +5 -4
- package/src/scripts/code_graph/docs_layer.ts +57 -0
- package/src/scripts/code_graph/extract.ts +58 -13
- package/src/scripts/code_graph/extract_more.ts +314 -0
- package/src/scripts/code_graph/laravel_overlay.ts +454 -0
- package/src/scripts/code_graph/map.ts +846 -0
- package/src/scripts/code_graph/map_model.ts +977 -0
- package/src/scripts/code_graph/map_verify.ts +140 -0
- package/src/scripts/code_graph/map_viewer/viewer.css +278 -0
- package/src/scripts/code_graph/map_viewer/viewer.js +756 -0
- package/src/scripts/code_graph/scip_reader.ts +201 -0
- package/src/scripts/code_graph/sqlite_store.ts +8 -1
- package/src/scripts/code_graph/types.ts +81 -15
- package/src/scripts/code_graph/validate.ts +16 -26
- package/src/scripts/code_graph/verbs.ts +7 -0
- package/src/scripts/council_cli.ts +10 -8
- package/src/scripts/hook_chunks.mjs +7 -0
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +23 -0
- package/src/scripts/hooks/dispatch_hook.ts +4 -4
- package/src/scripts/hooks/instructions_observer_hook.ts +25 -6
- package/src/scripts/hooks/lazy_concern.ts +4 -0
- package/src/scripts/hooks/payload_stub.ts +27 -0
- package/src/scripts/hooks/spawn_guard_shadow_hook.ts +29 -70
- package/src/scripts/hooks/subagent_ledger_hook.ts +80 -0
- package/src/scripts/install-hooks.sh +5 -0
- package/src/scripts/install.ts +2 -2
- package/src/scripts/lint_agents_layout.ts +2 -0
- package/src/scripts/lint_decision_classes.ts +34 -0
- package/src/scripts/lint_hook_manifest.ts +25 -0
- package/src/scripts/lint_roadmap_blockers.ts +52 -3
- package/src/scripts/mcp_server/consumer_tool_catalog.json +53 -6
- package/src/scripts/mcp_server/graph_tools.ts +73 -1
- package/src/scripts/mcp_server/tools.ts +19 -36
- package/src/scripts/release.ts +5 -9
- package/src/scripts/release_drill.ts +11 -165
- package/src/scripts/release_publication.ts +0 -9
- package/src/scripts/report_production_reach.ts +35 -0
- package/src/scripts/worker_reuse_shadow_report.ts +399 -1
- package/src/server/schemas/settings.ts +1 -1
- package/src/vendor/grammars/README.md +10 -5
- package/src/vendor/grammars/tree-sitter-go.wasm +0 -0
- package/src/vendor/grammars/tree-sitter-java.wasm +0 -0
- package/src/vendor/grammars/tree-sitter-python.wasm +0 -0
- package/dist/cli-delegate/chunk-A4QJ6ENT.js +0 -50
- /package/dist/cli-delegate/{chunk-E6XNBVE4.js → chunk-KR5ZIFPO.js} +0 -0
package/README.md
CHANGED
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
# Agent Config — every claim machine-checked, including the artifact counts in these badges
|
|
4
4
|
|
|
5
|
-
[](https://github.com/event4u-app/agent-config/actions/workflows/smoke.yml) [](https://github.com/event4u-app/agent-config/actions/workflows/smoke-public-install.yml) [](https://www.npmjs.com/package/@event4u/agent-config) [](https://glama.ai/mcp/servers/event4u-app/agent-config) [](https://mcptoplist.com/server/glama%2Fevent4u-app%2Fagent-config)
|
|
5
|
+
[](https://github.com/event4u-app/agent-config/actions/workflows/smoke.yml) [](https://github.com/event4u-app/agent-config/actions/workflows/smoke-public-install.yml) [](https://www.npmjs.com/package/@event4u/agent-config) [](https://glama.ai/mcp/servers/event4u-app/agent-config) [](https://mcptoplist.com/server/glama%2Fevent4u-app%2Fagent-config)
|
|
6
6
|
|
|
7
|
-
[](dist/agent-src/skills/) [](dist/agent-src/rules/) [](dist/agent-src/skills/) [](dist/agent-src/rules/) [](dist/agent-src/commands/) [](docs/guidelines/) [](dist/agent-src/personas/) [](dist/agent-src/personas/advisors/) <!-- claim:published-artifact-counts -->
|
|
8
|
+
[](https://www.npmjs.com/package/@event4u/agent-config)
|
|
8
9
|
|
|
9
|
-
<sub>**How these are counted** — one canonical counter, `agent-config` → `update_counts --check`, re-derives all six from the tree and fails CI when one is off by one. Two bases are not what the linked directory shows, so they are stated here rather than left to be inferred: **Commands
|
|
10
|
+
<sub>**How these are counted** — one canonical counter, `agent-config` → `update_counts --check`, re-derives all six from the tree and fails CI when one is off by one. Two bases are not what the linked directory shows, so they are stated here rather than left to be inferred: **Commands 210** counts every command file **recursively** (the linked directory holds 62 at its top level) and **Rules 122** counts the **source** rules while the linked projection holds 121 — one rule is dormant and is not projected. **Personas 29** excludes the directory README. Counts are of files and directories: none of them measures quality, activation or adoption. <!-- claim:published-artifact-counts --></sub>
|
|
10
11
|
|
|
11
12
|
**Try it in 30 seconds** — drop one read-only subagent into any repo and watch it check "done": `@production-validator check this branch is actually done`. No wizard, no lock-in, nothing else installed — the [30-second wedge ↓](#quickstart) is the whole first step. Start at the proof, not the catalog: **[event4u-app.github.io/agent-config/proof/](https://event4u-app.github.io/agent-config/proof/)**.
|
|
12
13
|
|
|
@@ -31,7 +31,9 @@ Gather in parallel:
|
|
|
31
31
|
- Check for: `artisan`, `Makefile`, `Taskfile.yml`, `docker-compose.yml`
|
|
32
32
|
- Check for: `phpstan.neon`, `ecs.php`, `rector.php`, `config-dev/`
|
|
33
33
|
- Check for: `.github/workflows/`, `CODEOWNERS`, `.editorconfig`
|
|
34
|
-
- Check for module roots (resolve via `scripts/_lib/agent_settings.ts::enumerate_modules()`; Laravel shape: `app/Modules/`)
|
|
34
|
+
- Check for module roots (resolve via `scripts/_lib/agent_settings.ts::enumerate_modules()`; Laravel shape: `app/Modules/`)
|
|
35
|
+
- Probe the database connections the project declares (`config/database.php` `connections`, `DB_CONNECTION*` keys in `.env.example`, `$connection` properties on models); more than one connection used by models is a multi-database / multi-tenant indicator — name the connections as found, never assume their names
|
|
36
|
+
- Build or refresh the code map: `agent-config code-graph map`. Structure (areas, hubs, cycles, request paths) is read from `agents/map/MAP.md` below, not re-derived by hand <!-- ref-ignore -->
|
|
35
37
|
- Read: `AGENTS.md`, `.github/copilot-instructions.md` (if exist)
|
|
36
38
|
|
|
37
39
|
**Assurance dimensions — do NOT hand-detect these.** Run
|
|
@@ -137,6 +139,7 @@ full pass, so "continue" is dominant and asking is a routine confirmation.
|
|
|
137
139
|
Analyze the directory structure:
|
|
138
140
|
|
|
139
141
|
- Map top-level directories with file counts
|
|
142
|
+
- Read `agents/map/MAP.md` first: its areas, infrastructure files, cycles and request paths ARE the structure section — link to it rather than restating it <!-- ref-ignore -->
|
|
140
143
|
- Identify pattern: MVC, modules, services, repositories, DTOs
|
|
141
144
|
- Count: Models, Controllers, Services, Jobs, Commands, Events, Policies
|
|
142
145
|
- Detect: multi-tenancy, API versioning, queue usage
|
|
@@ -150,13 +153,14 @@ ARCHITECTURE:
|
|
|
150
153
|
|
|
151
154
|
Pattern: {Modular MVC + Service Layer + Repository}
|
|
152
155
|
API: {Versioned REST (/api/v1/, /api/v2/)}
|
|
153
|
-
|
|
156
|
+
Databases: {connections the models use, as probed — e.g. "2 (mysql, tenant)" | 1}
|
|
157
|
+
Map: agents/map/MAP.md ({n} areas · largest {name})
|
|
154
158
|
|
|
155
159
|
───────────────────────────────────────────────
|
|
156
160
|
CODE INVENTORY:
|
|
157
161
|
───────────────────────────────────────────────
|
|
158
162
|
|
|
159
|
-
Models: {count} (
|
|
163
|
+
Models: {count} (per connection, when more than one is in use)
|
|
160
164
|
Controllers: {count}
|
|
161
165
|
Services: {count}
|
|
162
166
|
Repositories: {count}
|
|
@@ -288,9 +292,8 @@ Write all remaining analysis files that haven't been created yet:
|
|
|
288
292
|
- `agents/evidence/analysis/architecture/database.md` — schema, connections, multi-tenancy
|
|
289
293
|
- `agents/evidence/analysis/architecture/api.md` — versioning, routes, middleware, auth
|
|
290
294
|
- `agents/evidence/analysis/architecture/infrastructure.md` — Docker, CI/CD, deployment
|
|
291
|
-
- `agents/evidence/analysis/architecture/patterns.md` — design patterns used
|
|
292
|
-
- `agents/evidence/analysis/models
|
|
293
|
-
- `agents/evidence/analysis/models/customer-database.md` — all customer_database models
|
|
295
|
+
- `agents/evidence/analysis/architecture/patterns.md` — design patterns used; for module and area structure, link `agents/map/MAP.md` instead of restating it <!-- ref-ignore -->
|
|
296
|
+
- `agents/evidence/analysis/models/<connection>.md` — one per database connection the probe found, all models on it
|
|
294
297
|
- `agents/evidence/analysis/modules/{module}.md` — one per module
|
|
295
298
|
- `agents/evidence/analysis/testing/test-map.md` — test suites, coverage, strategy
|
|
296
299
|
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
model_tier: lite
|
|
3
|
+
name: project-map
|
|
4
|
+
pack: engineering-base
|
|
5
|
+
visibility: internal
|
|
6
|
+
sub: map
|
|
7
|
+
cluster: project
|
|
8
|
+
skills: [code-intelligence]
|
|
9
|
+
description: Draw the code map into agents/map/
|
|
10
|
+
suggestion:
|
|
11
|
+
eligible: false
|
|
12
|
+
rationale: "Cluster sub-command — reached via its cluster head's routing or its explicit /cluster:sub name; not independently suggested (surface-consolidation)."
|
|
13
|
+
workspaces:
|
|
14
|
+
- agent-config-maintainer
|
|
15
|
+
packs:
|
|
16
|
+
- meta
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# project-map
|
|
20
|
+
|
|
21
|
+
## Instructions
|
|
22
|
+
|
|
23
|
+
Build the map of the project the user is standing in, then point at it. The map is
|
|
24
|
+
deterministic and local: no model call, no network, nothing committed by default
|
|
25
|
+
(`agents/map/` is gitignored, ADR-297). <!-- ref-ignore -->
|
|
26
|
+
|
|
27
|
+
### 1. Build
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
agent-config code-graph map
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
It builds or updates the code graph first when it is absent or behind, then writes
|
|
34
|
+
`agents/map/index.html`, `agents/map/MAP.md`, one `agents/map/areas/<id>.md` per <!-- ref-ignore -->
|
|
35
|
+
area of five or more files, and `agents/map/map.json`. With Playwright present it <!-- ref-ignore -->
|
|
36
|
+
also renders the page at three widths and reports the render check; without it the
|
|
37
|
+
check reads `unverified`, which is not a pass.
|
|
38
|
+
|
|
39
|
+
`--root <path>` maps another checkout; `--open` opens the page; `--no-verify`
|
|
40
|
+
skips the render check.
|
|
41
|
+
|
|
42
|
+
### 2. Report
|
|
43
|
+
|
|
44
|
+
Quote the command's summary lines (files, areas, largest area, graph state, render
|
|
45
|
+
check) and give the path to `agents/map/index.html`. Do not paraphrase the counts. <!-- ref-ignore -->
|
|
46
|
+
|
|
47
|
+
### 3. Answer from the map, when the user asked a question
|
|
48
|
+
|
|
49
|
+
Read `agents/map/MAP.md` first, then the page of the area in question. Say which <!-- ref-ignore -->
|
|
50
|
+
answers came from the map and which from a follow-up `code-graph query` or a file
|
|
51
|
+
read — the map groups files by coupling, it does not explain what they do.
|
|
52
|
+
|
|
53
|
+
## Rules
|
|
54
|
+
|
|
55
|
+
- **Never edit `agents/map/` by hand.** Every file there is regenerated. <!-- ref-ignore -->
|
|
56
|
+
- **A `behind:N` or `edited` graph state is part of the answer.** Say it.
|
|
57
|
+
- **"Isolated" is not "dead".** A file reached by reflection, a string path or a
|
|
58
|
+
framework convention the engine does not read is isolated too.
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
model_tier: medium
|
|
3
3
|
name: project
|
|
4
4
|
disable-model-invocation: true
|
|
5
|
-
argument-hint: "[analyze|health]"
|
|
5
|
+
argument-hint: "[analyze|health|map]"
|
|
6
6
|
pack: engineering-base
|
|
7
|
-
intent: "Project dispatcher — full analysis
|
|
8
|
-
routes_to: [project-analyze, project-health]
|
|
7
|
+
intent: "Project dispatcher — full analysis, quick health check, or the project map"
|
|
8
|
+
routes_to: [project-analyze, project-health, project-map]
|
|
9
9
|
replaces: []
|
|
10
10
|
visibility: internal
|
|
11
11
|
description: Project orchestrator — routes to analyze (full audit) and health (read-only status check)
|
|
@@ -35,6 +35,7 @@ Top-level orchestrator for the `/project` family — project-wide inspection.
|
|
|
35
35
|
|---|---|---|
|
|
36
36
|
| `/project analyze` | `commands/project/analyze.md` | Full project analysis — detect stack, inventory modules, audit docs, create missing contexts |
|
|
37
37
|
| `/project health` | `commands/project/health.md` | Quick health check — status of docs, modules, contexts, roadmaps; creates nothing |
|
|
38
|
+
| `/project map` | `commands/project/map.md` | Draw the code map into `agents/map/` — areas, files, links; offline, gitignored |
|
|
38
39
|
|
|
39
40
|
Sub-command names match the locked contract in
|
|
40
41
|
[`docs/contracts/command-clusters.md`](../docs/contracts/command-clusters.md).
|
|
@@ -50,6 +51,7 @@ Sub-command names match the locked contract in
|
|
|
50
51
|
|
|
51
52
|
> 1. analyze — full project audit (writes missing contexts)
|
|
52
53
|
> 2. health — read-only status check (creates nothing)
|
|
54
|
+
> 3. map — draw the code map into `agents/map/`
|
|
53
55
|
|
|
54
56
|
## Rules
|
|
55
57
|
|
|
@@ -37,7 +37,9 @@ host, never a configuration decision (always-on orchestration, Phase 1):
|
|
|
37
37
|
2. A live environment probe merged on top: `agent_teams` resolves `true`
|
|
38
38
|
when `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS` is set in the process
|
|
39
39
|
environment — the one host fact this repo can observe about Claude
|
|
40
|
-
Code's experimental multi-instance Agent Teams feature.
|
|
40
|
+
Code's experimental multi-instance Agent Teams feature. On `claude` the
|
|
41
|
+
same flag also sets `worker_resume`: the by-name re-task was observed
|
|
42
|
+
there only under it (cold-start 1.4, 2.1.306; council 2026-10-22).
|
|
41
43
|
3. `SAFE_DEFAULT` (all `false`) for an unrecognized host or an unset probe.
|
|
42
44
|
|
|
43
45
|
`resolveHostCapabilities(hostId, override?)` still accepts an optional
|
|
@@ -92,7 +94,7 @@ SAFE DEGRADATION, NOT BECAUSE ANYTHING WAS MEASURED.
|
|
|
92
94
|
|
|
93
95
|
The seven booleans look alike and are not. `HOST_CAPABILITY_REGISTRY` holds
|
|
94
96
|
exactly one row today, so on every other host **all six** fields are the safe
|
|
95
|
-
default — and `agent_teams` is the only field any live check touches. The name
|
|
97
|
+
default — and `agent_teams` (plus `worker_resume` on `claude`) is the only field any live check touches. The name
|
|
96
98
|
`probeHostCapabilities` says "detected" about values that were mostly asserted
|
|
97
99
|
at authoring time.
|
|
98
100
|
|
|
@@ -136,7 +138,7 @@ A prober that decides for itself what counts as evidence is the inference
|
|
|
136
138
|
| `status_polling` | a **completed poll returning a state the parent did not already hold**. A poll that returns what the parent knew is not an observation of polling |
|
|
137
139
|
| `separate_quota_pool` | a **child leg continuing across a parent quota condition** — the parent constrained, the child proceeding |
|
|
138
140
|
| `worker_respawn` | **one task continuing across a killed and re-spawned worker, same task id.** Never inferred from the fact that spawning and killing both exist separately |
|
|
139
|
-
| `worker_resume` | **a finished leg re-tasked by name whose next `SubagentStart` carries the same ledger `ref`, and whose first call in that run reads more than half its input from cache.** Never inferred from the host documenting a resume or message tool |
|
|
141
|
+
| `worker_resume` | **a finished leg re-tasked by name whose next `SubagentStart` carries the same ledger `ref`, and whose first call in that run reads more than half its input from cache.** Never inferred from the host documenting a resume or message tool. On `claude` the agent-teams flag stands in for this row: the by-name re-task was observed only under it (2.1.306), so the live probe sets the field from the flag (council 2026-10-22) |
|
|
140
142
|
| `fork_shares_cache` | **a fork whose first call reads more than half its input from cache and whose tool list equals the parent's.** Never inferred from documentation |
|
|
141
143
|
| `structured_ask` | **the host's delivered tool surface, in a real session, carrying (or not carrying) a question-picker tool.** The delivered surface is the observation — never the vendor's documentation, and never another host by analogy. A `false` written from an observed surface is "checked, absent"; omitting the field is "never looked" |
|
|
142
144
|
| `reads_project_mcp_config` | **a server named only in the project-scope config appearing in that host's own tool list.** Never inferred from the host documenting MCP support, which does not say which scope it reads |
|
|
@@ -38,6 +38,10 @@ code-graph and no appetite to build one — plain `grep`/read is right there.
|
|
|
38
38
|
|
|
39
39
|
## Procedure
|
|
40
40
|
|
|
41
|
+
0. **Orient first, when the question is "where does X live" rather than "who
|
|
42
|
+
calls X".** If `agents/map/MAP.md` exists, read it: it names the project's <!-- ref-ignore -->
|
|
43
|
+
areas (files grouped by coupling), its infrastructure files and its cycles.
|
|
44
|
+
No map yet? `agent-config code-graph map` builds one in seconds. Then query.
|
|
41
45
|
1. **Detect the source.** `agent-config code-graph detect` — is a fresh consumer
|
|
42
46
|
`graph.json` or native cache present? (A consumer-shipped fresh index wins;
|
|
43
47
|
the native engine covers stale-or-absent — ADR-124 § 2.)
|
|
@@ -246,6 +250,8 @@ paragraph claiming "the same five answers" directly after a list of four:
|
|
|
246
250
|
| `graph_query` | `query` |
|
|
247
251
|
| `graph_path` | `path` |
|
|
248
252
|
| `graph_node` | no CLI verb — one symbol's location, in-edges, out-edges and degree |
|
|
253
|
+
| `graph_map_status` | whether `agents/map/` exists, its counts and freshness | <!-- ref-ignore -->
|
|
254
|
+
| `graph_area` | one area of the map: files, hubs, what it depends on |
|
|
249
255
|
|
|
250
256
|
`untested` has no tool of its own; it is a flag on `graph_impact`, because the
|
|
251
257
|
two answer the same question over the same diff and a separate tool would have
|
|
@@ -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: "17.
|
|
42
|
+
agent_config_version: "17.2.0"
|
|
43
43
|
|
|
44
44
|
# --- Project identity ---
|
|
45
45
|
project:
|
|
@@ -731,7 +731,11 @@ that was never a judgement call.
|
|
|
731
731
|
(ADR-268 § 10). `resolved by` is one of `evidence`, `agent`,
|
|
732
732
|
`independent:<session or model>`, `council:<record>`, `team:<record>`,
|
|
733
733
|
`owner` — the prefixed forms carry their record, because a resolver
|
|
734
|
-
with no record is a claim rather than a resolution.
|
|
734
|
+
with no record is a claim rather than a resolution. The three locked
|
|
735
|
+
classes (`product-owned`, `business-owned`, `destructive-owned`) take
|
|
736
|
+
`owner` only; a council answer on one is recorded with `owner` and a
|
|
737
|
+
decision cell starting `proposed`. A resolved human-only blocker needs
|
|
738
|
+
a dated `owner` row naming it.
|
|
735
739
|
|
|
736
740
|
`revisit if` names the condition that reopens the row. Execution reads
|
|
737
741
|
the table **before any step**, and a closed decision is re-asked only
|
package/dist/cli/registry.js
CHANGED
|
@@ -77,7 +77,7 @@ export const REGISTRY = [
|
|
|
77
77
|
{ name: 'affected', disposition: 'delegate', synopsis: 'Artefacts related to <artefact> via the discovery relation-graph (BFS).' },
|
|
78
78
|
{ name: 'graph-explain', disposition: 'delegate', synopsis: 'Seed on a <concept>, expand 2 hops over the discovery relation-graph with a node budget.' },
|
|
79
79
|
{ name: 'benchmark', disposition: 'delegate', synopsis: 'Report context-token reduction vs the full always-loaded projection.' },
|
|
80
|
-
{ name: 'code-graph', disposition: 'delegate', synopsis: 'Deterministic code-graph engine: build|detect|refresh|validate|query|affected|path|explain, plus the gate verbs impact|tests-for|untested|dead.' },
|
|
80
|
+
{ name: 'code-graph', disposition: 'delegate', synopsis: 'Deterministic code-graph engine: build|detect|refresh|validate|query|affected|path|explain|map, plus the gate verbs impact|tests-for|untested|dead.' },
|
|
81
81
|
{ name: 'hooks:install', disposition: 'delegate', synopsis: 'Install the combined pre-commit hook.' },
|
|
82
82
|
{ name: 'hooks:status', disposition: 'delegate', synopsis: 'Print the runtime hook matrix (per-platform install + bindings).' },
|
|
83
83
|
{ name: 'hooks:doctor', disposition: 'delegate', synopsis: 'Diagnose hook health: concerns, posture, missing trampolines (read-only).' },
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { createRequire as __acCreateRequire } from 'node:module'; const require = globalThis.require ?? __acCreateRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
getLogPath
|
|
4
|
+
} from "./chunk-W5JXMF2T.js";
|
|
2
5
|
import {
|
|
3
6
|
classifyOwnership
|
|
4
7
|
} from "./chunk-J2SJZICO.js";
|
|
@@ -7,14 +10,21 @@ import {
|
|
|
7
10
|
var SIDECAR_SUFFIX = ".agent-config.new";
|
|
8
11
|
var EXIT_COMPLETED_WITH_CONFLICTS = 3;
|
|
9
12
|
function isLedgerMigration(inputs) {
|
|
10
|
-
if (!inputs.exists || inputs.force) return false;
|
|
13
|
+
if (!inputs.exists || inputs.force || inputs.loggedWrite === true) return false;
|
|
11
14
|
if (inputs.ledgerListed !== true) return false;
|
|
12
15
|
if (inputs.onDiskSha256 === null) return false;
|
|
13
16
|
return classifyOwnership(inputs.recordedSha256, inputs.onDiskSha256) === "unknown";
|
|
14
17
|
}
|
|
18
|
+
function logProofApplies(inputs) {
|
|
19
|
+
if (!inputs.exists || inputs.force || inputs.onDiskSha256 === null) return false;
|
|
20
|
+
const ownership = classifyOwnership(inputs.recordedSha256, inputs.onDiskSha256);
|
|
21
|
+
if (ownership === "recorded-modified") return inputs.recordedIsStaged === true;
|
|
22
|
+
return ownership === "unknown" && isLedgerMigration({ ...inputs, loggedWrite: false });
|
|
23
|
+
}
|
|
15
24
|
function decideDeployWrite(inputs) {
|
|
16
25
|
if (!inputs.exists) return "write";
|
|
17
26
|
if (inputs.force) return "write";
|
|
27
|
+
if (inputs.loggedWrite === true && logProofApplies(inputs)) return "write";
|
|
18
28
|
const ownership = classifyOwnership(inputs.recordedSha256, inputs.onDiskSha256);
|
|
19
29
|
if (ownership === "recorded-modified") return "preserve";
|
|
20
30
|
if (ownership === "unknown" && isLedgerMigration(inputs)) {
|
|
@@ -39,13 +49,97 @@ function foreignSidecarMessage(target, sidecar) {
|
|
|
39
49
|
return `Refusing to replace ${sidecar}: it already exists with different content and this install cannot show it wrote it. Package content for ${target} was NOT staged. Move or delete that file and re-run, or rerun with --force to replace the managed file instead.`;
|
|
40
50
|
}
|
|
41
51
|
|
|
52
|
+
// src/install/loggedWrites.ts
|
|
53
|
+
import { gunzipSync } from "node:zlib";
|
|
54
|
+
import { existsSync, readdirSync, readFileSync, realpathSync, statSync } from "node:fs";
|
|
55
|
+
import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
56
|
+
var WRITE_MARKER = '"kind":"write"';
|
|
57
|
+
var fileCache = /* @__PURE__ */ new Map();
|
|
58
|
+
var dirRealpaths = /* @__PURE__ */ new Map();
|
|
59
|
+
function canonicalPath(p) {
|
|
60
|
+
const abs = resolve(p);
|
|
61
|
+
const dir = dirname(abs);
|
|
62
|
+
let real = dirRealpaths.get(dir);
|
|
63
|
+
if (real === void 0) {
|
|
64
|
+
try {
|
|
65
|
+
real = realpathSync(dir);
|
|
66
|
+
} catch {
|
|
67
|
+
real = dir;
|
|
68
|
+
}
|
|
69
|
+
dirRealpaths.set(dir, real);
|
|
70
|
+
}
|
|
71
|
+
return join(real, basename(abs));
|
|
72
|
+
}
|
|
73
|
+
function logFiles(logPath) {
|
|
74
|
+
const dir = dirname(logPath);
|
|
75
|
+
if (!existsSync(dir)) return [];
|
|
76
|
+
const stem = basename(logPath).replace(/\.jsonl$/, "");
|
|
77
|
+
try {
|
|
78
|
+
return readdirSync(dir).filter((n) => n.startsWith(stem) && (n.endsWith(".jsonl") || n.endsWith(".jsonl.gz"))).map((n) => join(dir, n)).sort();
|
|
79
|
+
} catch {
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function writesIn(file) {
|
|
84
|
+
let stamp;
|
|
85
|
+
try {
|
|
86
|
+
const st = statSync(file);
|
|
87
|
+
stamp = `${st.size}:${Math.trunc(st.mtimeMs)}`;
|
|
88
|
+
} catch {
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
const cached = fileCache.get(file);
|
|
92
|
+
if (cached !== void 0 && cached.stamp === stamp) return cached.entries;
|
|
93
|
+
let text = "";
|
|
94
|
+
try {
|
|
95
|
+
const raw = readFileSync(file);
|
|
96
|
+
text = (file.endsWith(".gz") ? gunzipSync(raw) : raw).toString("utf8");
|
|
97
|
+
} catch {
|
|
98
|
+
text = "";
|
|
99
|
+
}
|
|
100
|
+
const entries = [];
|
|
101
|
+
for (const line of text.split("\n")) {
|
|
102
|
+
if (!line.includes(WRITE_MARKER)) continue;
|
|
103
|
+
let entry;
|
|
104
|
+
try {
|
|
105
|
+
entry = JSON.parse(line);
|
|
106
|
+
} catch {
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
if (typeof entry.path !== "string" || typeof entry.sha256 !== "string" || entry.sha256 === "") continue;
|
|
110
|
+
entries.push([canonicalPath(entry.path), entry.sha256]);
|
|
111
|
+
}
|
|
112
|
+
fileCache.set(file, { stamp, entries });
|
|
113
|
+
return entries;
|
|
114
|
+
}
|
|
115
|
+
function loggedWriteDigests(logPath = getLogPath()) {
|
|
116
|
+
const writes = /* @__PURE__ */ new Map();
|
|
117
|
+
for (const file of logFiles(logPath)) {
|
|
118
|
+
for (const [target, sha] of writesIn(file)) {
|
|
119
|
+
let set = writes.get(target);
|
|
120
|
+
if (set === void 0) writes.set(target, set = /* @__PURE__ */ new Set());
|
|
121
|
+
set.add(sha);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return writes;
|
|
125
|
+
}
|
|
126
|
+
function onlyDeployed(anchor, currentFiles, log) {
|
|
127
|
+
return (target) => {
|
|
128
|
+
const rel = relative(resolve(anchor), resolve(target)).split(sep).join("/");
|
|
129
|
+
if (currentFiles.has(rel)) log(target);
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
function wroteTheseBytes(target, onDiskSha256, writes) {
|
|
133
|
+
return writes.get(canonicalPath(target))?.has(onDiskSha256) === true;
|
|
134
|
+
}
|
|
135
|
+
|
|
42
136
|
// src/install/plan.ts
|
|
43
137
|
import { createHash } from "node:crypto";
|
|
44
|
-
import { readFileSync, readdirSync, statSync } from "node:fs";
|
|
45
|
-
import { join, relative, resolve } from "node:path";
|
|
138
|
+
import { readFileSync as readFileSync2, readdirSync as readdirSync2, statSync as statSync2 } from "node:fs";
|
|
139
|
+
import { join as join2, relative as relative2, resolve as resolve2 } from "node:path";
|
|
46
140
|
function sha256File(path) {
|
|
47
141
|
try {
|
|
48
|
-
const data =
|
|
142
|
+
const data = readFileSync2(path);
|
|
49
143
|
return createHash("sha256").update(data).digest("hex");
|
|
50
144
|
} catch {
|
|
51
145
|
return null;
|
|
@@ -66,15 +160,15 @@ function walkSourceTree(dir) {
|
|
|
66
160
|
function walkInto(dir, out) {
|
|
67
161
|
let entries;
|
|
68
162
|
try {
|
|
69
|
-
entries =
|
|
163
|
+
entries = readdirSync2(dir).sort();
|
|
70
164
|
} catch {
|
|
71
165
|
return;
|
|
72
166
|
}
|
|
73
167
|
for (const name of entries) {
|
|
74
|
-
const full =
|
|
168
|
+
const full = join2(dir, name);
|
|
75
169
|
let isDir;
|
|
76
170
|
try {
|
|
77
|
-
isDir =
|
|
171
|
+
isDir = statSync2(full).isDirectory();
|
|
78
172
|
} catch {
|
|
79
173
|
continue;
|
|
80
174
|
}
|
|
@@ -94,8 +188,8 @@ function buildInstallPlan(inputs) {
|
|
|
94
188
|
files = files.filter(source.fileFilter);
|
|
95
189
|
}
|
|
96
190
|
for (const srcFile of files) {
|
|
97
|
-
const rel =
|
|
98
|
-
const destPath =
|
|
191
|
+
const rel = relative2(source.srcDir, srcFile);
|
|
192
|
+
const destPath = resolve2(source.destDir, rel);
|
|
99
193
|
bucket.push(
|
|
100
194
|
fileEntry(srcFile, source.kind, {
|
|
101
195
|
hashContent: source.kind !== "bridge"
|
|
@@ -126,12 +220,16 @@ function buildInstallPlan(inputs) {
|
|
|
126
220
|
export {
|
|
127
221
|
EXIT_COMPLETED_WITH_CONFLICTS,
|
|
128
222
|
isLedgerMigration,
|
|
223
|
+
logProofApplies,
|
|
129
224
|
decideDeployWrite,
|
|
130
225
|
sidecarPathFor,
|
|
131
226
|
preservedFileMessage,
|
|
132
227
|
migrationPreservedMessage,
|
|
133
228
|
conflictSummaryMessage,
|
|
134
229
|
foreignSidecarMessage,
|
|
230
|
+
loggedWriteDigests,
|
|
231
|
+
onlyDeployed,
|
|
232
|
+
wroteTheseBytes,
|
|
135
233
|
sha256File,
|
|
136
234
|
buildInstallPlan
|
|
137
235
|
};
|
|
@@ -42,7 +42,7 @@ import {
|
|
|
42
42
|
readUserPin,
|
|
43
43
|
residualReport,
|
|
44
44
|
runtimeRootFor
|
|
45
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-QBHEI5N4.js";
|
|
46
46
|
import {
|
|
47
47
|
LEGACY_ALL,
|
|
48
48
|
excludedRuleBasenames,
|
|
@@ -89,7 +89,7 @@ import {
|
|
|
89
89
|
readCanaryStatusLine,
|
|
90
90
|
runCensus,
|
|
91
91
|
summaryLine
|
|
92
|
-
} from "./chunk-
|
|
92
|
+
} from "./chunk-BZJ4Y3CI.js";
|
|
93
93
|
import {
|
|
94
94
|
EGRESS_RULES,
|
|
95
95
|
REVIEW_CREDENTIAL_ROWS,
|
|
@@ -101,7 +101,7 @@ import {
|
|
|
101
101
|
replaceSpans,
|
|
102
102
|
resolveOverlaps,
|
|
103
103
|
vendorPrefix
|
|
104
|
-
} from "./chunk-
|
|
104
|
+
} from "./chunk-KR5ZIFPO.js";
|
|
105
105
|
import {
|
|
106
106
|
classifyFileState,
|
|
107
107
|
classifyOwnership,
|
|
@@ -468,7 +468,7 @@ function censusRuleDir(dir) {
|
|
|
468
468
|
}
|
|
469
469
|
|
|
470
470
|
// src/scripts/cache_realization_report.ts
|
|
471
|
-
import { execFileSync } from "node:child_process";
|
|
471
|
+
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
472
472
|
import * as fs7 from "node:fs";
|
|
473
473
|
import { homedir as homedir2 } from "node:os";
|
|
474
474
|
import * as path12 from "node:path";
|
|
@@ -809,6 +809,7 @@ if (process.argv[1] !== void 0) {
|
|
|
809
809
|
}
|
|
810
810
|
|
|
811
811
|
// src/scripts/hooks/subagent_ledger_hook.ts
|
|
812
|
+
import { execFileSync } from "node:child_process";
|
|
812
813
|
import * as crypto from "node:crypto";
|
|
813
814
|
import * as fs5 from "node:fs";
|
|
814
815
|
import * as path10 from "node:path";
|
|
@@ -1069,6 +1070,41 @@ function appendLedgerLine(root, ts, line) {
|
|
|
1069
1070
|
fs5.appendFileSync(file, `${JSON.stringify(line)}
|
|
1070
1071
|
`, "utf8");
|
|
1071
1072
|
}
|
|
1073
|
+
var INDEX_SUBDIR = "index";
|
|
1074
|
+
function writeIndexEntry(root, ts, key, value) {
|
|
1075
|
+
if (is_replay_mode()) return;
|
|
1076
|
+
const dir = path10.join(root, LEDGER_DIR, INDEX_SUBDIR, ts.slice(0, 7));
|
|
1077
|
+
fs5.mkdirSync(dir, { recursive: true });
|
|
1078
|
+
const tmp = path10.join(dir, `.${key}.${process.pid}.tmp`);
|
|
1079
|
+
try {
|
|
1080
|
+
fs5.writeFileSync(tmp, value, "utf8");
|
|
1081
|
+
fs5.renameSync(tmp, path10.join(dir, key));
|
|
1082
|
+
} finally {
|
|
1083
|
+
fs5.rmSync(tmp, { force: true });
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
function headOf(dir) {
|
|
1087
|
+
try {
|
|
1088
|
+
const env = Object.fromEntries(Object.entries(process.env).filter(([k]) => !k.startsWith("GIT_")));
|
|
1089
|
+
return execFileSync("git", ["-C", dir, "rev-parse", "HEAD"], { encoding: "utf8", timeout: 2e3, stdio: ["ignore", "pipe", "ignore"], env }).trim() || null;
|
|
1090
|
+
} catch {
|
|
1091
|
+
return null;
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
function stateStamp(cwd) {
|
|
1095
|
+
let epoch = null;
|
|
1096
|
+
try {
|
|
1097
|
+
epoch = fs5.statSync(fileURLToPath(import.meta.url)).mtimeMs;
|
|
1098
|
+
} catch {
|
|
1099
|
+
}
|
|
1100
|
+
return typeof cwd === "string" && cwd ? { head: headOf(cwd), cwd_key: refFor(cwd), epoch } : { head: null, cwd_key: null, epoch };
|
|
1101
|
+
}
|
|
1102
|
+
function stopIndexKey(sessionId, ref) {
|
|
1103
|
+
return refFor(`subagent-stop\0${sessionId}\0${ref}`);
|
|
1104
|
+
}
|
|
1105
|
+
function recordStopIndex(root, ts, sessionId, ref) {
|
|
1106
|
+
writeIndexEntry(root, ts, stopIndexKey(sessionId, ref), "");
|
|
1107
|
+
}
|
|
1072
1108
|
var WALL_CLOCK_ARMS_MS = [
|
|
1073
1109
|
{ label: "5m", ms: 5 * 60 * 1e3 },
|
|
1074
1110
|
{ label: "15m", ms: 15 * 60 * 1e3 },
|
|
@@ -1236,8 +1272,13 @@ function handleStop(root, payload, nowIso, sessionId) {
|
|
|
1236
1272
|
// Beside the count, never instead of it: the count says how wrong the
|
|
1237
1273
|
// candidate was, this says whether it was aimed at the envelope.
|
|
1238
1274
|
envelope_field_hits: parse3.field_hits,
|
|
1239
|
-
concurrent_open: countOpen(root)
|
|
1275
|
+
concurrent_open: countOpen(root),
|
|
1276
|
+
...stateStamp(payload["cwd"])
|
|
1240
1277
|
});
|
|
1278
|
+
try {
|
|
1279
|
+
if (sessionId !== null) recordStopIndex(root, nowIso, sessionId, ref);
|
|
1280
|
+
} catch {
|
|
1281
|
+
}
|
|
1241
1282
|
}
|
|
1242
1283
|
function processEnvelope(envelope, consumerRoot) {
|
|
1243
1284
|
try {
|
|
@@ -1827,7 +1868,7 @@ function encodeProjectPath(cwd) {
|
|
|
1827
1868
|
}
|
|
1828
1869
|
function listGitWorktrees(cwd) {
|
|
1829
1870
|
try {
|
|
1830
|
-
const out =
|
|
1871
|
+
const out = execFileSync2("git", ["worktree", "list", "--porcelain"], { cwd, encoding: "utf-8", timeout: 1e4 });
|
|
1831
1872
|
const paths = [];
|
|
1832
1873
|
for (const line of out.split("\n")) {
|
|
1833
1874
|
if (line.startsWith("worktree ")) paths.push(line.slice("worktree ".length).trim());
|
|
@@ -1900,7 +1941,7 @@ function computeWorktreeFragmentation(projectsRoot, worktreePaths, maxAgeDays) {
|
|
|
1900
1941
|
}
|
|
1901
1942
|
function hostVersion() {
|
|
1902
1943
|
try {
|
|
1903
|
-
const out =
|
|
1944
|
+
const out = execFileSync2("claude", ["--version"], { encoding: "utf-8", timeout: 5e3 }).trim();
|
|
1904
1945
|
return out.length > 0 ? out : "unknown";
|
|
1905
1946
|
} catch {
|
|
1906
1947
|
return "unknown";
|
|
@@ -8060,9 +8101,10 @@ var CliClient = class extends ExternalAIClient {
|
|
|
8060
8101
|
_cli_calls_path;
|
|
8061
8102
|
/** Attribution label for every booking this client makes. */
|
|
8062
8103
|
_consumer;
|
|
8063
|
-
/** The session the last answered call ran in; `resumeNext` continues it once,
|
|
8104
|
+
/** The session the last answered call ran in; `resumeNext` continues it once, never while `blind`. */
|
|
8064
8105
|
lastSession = null;
|
|
8065
8106
|
resumeNext = null;
|
|
8107
|
+
blind = false;
|
|
8066
8108
|
static _AUTH_FAILURE_PATTERNS = [
|
|
8067
8109
|
"authentication",
|
|
8068
8110
|
"unauthorized",
|
|
@@ -8435,7 +8477,7 @@ var AnthropicCliClient = class extends CliClient {
|
|
|
8435
8477
|
void max_tokens;
|
|
8436
8478
|
return [
|
|
8437
8479
|
this.binary,
|
|
8438
|
-
...seatResumeArgs(this.name, this.resumeNext, { blind:
|
|
8480
|
+
...seatResumeArgs(this.name, this.resumeNext, { blind: this.blind, now_ms: Date.now() }),
|
|
8439
8481
|
"--print",
|
|
8440
8482
|
// The seat never needs the user environment; only a version the light
|
|
8441
8483
|
// launch was probed on gets the flag (`LIGHT_LAUNCH_PROBES`).
|
|
@@ -8538,7 +8580,7 @@ var OpenAICliClient = class extends CliClient {
|
|
|
8538
8580
|
void user_prompt;
|
|
8539
8581
|
void max_tokens;
|
|
8540
8582
|
const modelArgs = this.model === OPENAI_CLI_VENDOR_DEFAULT ? [] : ["--model", this.model];
|
|
8541
|
-
const resume = seatResumeArgs(this.name, this.resumeNext, { blind:
|
|
8583
|
+
const resume = seatResumeArgs(this.name, this.resumeNext, { blind: this.blind, now_ms: Date.now() });
|
|
8542
8584
|
const bound = resume.length === 0 ? boundFor("openai") : resumeBound(boundFor("openai"));
|
|
8543
8585
|
return [this.binary, "exec", ...resume, "--json", "--skip-git-repo-check", ...bound, ...modelArgs, "-"];
|
|
8544
8586
|
}
|
|
@@ -2,11 +2,15 @@ import { createRequire as __acCreateRequire } from 'node:module'; const require
|
|
|
2
2
|
import {
|
|
3
3
|
buildInstallPlan,
|
|
4
4
|
isLedgerMigration,
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
logProofApplies,
|
|
6
|
+
loggedWriteDigests,
|
|
7
|
+
sha256File,
|
|
8
|
+
sidecarPathFor,
|
|
9
|
+
wroteTheseBytes
|
|
10
|
+
} from "./chunk-3PK3VZHB.js";
|
|
7
11
|
import {
|
|
8
12
|
detectToolPresence
|
|
9
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-W5JXMF2T.js";
|
|
10
14
|
import {
|
|
11
15
|
classifyOwnership,
|
|
12
16
|
ledgerListedPaths,
|
|
@@ -23,10 +27,11 @@ import { existsSync } from "node:fs";
|
|
|
23
27
|
function isJsonTarget(entry) {
|
|
24
28
|
return entry.kind === "deployed" && entry.path.endsWith(".json");
|
|
25
29
|
}
|
|
26
|
-
function computeConflicts(plan, recordedOverride) {
|
|
30
|
+
function computeConflicts(plan, recordedOverride, loggedOverride) {
|
|
27
31
|
if (plan.policy.force) return [];
|
|
28
32
|
const recorded = recordedOverride ?? recordedHashesWithLedger(plan.root);
|
|
29
33
|
let ledgerFiles = null;
|
|
34
|
+
let logged;
|
|
30
35
|
const ledgerLists = (p) => {
|
|
31
36
|
ledgerFiles ??= ledgerListedPaths();
|
|
32
37
|
return ledgerFiles.has(p);
|
|
@@ -40,6 +45,19 @@ function computeConflicts(plan, recordedOverride) {
|
|
|
40
45
|
const onDisk = sha256File(entry.path);
|
|
41
46
|
const ownership = classifyOwnership(recorded.get(entry.path), onDisk);
|
|
42
47
|
if (ownership === "recorded-unchanged") continue;
|
|
48
|
+
const recordedSha = recorded.get(entry.path);
|
|
49
|
+
const unproven = {
|
|
50
|
+
exists: true,
|
|
51
|
+
recordedSha256: recordedSha,
|
|
52
|
+
onDiskSha256: onDisk,
|
|
53
|
+
force: false,
|
|
54
|
+
ledgerListed: ledgerLists(entry.path),
|
|
55
|
+
recordedIsStaged: typeof recordedSha === "string" && recordedSha === recorded.get(sidecarPathFor(entry.path))
|
|
56
|
+
};
|
|
57
|
+
if (logProofApplies(unproven)) {
|
|
58
|
+
logged ??= loggedOverride ?? loggedWriteDigests();
|
|
59
|
+
if (wroteTheseBytes(entry.path, onDisk, logged)) continue;
|
|
60
|
+
}
|
|
43
61
|
if (ownership === "unknown" && plan.policy.knownPaths.has(entry.path)) continue;
|
|
44
62
|
const migration = ownership === "unknown" && isLedgerMigration({
|
|
45
63
|
exists: true,
|