@event4u/agent-config 17.2.1 → 17.4.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/.claude-plugin/skills/install-agent-config/SKILL.md +9 -9
- package/CHANGELOG.md +167 -193
- package/CREDITS.md +2 -2
- package/README.md +1 -1
- package/dist/agent-src/skills/code-intelligence/SKILL.md +16 -12
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/scripts/check_memory.ts +1 -1
- package/dist/cli/commands/recordTriggerEval.js +1 -1
- package/dist/cli/registry.js +2 -2
- package/dist/cli-delegate/{chunk-KR5ZIFPO.js → chunk-5AYJGUA3.js} +1 -3
- package/dist/cli-delegate/chunk-DIFZBP4G.js +1336 -0
- package/dist/cli-delegate/chunk-E7ACTJTJ.js +6792 -0
- package/dist/cli-delegate/{chunk-VYZGJLCA.js → chunk-RKNT4LIK.js} +22 -1286
- package/dist/cli-delegate/{chunk-BZJ4Y3CI.js → chunk-WY5ZZPGL.js} +2 -2
- package/dist/cli-delegate/{chunk-CMZEKSNN.js → chunk-X6LZ7W5A.js} +73 -10
- package/dist/cli-delegate/cmd_conformance.js +190 -192
- package/dist/cli-delegate/cmd_doctor.js +5 -5
- package/dist/cli-delegate/cmd_doctor_neighbours.js +3 -3
- package/dist/cli-delegate/cmd_explain.js +1 -1
- package/dist/cli-delegate/cmd_export.js +2 -2
- package/dist/cli-delegate/cmd_handoff.js +2 -2
- package/dist/cli-delegate/cmd_memory_get.js +1 -1
- package/dist/cli-delegate/cmd_prune.js +2 -2
- package/dist/cli-delegate/cmd_route_audit.js +1 -1
- package/dist/cli-delegate/cmd_session_recycle.js +2 -2
- package/dist/cli-delegate/cmd_settings_migrate.js +2 -2
- package/dist/cli-delegate/cmd_settings_set.js +8 -4
- package/dist/cli-delegate/cmd_sync.js +2 -2
- package/dist/cli-delegate/cmd_uninstall.js +2 -2
- package/dist/cli-delegate/cmd_update.js +24 -13
- package/dist/cli-delegate/cmd_upgrade.js +2 -2
- package/dist/cli-delegate/cmd_validate.js +2 -2
- package/dist/cli-delegate/dist-25AZAHOP.js +3240 -0
- package/dist/cli-delegate/dist-P7MFPMF3.js +411 -0
- package/dist/cli-delegate/dist-XAS5ZLQB.js +6 -0
- package/dist/cli-delegate/{upgrade_unattended-VVL6JLSX.js → upgrade_unattended-QCWOKTUN.js} +178 -163
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +3 -3
- 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/code_graph_refresh.chunk.cjs +443 -0
- package/dist/hooks/code_graph_refresh.chunk.cjs.sha256 +1 -0
- package/dist/hooks/dispatch.js +1001 -938
- package/dist/hooks/dispatch.sha256 +1 -1
- package/dist/hooks/egress_engine.chunk.cjs +57 -7
- package/dist/hooks/egress_engine.chunk.cjs.sha256 +1 -1
- package/dist/hooks/update_notice.chunk.cjs +914 -0
- package/dist/hooks/update_notice.chunk.cjs.sha256 +1 -0
- package/dist/install/install.mjs +6974 -6037
- package/dist/mcp/mcp-cloudflare-catalogue.json +1 -0
- package/dist/mcp/registry-manifest.json +3 -2
- package/dist/mcp/server.json +13 -4
- package/dist/mcp/server.mjs +71202 -63282
- package/dist/scripts/_lib/egress_rules.js +8 -2
- package/dist/scripts/condense.js +18 -15
- package/dist/server/routes/discovery.js +1 -1
- package/dist/server/routes/install.js +1 -1
- package/dist/server/routes/ping.js +1 -1
- package/dist/server/routes/schema.js +4 -4
- package/dist/server/routes/settings.js +2 -6
- package/dist/server/routes/wizard.js +6 -6
- package/dist/server/schemas/settings.js +42 -42
- package/dist/shared/settingsSurface.js +1 -1
- package/dist/shared/userMd/schema.js +1 -1
- package/dist/shared/zodJsonSchema.js +47 -0
- package/dist/ui/assets/index-B0bcIgi0.js +77 -0
- package/dist/ui/index.html +1 -1
- package/package.json +6 -3
- package/src/agent-src/templates/scripts/check_memory.ts +1 -1
- package/src/config/ci-local-parity.yml +11 -0
- package/src/config/continuity-surface.json +9 -2
- package/src/config/evaluator-budgets.json +9 -8
- package/src/config/gate-violation-baselines.json +3 -3
- package/src/config/gitignore-block.txt +6 -5
- package/src/config/hook-bundle-budget.json +46 -6
- package/src/config/pack-size-budget.json +12 -1
- package/src/config/packed-binary-manifest.json +18 -0
- package/src/config/sigstore/npm_keys.json +50 -0
- package/src/config/sigstore/trust-material.json +9 -0
- package/src/config/sigstore/trusted_root.json +126 -0
- package/src/config/skill-body-budget.json +7 -1
- package/src/scripts/_cli/cmd_settings_set.ts +3 -2
- package/src/scripts/_cli/cmd_update.ts +48 -20
- package/src/scripts/_cli/cmd_upgrade.ts +7 -1
- package/src/scripts/_cli/upgrade_unattended.ts +90 -76
- package/src/scripts/_dispatch.bash +4 -3
- package/src/scripts/_lib/confusables.ts +0 -19
- package/src/scripts/_lib/egress_normalize.ts +53 -23
- package/src/scripts/_lib/egress_rules.ts +8 -2
- package/src/scripts/_lib/egress_text.ts +5 -3
- package/src/scripts/_lib/egress_token.ts +7 -5
- package/src/scripts/_lib/gate_collector_experimental.ts +633 -0
- package/src/scripts/_lib/git_common_dir.ts +10 -0
- package/src/scripts/_lib/graph_feeder_record.ts +3 -2
- package/src/scripts/_lib/install_reach_checks.ts +32 -2
- package/src/scripts/_lib/lineage_backfill.ts +136 -0
- package/src/scripts/_lib/lineage_ledger.ts +211 -0
- package/src/scripts/_lib/lineage_map.ts +55 -0
- package/src/scripts/_lib/lineage_query.ts +140 -0
- package/src/scripts/_lib/lineage_seed.ts +116 -0
- package/src/scripts/_lib/lineage_watch.ts +249 -0
- package/src/scripts/_lib/link_crypto.ts +8 -4
- package/src/scripts/_lib/listing_manifests.ts +85 -0
- package/src/scripts/_lib/neighbour_census.ts +1 -0
- package/src/scripts/_lib/production_reach.ts +3 -3
- package/src/scripts/_lib/project_registry.ts +227 -0
- package/src/scripts/_lib/provenance_verify.ts +14 -242
- package/src/scripts/_lib/release_settings_surface.ts +2 -6
- package/src/scripts/_lib/sigstore_provenance.ts +177 -0
- package/src/scripts/_lib/source_id.ts +48 -0
- package/src/scripts/_lib/source_shape.ts +4 -0
- package/src/scripts/_lib/unattended_gates.ts +6 -1
- package/src/scripts/adoption_status.ts +231 -27
- package/src/scripts/advisories.ts +26 -10
- package/src/scripts/ai_council/council_egress.ts +5 -6
- package/src/scripts/bench_graph_feeder_latency.ts +10 -3
- package/src/scripts/build_mcp_registry_manifest.ts +23 -12
- package/src/scripts/check_dependency_floors.ts +14 -0
- package/src/scripts/check_egress_mutations.ts +1 -0
- package/src/scripts/check_release_manifest_content.ts +17 -2
- package/src/scripts/check_release_pr_shape.ts +5 -0
- package/src/scripts/code_graph/build.ts +145 -45
- package/src/scripts/code_graph/cli.ts +382 -35
- package/src/scripts/code_graph/conventions_default.ts +247 -0
- package/src/scripts/code_graph/detect.ts +5 -5
- package/src/scripts/code_graph/estate_cli.ts +135 -0
- package/src/scripts/code_graph/estate_index.ts +394 -0
- package/src/scripts/code_graph/estate_manifests.ts +223 -0
- package/src/scripts/code_graph/estate_map.ts +141 -0
- package/src/scripts/code_graph/extract.ts +8 -2
- package/src/scripts/code_graph/extract_more.ts +241 -2
- package/src/scripts/code_graph/graph_budget.ts +158 -0
- package/src/scripts/code_graph/graph_home.ts +80 -0
- package/src/scripts/code_graph/lineage_cli.ts +315 -0
- package/src/scripts/code_graph/loader.ts +10 -2
- package/src/scripts/code_graph/map.ts +195 -53
- package/src/scripts/code_graph/map_model.ts +113 -20
- package/src/scripts/code_graph/map_verify.ts +80 -5
- package/src/scripts/code_graph/map_viewer/viewer.css +18 -0
- package/src/scripts/code_graph/map_viewer/viewer.js +146 -15
- package/src/scripts/code_graph/passes.ts +173 -0
- package/src/scripts/code_graph/project_ref.ts +25 -0
- package/src/scripts/code_graph/projects_cli.ts +254 -0
- package/src/scripts/code_graph/providers/angular.ts +55 -0
- package/src/scripts/code_graph/providers/aspnetcore.ts +182 -0
- package/src/scripts/code_graph/providers/catalog.ts +299 -0
- package/src/scripts/code_graph/providers/django.ts +206 -0
- package/src/scripts/code_graph/providers/express.ts +25 -0
- package/src/scripts/code_graph/providers/fastapi.ts +49 -0
- package/src/scripts/code_graph/providers/flask.ts +99 -0
- package/src/scripts/code_graph/providers/go_http.ts +121 -0
- package/src/scripts/code_graph/providers/index.ts +103 -0
- package/src/scripts/code_graph/{laravel_overlay.ts → providers/laravel.ts} +113 -7
- package/src/scripts/code_graph/providers/nestjs.ts +34 -0
- package/src/scripts/code_graph/providers/nextjs.ts +91 -0
- package/src/scripts/code_graph/providers/nuxt.ts +55 -0
- package/src/scripts/code_graph/providers/rails.ts +204 -0
- package/src/scripts/code_graph/providers/react-router.ts +58 -0
- package/src/scripts/code_graph/providers/shared/detect.ts +78 -0
- package/src/scripts/code_graph/providers/shared/extractors.ts +249 -0
- package/src/scripts/code_graph/providers/shared/js.ts +252 -0
- package/src/scripts/code_graph/providers/shared/kit.ts +210 -0
- package/src/scripts/code_graph/providers/shared/php.ts +64 -0
- package/src/scripts/code_graph/providers/shared/python.ts +223 -0
- package/src/scripts/code_graph/providers/spring.ts +175 -0
- package/src/scripts/code_graph/providers/sqlalchemy.ts +62 -0
- package/src/scripts/code_graph/providers/sveltekit.ts +59 -0
- package/src/scripts/code_graph/providers/symfony.ts +142 -0
- package/src/scripts/code_graph/providers/typeorm.ts +58 -0
- package/src/scripts/code_graph/providers/types.ts +56 -0
- package/src/scripts/code_graph/providers/vue-router.ts +21 -0
- package/src/scripts/code_graph/providers/wordpress.ts +128 -0
- package/src/scripts/code_graph/query.ts +9 -9
- package/src/scripts/code_graph/refresh_cli.ts +81 -0
- package/src/scripts/code_graph/refresh_lock.ts +197 -0
- package/src/scripts/code_graph/repo_identity.ts +169 -0
- package/src/scripts/code_graph/resolution_tiers.ts +19 -7
- package/src/scripts/code_graph/scip_reader.ts +2 -2
- package/src/scripts/code_graph/sqlite_store.ts +31 -28
- package/src/scripts/code_graph/types.ts +79 -41
- package/src/scripts/code_graph/validate.ts +6 -8
- package/src/scripts/condense.ts +15 -15
- package/src/scripts/generate_settings_reference.ts +2 -6
- package/src/scripts/hook_chunks.mjs +11 -0
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +43 -23
- package/src/scripts/hooks/code_graph_refresh_hook.ts +163 -0
- package/src/scripts/hooks/dispatch_hook.ts +6 -7
- package/src/scripts/hooks/host_semantics.ts +72 -0
- package/src/scripts/hooks/lazy_concern.ts +8 -0
- package/src/scripts/hooks/user_notice.ts +105 -0
- package/src/scripts/install-hooks.sh +54 -33
- package/src/scripts/install.ts +2 -6
- package/src/scripts/lint_harvest_provenance.ts +137 -11
- package/src/scripts/lint_hook_manifest.ts +2 -0
- package/src/scripts/lint_marketplace.ts +33 -0
- package/src/scripts/lint_mcp_registry_manifest.ts +36 -0
- package/src/scripts/mcp_server/consumer_tool_catalog.json +70 -15
- package/src/scripts/mcp_server/graph_tools.ts +165 -41
- package/src/scripts/network_sources.ts +24 -6
- package/src/scripts/release.ts +2 -5
- package/src/scripts/release_drill.ts +4 -1
- package/src/scripts/release_env.ts +17 -0
- package/src/scripts/release_mix_taxonomy.json +3 -0
- package/src/scripts/schemas/provenance-mechanism.schema.json +46 -0
- package/src/scripts/update_notice_hook.ts +75 -7
- package/src/server/schemas/settings.ts +42 -42
- package/src/shared/settingsSurface.ts +1 -1
- package/src/shared/userMd/schema.ts +1 -1
- package/src/shared/zodJsonSchema.ts +41 -0
- package/src/vendor/grammars/README.md +8 -6
- package/src/vendor/grammars/tree-sitter-c_sharp.wasm +0 -0
- package/src/vendor/grammars/tree-sitter-ruby.wasm +0 -0
- package/dist/cli-delegate/chunk-XIAPY44N.js +0 -4587
- package/dist/ui/assets/index-w70Ado09.js +0 -23
- /package/dist/cli-delegate/{chunk-FKYZOWVD.js → chunk-QBAFP67O.js} +0 -0
- /package/dist/cli-delegate/{chunk-BMGUGSY6.js → chunk-TQG6UMPC.js} +0 -0
package/dist/ui/index.html
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
document.documentElement.setAttribute('data-theme', theme);
|
|
28
28
|
})();
|
|
29
29
|
</script>
|
|
30
|
-
<script type="module" crossorigin src="/assets/index-
|
|
30
|
+
<script type="module" crossorigin src="/assets/index-B0bcIgi0.js"></script>
|
|
31
31
|
<link rel="stylesheet" crossorigin href="/assets/index-Cyjy8bWO.css">
|
|
32
32
|
</head>
|
|
33
33
|
<body>
|
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": "17.
|
|
4
|
+
"version": "17.4.0",
|
|
5
5
|
"description": "Governed skills, rules and commands for AI coding tools (Claude Code, Cursor, Windsurf, Copilot) — every claim machine-checked, including the artifact counts in these badges.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"private": false,
|
|
@@ -132,6 +132,9 @@
|
|
|
132
132
|
"@fastify/static": "^10.1.2",
|
|
133
133
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
134
134
|
"@preact/signals": "^2.10.0",
|
|
135
|
+
"@sigstore/bundle": "5.0.0",
|
|
136
|
+
"@sigstore/protobuf-specs": "0.5.2",
|
|
137
|
+
"@sigstore/verify": "4.1.2",
|
|
135
138
|
"commander": "^15.0.0",
|
|
136
139
|
"execa": "^9.5.0",
|
|
137
140
|
"fastify": "^5.11.0",
|
|
@@ -143,13 +146,13 @@
|
|
|
143
146
|
"preact": "^10.29.0",
|
|
144
147
|
"web-tree-sitter": "0.24.7",
|
|
145
148
|
"yaml": "^2.9.0",
|
|
146
|
-
"zod": "^
|
|
147
|
-
"zod-to-json-schema": "^3.25.0"
|
|
149
|
+
"zod": "^4.6.6"
|
|
148
150
|
},
|
|
149
151
|
"overrides": {
|
|
150
152
|
"@hono/node-server": "^2.0.5"
|
|
151
153
|
},
|
|
152
154
|
"agentConfig": {
|
|
155
|
+
"registryDescription": "Governed skills, rules and commands for AI coding agents, served by a read-only MCP server.",
|
|
153
156
|
"impact": {
|
|
154
157
|
"17.0.0": {
|
|
155
158
|
"impact": "notice"
|
|
@@ -136,7 +136,7 @@ export const REDACTION_PATTERNS: ReadonlyArray<readonly [RegExp, string]> = [
|
|
|
136
136
|
// Key=value secret with a clear credential-word prefix. The value must
|
|
137
137
|
// be a single token (no spaces, no "/" — skips filepaths and URLs).
|
|
138
138
|
[
|
|
139
|
-
/\b(api[_-]?key|auth[_-]?token|access[_-]?token|bearer|secret|password|passwd|private[_-]?key)\b\s*
|
|
139
|
+
/\b(api[_-]?key|auth[_-]?token|access[_-]?token|bearer|secret|password|passwd|private[_-]?key)\b\s*(?::|=(?!==|=\s|>)=?)\s*[A-Za-z0-9+/=_\-]{8,}(?![/.\w])/i,
|
|
140
140
|
'inline credential',
|
|
141
141
|
],
|
|
142
142
|
[/https?:\/\/[^\s"'/]*:[^\s"'/]*@/, 'url with credentials'],
|
|
@@ -109,6 +109,17 @@ ci_only:
|
|
|
109
109
|
# self-test is the half that IS worth running locally, and it is reachable —
|
|
110
110
|
# `classify_change_risk --self-test` — but the workflow invokes it as a step of
|
|
111
111
|
# its own rather than through the aggregate, which is what this checker sees.
|
|
112
|
+
# road-to-listings-a-release-keeps-current Phase 5. The daily release-adjacent
|
|
113
|
+
# health job runs `adoption_status --check-upstream --fail-on-action`, which
|
|
114
|
+
# reads every ledger row's live upstream (gh for a pull request, curl for a
|
|
115
|
+
# listing or registry query). Its verdict is a property of third-party sites on
|
|
116
|
+
# the day it runs, not of a change, so it does not belong in `task ci`; the
|
|
117
|
+
# judging logic is covered offline by tests/scripts/adoption_status.test.ts.
|
|
118
|
+
# Reachable on demand: `./scripts-run src/scripts/adoption_status --check-upstream --fail-on-action`.
|
|
119
|
+
- id: adoption_status
|
|
120
|
+
class: network
|
|
121
|
+
reason: "reads live third-party upstreams (gh pr view, listing pages, the MCP registry); the verdict describes those sites on the day it runs, not the change, and the judging logic runs offline in the vitest suite"
|
|
122
|
+
|
|
112
123
|
# road-to-npm-payload-reduction Phase 3.1. `report_pack_delta` measures the
|
|
113
124
|
# BRANCH-vs-BASE packed payload, which has no meaning without a pull request:
|
|
114
125
|
# locally `--base origin/main --head HEAD` on main reads +0.0 KB every time, and
|
|
@@ -96,8 +96,15 @@
|
|
|
96
96
|
"id": "code-graph-refresh.lock",
|
|
97
97
|
"axis": "persistent_continuity_artefacts",
|
|
98
98
|
"disposition": "excluded",
|
|
99
|
-
"reason": "A concurrency lock guarding the code-graph refresh so two checkouts do not rebuild the index at once. Held for the duration of one refresh; it carries no state anyone reads afterwards.",
|
|
100
|
-
"locus": "src/scripts/
|
|
99
|
+
"reason": "A concurrency lock guarding the code-graph refresh so two checkouts do not rebuild the index at once, taken by `code-graph refresh --single-flight` (which the git hooks and the session concern run) and by `code-graph map`. Its sibling `.owner.json` names the holding pid so a crashed holder's lock can be reclaimed, and a sibling `.reclaim` directory is the short-lived mutex a reclaim holds. Held for the duration of one refresh; it carries no state anyone reads afterwards.",
|
|
100
|
+
"locus": "src/scripts/code_graph/refresh_lock.ts:24"
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"id": "code-graph-auto-refresh.json",
|
|
104
|
+
"axis": "persistent_continuity_artefacts",
|
|
105
|
+
"disposition": "excluded",
|
|
106
|
+
"reason": "A per-project opt-in written by `code-graph auto-refresh on` and removed by `off`. The session-start refresh concern reads only its presence; it carries a timestamp nobody restores anything from, and a successor session that finds it learns a preference, not where the work stood.",
|
|
107
|
+
"locus": "src/scripts/code_graph/refresh_lock.ts:26"
|
|
101
108
|
},
|
|
102
109
|
{
|
|
103
110
|
"id": "code-graph-v1.json",
|
|
@@ -40,13 +40,14 @@
|
|
|
40
40
|
]
|
|
41
41
|
},
|
|
42
42
|
"runtime_dep_count": {
|
|
43
|
-
"max":
|
|
44
|
-
"last_measured":
|
|
45
|
-
"last_measured_at": "2026-
|
|
43
|
+
"max": 210,
|
|
44
|
+
"last_measured": 204,
|
|
45
|
+
"last_measured_at": "2026-10-24",
|
|
46
46
|
"method": "package-lock.json packages count (minus root) of the clean --omit=dev install",
|
|
47
47
|
"inputs": [
|
|
48
48
|
"package-lock.json"
|
|
49
|
-
]
|
|
49
|
+
],
|
|
50
|
+
"baseline_note": "187 → 204, max 200 → 210 on 2026-10-24 (release 17.4.0 gate). The growth crossing the cap is the sigstore verification chain (`@sigstore/verify`, `@sigstore/bundle`, `@sigstore/protobuf-specs` and their transitive deps), added by #2622 for road-to-an-update-that-installs-itself-only-when-it-is-safe step 2.1: unattended upgrades now verify the npm provenance attestations against a pinned Sigstore trust root before installing. That dependency was the recorded decision D15 (option a — the maintained sigstore verifier over a hand-rolled DSSE check), so the cap is raised consciously rather than the verification dropped. Measured 204 by the packed-artifact evaluation of release PR #2630. Headroom is 6 — the next dependency addition meets this gate again."
|
|
50
51
|
},
|
|
51
52
|
"cli_version_cold_ms": {
|
|
52
53
|
"max": 1500,
|
|
@@ -75,14 +76,14 @@
|
|
|
75
76
|
"baseline_note": "80 → 81 on 2026-08-03 (release 9.15.0 gate). This RECORDS growth that already shipped through its own reviewed PR; it does not authorize new surface. The +1 is f02db54c2 (fix(cli): register routing:doctor in the CLI registry) — the command existed, only its registry entry was missing, and the registering PR did not move this budget. The gate did its job again: breach WARNS on main and BLOCKS on release, which is the conscious-decision point rather than a silently raised cap. Re-measured 2026-08-03 via the pinned method: 81. Headroom stays zero by design — the next registry addition must move this number in its own PR. 81 → 82 on 2026-08-04: the `handoff` subcommand (road-to-agent-handoff-resume Phase 4) registers in the same PR that adds the surface, per this record's own contract. Re-measured via the pinned method: 82. 82 → 84 on 2026-08-04: the `route:explain` + `route:audit` verbs (routing-correctness validation surface) register in the same PR that adds the surface. Re-measured via the pinned method: 84. 84 → 85 on 2026-08-05: the `settings:set` verb (road-to-zero-ceremony-settings Phase 2 — the one agent-reachable settings writer) registers in the same PR that adds the surface, per this record's own contract. Re-measured via the pinned method: 85. 85 → 86 on 2026-08-06: the `conformance:behavior` verb (road-to-agent-behavior-conformance Phase 5 — replays the local transcript store through the four mechanised conformance checks) registers in the same PR that adds the surface, per this record's own contract. Re-measured via the pinned method: 86. 86 → 88 on 2026-08-07: the `sessions:list` + `sessions:claim` verbs (road-to-parallel-session-coordination — the shell surface of the shared session register, needed because /roadmap:next is command markdown and can only reach the register through a shell call) register in the same PR that adds the surface, per this record's own contract. Re-measured via the pinned method: 88. 88 → 89 on 2026-08-08: the `council:status` verb registers in the same PR that adds the surface, per this record's own contract. It exists because an agent in a consumer project announced \"kein Council konfiguriert (keine .agent-settings.yml)\" and substituted a weaker path while the council was configured user-globally the whole time — there was no verb that answered availability, so the only route was an inference from a filename, and the intuitive filename is the one location ADR-104 guarantees is never consulted. Re-measured via the pinned method: 89. 89 → 91 on 2026-08-08: the `self-repair:status` + `self-repair:release` verbs (the queued-defect reader and the single Hard-Floor-gated outward step of the self-repair loop — the loop is deliberately unable to publish unless a human runs the release command) register in the same PR that adds the surface, per this record's own contract. Landed alongside the +1 council:status move in the same branch. Re-measured via the pinned method: 91. 91 → 94 on 2026-08-08: the `packs:active`, `settings:get` and `mcp:available` verbs (road-to-capability-answerability Phase 2 — the three capability probes for the gaps that had none) register in the same PR that adds the surface, per this record's own contract. Each answers a question that was previously only inferable from a filename: which packs are active and from which file, what a setting resolves to and which file set it, and what is declared in mcp.json versus what can actually launch. 94 -> 95 in the same PR: `brand:status` (Phase 2.4 — brand-layer presence, which the rule depended on and no surface could answer). Re-measured twice via the pinned method on the unchanged tree: 95/95. 95 → 96 on 2026-08-10: the `session:recycle` verb (road-to-token-economy-recycling Phase 2.2 — the deterministic producer of the main-session recycle envelope; the recycle advisory names this exact verb, so it must exist as a shell surface) registers in the same PR that adds the surface, per this record's own contract. Re-measured via the pinned method: 96. 96 -> 97 on 2026-08-10: the `gates` verb registers in the same PR that adds the surface, per this record's own contract. It exists because the blocker fields the dashboard already parses (Owner, What to do, Resolved when — CI-enforced by lint_roadmap_blockers) had no owner-filtered reader: the dashboard counts the open blockers across a 600-line file and links each to a per-roadmap anchor, so \"which of these are mine\" was a manual read of every anchor. The same inference-from-a-filename shape as the council:status entry above, one layer up. This branch and the session:recycle branch each measured 96 independently and landed on the same number for different verbs; the merge makes it 97, re-measured twice via the pinned method on the merged tree: 97/97. 97 -> 98 on 2026-08-15: the `workspace:doctor` verb (road-to-inbox-harvest-2026-08-c-workspace-identity Phase 3 — the read-only report over the new `workspaceIdentity()` resolver) registers in the same PR that adds the surface, per this record's own contract. It exists for the same inference-from-a-filename shape as the council:status and gates entries above, one layer down: the tree answered \"where am I\" in eight ad-hoc places across six files, and the 12.0.0 span shipped the same worktree misclassification twice, so no verb could be asked which checkout is the main one. Read-only by construction — the roadmap's Non-goals put worktree disposal out of scope and its Risk 3 names \"the pressure read becomes a disposal path by accident\" as the failure to design against, so the command carries no --fix and no --prune. Re-measured twice via the pinned method on the unchanged tree: 98/98. 98 -> 99 on 2026-08-17: the `council:quota` verb (road-to-council-quota-accounting-truth Phase 2) registers in the same PR that adds the surface, per this record's own contract. Exactly the inference-from-a-filename shape as the council:status entry above, one layer down: `cmd_quota` had existed in council_cli.ts and been reachable only via `scripts-run`, so the documented recovery path for an exhausted shared counter -- read the usage, reset one provider -- did not resolve through `agent-config`, and an operator debugging a quota failure met `unknown command`. The verb is read-only apart from the pre-existing `--reset <provider>`, which already required `--confirm`. Re-measured twice via the pinned method on the unchanged tree: 99/99. 99 -> 100 on 2026-08-19: the `decision:memo` verb (road-to-long-horizon-execution Phase 2.2, sequencing UOTL Phase 4.3 -- the decision-memo channel) registers in the same PR that adds the surface, per this record's own contract. It exists because the question ladder gained a rung between \"halt and ask\" and \"decide silently\": a resolution the run makes without contacting the operator is only legitimate if it is reviewable afterwards, and there was no surface that wrote such a record with a fixed shape. Write-and-list only, local-only (agents/runtime/ is gitignored), and it gates nothing -- the locked decision classes are refused at the config schema, never in the ledger. 100 -> 101 in the same PR: `run:supervise` (Phase 3.1 -- the out-of-process watcher for runs whose session died with open steps left). It is the operator-facing half of session continuity: nothing anywhere had the job of noticing that a claimed run stopped moving, so a roadmap 40% done and a roadmap finished looked identical from outside the dead session. Report-only by default and it NEVER merges, pushes or closes -- the auto-merge the reference design carries is a named rejection in the roadmap's harvest section, not an unbuilt feature. Re-measured twice via the pinned method on the unchanged tree: 101/101. 101 → 102 on 2026-08-22: the `adr:effective` verb (road-to-evidence-based-adr-governance step 2.2 — the effective-state projection over one decision record) registers in the same PR that adds the surface, per this record's own contract. It exists because current truth about an ADR was only reconstructable from linear prose: an agent had to read the body, then every amendment, and decide for itself which clauses still stand. The verb reports status, the Decision verbatim, clauses the record's own amendments superseded, active amendments, the three descriptive axes and the review-trigger state. It AUTHORIZES NOTHING — Phase 2 of that roadmap is titled \"surfacing only; no authority\" and its AC-7 forbids any authority consequence, so the verb reports an absent axis as absent (`— (no provenance axis)`, `— (ungraded)`, `absent → evidence`) and an unresolvable trigger as `indeterminate` rather than inferring one. Re-measured twice via the pinned method on the unchanged tree: 102/102. 102 → 104 on 2026-08-22: the `council:grant-billing` + `council:revoke-billing` verbs (road-to-billing-cliff-gate Phase 2 — the run-scoped billing grant that lets `ai_council.fallback.api_on_quota: 'ask'` be answered once per run instead of once per seat) register in the same PR that adds the surface, per this record's own contract. The two are a pair by construction rather than by convenience: a grant that can be issued and not revoked would outlive its run, which is the failure the run-scoped TTL exists to prevent. Re-measured via the pinned method: 104. 104 -> 106 on 2026-08-23: the `ui:audit` + `ui:render` verbs (road-to-frontend-power E2.1 and E3.1 -- the two Class-A commands that give the frontend obligations an artefact a gate can read and a render a verdict can cite) register in the same PR that adds the surface, per this record's own contract. The two are a pair by construction rather than by convenience: `ui-audit-gate`'s enforced_by moved from `none` to a carrier in the same change, and that carrier reports `verification: degraded` whenever the render artefact is absent -- so an audit verb without a render verb would ship a gate that can never reach `verified`. Both are Class A under ADR-124: they terminate, their whole state is a rebuildable directory under agents/runtime/state/, and ui:render closes chromium in a `finally` on every path with no --serve, watch or cache for a resident browser to hide in. Re-measured via the pinned method on the unchanged tree: 106. 106 → 107 on 2026-08-23: the `roadmap:context` verb (road-to-roadmap-situational-awareness — the single live probe that answers what else is in flight before a roadmap is picked) registers in the same PR that adds the surface, per this record's own contract. Its branch measured 105 against a base of 104 and this branch measured 106 against the same base for `ui:audit` + `ui:render`; the merge makes it 107, re-measured on the merged tree via the pinned method (registry enumeration): 107. 107 → 108 on 2026-08-26: the `roadmap:set-step` verb (road-to-skill-ecosystem-runtime-enforcement Phase 6 — the single sanctioned writer of a checkbox glyph) registers in the same PR that adds the surface, per this record's own contract. It exists because the glyph is written today by whatever edits the file, and a concurrent writer destroys work SILENTLY: the loser of an overwrite receives no error. The verb carries an advisory lock, a line-anchored edit that cannot span entries even in principle, a step-count invariant asserted against the LIVE pre-write file rather than an in-memory snapshot, and a post-write survival check. Re-measured via the pinned method (registry enumeration) on the unchanged tree: 108. 108 → 109 on 2026-08-26: the `stubs:due` verb (road-to-inbox-harvest-2026-08-f-owner-decision-queue step 2.1 — the read-only reader over `agents/roadmaps/stubs/` frontmatter) registers in the same PR that adds the surface, per this record's own contract. It exists because step 1.2 backfills a `review_by:` date into 77 parked files, and an AI council (2026-08-26, 2/2) made the ordering a RULE rather than a preference: dates without a reader are strictly worse than no dates, because a stale date certifies attention nobody paid. The verb is read-only by construction — it authors nothing under `agents/roadmaps/stubs/`, so `check_no_stub_inventory_table` stays green and unmodified, and `roadmap:progress` consumes only its two COUNTS for the dashboard header (two integers, no rows, nothing for the deleted index tables to grow back from). Re-measured via the pinned method (registry enumeration) on the unchanged tree: 109. 109 → 110 on 2026-09-03: the `hooks:effect` verb (road-to-wired-instruments Phase 1.1 — the CLI entry for `hook_effect_doctor`) registers in the same PR that adds the surface, per this record's own contract. It exists because the probe and its five-state vocabulary were built, tested and reachable from nothing: `grep -rn 'hook_effect_doctor|hook_effect_probe' src Taskfile.yml .github` returned only the two modules themselves, and a closed roadmap recorded the wiring as landed at `src/scripts/hooks_doctor.ts:88`, a line that is the closing brace of a filesystem helper in a file with zero references to the probe. Deliberately NOT merged into `hooks:doctor`: that verb reads the MANIFEST (what is declared) and this one reads what happened (what took effect), and the probe's own header names merging them as the thing to avoid — a declaration report and an execution report are different instruments, and merging them makes the cheap one expensive. Read-only apart from a scratch root it removes in a `finally`. Re-measured via the pinned method (registry enumeration) on the unchanged tree: 110. 110 → 111 on 2026-10-07: the `git:convention` verb (road-to-a-git-convention-that-reaches-every-checkout step 1.2) registers in the same PR that adds the surface, per this record's own contract. It exists because a consumer project has neither `scripts-run` nor `node_modules`, so the `agent-config` binary is the only code an installed command reaches, and `settings:get` reports a settings file that does not parse as \"not set\" — the reading that turned a declared `rebase` into a merge. The verb reports each git.* key with its value, source file and one of five states, exits 1 when a key cannot be read, and takes its subcommands from one table so later git surfaces are rows under this verb rather than new verbs. Read-only. Re-measured via the pinned method (registry enumeration) on the unchanged tree: 111. 111 → 112 on 2026-10-15: the +1 is `ci:settle`, registered in the SAME PR that adds it (fix/bytes-council-findings, the council-review follow-up to #2363). Why a verb rather than the script path: the 2026-10-15 council review (2/2) found that `/fix ci` and `/create-pr` invoked `npx tsx node_modules/@event4u/agent-config/src/scripts/ci_settle.ts`, which fails on a global or ephemeral install and pulls tsx from the registry; the packaged executable is the only invocation that works in every install shape. Verified from a packed tarball installed with --omit=dev, with neither tsx nor npx on PATH. Re-measured via the pinned method: 112. 112 → 114 on 2026-10-21: `worktree:cleanup` and `audit:deps` register in the SAME PR that adds them (road-to-worktrees-that-leave-after-the-merge 4.1, road-to-advisories-heard-the-same-day 5.1). Why verbs rather than script paths: both are reached by a consumer with a global install, where `node_modules/@event4u/agent-config/…` does not exist — the same reason `ci:settle` became a verb. Re-measured via the pinned method: 114. Headroom stays zero by design."
|
|
76
77
|
},
|
|
77
78
|
"mcp_public_tool_count": {
|
|
78
|
-
"max":
|
|
79
|
-
"last_measured":
|
|
80
|
-
"last_measured_at": "2026-10-
|
|
79
|
+
"max": 29,
|
|
80
|
+
"last_measured": 29,
|
|
81
|
+
"last_measured_at": "2026-10-24",
|
|
81
82
|
"method": "tools/list length on the stdio server (post-ADR-132: implemented tools only)",
|
|
82
83
|
"inputs": [
|
|
83
84
|
"src/scripts/mcp_server/**"
|
|
84
85
|
],
|
|
85
|
-
"baseline_note": "19 → 20 on 2026-08-17 (release 13.0.0 gate). The +1 is 866bd9861 (feat(mcp): recover what the host dropped — real ranker tool + a route to it, road-to-inbox-harvest-2026-08-d-runtime-skill-routing Phase 4): `suggest_skill_for_task` was promoted from a discovery STUB to a real ALLOWLIST entry and removed from STUB_TOOLS. Worth stating precisely, because the consumer-visible NAME did not grow — the stub already published that name and its `task` + `limit` input schema, which the promotion carried over verbatim. What grew is the count of tools tools/list actually returns, which is exactly what this metric measures post-ADR-132: implemented tools only. Same shape as the cli_help_command_count history above — this RECORDS growth that already shipped through its own reviewed PR (866bd9861 is on main), it does not authorize new surface. The registering PR did not move this budget, so the gate did its job: the breach warned on main and blocked on the release ref, which is the conscious-decision point rather than a silently raised cap. Re-measured twice via the pinned method on a freshly built dist/mcp/server.mjs: 20/20. Headroom stays zero by design — the next tool that leaves STUB_TOOLS must move this number in its own PR. 20 → 25 on 2026-09-09 (release 14.23.0 gate). The +5 are `graph_impact`, `graph_tests_for`, `graph_dead`, `graph_query` and `graph_path` — 9452f29b4 (feat(mcp): five graph tools, the pinned install hint, and the skill description; road-to-a-graph-that-is-shipped Phase 4.1), which is on main. They are the agent-facing readers of the code graph: the roadmap Risk-Register rank 1 is \"the install grows and the graph is still unread\", and an agent that has to shell out to reach a verb will not, so the tools ARE the mitigation rather than a convenience. Same shape as every entry above — this RECORDS growth that already shipped through its own reviewed PR; it does not authorize new surface. The registering PR did not move this budget, so the gate did its job again: the breach warned on main and BLOCKED on the release ref, which is the conscious-decision point rather than a silently raised cap. The move is +25%, over the 10% creep rule, and that is the intended reading: five tools in one commit is a surface decision, not creep. Re-measured three times via the pinned method on a freshly built dist/mcp/server.mjs: 25/25/25, the returned name set differing from the 20-tool set by exactly the five graph_* entries. Headroom stays zero by design — the next tool that leaves STUB_TOOLS must move this number in its own PR. 25 → 26 on 2026-10-01: the +1 is `graph_node` (road-to-a-graph-that-feeds-the-gate step 3.1), and this entry moves in the SAME PR that adds the surface, which is what every entry above asks of the next one. Why a sixth graph tool rather than an argument on one of the five: the five all answer about a NEIGHBOURHOOD (`graph_query`, `graph_path`, `graph_impact`) or about a SET (`graph_dead`, `graph_tests_for`), and none answers the question an agent asks first — where does this symbol live, who reaches it, what does it reach, how connected is it — which had to be assembled from two calls plus a file read. It walks the edge maps `affected` already walks, so it adds a view and not an index. It is also the one graph tool that REFUSES rather than guesses: it resolves on the exact tiers of the existing seed ladder (node id, then label) and returns a refusal naming the candidates when a label is ambiguous or nothing matches exactly, because free-text retrieval is the row the graph measurably lost (`docs/CLAIMS.md` code-graph-retrieval-null) and every field it returns is a statement about ONE node. Re-measured twice via the pinned method on a freshly built dist/mcp/server.mjs: 26/26, the returned name set differing from the 25-tool set by exactly `graph_node`. Headroom stays zero by design. 26 → 28 on 2026-10-23: `graph_map_status` and `graph_area` (road-to-a-map-that-draws-itself 5.2) register in the SAME PR that adds them. They are the agent-facing readers of the new project map: one says whether a map exists and how fresh it is, the other returns one area (files, hubs, what it depends on) by exact id, name or member file and refuses anything else with candidates. Both are read-only and read agents/map/map.json; no free-text search tool was added, because graph_query already covers it. Headroom stays zero by design."
|
|
86
|
+
"baseline_note": "19 → 20 on 2026-08-17 (release 13.0.0 gate). The +1 is 866bd9861 (feat(mcp): recover what the host dropped — real ranker tool + a route to it, road-to-inbox-harvest-2026-08-d-runtime-skill-routing Phase 4): `suggest_skill_for_task` was promoted from a discovery STUB to a real ALLOWLIST entry and removed from STUB_TOOLS. Worth stating precisely, because the consumer-visible NAME did not grow — the stub already published that name and its `task` + `limit` input schema, which the promotion carried over verbatim. What grew is the count of tools tools/list actually returns, which is exactly what this metric measures post-ADR-132: implemented tools only. Same shape as the cli_help_command_count history above — this RECORDS growth that already shipped through its own reviewed PR (866bd9861 is on main), it does not authorize new surface. The registering PR did not move this budget, so the gate did its job: the breach warned on main and blocked on the release ref, which is the conscious-decision point rather than a silently raised cap. Re-measured twice via the pinned method on a freshly built dist/mcp/server.mjs: 20/20. Headroom stays zero by design — the next tool that leaves STUB_TOOLS must move this number in its own PR. 20 → 25 on 2026-09-09 (release 14.23.0 gate). The +5 are `graph_impact`, `graph_tests_for`, `graph_dead`, `graph_query` and `graph_path` — 9452f29b4 (feat(mcp): five graph tools, the pinned install hint, and the skill description; road-to-a-graph-that-is-shipped Phase 4.1), which is on main. They are the agent-facing readers of the code graph: the roadmap Risk-Register rank 1 is \"the install grows and the graph is still unread\", and an agent that has to shell out to reach a verb will not, so the tools ARE the mitigation rather than a convenience. Same shape as every entry above — this RECORDS growth that already shipped through its own reviewed PR; it does not authorize new surface. The registering PR did not move this budget, so the gate did its job again: the breach warned on main and BLOCKED on the release ref, which is the conscious-decision point rather than a silently raised cap. The move is +25%, over the 10% creep rule, and that is the intended reading: five tools in one commit is a surface decision, not creep. Re-measured three times via the pinned method on a freshly built dist/mcp/server.mjs: 25/25/25, the returned name set differing from the 20-tool set by exactly the five graph_* entries. Headroom stays zero by design — the next tool that leaves STUB_TOOLS must move this number in its own PR. 25 → 26 on 2026-10-01: the +1 is `graph_node` (road-to-a-graph-that-feeds-the-gate step 3.1), and this entry moves in the SAME PR that adds the surface, which is what every entry above asks of the next one. Why a sixth graph tool rather than an argument on one of the five: the five all answer about a NEIGHBOURHOOD (`graph_query`, `graph_path`, `graph_impact`) or about a SET (`graph_dead`, `graph_tests_for`), and none answers the question an agent asks first — where does this symbol live, who reaches it, what does it reach, how connected is it — which had to be assembled from two calls plus a file read. It walks the edge maps `affected` already walks, so it adds a view and not an index. It is also the one graph tool that REFUSES rather than guesses: it resolves on the exact tiers of the existing seed ladder (node id, then label) and returns a refusal naming the candidates when a label is ambiguous or nothing matches exactly, because free-text retrieval is the row the graph measurably lost (`docs/CLAIMS.md` code-graph-retrieval-null) and every field it returns is a statement about ONE node. Re-measured twice via the pinned method on a freshly built dist/mcp/server.mjs: 26/26, the returned name set differing from the 25-tool set by exactly `graph_node`. Headroom stays zero by design. 26 → 28 on 2026-10-23: `graph_map_status` and `graph_area` (road-to-a-map-that-draws-itself 5.2) register in the SAME PR that adds them. They are the agent-facing readers of the new project map: one says whether a map exists and how fresh it is, the other returns one area (files, hubs, what it depends on) by exact id, name or member file and refuses anything else with candidates. Both are read-only and read agents/map/map.json; no free-text search tool was added, because graph_query already covers it. Headroom stays zero by design. 28 → 29 on 2026-10-24 (release 17.4.0 gate): `graph_estate` (road-to-a-graph-that-follows-you 5.2) shipped in 3b67f4900d without moving this budget. This RECORDS growth that already shipped through its own reviewed PR; it does not authorize new surface. The tool answers estate queries (where-used, projects-using, advisory-impact) from the local estate index and is read-only. Measured 29 by the packed-artifact evaluation of release PR #2630. Headroom stays zero by design."
|
|
86
87
|
}
|
|
87
88
|
}
|
|
88
89
|
}
|
|
@@ -35,9 +35,9 @@
|
|
|
35
35
|
"note": "Lowered 47 -> 46 on 2026-08-30 by road-to-source-silence-cutover step 3.1, and the gain was INCIDENTAL rather than sought: narrowing the `source-header` class replaced a whole-value scan with a per-token one, and one hardcoded scan root went with the code that no longer needed it. Set to the EXACT live total, per this file's convention — the gate reported the tree at 46 against a baseline of 47 and said so, which is how a loose ratchet surfaces here rather than by inspection. `landed` refreshed deliberately: checkRatchet returns `improved` BEFORE it evaluates staleness, so an entry left at the old number while the tree measures lower would never expire at any age. Prior entry: Lines under src/scripts/**/*.{ts,mts,mjs} that pass the retired `.agent-src.uncondensed` directory into `path.join(...)` — a filesystem path CONSTRUCTED against the tree ADR-051 abandoned, which is the exact shape of all 14 dead gates. Deliberately narrow so the number is signal, not noise: 236 raw mentions under src/scripts → 147 string-literal lines → 67 path-constructing lines when the pass was written, after exempting src/scripts/_lib/agent_src.ts (the shared resolver, whose job IS owning the constant — gates that route through it survived the move). Detectors holding the literal as data t"
|
|
36
36
|
},
|
|
37
37
|
"check_source_size_budget": {
|
|
38
|
-
"count":
|
|
39
|
-
"landed": "2026-10-
|
|
40
|
-
"note": "Lowered 17,354 -> 17,337 on 2026-10-23 by road-to-a-map-that-draws-itself: trimming the chat_history_read and memory_lookup descriptions to fit the two map tools into the kernel payload band removed seventeen lines from src/scripts/mcp_server/tools.ts, which sits above the 1500-line budget. Prior entry: Lowered 17,358 -> 17,354 on 2026-10-22 by fix/release-without-review-gate: release.ts step 7 no longer reads the findings ledger, which removed four lines above the 1500-line budget. Prior entry: Lowered 17,363 -> 17,358 on 2026-10-22 by feat/subagent-system-2583: the seat launch environment (model-ceiling memo, CLI version probe) moved out of src/scripts/ai_council/clients.ts into cli_launch_env.ts, which more than offset the light-launch and seat-resume additions there and in council_cli.ts and orchestrator.ts. Set to the exact live total, per this file's convention. Prior entry: Lowered 17,365 -> 17,363 on 2026-10-21 by fix/release-no-trailer-refusal: removing the Consumer-Impact span refusal took two lines out of src/scripts/release.ts, which sits above the 1,500-line cap. Set to the exact live total, per this file's convention. Prior entry: MERGE RECONCILIATION 2026-10-21, 17,369/17,368 -> 17,365: main lowered 17,372 -> 17,368 (cmd_doctor.ts, below) and this branch lowered 17,372 -> 17,369; the two gains are independent and add. Branch entry: lowered 17,372 -> 17,369 on 2026-10-21 by drain/road-to-one-detector-senders-20261020, and the gate asked for it by name (ratchet is loose, naming 17,369). The branch's CLI egress refusal (+16 in ai_council/clients.ts) and the injection filter (+2 in hooks/dispatch_hook.ts, which crossed 1,500) were paid for by folding five identical CliClient.ask failure constructions into one _cliFailure helper; dispatch_hook.ts is a ratified hook-plumbing source and was left untouched. Main entry: LOWERED 17,372 -> 17,368 on 2026-10-21 by fix/install-runtime-resolution-20261021, and the gate asked for it by name. The gain IS this branch's: cmd_doctor.ts loses four lines because the no-project-install message moved into doctor_ownership_ledger.ts, where it now reports the global scope too. install.ts stays net-zero — a dry-run block that first added sixteen lines there was moved to wizard-plan.ts rather than paid for. PRIOR ENTRY: LOWERED 17,386 -> 17,375 on 2026-10-19 by drain/road-to-skills-that-arrive-when-called-20261019z, measured by CI (the baseline-equals-live test named 17,375): install.ts's _prune_scoped_modules wrapper became a one-line alias of scoped_projection.prune_scoped_modules, which now carries the declared-skill closure. Before that: LOWERED 17,407 -> 17,386 on 2026-10-18 by drain/road-to-a-release-that-says-whether-it-needs-you-20261018x, and the gate asked for it by name (ratchet is loose, naming 17,386). The gain is an EXTRACTION paying for doctor --json's new update_verdict block (two lines in cmd_doctor.ts): STATUS_SYMBOLS and _emit_checks_text moved verbatim into _doctor_emit.ts, re-exported unchanged, so cmd_doctor.ts goes 3,560 -> 3,539. No ceiling was edited. PRIOR ENTRY: LOWERED 17,410 -> 17,407 on 2026-10-18 by drain/road-to-an-ownership-record-20261018, and the gate asked for it by name (ratchet is loose, naming 17,407). The gain is a compaction inside the function this branch changed: _deploy_claude_desktop's marker call collapsed onto one line beside the new one-line claude-desktop ledger record, leaving src/scripts/install.ts 3 lines shorter than on main. PRIOR ENTRY: MERGE RECONCILIATION 2026-10-18, 17,415/17,414 -> 17,410 — merging origin/main into drain/road-to-one-detector-and-the-senders-we-own-20261018b: main lowered to 17,415 (subagent_native_fields extraction) and this branch to 17,414 (ai_council/config.ts onto the shared rule table) from different reductions; the gate measured the merged tree at 17,410 and named it. PRIOR ENTRY: LOWERING 2026-10-18, 17,419 -> 17,415 — the gate asked for it by name (`ratchet is loose`, naming 17,415), and `check_source_size_budget.test.ts` pins baseline == live total. The gain is an EXTRACTION: road-to-a-cold-start-paid-once 2.2 needed the subagent projector to emit four new optional native fields, so the per-field logic, including the existing `effort` pass-through, moved out of `condense.ts` into `src/scripts/_lib/subagent_native_fields.ts`, which owns nothing else; condense.ts goes 2,695 -> 2,691. No ceiling was edited and no file was split to game the metric. PRIOR ENTRY: LOWERING 2026-10-18, 17,424 -> 17,419 — the gate asked for it by name (`ratchet is loose`, naming 17,419). The gain is an EXTRACTION: `install --full` (road-to-a-setup-that-decides-itself 3.5) needed seven lines in `src/scripts/install.ts`, a file 3,618 lines past the ceiling, so the `--tools`/`--ai` merge helper moved out to `src/install/toolsArg.ts`, which owns nothing else; install.ts goes 5,118 -> 5,113. No ceiling was edited and no file was split to game the metric. PRIOR ENTRY: LOWERING 2026-10-13, 17,485 -> 17,466 — the gate asked for it by name (`ratchet is loose`, naming 17,466), and `check_source_size_budget.test.ts` pins baseline == live total, so it is required rather than optional. The gain is an EXTRACTION, which is the shape this convention accepts: the settings-surface assertion needed three lines in `src/scripts/release.ts`, a file 211 lines past the ceiling, so `set_template_pin` moved out to `src/scripts/release_env.ts`, which already owns its two manifest-version siblings for exactly this stated reason and sits far under the ceiling; release.ts goes 1,730 -> 1,711. The `die` call is inlined there as a stderr write plus `SystemExitError`, because `release_publication.ts` imports from `release_env.ts` and reaching back for `die` would be a cycle. No ceiling was edited and no file was split to game the metric. PRIOR ENTRY: LOWERING 2026-10-13, 17,516 -> 17,485 — the gate asked for it by name (`ratchet is loose`, naming 17,485), and the gain is an EXTRACTION, which is the shape this convention accepts. road-to-a-search-answer-a-model-can-choose-from 1.1/1.2 described `suggest_skill_for_task` properly in `tools.ts` — what a row now carries, and why the default depth is 8 — which cost six lines in a file 521 lines past the ceiling and reddened this ratchet by exactly those six. Rather than re-pin the baseline, the whole allowlist ENTRY moved to `src/scripts/mcp_server/suggest_skill.ts`, which already owns that tool’s handler for the same stated reason; `tools.ts` goes 2,021 -> 1,984 and the net is -31. The import back is TYPE-only, so the cycle is erased at runtime. No ceiling was edited and no file was split to game the metric. PRIOR ENTRY: LOWERING 2026-10-09, 17,550 -> 17,516 — the gate asked for it by name after `REMOVED_KEYS` and its once-per-run warning moved out of `src/scripts/_lib/agent_settings.ts` (1,510 lines) into `src/scripts/_lib/settings_removed_keys.ts`, so the settings-key retirement batch adds its registry entries in a file under the ceiling instead of growing the excess; the retirement itself also deletes legacy rename-map rows and the setup-hint settings read from `src/scripts/install.ts`. Earlier: LOWERING 2026-10-05, 17,571 -> 17,550 — a lowering commit, and the gate asked for it BY NAME: it reported `ratchet is loose` and named 17,550; `check_source_size_budget.test.ts` then pins baseline == live total, so this is required rather than optional. The gain IS this branch's own work and it is a DEDUPLICATION, which this convention accepts: all five CliClient subclass constructors forwarded six option fields to super() by name, which is why a seventh (`consumer`) was silently dropped and every CLI call booked as `unknown`. Replacing the five field lists with `{ ...opts, model: ... }` removes 27 lines from src/scripts/ai_council/clients.ts (2,858 -> 2,831) against the +6 the consumer fix added, so the net is -21. No ceiling was edited and no file was split to game the metric. The count is tree-derived (line counts over src/**/*.ts) and container-independent, unlike the projection-surface gates whose local readings diverge. Verified with `npx tsc --noEmit` clean and the clients suite green in this checkout. PRIOR ENTRY: LOWERING 2026-10-05, 17,585 -> 17,571 — a lowering commit, and the gate asked for it BY NAME: it reported `ratchet is loose` and named 17,571. The gain IS this branch's own work and it is an EXTRACTION, which is the only shape this convention accepts: road-to-an-installed-layer-that-is-thinned step 1.1 adds a thinning call to the global deploy loop, and pays for those lines by moving `_resolve_global_rule_scope` out of `src/scripts/install.ts` into `src/install/globalRuleScope.ts` behind a same-signature wrapper, and removes the two imports the extraction orphaned (install.ts 5,180 -> 5,156). The user-global whitelist rows in `src/scripts/_lib/agent_settings.ts` push that file 1,499 -> 1,510, so the net is -5 rather than -15. No ceiling was edited and no file was split to game the metric. Verified by running the gate in this worktree after `npx tsc --noEmit` passed clean. PRIOR ENTRY: LOWERING 2026-10-02, 17,620 -> 17,592 — a lowering commit, and the gate asked for it BY NAME: it reported `ratchet is loose` and named 17,592. The gain IS this branch's own work, and it is a deduplication rather than a sweep. `GLOBAL_DEPLOY_SOURCES` was defined TWICE — in `src/scripts/install.ts` and in `src/install/wizard-plan.ts` — and the two copies were byte-identical across all 18 host rows, which is a duplicate that stays correct exactly until somebody edits one of them. road-to-rule-triggers-and-links-that-hold step 1.2 did that: it added `contexts/` and `guidelines/` to the install.ts copy and the wizard kept installing without them, so the deduplication is the fix for a defect this branch introduced, not an opportunistic tidy. install.ts now imports and re-exports the wizard-plan definition, so every caller is unchanged, and the file goes 5,231 -> 5,175 lines. Verified by running the gate in this worktree after `npm run typecheck` passed clean. PRIOR ENTRY: LOWERING 2026-10-02, 17,734 -> 17,620 — a lowering commit, and the gate asked for it BY NAME: it reported `ratchet is loose` and named 17,620 as the number to write. The gain is not this branch's own work; it is the net of the lanes that merged into main while this branch was in flight, which is exactly the case the clause below exists for — a tree that got smaller while a baseline stood still would let the gain be given back silently by the next change. Verified in a FRESH detached checkout of the pushed head rather than in the working worktree, because the first reading was taken in a tree that had not finished its base sync and reported the two numbers the other way round; the fresh checkout measures 17,620 against a 17,734 baseline over 1,582 scanned files. `landed` is refreshed deliberately, for the reason every entry below gives: checkRatchet returns `improved` BEFORE it evaluates staleness, so an entry left high while the tree measures lower would never expire at any age. PRIOR ENTRY: LOWERING 2026-10-01, 17,745 -> 17,734 — a lowering commit, and the gate asked for it by name. road-to-a-hook-bundle-with-one-yaml-reader 3.1 split the windsurf renderer out of `condense.ts` into the new under-cap `src/scripts/_lib/windsurf_render.ts`, and `strip_frontmatter` moved with it as the render's one non-trivial dependency. `condense.ts` went 2,728 -> 2,717 excess lines. The direction is honest about its own history: an earlier commit on this branch kept the renderer INLINE in `condense.ts` and CI caught it as 20 new violations — this entry is that fix, not a sweep, and the lowering is the by-product of putting the code where it belonged. Nothing was deleted: the renderer and the stripper are both still called, by TWO callers now rather than one, and `condense.ts` re-exports `strip_frontmatter` so no importer's path changed. The new module lands at 64 lines, far under its own cap, so it contributes zero excess. LOCAL READING, same discriminator every entry below uses: the gate walks authored source under `src/`, and the only untracked path `git status --porcelain -uall -- src` reports is that new module, committed in this same change — so a clean CI checkout of this commit measures the same 17,734. If CI reads anything else, CI's number is the correct one and this note is the record of why. `landed` is refreshed deliberately, for the reason the prior entry gives: checkRatchet returns `improved` BEFORE it evaluates staleness, so an entry left high while the tree measures lower would never expire at any age. PRIOR ENTRY: LOWERING 2026-09-30, 17,746 -> 17,745 — a lowering commit, and the gate asked for it by name. The direction is the surprising one again: this branch ADDED a feature to `install.ts` (an opt-in host env write) and that file came out SHORTER than it went in, 5,270 -> 5,269. The whole mechanism — the two-row allow table, the settings reader, the env-block builder and the bridge wrapper — lives in the new under-cap `src/scripts/_lib/host_env_write.ts`, so `install.ts` pays ONE import line and one expression for it; and the three-line `for` loop over healed plugin ids in the same function collapsed to one, which is inside the function the change already edits. The gain is a MOVE plus one tightening, never a deletion: nothing was dropped and nothing was swept. That module boundary is also the better one on its own terms — one place now owns which host variable this package may write, which is the question the owner decision of 2026-09-30 turns on. LOCAL READING, on the same discriminator every entry below uses: the gate walks authored source under `src/`, and `git status --porcelain -uall -- src` reported ZERO untracked files, so a clean CI checkout of this commit measures the same 17,745. If CI reads anything else, CI's number is the correct one and this note is the record of why. `landed` is refreshed deliberately: checkRatchet returns `improved` BEFORE it evaluates staleness, so an entry left at 17,746 while the tree measures 17,745 would never expire at any age. PRIOR ENTRY: LOWERING 2026-09-29, 17,748 -> 17,746 — a lowering commit, same doctrine as every entry below, and the gate asked for it by name. This branch ADDED two gate scripts, a guard and a shared lib under `src/`, so the direction is the surprising one and worth stating: the new files each land under their own cap and contribute zero EXCESS, while factoring the shell write shapes out of `block_kernel_rule_writes` into `_lib/shell_write_shapes.ts` moved lines out of a file that was over its cap and into one that is not. Net -2. LOCAL READING, on the same discriminator every entry below uses: the gate walks authored source under `src/`, and `git status --porcelain -uall -- src` reported ZERO untracked files, so a clean CI checkout of this commit measures the same 17,746. If CI reads anything else, CI's number is the correct one and this note is the record of why. `landed` is refreshed deliberately: checkRatchet returns `improved` BEFORE it evaluates staleness, so an entry left at 17,748 while the tree measures 17,746 would never expire at any age. PRIOR ENTRY: LOWERING 2026-09-29, 17,762 -> 17,748 — a lowering commit, same doctrine as every entry below, and the gate asked for it by name. Reporting the host traffic environment in `doctor` needed a new surface; rather than pay those lines against `src/scripts/_cli/cmd_doctor.ts`, already far over the cap, the whole network-posture block moved out into the new under-cap `src/scripts/_cli/doctor_network_posture.ts`, which is also where the new logic lives: one module owns which traffic variables exist, how each is read, and how an absent one is reported, so the unit is coherent rather than a line-count trim. cmd_doctor.ts 3,618 -> 3,604; total 17,762 -> 17,748. The gain is a MOVE, not a deletion — nothing was dropped and nothing was swept. `landed` is refreshed deliberately, for the reason the prior entries record: checkRatchet returns `improved` BEFORE it evaluates staleness, so an entry left at 17,762 while the tree measures 17,748 would never expire at any age, and the gate only ADVISES on a loose ratchet while `check_source_size_budget.test.ts` blocks — that asymmetry is what forces a lowering commit to carry its own baseline update. PRIOR ENTRY: LOWERING 2026-09-27, 17,765 -> 17,762 — the second half of the same repair, and a lowering for the same reason. Closing the remaining preservation defects needed lines in two over-cap files: `src/scripts/install.ts` (route the generated Claude Desktop marker through the tracker, hand the rule-rewrite its skip set) and `src/server/routes/wizard.ts` (surface the conflict count, stop reporting exit 3 as a failure). Both were paid from the same subject rather than from the ratchet: `_files_by_tool_from_bridges` joined its sibling in `src/install/manifestFiles.ts`, which now owns the whole per-tool inventory, and the wizard's exit-code semantics moved into `src/install/preserve.ts` beside `installDoneSummary`, which already lives there for this exact reason. install.ts 5,277 -> 5,270; wizard.ts 1,500 -> 1,504. PRIOR ENTRY: LOWERING 2026-09-27, 17,784 -> 17,765 — a lowering commit, same doctrine as the entry it replaces. Repairing the install-manifest digest loss needed new state in `_update_installed_tools_manifest` (a recorded-inventory read, a preserved-path index, a reconciliation call). Rather than pay that against `src/scripts/install.ts`, already 3,777 over the cap, the manifest file-inventory block (`_sha256_of_file`, `_file_entry`, `_files_by_tool_from_deploy` — 29 lines) moved out into the under-cap `src/install/manifestFiles.ts`, which is where the new logic lives too: one module now owns what the manifest's per-tool `files[]` holds, how it is read back, and how the two reconcile, so the unit is coherent rather than a line-count trim. install.ts 5,296 -> 5,277; total 17,784 -> 17,765. PRIOR ENTRY: LOWERING 2026-09-20, 17,858 -> 17,784 — a lowering commit, not a reconciliation, but measured under the same doctrine the four entries below carry: the committed number is the gate's own reading on the MERGED tree, taken after origin/main was merged into drain/headless-log-write rather than from either side. The branch's transaction-log write added 27 lines to `src/scripts/install.ts`, already 3,897 over the cap, taking the total to 17,885. Rather than pay that, the `json.dumps` byte-parity block (`jsonStrNoAscii`, `_jsonScalar`, `_dumpIndent`, `jsonDumpsIndent`, `jsonDumpsCompact` — 101 lines) moved out of `install.ts` into the under-cap `src/scripts/_lib/json_python_parity.ts`: pure, total functions of their input carrying no installer state, so the unit is coherent rather than a line-count trim. install.ts 5,397 -> 5,296; total 17,885 -> 17,784, a net -74 against the prior baseline. PRIOR ENTRY: MERGE RECONCILIATION 2026-09-14, 17,861 -> 17,858 — the FOURTH reconciliation of this entry, same doctrine as the three below: the committed number is the gate's own reading on the MERGED tree, never either side's. Neither branch earned the -3; it falls out of main having absorbed drain/release-head-field, whose `derive_head_prefill` extraction moved the span-to-prefill composition into an under-cap module. Taking this branch's 17,861 would have silently given that gain back. PRIOR ENTRY: MERGE RECONCILIATION 2026-09-13, 17,863 -> 17,861 — the THIRD reconciliation of this entry in one day, and re-measured on the merged tree rather than taken from either side, which is the only resolution that converges. drain/adversarial-verification reached 17,864 by paying for a `forge_protection` block and a cascade-base module entirely in files under the 1,500-line cap; the incoming reconciliation reached 17,863 from different work. Neither describes the merge. PRIOR ENTRY: MERGE RECONCILIATION 2026-09-13, 17,944/17,866 -> 17,863. drain/decision-closure and drain/breaking-line-contradiction each lowered from the SAME 17,947 base in parallel -- this branch to 17,944 (net -3: the ownership vocabulary, its two Iron-Law sets and the merged default-mode map moved out of ai_council/config.ts into ai_council/ownership_classes.ts, and the settings-rename block moved out of _lib/agent_settings.ts into _lib/settings_renamed_keys.ts, both UNDER the 1500 cap so both cost nothing) and main to 17,866. Taking either side alone is wrong in a different direction, which is the doctrine this entry already carries from 2026-09-03 and 2026-09-07: main's value silently discards this branch's earned -3, and this branch's value RAISES the baseline against main and weakens the gate. The committed number is neither -- it is the gate's own output on the MERGED tree, where both reductions apply. MAIN-SIDE ENTRY, carried so neither branch's record is lost: Lowered 17,947 -> 17,866 on 2026-09-13 by drain/breaking-line-contradiction, on this entry's own doctrine. The branch adds the BACKWARD half of the MIGRATION.md obligation -- a refusal for a major cut whose BREAKING section has no migration entry -- and writing it into release.ts came in at +61, because that file sits ~375 lines PAST the 1500 cap so every line there is one unit. Paid down rather than baselined, and the move was the coherent unit rather than the minimum one: BOTH refusals went, the new backward half and the pre-existing forward half (assert_scheduled_deprecations_clear), into _lib/release_migration_gate.ts at 184 lines and therefore UNDER the cap, so the pair and all their rationale now cost nothing. They moved on merit rather than only on arithmetic -- they are the two halves of one obligation, written eleven months apart, and release.ts held only the two call sites. parse_version stayed module-private in release.ts and the lib carries a two-line _minor_patch instead: exporting a private helper to serve one caller would widen the surface of the file the move exists to narrow. release.ts 1,875 -> 1,733: a branch that ADDED a pipeline refusal leaves the file eighty-one lines shorter than it found it. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports nothing staged and nothing untracked at this commit, so a clean CI checkout measures the same 17,866. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in this commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises -- which is how CI found it: the gate exited 0 with a loose-ratchet warning and the test went red. PRIOR ENTRY: Lowered 17,959 -> 17,947 on 2026-09-11 by the findings-ledger branch, on this entry's own doctrine. The branch adds step 7 to release.ts, which sits ~326 lines PAST the 1500 cap so every line there is one unit, and it came in at +145. Paid down rather than baselined, in two moves. `settle_findings_ledger` and `_blocking_without_disposition` moved out of release.ts into _lib/release_findings_ingest.ts -- 95 lines, and that module is under the cap, so the step and its rationale now cost nothing. It moved on merit rather than only on arithmetic: the module already owns every message the step prints and every argv it builds, and release.ts held only the sequencing. Then the `--ci` fallback dispatch of the three tag-triggered workflows -- 24 lines of loop and warning with no reader elsewhere in step 10 -- moved into _lib/release_tag_dispatch.ts, also under the cap. release.ts 1,826 -> 1,814: a branch that ADDED a pipeline step leaves the file twelve lines shorter than it found it. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports the branch's new src/ file staged and nothing untracked, so a clean CI checkout of this commit measures the same 17,947. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in this commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises. PRIOR ENTRY: Lowered 17,963 -> 17,959 on 2026-09-09 by feat/cdd-fidelity-council, on the same shape as the entry below and with the same discriminator. The branch's src-link rewrite (a blind review found 253 of 268 links under dist/agent-src/guidelines/ dead, because condense.ts folded only the docs/ prefixes and never (../)+src/rules|skills) came in at +15 excess: condense.ts sits ~1,208 lines PAST the 1500 cap, so every line there is one unit. Paid down rather than baselined, in the way this entry's doctrine prescribes. `_rewrite_body_links` and its two regex constants moved out of condense.ts into _lib/guidelines_lane.ts, 151 lines and therefore UNDER the cap, so the function and its prose now cost nothing. It moved on merit rather than only on arithmetic: every rule the rewriter applies is a statement about which source tree projects where, which is that module's own subject, and condense.ts held it only because that is where the projector lives. condense.ts 2,712 -> 2,708 net, after the one import line and the one call-site rename -- a branch that ADDED a rewrite rule leaves the file four lines shorter than it found it. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports the branch's new src/ files tracked and nothing untracked, so a clean CI checkout of this commit measures the same 17,959. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in this commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises. PRIOR ENTRY: Lowered 17,973 -> 17,963 on 2026-09-08 by drain/graph-shipped-close. The branch registers five code-graph MCP tools (road-to-a-graph-that-is-shipped 4.1). Their five records and schemas are ~250 lines, and putting them in mcp_server/tools.ts -- which sits ~500 lines PAST the 1500 cap, so every line there is one unit -- would have cost ~250 excess. They live in mcp_server/graph_tools.ts instead (~280 lines, UNDER the cap, so they and their prose cost nothing), and tools.ts spreads them into ALLOWLIST in two lines: one import and one `...GRAPH_TOOLS,`. Those two were paid for rather than baselined, in the way this entry's doctrine prescribes: `_strip` and `_resolvePath` -- a whitespace trim and a tolerant realpath, generic by nature -- moved out of tools.ts into mcp_server/path_util.ts, also under the cap. They are imported under their original underscore names, so all 28 call sites are unchanged and a two-function move does not read as a sweep. tools.ts 2,025 -> 2,015: -12 from the extraction, +2 from the registration, net -10 for a branch that ADDED a feature. CORRECTED 2026-09-08 after an independent review checked the figure against the tree -- this sentence read '2,025 -> 2,013, net -12, against the +2 the registration needed', which states an intermediate file length as the final one and leaves the arithmetic (-12) and the conclusion (-10) describing different trees. `git show origin/main:...tools.ts | wc -l` is 2025 and the working tree is 2015. The TOTAL, 17,963, was always the gate's own output and is unchanged. Every other file this branch touches or creates -- code_graph/verbs.ts, code_graph/cli.ts, code_graph/build.ts, code_graph/detect.ts, code_graph/query.ts, code_graph/sqlite_store.ts, code_graph/types.ts, _lib/regression_neighbourhood.ts -- is under the 1500 ceiling before and after, so it contributes zero excess whatever it grew by. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports the two new src/ files staged and nothing untracked, so a clean CI checkout of this commit measures the same 17,963. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in this commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises. PRIOR ENTRY: Lowered 17,974 -> 17,973 on 2026-09-08 by drain/topology-c1. The branch adds a live-path emit to council_cli.ts, which sits 2,454 lines PAST the 1500 cap so every line there is one unit, and paid its own way down rather than raising the baseline, in the way this entry's doctrine prescribes. The twelve-line `all_responses` assembly (a spread, three conditionals and a push) moved out of council_cli.ts into ai_council/deliberation_metrics.ts::runCallsFrom, 353 lines and therefore UNDER the cap, so the six stage labels and their prose cost nothing. It moved on merit rather than only on arithmetic: 'which calls did this run make, and at which stage' is that module's own subject, and the CLI held the list only as a flat array with the stage boundaries implicit in the order -- both readings now come out of one walk, so the billing total and the attribution can never be computed over different sets. council_cli.ts 3,955 -> 3,954 net, after the two call lines, the import and the one payload key the feature needed. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports the two new src/ files staged and nothing untracked, so a clean CI checkout of this commit measures the same 17,973. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in this commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises. PRIOR ENTRY: Lowered 18,016 -> 17,974 on 2026-09-07 by fix/single-delivery-unconditional. SETTLED FIGURE, and it supersedes an intra-session 17,962 this same branch committed earlier — read the direction against MAIN, which is what the ratchet protects: main is 18,016, the branch leaves 17,974, net -42. The 17,962 was this branch's own low before a neutral review returned twelve findings; fixing them added a real mechanism to mcp_server and condense.ts (the flat-wrapper carriage gate the review showed was missing, plus its four-skip predicate), and condense.ts sits ~1,215 lines PAST the cap so each of those lines is one unit. Paid down first, in the way this entry's doctrine prescribes: _suggestSkillForTaskHandler and its 18-line docstring moved out of mcp_server/tools.ts (2,079 -> 2,025) into mcp_server/suggest_skill.ts, 72 lines and UNDER the cap, so its prose costs nothing. The residual +12 against the intra-session low is the gate's own output on the settled tree and is recorded rather than engineered away, because the alternative was extracting _nested_command_subpath and its two callers out of condense.ts - which needs MODULE_STATE, _relativeToPosix and _domains_command_logical passed in, a wider diff than the finding warrants and one no review asked for. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports the three new src/ files staged and nothing untracked, so a clean CI checkout of this commit measures the same 17,974. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in this commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises. PRIOR ENTRY: MERGE RECONCILIATION 2026-09-07, 18,061/18,017 -> 18,016. drain/admissible-council-seats and fix/release-obligation-answerable each lowered from the SAME 18,062 base in parallel — main to 18,061 (net -1: curlJsonPost, the seat-status helpers and the per-seat config parsing moved out of the three over-ceiling council files) and the branch to 18,017 (net -45: the /dev/tty prompt helpers moved out of release.ts into _lib/tty_prompt.ts, 76 lines and UNDER the cap, taking release.ts 1871 -> 1826). Taking either side alone is wrong in a different direction, which is the reconciliation doctrine this entry already carried from 2026-09-03: main's value silently discards the branch's earned -45, and the branch's value RAISES the baseline against main and weakens the gate. The committed number is neither — it is the gate's own output on the MERGED tree, where both reductions apply, and it equals the arithmetic (18,062 - 45 - 1 = 18,016) rather than being reconciled by it. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports ZERO untracked files, so a clean CI checkout of this commit measures the same 18,016. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in the merge commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises. PRIOR ENTRY: Lowered 18,062 -> 18,061 on 2026-09-07 by drain/admissible-council-seats. The branch's own additions to the three over-ceiling files (ai_council/config.ts, council_cli.ts, ai_council/clients.ts) came in at +96 excess and were paid down to -1 rather than baselined, in the four ways this entry's doctrine prescribes: `curlJsonPost` moved out of clients.ts into ai_council/api_transport.ts (UNDER the cap, so the prose and the three new provider shims cost nothing); the seat-status helpers moved out of council_cli.ts into ai_council/status_surface.ts, taking an orphaned doc comment with them; the three new per-seat config fields' parsing moved out of config.ts into ai_council/seat_policy.ts::parseSeatFields; and three prose blocks that the branch's own transport repair made FACTUALLY FALSE (the `openai` / `google-genai` Python-SDK claims, and a `_curlJsonPost` pointer to a function that had moved) were corrected and shortened in the same change. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports zero untracked files with the five new src/ files staged, so a clean CI checkout of this commit measures the same 18,061. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried here because tests/scripts/check_source_size_budget.test.ts:166 asserts baseline == live and therefore blocks where the gate only advises -- the lowering commit must carry its own baseline update. Lowered 18,068 -> 18,062 on 2026-09-06 by drain/host-enforcement-truth. Collapsing the five per-host binding constants in install.ts into src/scripts/hooks/host_lowering.yaml removed 29 lines from a file ~3,900 past the 1500 cap, where every line costs one excess; the journal's surface column and its extracted migration helper gave 23 back. Lowered 18,245 -> 18,230 on 2026-09-02 by drain/publication-integrity-option-a. Phase 2 Option A moved the authoring instruction out of the generator: release.ts, which sits ~530 lines PAST the 1500 cap so every line there costs one excess, loses the comment emission, a 16-line HEAD_DEFAULT doc block and its alias const, and gains a shorter writer docstring. The doc block moved to _lib/release_material.ts, which is 289 lines and therefore UNDER the cap, so the same prose now costs nothing. Net -15. The branch first came in at +8 and paid its own way down rather than raising the baseline. BRANCH-SIDE ENTRY: Lowered 17,947 -> 17,944 on 2026-09-13 by drain/decision-closure, on this entry's own doctrine and at the gate's own request. The branch's ownership-axis additions to ai_council/config.ts came in at +86 excess: that file sits ~700 lines PAST the 1500 cap, so every line there is one unit. Paid down rather than baselined, in one move. The eight ownership class names, the two Iron-Law sets, the merged default-mode map and the mode-check function moved out of config.ts into ai_council/ownership_classes.ts -- 91 lines, UNDER the cap, so the vocabulary and its prose now cost nothing. It moved on merit rather than only on arithmetic: the roadmap-side gate lint_decision_classes needs the same eight names and has no business importing the council's whole schema to learn them, and the loader now carries three lines where it carried twenty-four. config.ts 2,182 -> 2,179: a branch that ADDED an entire decision axis leaves the file three lines shorter than it found it. Every other src/ file this branch creates -- lint_decision_classes.ts, lint_roadmap_producers.ts, closure_scan.ts, council_record_shape.ts, scope_growth.ts, ownership_classes.ts -- is under the 1500 ceiling, so it contributes zero excess whatever it grew by. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports the branch's new src/ files tracked and nothing untracked, so a clean CI checkout of this commit measures the same 17,944. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in this commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises. PRIOR ENTRY: Lowered 17,959 -> 17,947 on 2026-09-11 by the findings-ledger branch, on this entry's own doctrine. The branch adds step 7 to release.ts, which sits ~326 lines PAST the 1500 cap so every line there is one unit, and it came in at +145. Paid down rather than baselined, in two moves. `settle_findings_ledger` and `_blocking_without_disposition` moved out of release.ts into _lib/release_findings_ingest.ts -- 95 lines, and that module is under the cap, so the step and its rationale now cost nothing. It moved on merit rather than only on arithmetic: the module already owns every message the step prints and every argv it builds, and release.ts held only the sequencing. Then the `--ci` fallback dispatch of the three tag-triggered workflows -- 24 lines of loop and warning with no reader elsewhere in step 10 -- moved into _lib/release_tag_dispatch.ts, also under the cap. release.ts 1,826 -> 1,814: a branch that ADDED a pipeline step leaves the file twelve lines shorter than it found it. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports the branch's new src/ file staged and nothing untracked, so a clean CI checkout of this commit measures the same 17,947. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in this commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises. PRIOR ENTRY: Lowered 17,963 -> 17,959 on 2026-09-09 by feat/cdd-fidelity-council, on the same shape as the entry below and with the same discriminator. The branch's src-link rewrite (a blind review found 253 of 268 links under dist/agent-src/guidelines/ dead, because condense.ts folded only the docs/ prefixes and never (../)+src/rules|skills) came in at +15 excess: condense.ts sits ~1,208 lines PAST the 1500 cap, so every line there is one unit. Paid down rather than baselined, in the way this entry's doctrine prescribes. `_rewrite_body_links` and its two regex constants moved out of condense.ts into _lib/guidelines_lane.ts, 151 lines and therefore UNDER the cap, so the function and its prose now cost nothing. It moved on merit rather than only on arithmetic: every rule the rewriter applies is a statement about which source tree projects where, which is that module's own subject, and condense.ts held it only because that is where the projector lives. condense.ts 2,712 -> 2,708 net, after the one import line and the one call-site rename -- a branch that ADDED a rewrite rule leaves the file four lines shorter than it found it. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports the branch's new src/ files tracked and nothing untracked, so a clean CI checkout of this commit measures the same 17,959. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in this commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises. PRIOR ENTRY: Lowered 17,973 -> 17,963 on 2026-09-08 by drain/graph-shipped-close. The branch registers five code-graph MCP tools (road-to-a-graph-that-is-shipped 4.1). Their five records and schemas are ~250 lines, and putting them in mcp_server/tools.ts -- which sits ~500 lines PAST the 1500 cap, so every line there is one unit -- would have cost ~250 excess. They live in mcp_server/graph_tools.ts instead (~280 lines, UNDER the cap, so they and their prose cost nothing), and tools.ts spreads them into ALLOWLIST in two lines: one import and one `...GRAPH_TOOLS,`. Those two were paid for rather than baselined, in the way this entry's doctrine prescribes: `_strip` and `_resolvePath` -- a whitespace trim and a tolerant realpath, generic by nature -- moved out of tools.ts into mcp_server/path_util.ts, also under the cap. They are imported under their original underscore names, so all 28 call sites are unchanged and a two-function move does not read as a sweep. tools.ts 2,025 -> 2,015: -12 from the extraction, +2 from the registration, net -10 for a branch that ADDED a feature. CORRECTED 2026-09-08 after an independent review checked the figure against the tree -- this sentence read '2,025 -> 2,013, net -12, against the +2 the registration needed', which states an intermediate file length as the final one and leaves the arithmetic (-12) and the conclusion (-10) describing different trees. `git show origin/main:...tools.ts | wc -l` is 2025 and the working tree is 2015. The TOTAL, 17,963, was always the gate's own output and is unchanged. Every other file this branch touches or creates -- code_graph/verbs.ts, code_graph/cli.ts, code_graph/build.ts, code_graph/detect.ts, code_graph/query.ts, code_graph/sqlite_store.ts, code_graph/types.ts, _lib/regression_neighbourhood.ts -- is under the 1500 ceiling before and after, so it contributes zero excess whatever it grew by. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports the two new src/ files staged and nothing untracked, so a clean CI checkout of this commit measures the same 17,963. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in this commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises. PRIOR ENTRY: Lowered 17,974 -> 17,973 on 2026-09-08 by drain/topology-c1. The branch adds a live-path emit to council_cli.ts, which sits 2,454 lines PAST the 1500 cap so every line there is one unit, and paid its own way down rather than raising the baseline, in the way this entry's doctrine prescribes. The twelve-line `all_responses` assembly (a spread, three conditionals and a push) moved out of council_cli.ts into ai_council/deliberation_metrics.ts::runCallsFrom, 353 lines and therefore UNDER the cap, so the six stage labels and their prose cost nothing. It moved on merit rather than only on arithmetic: 'which calls did this run make, and at which stage' is that module's own subject, and the CLI held the list only as a flat array with the stage boundaries implicit in the order -- both readings now come out of one walk, so the billing total and the attribution can never be computed over different sets. council_cli.ts 3,955 -> 3,954 net, after the two call lines, the import and the one payload key the feature needed. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports the two new src/ files staged and nothing untracked, so a clean CI checkout of this commit measures the same 17,973. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in this commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises. PRIOR ENTRY: Lowered 18,016 -> 17,974 on 2026-09-07 by fix/single-delivery-unconditional. SETTLED FIGURE, and it supersedes an intra-session 17,962 this same branch committed earlier — read the direction against MAIN, which is what the ratchet protects: main is 18,016, the branch leaves 17,974, net -42. The 17,962 was this branch's own low before a neutral review returned twelve findings; fixing them added a real mechanism to mcp_server and condense.ts (the flat-wrapper carriage gate the review showed was missing, plus its four-skip predicate), and condense.ts sits ~1,215 lines PAST the cap so each of those lines is one unit. Paid down first, in the way this entry's doctrine prescribes: _suggestSkillForTaskHandler and its 18-line docstring moved out of mcp_server/tools.ts (2,079 -> 2,025) into mcp_server/suggest_skill.ts, 72 lines and UNDER the cap, so its prose costs nothing. The residual +12 against the intra-session low is the gate's own output on the settled tree and is recorded rather than engineered away, because the alternative was extracting _nested_command_subpath and its two callers out of condense.ts - which needs MODULE_STATE, _relativeToPosix and _domains_command_logical passed in, a wider diff than the finding warrants and one no review asked for. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports the three new src/ files staged and nothing untracked, so a clean CI checkout of this commit measures the same 17,974. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in this commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises. PRIOR ENTRY: MERGE RECONCILIATION 2026-09-07, 18,061/18,017 -> 18,016. drain/admissible-council-seats and fix/release-obligation-answerable each lowered from the SAME 18,062 base in parallel — main to 18,061 (net -1: curlJsonPost, the seat-status helpers and the per-seat config parsing moved out of the three over-ceiling council files) and the branch to 18,017 (net -45: the /dev/tty prompt helpers moved out of release.ts into _lib/tty_prompt.ts, 76 lines and UNDER the cap, taking release.ts 1871 -> 1826). Taking either side alone is wrong in a different direction, which is the reconciliation doctrine this entry already carried from 2026-09-03: main's value silently discards the branch's earned -45, and the branch's value RAISES the baseline against main and weakens the gate. The committed number is neither — it is the gate's own output on the MERGED tree, where both reductions apply, and it equals the arithmetic (18,062 - 45 - 1 = 18,016) rather than being reconciled by it. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports ZERO untracked files, so a clean CI checkout of this commit measures the same 18,016. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in the merge commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises. PRIOR ENTRY: Lowered 18,062 -> 18,061 on 2026-09-07 by drain/admissible-council-seats. The branch's own additions to the three over-ceiling files (ai_council/config.ts, council_cli.ts, ai_council/clients.ts) came in at +96 excess and were paid down to -1 rather than baselined, in the four ways this entry's doctrine prescribes: `curlJsonPost` moved out of clients.ts into ai_council/api_transport.ts (UNDER the cap, so the prose and the three new provider shims cost nothing); the seat-status helpers moved out of council_cli.ts into ai_council/status_surface.ts, taking an orphaned doc comment with them; the three new per-seat config fields' parsing moved out of config.ts into ai_council/seat_policy.ts::parseSeatFields; and three prose blocks that the branch's own transport repair made FACTUALLY FALSE (the `openai` / `google-genai` Python-SDK claims, and a `_curlJsonPost` pointer to a function that had moved) were corrected and shortened in the same change. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports zero untracked files with the five new src/ files staged, so a clean CI checkout of this commit measures the same 18,061. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried here because tests/scripts/check_source_size_budget.test.ts:166 asserts baseline == live and therefore blocks where the gate only advises -- the lowering commit must carry its own baseline update. Lowered 18,068 -> 18,062 on 2026-09-06 by drain/host-enforcement-truth. Collapsing the five per-host binding constants in install.ts into src/scripts/hooks/host_lowering.yaml removed 29 lines from a file ~3,900 past the 1500 cap, where every line costs one excess; the journal's surface column and its extracted migration helper gave 23 back. Lowered 18,245 -> 18,230 on 2026-09-02 by drain/publication-integrity-option-a. Phase 2 Option A moved the authoring instruction out of the generator: release.ts, which sits ~530 lines PAST the 1500 cap so every line there costs one excess, loses the comment emission, a 16-line HEAD_DEFAULT doc block and its alias const, and gains a shorter writer docstring. The doc block moved to _lib/release_material.ts, which is 289 lines and therefore UNDER the cap, so the same prose now costs nothing. Net -15. The branch first came in at +8 and paid its own way down rather than raising the baseline.",
|
|
38
|
+
"count": 17329,
|
|
39
|
+
"landed": "2026-10-24",
|
|
40
|
+
"note": "Lowered 17,330 -> 17,329 on 2026-10-24 by drain/update-installs-itself-20261024: the user-notice plumbing moved into helper modules so src/scripts/hooks/dispatch_hook.ts ends one line under main (1,500), taking that file off the over-cap list. Set to the exact live total, per this file's convention. Previous note: Lowered 17,333 -> 17,330 on 2026-10-24 by road-to-listings-a-release-keeps-current: folding release.ts's two augment-manifest version calls into one set_plugin_manifest_versions call took 3 lines out of that over-cap file, measured after merging main's own 17,333. Previous note: Lowered 17,337 -> 17,333 on 2026-10-24 by fix/zod-4-advisory: the zod 4 migration replaced the multi-line zodToJsonSchema(settingsSchema, {...}) call in src/scripts/install.ts with one toJsonSchema7(settingsSchema, name) line, which removed four lines above the 1500-line budget. Set to the exact live total, per this file's convention. Prior entry: Lowered 17,354 -> 17,337 on 2026-10-23 by road-to-a-map-that-draws-itself: trimming the chat_history_read and memory_lookup descriptions to fit the two map tools into the kernel payload band removed seventeen lines from src/scripts/mcp_server/tools.ts, which sits above the 1500-line budget. Prior entry: Lowered 17,358 -> 17,354 on 2026-10-22 by fix/release-without-review-gate: release.ts step 7 no longer reads the findings ledger, which removed four lines above the 1500-line budget. Prior entry: Lowered 17,363 -> 17,358 on 2026-10-22 by feat/subagent-system-2583: the seat launch environment (model-ceiling memo, CLI version probe) moved out of src/scripts/ai_council/clients.ts into cli_launch_env.ts, which more than offset the light-launch and seat-resume additions there and in council_cli.ts and orchestrator.ts. Set to the exact live total, per this file's convention. Prior entry: Lowered 17,365 -> 17,363 on 2026-10-21 by fix/release-no-trailer-refusal: removing the Consumer-Impact span refusal took two lines out of src/scripts/release.ts, which sits above the 1,500-line cap. Set to the exact live total, per this file's convention. Prior entry: MERGE RECONCILIATION 2026-10-21, 17,369/17,368 -> 17,365: main lowered 17,372 -> 17,368 (cmd_doctor.ts, below) and this branch lowered 17,372 -> 17,369; the two gains are independent and add. Branch entry: lowered 17,372 -> 17,369 on 2026-10-21 by drain/road-to-one-detector-senders-20261020, and the gate asked for it by name (ratchet is loose, naming 17,369). The branch's CLI egress refusal (+16 in ai_council/clients.ts) and the injection filter (+2 in hooks/dispatch_hook.ts, which crossed 1,500) were paid for by folding five identical CliClient.ask failure constructions into one _cliFailure helper; dispatch_hook.ts is a ratified hook-plumbing source and was left untouched. Main entry: LOWERED 17,372 -> 17,368 on 2026-10-21 by fix/install-runtime-resolution-20261021, and the gate asked for it by name. The gain IS this branch's: cmd_doctor.ts loses four lines because the no-project-install message moved into doctor_ownership_ledger.ts, where it now reports the global scope too. install.ts stays net-zero — a dry-run block that first added sixteen lines there was moved to wizard-plan.ts rather than paid for. PRIOR ENTRY: LOWERED 17,386 -> 17,375 on 2026-10-19 by drain/road-to-skills-that-arrive-when-called-20261019z, measured by CI (the baseline-equals-live test named 17,375): install.ts's _prune_scoped_modules wrapper became a one-line alias of scoped_projection.prune_scoped_modules, which now carries the declared-skill closure. Before that: LOWERED 17,407 -> 17,386 on 2026-10-18 by drain/road-to-a-release-that-says-whether-it-needs-you-20261018x, and the gate asked for it by name (ratchet is loose, naming 17,386). The gain is an EXTRACTION paying for doctor --json's new update_verdict block (two lines in cmd_doctor.ts): STATUS_SYMBOLS and _emit_checks_text moved verbatim into _doctor_emit.ts, re-exported unchanged, so cmd_doctor.ts goes 3,560 -> 3,539. No ceiling was edited. PRIOR ENTRY: LOWERED 17,410 -> 17,407 on 2026-10-18 by drain/road-to-an-ownership-record-20261018, and the gate asked for it by name (ratchet is loose, naming 17,407). The gain is a compaction inside the function this branch changed: _deploy_claude_desktop's marker call collapsed onto one line beside the new one-line claude-desktop ledger record, leaving src/scripts/install.ts 3 lines shorter than on main. PRIOR ENTRY: MERGE RECONCILIATION 2026-10-18, 17,415/17,414 -> 17,410 — merging origin/main into drain/road-to-one-detector-and-the-senders-we-own-20261018b: main lowered to 17,415 (subagent_native_fields extraction) and this branch to 17,414 (ai_council/config.ts onto the shared rule table) from different reductions; the gate measured the merged tree at 17,410 and named it. PRIOR ENTRY: LOWERING 2026-10-18, 17,419 -> 17,415 — the gate asked for it by name (`ratchet is loose`, naming 17,415), and `check_source_size_budget.test.ts` pins baseline == live total. The gain is an EXTRACTION: road-to-a-cold-start-paid-once 2.2 needed the subagent projector to emit four new optional native fields, so the per-field logic, including the existing `effort` pass-through, moved out of `condense.ts` into `src/scripts/_lib/subagent_native_fields.ts`, which owns nothing else; condense.ts goes 2,695 -> 2,691. No ceiling was edited and no file was split to game the metric. PRIOR ENTRY: LOWERING 2026-10-18, 17,424 -> 17,419 — the gate asked for it by name (`ratchet is loose`, naming 17,419). The gain is an EXTRACTION: `install --full` (road-to-a-setup-that-decides-itself 3.5) needed seven lines in `src/scripts/install.ts`, a file 3,618 lines past the ceiling, so the `--tools`/`--ai` merge helper moved out to `src/install/toolsArg.ts`, which owns nothing else; install.ts goes 5,118 -> 5,113. No ceiling was edited and no file was split to game the metric. PRIOR ENTRY: LOWERING 2026-10-13, 17,485 -> 17,466 — the gate asked for it by name (`ratchet is loose`, naming 17,466), and `check_source_size_budget.test.ts` pins baseline == live total, so it is required rather than optional. The gain is an EXTRACTION, which is the shape this convention accepts: the settings-surface assertion needed three lines in `src/scripts/release.ts`, a file 211 lines past the ceiling, so `set_template_pin` moved out to `src/scripts/release_env.ts`, which already owns its two manifest-version siblings for exactly this stated reason and sits far under the ceiling; release.ts goes 1,730 -> 1,711. The `die` call is inlined there as a stderr write plus `SystemExitError`, because `release_publication.ts` imports from `release_env.ts` and reaching back for `die` would be a cycle. No ceiling was edited and no file was split to game the metric. PRIOR ENTRY: LOWERING 2026-10-13, 17,516 -> 17,485 — the gate asked for it by name (`ratchet is loose`, naming 17,485), and the gain is an EXTRACTION, which is the shape this convention accepts. road-to-a-search-answer-a-model-can-choose-from 1.1/1.2 described `suggest_skill_for_task` properly in `tools.ts` — what a row now carries, and why the default depth is 8 — which cost six lines in a file 521 lines past the ceiling and reddened this ratchet by exactly those six. Rather than re-pin the baseline, the whole allowlist ENTRY moved to `src/scripts/mcp_server/suggest_skill.ts`, which already owns that tool’s handler for the same stated reason; `tools.ts` goes 2,021 -> 1,984 and the net is -31. The import back is TYPE-only, so the cycle is erased at runtime. No ceiling was edited and no file was split to game the metric. PRIOR ENTRY: LOWERING 2026-10-09, 17,550 -> 17,516 — the gate asked for it by name after `REMOVED_KEYS` and its once-per-run warning moved out of `src/scripts/_lib/agent_settings.ts` (1,510 lines) into `src/scripts/_lib/settings_removed_keys.ts`, so the settings-key retirement batch adds its registry entries in a file under the ceiling instead of growing the excess; the retirement itself also deletes legacy rename-map rows and the setup-hint settings read from `src/scripts/install.ts`. Earlier: LOWERING 2026-10-05, 17,571 -> 17,550 — a lowering commit, and the gate asked for it BY NAME: it reported `ratchet is loose` and named 17,550; `check_source_size_budget.test.ts` then pins baseline == live total, so this is required rather than optional. The gain IS this branch's own work and it is a DEDUPLICATION, which this convention accepts: all five CliClient subclass constructors forwarded six option fields to super() by name, which is why a seventh (`consumer`) was silently dropped and every CLI call booked as `unknown`. Replacing the five field lists with `{ ...opts, model: ... }` removes 27 lines from src/scripts/ai_council/clients.ts (2,858 -> 2,831) against the +6 the consumer fix added, so the net is -21. No ceiling was edited and no file was split to game the metric. The count is tree-derived (line counts over src/**/*.ts) and container-independent, unlike the projection-surface gates whose local readings diverge. Verified with `npx tsc --noEmit` clean and the clients suite green in this checkout. PRIOR ENTRY: LOWERING 2026-10-05, 17,585 -> 17,571 — a lowering commit, and the gate asked for it BY NAME: it reported `ratchet is loose` and named 17,571. The gain IS this branch's own work and it is an EXTRACTION, which is the only shape this convention accepts: road-to-an-installed-layer-that-is-thinned step 1.1 adds a thinning call to the global deploy loop, and pays for those lines by moving `_resolve_global_rule_scope` out of `src/scripts/install.ts` into `src/install/globalRuleScope.ts` behind a same-signature wrapper, and removes the two imports the extraction orphaned (install.ts 5,180 -> 5,156). The user-global whitelist rows in `src/scripts/_lib/agent_settings.ts` push that file 1,499 -> 1,510, so the net is -5 rather than -15. No ceiling was edited and no file was split to game the metric. Verified by running the gate in this worktree after `npx tsc --noEmit` passed clean. PRIOR ENTRY: LOWERING 2026-10-02, 17,620 -> 17,592 — a lowering commit, and the gate asked for it BY NAME: it reported `ratchet is loose` and named 17,592. The gain IS this branch's own work, and it is a deduplication rather than a sweep. `GLOBAL_DEPLOY_SOURCES` was defined TWICE — in `src/scripts/install.ts` and in `src/install/wizard-plan.ts` — and the two copies were byte-identical across all 18 host rows, which is a duplicate that stays correct exactly until somebody edits one of them. road-to-rule-triggers-and-links-that-hold step 1.2 did that: it added `contexts/` and `guidelines/` to the install.ts copy and the wizard kept installing without them, so the deduplication is the fix for a defect this branch introduced, not an opportunistic tidy. install.ts now imports and re-exports the wizard-plan definition, so every caller is unchanged, and the file goes 5,231 -> 5,175 lines. Verified by running the gate in this worktree after `npm run typecheck` passed clean. PRIOR ENTRY: LOWERING 2026-10-02, 17,734 -> 17,620 — a lowering commit, and the gate asked for it BY NAME: it reported `ratchet is loose` and named 17,620 as the number to write. The gain is not this branch's own work; it is the net of the lanes that merged into main while this branch was in flight, which is exactly the case the clause below exists for — a tree that got smaller while a baseline stood still would let the gain be given back silently by the next change. Verified in a FRESH detached checkout of the pushed head rather than in the working worktree, because the first reading was taken in a tree that had not finished its base sync and reported the two numbers the other way round; the fresh checkout measures 17,620 against a 17,734 baseline over 1,582 scanned files. `landed` is refreshed deliberately, for the reason every entry below gives: checkRatchet returns `improved` BEFORE it evaluates staleness, so an entry left high while the tree measures lower would never expire at any age. PRIOR ENTRY: LOWERING 2026-10-01, 17,745 -> 17,734 — a lowering commit, and the gate asked for it by name. road-to-a-hook-bundle-with-one-yaml-reader 3.1 split the windsurf renderer out of `condense.ts` into the new under-cap `src/scripts/_lib/windsurf_render.ts`, and `strip_frontmatter` moved with it as the render's one non-trivial dependency. `condense.ts` went 2,728 -> 2,717 excess lines. The direction is honest about its own history: an earlier commit on this branch kept the renderer INLINE in `condense.ts` and CI caught it as 20 new violations — this entry is that fix, not a sweep, and the lowering is the by-product of putting the code where it belonged. Nothing was deleted: the renderer and the stripper are both still called, by TWO callers now rather than one, and `condense.ts` re-exports `strip_frontmatter` so no importer's path changed. The new module lands at 64 lines, far under its own cap, so it contributes zero excess. LOCAL READING, same discriminator every entry below uses: the gate walks authored source under `src/`, and the only untracked path `git status --porcelain -uall -- src` reports is that new module, committed in this same change — so a clean CI checkout of this commit measures the same 17,734. If CI reads anything else, CI's number is the correct one and this note is the record of why. `landed` is refreshed deliberately, for the reason the prior entry gives: checkRatchet returns `improved` BEFORE it evaluates staleness, so an entry left high while the tree measures lower would never expire at any age. PRIOR ENTRY: LOWERING 2026-09-30, 17,746 -> 17,745 — a lowering commit, and the gate asked for it by name. The direction is the surprising one again: this branch ADDED a feature to `install.ts` (an opt-in host env write) and that file came out SHORTER than it went in, 5,270 -> 5,269. The whole mechanism — the two-row allow table, the settings reader, the env-block builder and the bridge wrapper — lives in the new under-cap `src/scripts/_lib/host_env_write.ts`, so `install.ts` pays ONE import line and one expression for it; and the three-line `for` loop over healed plugin ids in the same function collapsed to one, which is inside the function the change already edits. The gain is a MOVE plus one tightening, never a deletion: nothing was dropped and nothing was swept. That module boundary is also the better one on its own terms — one place now owns which host variable this package may write, which is the question the owner decision of 2026-09-30 turns on. LOCAL READING, on the same discriminator every entry below uses: the gate walks authored source under `src/`, and `git status --porcelain -uall -- src` reported ZERO untracked files, so a clean CI checkout of this commit measures the same 17,745. If CI reads anything else, CI's number is the correct one and this note is the record of why. `landed` is refreshed deliberately: checkRatchet returns `improved` BEFORE it evaluates staleness, so an entry left at 17,746 while the tree measures 17,745 would never expire at any age. PRIOR ENTRY: LOWERING 2026-09-29, 17,748 -> 17,746 — a lowering commit, same doctrine as every entry below, and the gate asked for it by name. This branch ADDED two gate scripts, a guard and a shared lib under `src/`, so the direction is the surprising one and worth stating: the new files each land under their own cap and contribute zero EXCESS, while factoring the shell write shapes out of `block_kernel_rule_writes` into `_lib/shell_write_shapes.ts` moved lines out of a file that was over its cap and into one that is not. Net -2. LOCAL READING, on the same discriminator every entry below uses: the gate walks authored source under `src/`, and `git status --porcelain -uall -- src` reported ZERO untracked files, so a clean CI checkout of this commit measures the same 17,746. If CI reads anything else, CI's number is the correct one and this note is the record of why. `landed` is refreshed deliberately: checkRatchet returns `improved` BEFORE it evaluates staleness, so an entry left at 17,748 while the tree measures 17,746 would never expire at any age. PRIOR ENTRY: LOWERING 2026-09-29, 17,762 -> 17,748 — a lowering commit, same doctrine as every entry below, and the gate asked for it by name. Reporting the host traffic environment in `doctor` needed a new surface; rather than pay those lines against `src/scripts/_cli/cmd_doctor.ts`, already far over the cap, the whole network-posture block moved out into the new under-cap `src/scripts/_cli/doctor_network_posture.ts`, which is also where the new logic lives: one module owns which traffic variables exist, how each is read, and how an absent one is reported, so the unit is coherent rather than a line-count trim. cmd_doctor.ts 3,618 -> 3,604; total 17,762 -> 17,748. The gain is a MOVE, not a deletion — nothing was dropped and nothing was swept. `landed` is refreshed deliberately, for the reason the prior entries record: checkRatchet returns `improved` BEFORE it evaluates staleness, so an entry left at 17,762 while the tree measures 17,748 would never expire at any age, and the gate only ADVISES on a loose ratchet while `check_source_size_budget.test.ts` blocks — that asymmetry is what forces a lowering commit to carry its own baseline update. PRIOR ENTRY: LOWERING 2026-09-27, 17,765 -> 17,762 — the second half of the same repair, and a lowering for the same reason. Closing the remaining preservation defects needed lines in two over-cap files: `src/scripts/install.ts` (route the generated Claude Desktop marker through the tracker, hand the rule-rewrite its skip set) and `src/server/routes/wizard.ts` (surface the conflict count, stop reporting exit 3 as a failure). Both were paid from the same subject rather than from the ratchet: `_files_by_tool_from_bridges` joined its sibling in `src/install/manifestFiles.ts`, which now owns the whole per-tool inventory, and the wizard's exit-code semantics moved into `src/install/preserve.ts` beside `installDoneSummary`, which already lives there for this exact reason. install.ts 5,277 -> 5,270; wizard.ts 1,500 -> 1,504. PRIOR ENTRY: LOWERING 2026-09-27, 17,784 -> 17,765 — a lowering commit, same doctrine as the entry it replaces. Repairing the install-manifest digest loss needed new state in `_update_installed_tools_manifest` (a recorded-inventory read, a preserved-path index, a reconciliation call). Rather than pay that against `src/scripts/install.ts`, already 3,777 over the cap, the manifest file-inventory block (`_sha256_of_file`, `_file_entry`, `_files_by_tool_from_deploy` — 29 lines) moved out into the under-cap `src/install/manifestFiles.ts`, which is where the new logic lives too: one module now owns what the manifest's per-tool `files[]` holds, how it is read back, and how the two reconcile, so the unit is coherent rather than a line-count trim. install.ts 5,296 -> 5,277; total 17,784 -> 17,765. PRIOR ENTRY: LOWERING 2026-09-20, 17,858 -> 17,784 — a lowering commit, not a reconciliation, but measured under the same doctrine the four entries below carry: the committed number is the gate's own reading on the MERGED tree, taken after origin/main was merged into drain/headless-log-write rather than from either side. The branch's transaction-log write added 27 lines to `src/scripts/install.ts`, already 3,897 over the cap, taking the total to 17,885. Rather than pay that, the `json.dumps` byte-parity block (`jsonStrNoAscii`, `_jsonScalar`, `_dumpIndent`, `jsonDumpsIndent`, `jsonDumpsCompact` — 101 lines) moved out of `install.ts` into the under-cap `src/scripts/_lib/json_python_parity.ts`: pure, total functions of their input carrying no installer state, so the unit is coherent rather than a line-count trim. install.ts 5,397 -> 5,296; total 17,885 -> 17,784, a net -74 against the prior baseline. PRIOR ENTRY: MERGE RECONCILIATION 2026-09-14, 17,861 -> 17,858 — the FOURTH reconciliation of this entry, same doctrine as the three below: the committed number is the gate's own reading on the MERGED tree, never either side's. Neither branch earned the -3; it falls out of main having absorbed drain/release-head-field, whose `derive_head_prefill` extraction moved the span-to-prefill composition into an under-cap module. Taking this branch's 17,861 would have silently given that gain back. PRIOR ENTRY: MERGE RECONCILIATION 2026-09-13, 17,863 -> 17,861 — the THIRD reconciliation of this entry in one day, and re-measured on the merged tree rather than taken from either side, which is the only resolution that converges. drain/adversarial-verification reached 17,864 by paying for a `forge_protection` block and a cascade-base module entirely in files under the 1,500-line cap; the incoming reconciliation reached 17,863 from different work. Neither describes the merge. PRIOR ENTRY: MERGE RECONCILIATION 2026-09-13, 17,944/17,866 -> 17,863. drain/decision-closure and drain/breaking-line-contradiction each lowered from the SAME 17,947 base in parallel -- this branch to 17,944 (net -3: the ownership vocabulary, its two Iron-Law sets and the merged default-mode map moved out of ai_council/config.ts into ai_council/ownership_classes.ts, and the settings-rename block moved out of _lib/agent_settings.ts into _lib/settings_renamed_keys.ts, both UNDER the 1500 cap so both cost nothing) and main to 17,866. Taking either side alone is wrong in a different direction, which is the doctrine this entry already carries from 2026-09-03 and 2026-09-07: main's value silently discards this branch's earned -3, and this branch's value RAISES the baseline against main and weakens the gate. The committed number is neither -- it is the gate's own output on the MERGED tree, where both reductions apply. MAIN-SIDE ENTRY, carried so neither branch's record is lost: Lowered 17,947 -> 17,866 on 2026-09-13 by drain/breaking-line-contradiction, on this entry's own doctrine. The branch adds the BACKWARD half of the MIGRATION.md obligation -- a refusal for a major cut whose BREAKING section has no migration entry -- and writing it into release.ts came in at +61, because that file sits ~375 lines PAST the 1500 cap so every line there is one unit. Paid down rather than baselined, and the move was the coherent unit rather than the minimum one: BOTH refusals went, the new backward half and the pre-existing forward half (assert_scheduled_deprecations_clear), into _lib/release_migration_gate.ts at 184 lines and therefore UNDER the cap, so the pair and all their rationale now cost nothing. They moved on merit rather than only on arithmetic -- they are the two halves of one obligation, written eleven months apart, and release.ts held only the two call sites. parse_version stayed module-private in release.ts and the lib carries a two-line _minor_patch instead: exporting a private helper to serve one caller would widen the surface of the file the move exists to narrow. release.ts 1,875 -> 1,733: a branch that ADDED a pipeline refusal leaves the file eighty-one lines shorter than it found it. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports nothing staged and nothing untracked at this commit, so a clean CI checkout measures the same 17,866. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in this commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises -- which is how CI found it: the gate exited 0 with a loose-ratchet warning and the test went red. PRIOR ENTRY: Lowered 17,959 -> 17,947 on 2026-09-11 by the findings-ledger branch, on this entry's own doctrine. The branch adds step 7 to release.ts, which sits ~326 lines PAST the 1500 cap so every line there is one unit, and it came in at +145. Paid down rather than baselined, in two moves. `settle_findings_ledger` and `_blocking_without_disposition` moved out of release.ts into _lib/release_findings_ingest.ts -- 95 lines, and that module is under the cap, so the step and its rationale now cost nothing. It moved on merit rather than only on arithmetic: the module already owns every message the step prints and every argv it builds, and release.ts held only the sequencing. Then the `--ci` fallback dispatch of the three tag-triggered workflows -- 24 lines of loop and warning with no reader elsewhere in step 10 -- moved into _lib/release_tag_dispatch.ts, also under the cap. release.ts 1,826 -> 1,814: a branch that ADDED a pipeline step leaves the file twelve lines shorter than it found it. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports the branch's new src/ file staged and nothing untracked, so a clean CI checkout of this commit measures the same 17,947. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in this commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises. PRIOR ENTRY: Lowered 17,963 -> 17,959 on 2026-09-09 by feat/cdd-fidelity-council, on the same shape as the entry below and with the same discriminator. The branch's src-link rewrite (a blind review found 253 of 268 links under dist/agent-src/guidelines/ dead, because condense.ts folded only the docs/ prefixes and never (../)+src/rules|skills) came in at +15 excess: condense.ts sits ~1,208 lines PAST the 1500 cap, so every line there is one unit. Paid down rather than baselined, in the way this entry's doctrine prescribes. `_rewrite_body_links` and its two regex constants moved out of condense.ts into _lib/guidelines_lane.ts, 151 lines and therefore UNDER the cap, so the function and its prose now cost nothing. It moved on merit rather than only on arithmetic: every rule the rewriter applies is a statement about which source tree projects where, which is that module's own subject, and condense.ts held it only because that is where the projector lives. condense.ts 2,712 -> 2,708 net, after the one import line and the one call-site rename -- a branch that ADDED a rewrite rule leaves the file four lines shorter than it found it. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports the branch's new src/ files tracked and nothing untracked, so a clean CI checkout of this commit measures the same 17,959. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in this commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises. PRIOR ENTRY: Lowered 17,973 -> 17,963 on 2026-09-08 by drain/graph-shipped-close. The branch registers five code-graph MCP tools (road-to-a-graph-that-is-shipped 4.1). Their five records and schemas are ~250 lines, and putting them in mcp_server/tools.ts -- which sits ~500 lines PAST the 1500 cap, so every line there is one unit -- would have cost ~250 excess. They live in mcp_server/graph_tools.ts instead (~280 lines, UNDER the cap, so they and their prose cost nothing), and tools.ts spreads them into ALLOWLIST in two lines: one import and one `...GRAPH_TOOLS,`. Those two were paid for rather than baselined, in the way this entry's doctrine prescribes: `_strip` and `_resolvePath` -- a whitespace trim and a tolerant realpath, generic by nature -- moved out of tools.ts into mcp_server/path_util.ts, also under the cap. They are imported under their original underscore names, so all 28 call sites are unchanged and a two-function move does not read as a sweep. tools.ts 2,025 -> 2,015: -12 from the extraction, +2 from the registration, net -10 for a branch that ADDED a feature. CORRECTED 2026-09-08 after an independent review checked the figure against the tree -- this sentence read '2,025 -> 2,013, net -12, against the +2 the registration needed', which states an intermediate file length as the final one and leaves the arithmetic (-12) and the conclusion (-10) describing different trees. `git show origin/main:...tools.ts | wc -l` is 2025 and the working tree is 2015. The TOTAL, 17,963, was always the gate's own output and is unchanged. Every other file this branch touches or creates -- code_graph/verbs.ts, code_graph/cli.ts, code_graph/build.ts, code_graph/detect.ts, code_graph/query.ts, code_graph/sqlite_store.ts, code_graph/types.ts, _lib/regression_neighbourhood.ts -- is under the 1500 ceiling before and after, so it contributes zero excess whatever it grew by. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports the two new src/ files staged and nothing untracked, so a clean CI checkout of this commit measures the same 17,963. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in this commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises. PRIOR ENTRY: Lowered 17,974 -> 17,973 on 2026-09-08 by drain/topology-c1. The branch adds a live-path emit to council_cli.ts, which sits 2,454 lines PAST the 1500 cap so every line there is one unit, and paid its own way down rather than raising the baseline, in the way this entry's doctrine prescribes. The twelve-line `all_responses` assembly (a spread, three conditionals and a push) moved out of council_cli.ts into ai_council/deliberation_metrics.ts::runCallsFrom, 353 lines and therefore UNDER the cap, so the six stage labels and their prose cost nothing. It moved on merit rather than only on arithmetic: 'which calls did this run make, and at which stage' is that module's own subject, and the CLI held the list only as a flat array with the stage boundaries implicit in the order -- both readings now come out of one walk, so the billing total and the attribution can never be computed over different sets. council_cli.ts 3,955 -> 3,954 net, after the two call lines, the import and the one payload key the feature needed. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports the two new src/ files staged and nothing untracked, so a clean CI checkout of this commit measures the same 17,973. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in this commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises. PRIOR ENTRY: Lowered 18,016 -> 17,974 on 2026-09-07 by fix/single-delivery-unconditional. SETTLED FIGURE, and it supersedes an intra-session 17,962 this same branch committed earlier — read the direction against MAIN, which is what the ratchet protects: main is 18,016, the branch leaves 17,974, net -42. The 17,962 was this branch's own low before a neutral review returned twelve findings; fixing them added a real mechanism to mcp_server and condense.ts (the flat-wrapper carriage gate the review showed was missing, plus its four-skip predicate), and condense.ts sits ~1,215 lines PAST the cap so each of those lines is one unit. Paid down first, in the way this entry's doctrine prescribes: _suggestSkillForTaskHandler and its 18-line docstring moved out of mcp_server/tools.ts (2,079 -> 2,025) into mcp_server/suggest_skill.ts, 72 lines and UNDER the cap, so its prose costs nothing. The residual +12 against the intra-session low is the gate's own output on the settled tree and is recorded rather than engineered away, because the alternative was extracting _nested_command_subpath and its two callers out of condense.ts - which needs MODULE_STATE, _relativeToPosix and _domains_command_logical passed in, a wider diff than the finding warrants and one no review asked for. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports the three new src/ files staged and nothing untracked, so a clean CI checkout of this commit measures the same 17,974. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in this commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises. PRIOR ENTRY: MERGE RECONCILIATION 2026-09-07, 18,061/18,017 -> 18,016. drain/admissible-council-seats and fix/release-obligation-answerable each lowered from the SAME 18,062 base in parallel — main to 18,061 (net -1: curlJsonPost, the seat-status helpers and the per-seat config parsing moved out of the three over-ceiling council files) and the branch to 18,017 (net -45: the /dev/tty prompt helpers moved out of release.ts into _lib/tty_prompt.ts, 76 lines and UNDER the cap, taking release.ts 1871 -> 1826). Taking either side alone is wrong in a different direction, which is the reconciliation doctrine this entry already carried from 2026-09-03: main's value silently discards the branch's earned -45, and the branch's value RAISES the baseline against main and weakens the gate. The committed number is neither — it is the gate's own output on the MERGED tree, where both reductions apply, and it equals the arithmetic (18,062 - 45 - 1 = 18,016) rather than being reconciled by it. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports ZERO untracked files, so a clean CI checkout of this commit measures the same 18,016. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in the merge commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises. PRIOR ENTRY: Lowered 18,062 -> 18,061 on 2026-09-07 by drain/admissible-council-seats. The branch's own additions to the three over-ceiling files (ai_council/config.ts, council_cli.ts, ai_council/clients.ts) came in at +96 excess and were paid down to -1 rather than baselined, in the four ways this entry's doctrine prescribes: `curlJsonPost` moved out of clients.ts into ai_council/api_transport.ts (UNDER the cap, so the prose and the three new provider shims cost nothing); the seat-status helpers moved out of council_cli.ts into ai_council/status_surface.ts, taking an orphaned doc comment with them; the three new per-seat config fields' parsing moved out of config.ts into ai_council/seat_policy.ts::parseSeatFields; and three prose blocks that the branch's own transport repair made FACTUALLY FALSE (the `openai` / `google-genai` Python-SDK claims, and a `_curlJsonPost` pointer to a function that had moved) were corrected and shortened in the same change. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports zero untracked files with the five new src/ files staged, so a clean CI checkout of this commit measures the same 18,061. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried here because tests/scripts/check_source_size_budget.test.ts:166 asserts baseline == live and therefore blocks where the gate only advises -- the lowering commit must carry its own baseline update. Lowered 18,068 -> 18,062 on 2026-09-06 by drain/host-enforcement-truth. Collapsing the five per-host binding constants in install.ts into src/scripts/hooks/host_lowering.yaml removed 29 lines from a file ~3,900 past the 1500 cap, where every line costs one excess; the journal's surface column and its extracted migration helper gave 23 back. Lowered 18,245 -> 18,230 on 2026-09-02 by drain/publication-integrity-option-a. Phase 2 Option A moved the authoring instruction out of the generator: release.ts, which sits ~530 lines PAST the 1500 cap so every line there costs one excess, loses the comment emission, a 16-line HEAD_DEFAULT doc block and its alias const, and gains a shorter writer docstring. The doc block moved to _lib/release_material.ts, which is 289 lines and therefore UNDER the cap, so the same prose now costs nothing. Net -15. The branch first came in at +8 and paid its own way down rather than raising the baseline. BRANCH-SIDE ENTRY: Lowered 17,947 -> 17,944 on 2026-09-13 by drain/decision-closure, on this entry's own doctrine and at the gate's own request. The branch's ownership-axis additions to ai_council/config.ts came in at +86 excess: that file sits ~700 lines PAST the 1500 cap, so every line there is one unit. Paid down rather than baselined, in one move. The eight ownership class names, the two Iron-Law sets, the merged default-mode map and the mode-check function moved out of config.ts into ai_council/ownership_classes.ts -- 91 lines, UNDER the cap, so the vocabulary and its prose now cost nothing. It moved on merit rather than only on arithmetic: the roadmap-side gate lint_decision_classes needs the same eight names and has no business importing the council's whole schema to learn them, and the loader now carries three lines where it carried twenty-four. config.ts 2,182 -> 2,179: a branch that ADDED an entire decision axis leaves the file three lines shorter than it found it. Every other src/ file this branch creates -- lint_decision_classes.ts, lint_roadmap_producers.ts, closure_scan.ts, council_record_shape.ts, scope_growth.ts, ownership_classes.ts -- is under the 1500 ceiling, so it contributes zero excess whatever it grew by. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports the branch's new src/ files tracked and nothing untracked, so a clean CI checkout of this commit measures the same 17,944. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in this commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises. PRIOR ENTRY: Lowered 17,959 -> 17,947 on 2026-09-11 by the findings-ledger branch, on this entry's own doctrine. The branch adds step 7 to release.ts, which sits ~326 lines PAST the 1500 cap so every line there is one unit, and it came in at +145. Paid down rather than baselined, in two moves. `settle_findings_ledger` and `_blocking_without_disposition` moved out of release.ts into _lib/release_findings_ingest.ts -- 95 lines, and that module is under the cap, so the step and its rationale now cost nothing. It moved on merit rather than only on arithmetic: the module already owns every message the step prints and every argv it builds, and release.ts held only the sequencing. Then the `--ci` fallback dispatch of the three tag-triggered workflows -- 24 lines of loop and warning with no reader elsewhere in step 10 -- moved into _lib/release_tag_dispatch.ts, also under the cap. release.ts 1,826 -> 1,814: a branch that ADDED a pipeline step leaves the file twelve lines shorter than it found it. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports the branch's new src/ file staged and nothing untracked, so a clean CI checkout of this commit measures the same 17,947. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in this commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises. PRIOR ENTRY: Lowered 17,963 -> 17,959 on 2026-09-09 by feat/cdd-fidelity-council, on the same shape as the entry below and with the same discriminator. The branch's src-link rewrite (a blind review found 253 of 268 links under dist/agent-src/guidelines/ dead, because condense.ts folded only the docs/ prefixes and never (../)+src/rules|skills) came in at +15 excess: condense.ts sits ~1,208 lines PAST the 1500 cap, so every line there is one unit. Paid down rather than baselined, in the way this entry's doctrine prescribes. `_rewrite_body_links` and its two regex constants moved out of condense.ts into _lib/guidelines_lane.ts, 151 lines and therefore UNDER the cap, so the function and its prose now cost nothing. It moved on merit rather than only on arithmetic: every rule the rewriter applies is a statement about which source tree projects where, which is that module's own subject, and condense.ts held it only because that is where the projector lives. condense.ts 2,712 -> 2,708 net, after the one import line and the one call-site rename -- a branch that ADDED a rewrite rule leaves the file four lines shorter than it found it. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports the branch's new src/ files tracked and nothing untracked, so a clean CI checkout of this commit measures the same 17,959. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in this commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises. PRIOR ENTRY: Lowered 17,973 -> 17,963 on 2026-09-08 by drain/graph-shipped-close. The branch registers five code-graph MCP tools (road-to-a-graph-that-is-shipped 4.1). Their five records and schemas are ~250 lines, and putting them in mcp_server/tools.ts -- which sits ~500 lines PAST the 1500 cap, so every line there is one unit -- would have cost ~250 excess. They live in mcp_server/graph_tools.ts instead (~280 lines, UNDER the cap, so they and their prose cost nothing), and tools.ts spreads them into ALLOWLIST in two lines: one import and one `...GRAPH_TOOLS,`. Those two were paid for rather than baselined, in the way this entry's doctrine prescribes: `_strip` and `_resolvePath` -- a whitespace trim and a tolerant realpath, generic by nature -- moved out of tools.ts into mcp_server/path_util.ts, also under the cap. They are imported under their original underscore names, so all 28 call sites are unchanged and a two-function move does not read as a sweep. tools.ts 2,025 -> 2,015: -12 from the extraction, +2 from the registration, net -10 for a branch that ADDED a feature. CORRECTED 2026-09-08 after an independent review checked the figure against the tree -- this sentence read '2,025 -> 2,013, net -12, against the +2 the registration needed', which states an intermediate file length as the final one and leaves the arithmetic (-12) and the conclusion (-10) describing different trees. `git show origin/main:...tools.ts | wc -l` is 2025 and the working tree is 2015. The TOTAL, 17,963, was always the gate's own output and is unchanged. Every other file this branch touches or creates -- code_graph/verbs.ts, code_graph/cli.ts, code_graph/build.ts, code_graph/detect.ts, code_graph/query.ts, code_graph/sqlite_store.ts, code_graph/types.ts, _lib/regression_neighbourhood.ts -- is under the 1500 ceiling before and after, so it contributes zero excess whatever it grew by. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports the two new src/ files staged and nothing untracked, so a clean CI checkout of this commit measures the same 17,963. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in this commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises. PRIOR ENTRY: Lowered 17,974 -> 17,973 on 2026-09-08 by drain/topology-c1. The branch adds a live-path emit to council_cli.ts, which sits 2,454 lines PAST the 1500 cap so every line there is one unit, and paid its own way down rather than raising the baseline, in the way this entry's doctrine prescribes. The twelve-line `all_responses` assembly (a spread, three conditionals and a push) moved out of council_cli.ts into ai_council/deliberation_metrics.ts::runCallsFrom, 353 lines and therefore UNDER the cap, so the six stage labels and their prose cost nothing. It moved on merit rather than only on arithmetic: 'which calls did this run make, and at which stage' is that module's own subject, and the CLI held the list only as a flat array with the stage boundaries implicit in the order -- both readings now come out of one walk, so the billing total and the attribution can never be computed over different sets. council_cli.ts 3,955 -> 3,954 net, after the two call lines, the import and the one payload key the feature needed. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports the two new src/ files staged and nothing untracked, so a clean CI checkout of this commit measures the same 17,973. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in this commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises. PRIOR ENTRY: Lowered 18,016 -> 17,974 on 2026-09-07 by fix/single-delivery-unconditional. SETTLED FIGURE, and it supersedes an intra-session 17,962 this same branch committed earlier — read the direction against MAIN, which is what the ratchet protects: main is 18,016, the branch leaves 17,974, net -42. The 17,962 was this branch's own low before a neutral review returned twelve findings; fixing them added a real mechanism to mcp_server and condense.ts (the flat-wrapper carriage gate the review showed was missing, plus its four-skip predicate), and condense.ts sits ~1,215 lines PAST the cap so each of those lines is one unit. Paid down first, in the way this entry's doctrine prescribes: _suggestSkillForTaskHandler and its 18-line docstring moved out of mcp_server/tools.ts (2,079 -> 2,025) into mcp_server/suggest_skill.ts, 72 lines and UNDER the cap, so its prose costs nothing. The residual +12 against the intra-session low is the gate's own output on the settled tree and is recorded rather than engineered away, because the alternative was extracting _nested_command_subpath and its two callers out of condense.ts - which needs MODULE_STATE, _relativeToPosix and _domains_command_logical passed in, a wider diff than the finding warrants and one no review asked for. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports the three new src/ files staged and nothing untracked, so a clean CI checkout of this commit measures the same 17,974. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in this commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises. PRIOR ENTRY: MERGE RECONCILIATION 2026-09-07, 18,061/18,017 -> 18,016. drain/admissible-council-seats and fix/release-obligation-answerable each lowered from the SAME 18,062 base in parallel — main to 18,061 (net -1: curlJsonPost, the seat-status helpers and the per-seat config parsing moved out of the three over-ceiling council files) and the branch to 18,017 (net -45: the /dev/tty prompt helpers moved out of release.ts into _lib/tty_prompt.ts, 76 lines and UNDER the cap, taking release.ts 1871 -> 1826). Taking either side alone is wrong in a different direction, which is the reconciliation doctrine this entry already carried from 2026-09-03: main's value silently discards the branch's earned -45, and the branch's value RAISES the baseline against main and weakens the gate. The committed number is neither — it is the gate's own output on the MERGED tree, where both reductions apply, and it equals the arithmetic (18,062 - 45 - 1 = 18,016) rather than being reconciled by it. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports ZERO untracked files, so a clean CI checkout of this commit measures the same 18,016. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried in the merge commit because tests/scripts/check_source_size_budget.test.ts asserts baseline == live and therefore BLOCKS where the gate only advises. PRIOR ENTRY: Lowered 18,062 -> 18,061 on 2026-09-07 by drain/admissible-council-seats. The branch's own additions to the three over-ceiling files (ai_council/config.ts, council_cli.ts, ai_council/clients.ts) came in at +96 excess and were paid down to -1 rather than baselined, in the four ways this entry's doctrine prescribes: `curlJsonPost` moved out of clients.ts into ai_council/api_transport.ts (UNDER the cap, so the prose and the three new provider shims cost nothing); the seat-status helpers moved out of council_cli.ts into ai_council/status_surface.ts, taking an orphaned doc comment with them; the three new per-seat config fields' parsing moved out of config.ts into ai_council/seat_policy.ts::parseSeatFields; and three prose blocks that the branch's own transport repair made FACTUALLY FALSE (the `openai` / `google-genai` Python-SDK claims, and a `_curlJsonPost` pointer to a function that had moved) were corrected and shortened in the same change. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500-line ceiling, and `git status --porcelain -uall -- src/` reports zero untracked files with the five new src/ files staged, so a clean CI checkout of this commit measures the same 18,061. If CI reads anything else, CI's number is the correct one and this note is the record of why. Carried here because tests/scripts/check_source_size_budget.test.ts:166 asserts baseline == live and therefore blocks where the gate only advises -- the lowering commit must carry its own baseline update. Lowered 18,068 -> 18,062 on 2026-09-06 by drain/host-enforcement-truth. Collapsing the five per-host binding constants in install.ts into src/scripts/hooks/host_lowering.yaml removed 29 lines from a file ~3,900 past the 1500 cap, where every line costs one excess; the journal's surface column and its extracted migration helper gave 23 back. Lowered 18,245 -> 18,230 on 2026-09-02 by drain/publication-integrity-option-a. Phase 2 Option A moved the authoring instruction out of the generator: release.ts, which sits ~530 lines PAST the 1500 cap so every line there costs one excess, loses the comment emission, a 16-line HEAD_DEFAULT doc block and its alias const, and gains a shorter writer docstring. The doc block moved to _lib/release_material.ts, which is 289 lines and therefore UNDER the cap, so the same prose now costs nothing. Net -15. The branch first came in at +8 and paid its own way down rather than raising the baseline.",
|
|
41
41
|
"earlier_history": "LOWERED 17,426 -> 17,424 on 2026-10-18 by drain/road-to-a-hook-carrier-that-is-never-silent-20261018, and the gate asked for it BY NAME (ratchet is loose, naming 17,424). The gain is an EXTRACTION: the claude-code thin call site in src/scripts/install.ts became one call to deployClaudeCarrier in src/install/stagedRuntime.ts, which is under the cap, and the new doctor hook-carrier check lives there too rather than in cmd_doctor.ts. The branch first measured +58 against this baseline and paid its own way down. If CI reads a different number, CI's number wins. Prior entry: LOWERED 17,434 -> 17,426 on 2026-10-17 as the merged-tree reading of #2421 + #2422: merging main into drain/road-to-a-release-that-says-whether-it-needs-you, the gate reported `17426 violation(s), baseline 17434 - ratchet is loose` and named 17,426, because both PRs had lowered 17,442 -> 17,434 through DIFFERENT reductions and both now apply. #2421: `src/scripts/release.ts` went 1,711 -> 1,703 lines when its commit parsing moved into `src/scripts/_lib/consumer_impact.ts`; #2422: see the entry that follows. If CI reads a different number, CI's number wins. Prior entry: LOWERED 17,442 -> 17,434 on 2026-10-16 by drain/road-to-an-ownership-record-that-belongs-to-the-user, and the gate asked for it BY NAME (ratchet is loose, naming 17,434), with CI shard 4/4 measuring the same live total. The gain is an EXTRACTION: the inventory load, both reapers, the record and the save that src/scripts/install.ts ran inline for each global deploy moved into src/install/ownershipLedger.ts (recordGlobalDeploy), install.ts 5,132 -> 5,124. Prior entry: LOWERED 17,466 -> 17,442 on 2026-10-13 by drain/what-was-built-never-ran, and the gate asked for it BY NAME: it reported `17442 violation(s), baseline 17466 - ratchet is loose` and named 17,442 itself. The gain is a DELETION rather than an extraction: `src/scripts/hooks/run_continuation_hook.ts` (1,529 lines, 29 past the 1500 cap) was removed with its concern, which was withdrawn on its own pre-registered kill date (road-to-what-was-built-and-never-ran Phase 4, executing a dated kill criterion a converged two-seat council set on 2026-09-12). Only the 29 lines past the cap are what this gate counts, and the remaining movement comes from comment edits the same sweep made in files that also sit past it. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR, which the paragraphs below establish: the gate walks only SOURCE_ROOTS=['src'] counting excess over the 1500 ceiling, and a porcelain status over that root reports ZERO untracked files, so a clean CI checkout of this commit measures the same 17,442. If CI reads anything else, CI's number is the correct one and this note is the record of why. PRIOR REASON: Lowered 17,585 -> 17,571 on 2026-10-05 by lane/installed-layer-thinned, and the gate asked for it BY NAME. The gain is this branch's own, through two extractions rather than a sweep: `_resolve_global_rule_scope` to `src/install/globalRuleScope.ts` and the thinning mechanism to `src/scripts/_lib/thin_rules.ts`. PRIOR REASON: Lowered 17,590 -> 17,585 on 2026-10-03 by drain/rule-carrier-phase1b-20261002, and the gate asked for it BY NAME: it reported `ratchet is loose` and named 17,585. The gain is INCIDENTAL rather than sought, and it comes from two files that sit past the 1500-line cap. `src/scripts/ai_council/clients.ts` (2,852 lines, 1,352 past) lost the 18-line doc comment and declaration of `OPENAI_CLI_VENDOR_DEFAULT`, which moved to a new `ai_council/vendor_defaults.ts` well under the cap, so those lines stopped being charged; the move itself was made to break an import edge costing 51,523 B of composed hook bundle, not to shed lines. `src/scripts/install.ts` (5,229 lines, 3,729 past) gained a three-line call site for the headless `.gitignore` block and NOT the 44-line function behind it, which was written into `_lib/gitignore_block.ts` instead — that placement was chosen when this gate reported +44 and said a ratchet only turns one way, and it is the better home anyway. Net across both: -5. LOCAL READING, on the same discriminator the entries above use: the gate walks authored source under src/, and a porcelain status over that root reports no untracked files, so a clean CI checkout of this commit measures the same 17,585. `landed` is refreshed deliberately — checkRatchet returns `improved` BEFORE it evaluates staleness, so an entry left at 17,590 while the tree measures 17,585 would never expire at any age. PRIOR ENTRY: Lowered 17,592 -> 17,590 on 2026-10-03 by drain/rule-carrier-phase1-20261002, and the gain was INCIDENTAL rather than sought. The branch replaced `condense.ts::_lean_projection_settings` — an eight-line private reader of `lean_projection.mode` and `.hosts` — with one call to the shared `resolveLeanProjection`, net -2 lines in a file that sits ~1,195 lines PAST the 1500 cap, so every line removed there is one excess removed. Nothing was deleted to make a number: the projector reads the same settings file it always read, and `task sync` plus `task generate-tools` produce zero changes under `dist/agent-src/`, which is how that roadmap's risk 2 (one mode resolver moves the projector) was discharged. The gate reported the tree at 17,590 against a baseline of 17,592 and asked for exactly this lowering, so the gain cannot be silently given back. LOCAL READING, ADMISSIBLE ON THE SAME DISCRIMINATOR THIS FILE'S OTHER ENTRIES USE: the gate walks `src/` only, and a porcelain status over that root reported no untracked files, so a clean CI checkout of this commit measures the same 17,590. If CI reads anything else, CI's number is the correct one and this note is the record of why. PRIOR ENTRY: Lowered 18,230 -> 18,209 on 2026-09-03 by drain/artifact-location. `doctor --strict` needed 16 lines of integration wiring in cmd_doctor.ts, which sits ~2,100 lines PAST the 1500 cap so every line there costs one excess. The branch first came in at +137 and paid its own way down rather than raising the baseline: the strict semantics, threshold, kill switch, payload helper and argv fragments moved to _cli/_doctor_strict.ts (~160 lines, under the cap, costs nothing), taking it to +15; then the 37-line drift renderer moved to _cli/_doctor_emit.ts. Net -21. The renderer was chosen deliberately: pure rendering, two dependencies, no argparse involvement and therefore none of the byte-parity risk the parser surface carries against the retired Python implementation; nothing outside cmd_doctor.ts imported it. An AI council on the residual split (a: raise by 15 / d: descope the feature); neither was taken, because a parallel branch demonstrated the same day that paying down is achievable in this codebase, which is the evidence the split lacked. This gate's own test comment prescribes it: a commit that splits a god-file lowers the excess and must carry the lowered baseline. MERGE RECONCILIATION 2026-09-03, 18,209 -> 18,205: drain/wired-instruments and drain/artifact-location each lowered from the SAME 18,230 base in parallel -- the branch to 18,226 (net -4, run_continuation_hook.ts's termination ladder moved to _lib/continuation_ladder.ts and runtime_journal.ts's prose to _lib/outcome_vocabularies.ts, both under the cap) and main to 18,209 (net -21, the doctor --strict split above). Taking either side alone is wrong in a different direction: main's value silently discards the branch's earned -4, and the branch's value RAISES the baseline against main and weakens the gate. The committed number is neither -- it is the gate's own output on the merged tree, where both reductions apply. THIS LOCAL READING IS ADMISSIBLE HERE, and the discriminator matters because this file's ci-parity:local-only entry records a 165 -> 164 lowering that was reverted for exactly the opposite case: that count depends on how the environment resolves the projection surface, whereas this gate walks only SOURCE_ROOTS = ['src'] (check_source_size_budget.ts:88) counting excess lines over the 1500 ceiling, and `git status --porcelain -uall -- src/` reported ZERO untracked files, so a clean CI checkout of this commit measures the same 18,205. If CI reads anything else, CI's number is the correct one and this note is the record of why. LOWERED 18,205 -> 18,193 on 2026-09-03 by fix/release-curation-ask. The change adds a fifth publication guard, and its own additions landed at +10 excess: release.ts 2,008 -> 2,018, every line of which is past the 1500 cap. Paid down rather than baselined, in the two ways this gate's doctrine prescribes. The guard's rationale (~13 lines of docstring, including why prMerged is a parameter rather than a call-site if) lives in release_publication.ts, 915 lines and therefore UNDER the cap, so the prose costs nothing; and the two pure text helpers _splitlines and _rstrip moved out of release.ts into release_env.ts (333 lines, also under the cap), taking release.ts to 1,996 -- 12 BELOW where it started. The branch came in at +10 and leaves at -12. Recorded while moving them: _splitlines is duplicated a third and fourth time at adoption_report.ts:106 and readme_linter.ts:418; collapsing all three onto one definition touches three modules and was left out of this change rather than done silently. LOWERED 18,193 -> 18,180 on 2026-09-03 by fix/release-branch-reuse. The step-1 branch decision -- twenty lines of if/else in release.ts -- became one call to checkout_release_branch in release_publication.ts, which is 1,019 lines and therefore UNDER the 1500 cap, so the twenty lines plus a ~35-line rationale now cost nothing. release.ts 1,996 -> 1,983, every one of those lines being past the cap. The drill grew 765 -> 918 for two new scenarios and the snapshot/restore that keeps them from writing the real CHANGELOG, and it is under the cap too. A change that adds a feature and lowers the excess is the shape this gate's doctrine asks for; the alternative was a +13 raise for logic that had no business in the god-file. LOWERED 18,180 -> 18,068 on 2026-09-05 by fix/release-gate-producer-parity. The change wires the governance-mix obligation into the writer and the two local guards and adds a release-gate locality registry; its own additions to release.ts landed at +19 excess, every one of those lines past the 1500 cap. Paid down rather than baselined, in the way this entry's doctrine prescribes: the 132-line test-count-trend unit (_TEST_COUNT_LINE_RE, _TEST_LIST_MAX_BUFFER, _count_from_list_result, _count_tests_current, _previous_test_count_from_changelog, _render_test_trend_line) moved from release.ts into release_publication.ts, which is under the cap and where it now belongs on merit rather than only on arithmetic -- the same diff makes the missing `Tests: N` footer a section-level publication blocker, so the writer that emits the footer and the guard that refuses its absence sit in one module. release.ts 1,983 -> 1,871. All four names are re-exported from release.ts, so tests/scripts/release.test.ts is unchanged. LOCAL READING, ADMISSIBLE ON THIS ENTRY'S OWN DISCRIMINATOR: the gate walks only SOURCE_ROOTS=['src'] counting excess over the ceiling, and `git status --porcelain -uall -- src/` reports ZERO untracked files with the two new src/ files staged, so a clean CI checkout of this commit measures the same 18,068. If CI reads anything else, CI's number is the correct one and this note is the record of why."
|
|
42
42
|
},
|
|
43
43
|
"ci-parity:local-only": {
|
|
@@ -138,11 +138,12 @@
|
|
|
138
138
|
# above, and named anyway rather than left implicit — do not delete as
|
|
139
139
|
# duplication:
|
|
140
140
|
#
|
|
141
|
-
# · Some hosts key a prompt cache on a hash of the workspace file list.
|
|
142
|
-
# index is rewritten
|
|
143
|
-
# -
|
|
144
|
-
# never edits. An entry a reader
|
|
145
|
-
# is what makes that cost
|
|
141
|
+
# · Some hosts key a prompt cache on a hash of the workspace file list. After
|
|
142
|
+
# `agent-config code-graph auto-refresh on` the index is rewritten at every
|
|
143
|
+
# agent session start (the `code-graph-refresh` hook concern), so it is the
|
|
144
|
+
# most frequently-changing file a consumer never edits. An entry a reader
|
|
145
|
+
# can find by grepping the index's own name is what makes that cost
|
|
146
|
+
# traceable.
|
|
146
147
|
# · The twin and the lock are created beside the index by machinery a
|
|
147
148
|
# consumer never invokes directly; naming them says they are ours.
|
|
148
149
|
#
|