@event4u/agent-config 17.3.0 → 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/CHANGELOG.md +164 -342
- package/CREDITS.md +2 -2
- package/README.md +1 -1
- package/dist/agent-src/skills/code-intelligence/SKILL.md +3 -0
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/cli/registry.js +2 -2
- package/dist/cli-delegate/{chunk-DHSSP7V3.js → chunk-5AYJGUA3.js} +0 -2
- package/dist/cli-delegate/chunk-DIFZBP4G.js +1336 -0
- package/dist/cli-delegate/{chunk-MT2WOOCY.js → chunk-WY5ZZPGL.js} +2 -2
- package/dist/cli-delegate/{chunk-ORJPBER2.js → chunk-X6LZ7W5A.js} +73 -10
- package/dist/cli-delegate/cmd_conformance.js +175 -183
- 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_handoff.js +2 -2
- package/dist/cli-delegate/cmd_memory_get.js +1 -1
- 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_update.js +24 -13
- package/dist/cli-delegate/cmd_upgrade.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 +56 -27
- package/dist/hooks/code_graph_refresh.chunk.cjs.sha256 +1 -1
- package/dist/hooks/dispatch.js +982 -929
- package/dist/hooks/dispatch.sha256 +1 -1
- package/dist/hooks/egress_engine.chunk.cjs +56 -6
- 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/mcp/registry-manifest.json +1 -1
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +71259 -66437
- package/dist/scripts/condense.js +9 -6
- package/package.json +4 -1
- package/src/config/evaluator-budgets.json +9 -8
- package/src/config/gate-violation-baselines.json +2 -2
- package/src/config/hook-bundle-budget.json +31 -6
- package/src/config/packed-binary-manifest.json +9 -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_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 +3 -2
- package/src/scripts/_lib/confusables.ts +0 -19
- package/src/scripts/_lib/egress_normalize.ts +53 -23
- 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/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/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/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/check_dependency_floors.ts +7 -0
- package/src/scripts/check_egress_mutations.ts +1 -0
- package/src/scripts/code_graph/build.ts +67 -3
- package/src/scripts/code_graph/cli.ts +131 -28
- package/src/scripts/code_graph/conventions_default.ts +20 -1
- 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 +4 -1
- package/src/scripts/code_graph/extract_more.ts +137 -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/map.ts +22 -13
- package/src/scripts/code_graph/map_model.ts +67 -12
- package/src/scripts/code_graph/map_verify.ts +68 -5
- package/src/scripts/code_graph/map_viewer/viewer.css +12 -0
- package/src/scripts/code_graph/map_viewer/viewer.js +45 -15
- 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/catalog.ts +14 -5
- package/src/scripts/code_graph/providers/django.ts +52 -9
- package/src/scripts/code_graph/providers/index.ts +2 -0
- package/src/scripts/code_graph/providers/rails.ts +204 -0
- package/src/scripts/code_graph/providers/spring.ts +38 -1
- package/src/scripts/code_graph/query.ts +9 -9
- package/src/scripts/code_graph/refresh_lock.ts +12 -8
- package/src/scripts/code_graph/repo_identity.ts +169 -0
- package/src/scripts/code_graph/sqlite_store.ts +22 -25
- package/src/scripts/code_graph/types.ts +6 -2
- package/src/scripts/condense.ts +6 -6
- package/src/scripts/hook_chunks.mjs +7 -0
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +20 -17
- package/src/scripts/hooks/code_graph_refresh_hook.ts +10 -7
- 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 +4 -0
- package/src/scripts/hooks/user_notice.ts +105 -0
- package/src/scripts/lint_harvest_provenance.ts +137 -11
- package/src/scripts/mcp_server/consumer_tool_catalog.json +69 -15
- package/src/scripts/mcp_server/graph_tools.ts +161 -41
- package/src/scripts/network_sources.ts +24 -6
- package/src/scripts/schemas/provenance-mechanism.schema.json +46 -0
- package/src/scripts/update_notice_hook.ts +75 -7
- package/src/vendor/grammars/README.md +7 -6
- package/src/vendor/grammars/tree-sitter-ruby.wasm +0 -0
- /package/dist/cli-delegate/{chunk-FKYZOWVD.js → chunk-QBAFP67O.js} +0 -0
- /package/dist/cli-delegate/{chunk-BMGUGSY6.js → chunk-TQG6UMPC.js} +0 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A repository's identity on this machine (ADR-299, council decision O2).
|
|
3
|
+
*
|
|
4
|
+
* `repoId` is 12 hex of an HMAC-SHA256, keyed by a random key created once
|
|
5
|
+
* under the user-global `runtime/projects/`, over the canonical origin URL —
|
|
6
|
+
* userinfo, tokens, query and fragment removed, host lower-cased, default port
|
|
7
|
+
* dropped, ssh / scp / https forms and a trailing `.git` collapsed. Without a
|
|
8
|
+
* remote the main checkout's realpath stands in. Keyed rather than a plain hash
|
|
9
|
+
* because a hosting URL is dictionary-guessable and may carry a token.
|
|
10
|
+
*
|
|
11
|
+
* A linked worktree keeps its parent's `repoId` and gets an `instance`, so its
|
|
12
|
+
* writable caches never collide with the main checkout's while estate queries
|
|
13
|
+
* still count one project. Two separate clones of one origin share `repoId` too,
|
|
14
|
+
* so `checkout` — keyed over the main checkout's realpath — is what keeps their
|
|
15
|
+
* writable homes apart.
|
|
16
|
+
*
|
|
17
|
+
* File-based like `_lib/git_common_dir.ts`: an inherited `GIT_DIR` would
|
|
18
|
+
* redirect a `git config` subprocess to the wrong repository.
|
|
19
|
+
*/
|
|
20
|
+
import { createHmac, randomBytes } from 'node:crypto';
|
|
21
|
+
import * as fs from 'node:fs';
|
|
22
|
+
import * as path from 'node:path';
|
|
23
|
+
|
|
24
|
+
import { git_common_dir } from '../_lib/git_common_dir.js';
|
|
25
|
+
import { type EnvMap, event4u_root } from '../_lib/user_global_paths.js';
|
|
26
|
+
|
|
27
|
+
export interface RepoIdentity {
|
|
28
|
+
repoId: string;
|
|
29
|
+
/** Set for a linked worktree only. */
|
|
30
|
+
instance: string | null;
|
|
31
|
+
/** 8 hex over the main checkout's realpath: distinct per clone, shared by its worktrees. */
|
|
32
|
+
checkout: string;
|
|
33
|
+
source: 'origin' | 'realpath';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const DEFAULT_PORTS: Record<string, string> = { 'ssh:': '22', 'git+ssh:': '22', 'https:': '443', 'http:': '80', 'git:': '9418' };
|
|
37
|
+
|
|
38
|
+
export function projectsDir(env?: EnvMap | null): string {
|
|
39
|
+
return path.join(event4u_root(env), 'runtime', 'projects');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** `dir` overrides the projects directory, for a caller (advisories) that carries its own. */
|
|
43
|
+
export function machineKeyPath(env?: EnvMap | null, dir: string = projectsDir(env)): string {
|
|
44
|
+
return path.join(dir, 'machine.key');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The machine key, created on first use. Published with a hard link so a
|
|
49
|
+
* concurrent first use either wins or reads the winner's complete key — never
|
|
50
|
+
* an empty file. A key that exists but is malformed throws: replacing it would
|
|
51
|
+
* silently re-key every repository on the machine.
|
|
52
|
+
*/
|
|
53
|
+
export function machineKey(env?: EnvMap | null, dir?: string): Buffer {
|
|
54
|
+
const p = machineKeyPath(env, dir);
|
|
55
|
+
const read = (): Buffer => {
|
|
56
|
+
const hex = fs.readFileSync(p, 'utf-8').trim();
|
|
57
|
+
if (!/^[0-9a-f]{64}$/.test(hex)) throw new Error(`malformed machine key: ${p}`);
|
|
58
|
+
return Buffer.from(hex, 'hex');
|
|
59
|
+
};
|
|
60
|
+
if (fs.existsSync(p)) return read();
|
|
61
|
+
fs.mkdirSync(path.dirname(p), { recursive: true });
|
|
62
|
+
const tmp = `${p}.${process.pid}-${randomBytes(4).toString('hex')}.tmp`;
|
|
63
|
+
fs.writeFileSync(tmp, `${randomBytes(32).toString('hex')}\n`, { mode: 0o600 });
|
|
64
|
+
try {
|
|
65
|
+
fs.linkSync(tmp, p);
|
|
66
|
+
} catch (e) {
|
|
67
|
+
if ((e as NodeJS.ErrnoException).code !== 'EEXIST') throw e;
|
|
68
|
+
} finally {
|
|
69
|
+
fs.rmSync(tmp, { force: true });
|
|
70
|
+
}
|
|
71
|
+
return read();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function trimPath(p: string): string {
|
|
75
|
+
return p
|
|
76
|
+
.replace(/\/{2,}/g, '/')
|
|
77
|
+
.replace(/^\/+|\/+$/g, '')
|
|
78
|
+
.replace(/\.git$/i, '')
|
|
79
|
+
.replace(/\/+$/, '');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* The credential-free form two spellings of one remote share. A relative local
|
|
84
|
+
* path resolves against `base`, the repository root, because the process cwd
|
|
85
|
+
* is wherever the CLI happened to be started.
|
|
86
|
+
*/
|
|
87
|
+
export function canonicalOrigin(raw: string, base?: string): string {
|
|
88
|
+
const url = raw.trim();
|
|
89
|
+
const scp = /^(?:[^@/]+@)?([^:/]+):(?!\/\/)(.+)$/.exec(url);
|
|
90
|
+
if (!url.includes('://') && scp && !/^[a-zA-Z]:[\\/]/.test(url)) {
|
|
91
|
+
return `${(scp[1] as string).toLowerCase()}/${trimPath(scp[2] as string)}`;
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
const u = new URL(url);
|
|
95
|
+
if (u.protocol === 'file:') return `file:${trimPath(decodeURIComponent(u.pathname))}`;
|
|
96
|
+
const port = u.port && u.port !== DEFAULT_PORTS[u.protocol] ? `:${u.port}` : '';
|
|
97
|
+
return `${u.hostname.toLowerCase()}${port}/${trimPath(decodeURIComponent(u.pathname))}`;
|
|
98
|
+
} catch {
|
|
99
|
+
return `file:${trimPath(base === undefined ? path.resolve(url) : path.resolve(base, url))}`;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** The `origin` URL, else the first remote's, read from the common git config. */
|
|
104
|
+
export function remoteUrl(root: string): string | null {
|
|
105
|
+
const common = git_common_dir(root);
|
|
106
|
+
if (common === null) return null;
|
|
107
|
+
let text: string;
|
|
108
|
+
try {
|
|
109
|
+
text = fs.readFileSync(path.join(common, 'config'), 'utf-8');
|
|
110
|
+
} catch {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
const urls = new Map<string, string>();
|
|
114
|
+
let remote: string | null = null;
|
|
115
|
+
for (const line of text.split(/\r?\n/)) {
|
|
116
|
+
const section = /^\s*\[\s*remote\s+"([^"]+)"\s*\]/.exec(line);
|
|
117
|
+
if (section) {
|
|
118
|
+
remote = section[1] as string;
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
if (/^\s*\[/.test(line)) {
|
|
122
|
+
remote = null;
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
const kv = /^\s*url\s*=\s*(.+?)\s*$/.exec(line);
|
|
126
|
+
if (remote !== null && kv && !urls.has(remote)) urls.set(remote, (kv[1] as string).replace(/^"|"$/g, ''));
|
|
127
|
+
}
|
|
128
|
+
return urls.get('origin') ?? urls.values().next().value ?? null;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function realpathOr(p: string): string {
|
|
132
|
+
try {
|
|
133
|
+
return fs.realpathSync(p);
|
|
134
|
+
} catch {
|
|
135
|
+
return path.resolve(p);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function hmac(key: Buffer, value: string): string {
|
|
140
|
+
return createHmac('sha256', key).update(value).digest('hex');
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export function repoIdentity(root: string, env?: EnvMap | null, dir?: string): RepoIdentity {
|
|
144
|
+
const key = machineKey(env, dir);
|
|
145
|
+
const real = realpathOr(root);
|
|
146
|
+
const common = git_common_dir(real);
|
|
147
|
+
let linked = false;
|
|
148
|
+
try {
|
|
149
|
+
linked = !fs.statSync(path.join(real, '.git')).isDirectory();
|
|
150
|
+
} catch {
|
|
151
|
+
linked = false;
|
|
152
|
+
}
|
|
153
|
+
const origin = remoteUrl(real);
|
|
154
|
+
const main = common !== null && path.basename(common) === '.git' ? path.dirname(common) : real;
|
|
155
|
+
let source: RepoIdentity['source'] = 'origin';
|
|
156
|
+
let canonical: string;
|
|
157
|
+
if (origin !== null) {
|
|
158
|
+
canonical = `origin:${canonicalOrigin(origin, main)}`;
|
|
159
|
+
} else {
|
|
160
|
+
source = 'realpath';
|
|
161
|
+
canonical = `path:${main}`;
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
repoId: hmac(key, canonical).slice(0, 12),
|
|
165
|
+
instance: linked ? hmac(key, `instance:${real}`).slice(0, 8) : null,
|
|
166
|
+
checkout: hmac(key, `checkout:${main}`).slice(0, 8),
|
|
167
|
+
source,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
@@ -56,7 +56,7 @@ import type { CodeEdge, CodeGraph, CodeNode } from './types.js';
|
|
|
56
56
|
* 4 → 5 (`road-to-graph-providers-for-every-stack` 2.1): `edges` gained
|
|
57
57
|
* `provider_id`, the convention provider that drew a convention edge.
|
|
58
58
|
*/
|
|
59
|
-
export const GRAPH_STORE_VERSION =
|
|
59
|
+
export const GRAPH_STORE_VERSION = 6;
|
|
60
60
|
|
|
61
61
|
/**
|
|
62
62
|
* Edge count at or above which the indexed read path replaces the blob path.
|
|
@@ -81,11 +81,10 @@ export function sqliteTwinPath(jsonPath: string): string {
|
|
|
81
81
|
* JSON path remains the source of truth either way.
|
|
82
82
|
*
|
|
83
83
|
* Storage model: nodes/edges land in real tables (queryable, and the FTS-free
|
|
84
|
-
* structure the rollback triggers measure)
|
|
85
|
-
* the
|
|
86
|
-
* byte-identical answers without re-deriving key order.
|
|
84
|
+
* structure the rollback triggers measure). The JSON is the only full copy;
|
|
85
|
+
* the twin is a disposable, rebuildable projection of it.
|
|
87
86
|
*/
|
|
88
|
-
export function emitSqliteTwin(graph: CodeGraph,
|
|
87
|
+
export function emitSqliteTwin(graph: CodeGraph, jsonPath: string): boolean {
|
|
89
88
|
if (!isSqliteAvailableSync()) return false;
|
|
90
89
|
const twin = sqliteTwinPath(jsonPath);
|
|
91
90
|
const tmp = `${twin}.tmp-${process.pid}`;
|
|
@@ -120,7 +119,6 @@ export function emitSqliteTwin(graph: CodeGraph, serialized: string, jsonPath: s
|
|
|
120
119
|
meta.run('source_checksum', graph.source_checksum);
|
|
121
120
|
meta.run('json_size', String(stat.size));
|
|
122
121
|
meta.run('json_mtime_ms', String(stat.mtimeMs));
|
|
123
|
-
meta.run('graph_json', serialized);
|
|
124
122
|
// Counts live in meta so a reader can pick its path from one row
|
|
125
123
|
// instead of a COUNT(*) over the table it is deciding whether to
|
|
126
124
|
// read at all.
|
|
@@ -176,39 +174,38 @@ export function emitSqliteTwin(graph: CodeGraph, serialized: string, jsonPath: s
|
|
|
176
174
|
}
|
|
177
175
|
|
|
178
176
|
/**
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
177
|
+
* Whether the twin beside `jsonPath` mirrors it: present, the current store
|
|
178
|
+
* version, and recorded against the JSON's present size and mtime. A corrupt
|
|
179
|
+
* twin is a non-event — it is dropped so the next load re-emits it.
|
|
180
|
+
*
|
|
181
|
+
* The twin used to carry the whole serialized graph a second time and this
|
|
182
|
+
* returned it; that blob was the same bytes as the JSON and doubled the twin
|
|
183
|
+
* (road-to-a-graph-that-follows-you D2). The JSON is the only full copy now.
|
|
183
184
|
*/
|
|
184
|
-
export function
|
|
185
|
-
if (!isSqliteAvailableSync()) return
|
|
185
|
+
export function twinIsCurrent(jsonPath: string): boolean {
|
|
186
|
+
if (!isSqliteAvailableSync()) return false;
|
|
186
187
|
const twin = sqliteTwinPath(jsonPath);
|
|
187
|
-
if (!fs.existsSync(twin)) return
|
|
188
|
+
if (!fs.existsSync(twin)) return false;
|
|
188
189
|
let stat: fs.Stats;
|
|
189
190
|
try {
|
|
190
191
|
stat = fs.statSync(jsonPath);
|
|
191
192
|
} catch {
|
|
192
|
-
return
|
|
193
|
+
return false; // canonical JSON gone — the twin has no truth to mirror
|
|
193
194
|
}
|
|
194
195
|
try {
|
|
195
196
|
const { DatabaseSync } = loadSqliteSync('code_graph.sqlite_store');
|
|
196
197
|
const db = new DatabaseSync(twin, { readOnly: true });
|
|
197
198
|
try {
|
|
198
|
-
if (readUserVersion(db) !== GRAPH_STORE_VERSION) return
|
|
199
|
+
if (readUserVersion(db) !== GRAPH_STORE_VERSION) return false;
|
|
199
200
|
const rows = db.prepare('SELECT key, value FROM meta').all() as { key: string; value: string }[];
|
|
200
201
|
const meta = new Map(rows.map((r) => [r.key, r.value]));
|
|
201
|
-
|
|
202
|
-
if (meta.get('json_mtime_ms') !== String(stat.mtimeMs)) return null;
|
|
203
|
-
const serialized = meta.get('graph_json');
|
|
204
|
-
return serialized && serialized.length > 0 ? serialized : null;
|
|
202
|
+
return meta.get('json_size') === String(stat.size) && meta.get('json_mtime_ms') === String(stat.mtimeMs);
|
|
205
203
|
} finally {
|
|
206
204
|
db.close();
|
|
207
205
|
}
|
|
208
206
|
} catch {
|
|
209
|
-
// Corrupt twin is a non-event: drop it so the next build re-emits.
|
|
210
207
|
fs.rmSync(twin, { force: true });
|
|
211
|
-
return
|
|
208
|
+
return false;
|
|
212
209
|
}
|
|
213
210
|
}
|
|
214
211
|
|
|
@@ -218,9 +215,9 @@ export function loadSerializedFromTwin(jsonPath: string): string | null {
|
|
|
218
215
|
*
|
|
219
216
|
* Every export it had took a PATH and returned the whole graph: the serialized
|
|
220
217
|
* blob, or a pair of counts. So "the query path prefers SQLite" was true and
|
|
221
|
-
* bought nothing —
|
|
222
|
-
*
|
|
223
|
-
*
|
|
218
|
+
* bought nothing — the loader handed back the entire serialization, and the
|
|
219
|
+
* caller then parsed it and built a `Map` over every node and every edge. The
|
|
220
|
+
* twin was a cheaper blob transport, never an index.
|
|
224
221
|
*
|
|
225
222
|
* These reads take an id, a label, or a file, and touch only the rows that
|
|
226
223
|
* answer. Statements are prepared once per handle because a BFS calls
|
|
@@ -315,7 +312,7 @@ function toEdge(r: EdgeRow): CodeEdge {
|
|
|
315
312
|
/**
|
|
316
313
|
* Open the twin for INDEXED reads, or null when it cannot serve them.
|
|
317
314
|
*
|
|
318
|
-
* Null on exactly the conditions `
|
|
315
|
+
* Null on exactly the conditions `twinIsCurrent` refuses on —
|
|
319
316
|
* absent, stale against the JSON's size/mtime, corrupt, version-mismatched, no
|
|
320
317
|
* `node:sqlite` — so the two paths agree about when the twin is trustworthy
|
|
321
318
|
* and a caller never has to ask twice.
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
/** Launch set — the stacks this suite's consumers actually run. */
|
|
12
|
-
export type Lang = 'php' | 'typescript' | 'javascript' | 'python' | 'go' | 'java' | 'csharp';
|
|
12
|
+
export type Lang = 'php' | 'typescript' | 'javascript' | 'python' | 'go' | 'java' | 'csharp' | 'ruby';
|
|
13
13
|
|
|
14
14
|
/** Same scale as `discovery_graph.ts::EdgeConfidence` (reused, not forked). */
|
|
15
15
|
export type EdgeConfidence = 'EXTRACTED' | 'INFERRED' | 'AMBIGUOUS';
|
|
@@ -104,6 +104,8 @@ export type ResolvedVia =
|
|
|
104
104
|
| 'fs-route'
|
|
105
105
|
/** Stated by a compiler-grade SCIP index the project ships (`scip_reader.ts`). */
|
|
106
106
|
| 'compiler-index'
|
|
107
|
+
/** C#: the one type of that name in the namespaces the file can see (its own, their parents, its `using`s). */
|
|
108
|
+
| 'namespace-scope'
|
|
107
109
|
| 'test-import'
|
|
108
110
|
| 'name-lookup'
|
|
109
111
|
| 'dynamic'
|
|
@@ -159,7 +161,7 @@ export type EdgeProvider =
|
|
|
159
161
|
// One space-separated string per list: this module ships in the hook bundle,
|
|
160
162
|
// where an array literal costs a line per entry. `Words` splits it in the type.
|
|
161
163
|
const STATED_WORDS =
|
|
162
|
-
'same-file import-specifier path-alias psr4 route-table directive-scan schema-call orm-relation di-binding compiler-index test-import literal-path literal-dotted fs-route' as const;
|
|
164
|
+
'same-file import-specifier path-alias psr4 route-table directive-scan schema-call orm-relation di-binding compiler-index namespace-scope test-import literal-path literal-dotted fs-route' as const;
|
|
163
165
|
const GUESS_WORDS = 'name-lookup dynamic foreign' as const;
|
|
164
166
|
type Words<S extends string> = S extends `${infer H} ${infer T}` ? H | Words<T> : S;
|
|
165
167
|
/** Mechanisms in neither list; must be `never` (a test asserts it). */
|
|
@@ -362,6 +364,7 @@ export const EXT_LANG: Readonly<Record<string, Lang>> = {
|
|
|
362
364
|
'.go': 'go',
|
|
363
365
|
'.java': 'java',
|
|
364
366
|
'.cs': 'csharp',
|
|
367
|
+
'.rb': 'ruby',
|
|
365
368
|
'.vue': 'typescript',
|
|
366
369
|
};
|
|
367
370
|
|
|
@@ -374,6 +377,7 @@ export const GRAMMAR_WASM: Readonly<Record<Lang, string>> = {
|
|
|
374
377
|
go: 'tree-sitter-go.wasm',
|
|
375
378
|
java: 'tree-sitter-java.wasm',
|
|
376
379
|
csharp: 'tree-sitter-c_sharp.wasm',
|
|
380
|
+
ruby: 'tree-sitter-ruby.wasm',
|
|
377
381
|
};
|
|
378
382
|
|
|
379
383
|
/** The single ABI version the pinned grammar set is built against. */
|
package/src/scripts/condense.ts
CHANGED
|
@@ -2191,11 +2191,11 @@ export function generate_plugin_command_skills(): number {
|
|
|
2191
2191
|
const pointer_dir = path.join(MODULE_STATE.PLUGIN_SKILLS_DIR, PLUGIN_POINTER_SLUG);
|
|
2192
2192
|
_mkdirp(pointer_dir);
|
|
2193
2193
|
const pointer_file = path.join(pointer_dir, 'SKILL.md');
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
fs.writeFileSync(
|
|
2194
|
+
for (const file of [pointer_file, path.join(MODULE_STATE.PROJECT_ROOT, '.github', 'plugin', 'skills', PLUGIN_POINTER_SLUG, 'SKILL.md')]) {
|
|
2195
|
+
if (_isSymlink(file)) {
|
|
2196
|
+
fs.unlinkSync(file);
|
|
2197
|
+
}
|
|
2198
|
+
if (!_isFile(file) || fs.readFileSync(file, 'utf-8') !== PLUGIN_POINTER_SKILL_BODY) { fs.mkdirSync(path.dirname(file), { recursive: true }); fs.writeFileSync(file, PLUGIN_POINTER_SKILL_BODY); }
|
|
2199
2199
|
}
|
|
2200
2200
|
|
|
2201
2201
|
// 2. Prune every other skill dir so the tree converges to shim shape
|
|
@@ -2226,7 +2226,7 @@ export function generate_plugin_command_skills(): number {
|
|
|
2226
2226
|
}
|
|
2227
2227
|
}
|
|
2228
2228
|
|
|
2229
|
-
let msg = ' ✅ Plugin skills: bootstrap shim (1 pointer skill) in .claude-plugin/skills/';
|
|
2229
|
+
let msg = ' ✅ Plugin skills: bootstrap shim (1 pointer skill) in .claude-plugin/skills/ and .github/plugin/skills/';
|
|
2230
2230
|
if (removed_dirs) {
|
|
2231
2231
|
msg += ` (${removed_dirs} content entries pruned)`;
|
|
2232
2232
|
}
|
|
@@ -49,6 +49,13 @@ export const HOOK_CHUNKS = Object.freeze([
|
|
|
49
49
|
entry: 'src/scripts/hooks/code_graph_refresh_hook.ts',
|
|
50
50
|
outfile: 'dist/hooks/code_graph_refresh.chunk.cjs',
|
|
51
51
|
}),
|
|
52
|
+
// `yaml` external for the reason given at `chat_history`: the concern
|
|
53
|
+
// reads one user-global settings file with it.
|
|
54
|
+
Object.freeze({
|
|
55
|
+
entry: 'src/scripts/update_notice_hook.ts',
|
|
56
|
+
outfile: 'dist/hooks/update_notice.chunk.cjs',
|
|
57
|
+
external: Object.freeze(['yaml']),
|
|
58
|
+
}),
|
|
52
59
|
]);
|
|
53
60
|
|
|
54
61
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"fingerprint":"99ce8f951850440231d5d39bd342b1f53d09db94ae71722605bfab2c4dcb5dd0:111523","body_fingerprint":"7da30ee3fc8e8c873a295d7035ba34df3eb3f07e5a47d7dc3983bae823c3395c:21398","manifest":{"schema_version":1,"concerns":{"chat-history":{"script":"src/scripts/chat_history.ts","args":["hook-dispatch"],"fail_closed":false,"severity":"advisory","effect":"telemetry","needs_payload_bodies":["result"]},"hot-context":{"script":"src/scripts/hot_context_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"memory"},"handoff-context":{"script":"src/scripts/handoff_context_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"context"},"roadmap-progress":{"script":"src/scripts/roadmap_progress_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"formatting","needs_payload_bodies":["input"]},"onboarding-gate":{"script":"src/scripts/onboarding_gate_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification"},"context-hygiene":{"script":"src/scripts/context_hygiene_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"verify-before-complete":{"script":"src/scripts/before_complete_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","needs_payload_bodies":["input","result"]},"ship-diff-volume":{"script":"src/scripts/hooks/ship_diff_volume_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","needs_payload_bodies":["input"]},"minimal-safe-diff":{"script":"src/scripts/minimal_safe_diff_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","needs_payload_bodies":["input"]},"injection-scan":{"script":"src/scripts/injection_scan_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","needs_payload_bodies":["input","result"]},"block-no-verify":{"script":"src/scripts/hooks/block_no_verify.ts","args":[],"fail_closed":true,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"block-kernel-rule-writes":{"script":"src/scripts/hooks/block_kernel_rule_writes.ts","args":[],"fail_closed":true,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"block-plumbing-writes":{"script":"src/scripts/hooks/block_plumbing_writes.ts","args":[],"fail_closed":true,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"one-question-per-ask":{"script":"src/scripts/hooks/one_question_per_ask_hook.ts","args":[],"fail_closed":false,"severity":"blocking","effect":"permission","tools":["AskUserQuestion","AskQuestion","UserQuestion","ask_user_question","ask_question","user_question"],"needs_payload_bodies":["input"]},"block-speaking-inbox-dir":{"script":"src/scripts/hooks/block_speaking_inbox_dir.ts","args":[],"fail_closed":false,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"block-credential-reads":{"script":"src/scripts/hooks/block_credential_reads.ts","args":[],"fail_closed":false,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"block-config-weakening":{"script":"src/scripts/hooks/block_config_weakening.ts","args":[],"fail_closed":false,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"rtk-wrap":{"script":"src/scripts/hooks/rtk_wrap_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"formatting","needs_payload_bodies":["input"]},"design-slop":{"script":"src/scripts/hooks/design_slop_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","needs_payload_bodies":["input"]},"design-pass":{"script":"src/scripts/hooks/design_pass_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification","needs_payload_bodies":["input"]},"design-pass-stop":{"script":"src/scripts/hooks/design_pass_hook.ts","args":["--slot","stop"],"fail_closed":false,"severity":"advisory","effect":"notification"},"ui-route-nudge":{"script":"src/scripts/hooks/ui_route_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification","needs_payload_bodies":["input"]},"suggestion-capture":{"script":"src/scripts/hooks/suggestion_capture_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"chain-nudge":{"script":"src/scripts/hooks/chain_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification","needs_payload_bodies":["input"]},"code-graph-context":{"script":"src/scripts/hooks/code_graph_context_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"context","tools":["Grep","Glob","Read","Bash"],"needs_payload_bodies":["input"]},"memory-learn":{"script":"src/scripts/memory_learn_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"memory"},"first-run-gate":{"script":"src/scripts/first_run_gate_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification"},"profile-staleness":{"script":"src/scripts/profile_staleness_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification"},"wrapper-freshness":{"script":"src/scripts/wrapper_freshness_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification"},"surface-probe":{"script":"src/scripts/surface_probe_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"team-review-gate":{"script":"src/scripts/team_review_gate_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification"},"pr-url-reminder":{"script":"src/scripts/pr_url_reminder_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification","needs_payload_bodies":["input","result"]},"push-settle":{"script":"src/scripts/hooks/push_settle_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","needs_payload_bodies":["input","result"]},"language-mirror":{"script":"src/scripts/language_mirror_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"context"},"git-authorization":{"script":"src/scripts/git_authorization_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification"},"evidence-independence":{"script":"src/scripts/hooks/evidence_independence.ts","args":[],"fail_closed":false,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"session-canary":{"script":"src/scripts/session_canary_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"context"},"council-availability":{"script":"src/scripts/council_availability_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification"},"telemetry-disclosure":{"script":"src/scripts/telemetry_disclosure_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification"},"telemetry-flush":{"script":"src/scripts/hooks/telemetry_flush_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"self-repair":{"script":"src/scripts/self_repair_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"session-register":{"script":"src/scripts/session_register_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"orchestration-record":{"script":"src/scripts/hooks/orchestration_record_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry","tools":["Agent","Task"],"needs_payload_bodies":["input","result"]},"telemetry-usage":{"script":"src/scripts/hooks/telemetry_usage_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry","tools":["Skill"],"needs_payload_bodies":["input"]},"mcp-usage-observation":{"script":"src/scripts/hooks/mcp_usage_observation_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"delegation-nudge":{"script":"src/scripts/hooks/delegation_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification","nudge_rank":1},"skill-route":{"script":"src/scripts/hooks/skill_route_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"context","nudge_rank":2},"rule-inject":{"script":"src/scripts/hooks/rule_inject_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"context","needs_payload_bodies":["input"]},"obligation-settle":{"script":"src/scripts/hooks/obligation_settle_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification"},"end-review-nudge":{"script":"src/scripts/hooks/end_review_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification","skip_on_refusal_retry":true},"review-baseline":{"script":"src/scripts/hooks/review_baseline_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"turn-end-gate":{"script":"src/scripts/hooks/turn_end_gate_hook.ts","args":[],"fail_closed":false,"severity":"blocking","effect":"permission"},"comment-discipline":{"script":"src/scripts/hooks/comment_discipline_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","tools":["Write","Edit"],"needs_payload_bodies":["input"]},"edit-shape":{"script":"src/scripts/hooks/edit_shape_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","tools":["Write"],"needs_payload_bodies":["input"]},"reread-guard":{"script":"src/scripts/hooks/reread_guard_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","tools":["Read","Edit","Write"],"needs_payload_bodies":["input"]},"memory-recall":{"script":"src/scripts/hooks/memory_recall_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"memory","tools":["Bash","Edit","Write","MultiEdit","str-replace-editor","save-file","launch-process"],"needs_payload_bodies":["input"]},"session-eol":{"script":"src/scripts/hooks/session_eol_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification"},"interruption-ledger":{"script":"src/scripts/hooks/interruption_ledger_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry","skip_on_refusal_retry":true},"instructions-observer":{"script":"src/scripts/hooks/instructions_observer_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"code-graph-refresh":{"script":"src/scripts/hooks/code_graph_refresh_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"execution"},"subagent-ledger":{"script":"src/scripts/hooks/subagent_ledger_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"tool-result-bytes":{"script":"src/scripts/hooks/tool_result_bytes_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"spawn-guard-shadow":{"script":"src/scripts/hooks/spawn_guard_shadow_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry","tools":["Agent","Task","SendMessage"],"needs_payload_bodies":["input","result"],"payload_fields":["name","subagent_type","to","recipient_kind","agentId"]},"host-rate-marker":{"script":"src/scripts/hooks/host_rate_marker_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"source-first-gate":{"script":"src/scripts/hooks/source_first_gate_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry","needs_payload_bodies":["input"]},"journal-record":{"script":"src/scripts/hooks/journal_record_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"}},"roles":{"worker":{"drop":["delegation-nudge","skill-route","end-review-nudge","review-baseline","council-availability","team-review-gate","self-repair","session-eol","interruption-ledger"]}},"platforms":{"augment":{"ask":"text","session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register","code-graph-refresh"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress","telemetry-flush"],"stop":["chat-history","verify-before-complete","self-repair","session-register","roadmap-progress","design-pass-stop"],"pre_tool_use":["block-no-verify","evidence-independence","block-kernel-rule-writes","block-plumbing-writes","block-config-weakening","block-speaking-inbox-dir","block-credential-reads","rtk-wrap","design-slop","ui-route-nudge","code-graph-context","chain-nudge","ship-diff-volume","reread-guard","memory-recall"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","push-settle","orchestration-record","telemetry-usage","mcp-usage-observation","tool-result-bytes","edit-shape","comment-discipline","design-pass"]},"claude":{"ask":"native","session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register","review-baseline","journal-record","rule-inject","code-graph-refresh"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress","telemetry-flush","journal-record"],"stop":["chat-history","verify-before-complete","team-review-gate","end-review-nudge","obligation-settle","turn-end-gate","self-repair","session-register","session-eol","interruption-ledger","roadmap-progress","design-pass-stop","suggestion-capture","journal-record"],"user_prompt_submit":["chat-history","verify-before-complete","minimal-safe-diff","language-mirror","delegation-nudge","skill-route","git-authorization","session-canary","self-repair","session-register","rule-inject","suggestion-capture","journal-record"],"pre_tool_use":["block-no-verify","evidence-independence","block-kernel-rule-writes","block-plumbing-writes","block-config-weakening","block-speaking-inbox-dir","block-credential-reads","one-question-per-ask","rtk-wrap","design-slop","ui-route-nudge","code-graph-context","chain-nudge","ship-diff-volume","reread-guard","spawn-guard-shadow","source-first-gate","memory-recall"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","push-settle","orchestration-record","telemetry-usage","mcp-usage-observation","tool-result-bytes","edit-shape","comment-discipline","language-mirror","design-pass","journal-record","spawn-guard-shadow"],"pre_compact":["language-mirror","rule-inject","journal-record"],"subagent_start":["subagent-ledger","journal-record"],"subagent_stop":["subagent-ledger","journal-record"],"agent_error":["host-rate-marker"],"instructions_loaded":["instructions-observer"]},"cowork":{"ask":"text","session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register","code-graph-refresh"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress","telemetry-flush"],"stop":["chat-history","verify-before-complete","self-repair","session-register","roadmap-progress","design-pass-stop"],"user_prompt_submit":["chat-history","verify-before-complete","minimal-safe-diff","language-mirror","git-authorization","session-canary","self-repair","session-register"],"pre_tool_use":["block-no-verify","evidence-independence","block-kernel-rule-writes","block-plumbing-writes","block-config-weakening","block-speaking-inbox-dir","block-credential-reads","rtk-wrap","design-slop","ui-route-nudge","code-graph-context","chain-nudge","ship-diff-volume","reread-guard","spawn-guard-shadow","source-first-gate","memory-recall"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","push-settle","orchestration-record","telemetry-usage","mcp-usage-observation","tool-result-bytes","edit-shape","comment-discipline","design-pass","spawn-guard-shadow"],"subagent_start":["subagent-ledger"],"subagent_stop":["subagent-ledger"]},"cursor":{"ask":"text","session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register","code-graph-refresh"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress","telemetry-flush"],"stop":["chat-history","verify-before-complete","self-repair","session-register","roadmap-progress","design-pass-stop"],"user_prompt_submit":["chat-history","verify-before-complete","minimal-safe-diff","language-mirror","git-authorization","session-canary","self-repair","session-register"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","push-settle","orchestration-record","telemetry-usage","mcp-usage-observation","tool-result-bytes","edit-shape","comment-discipline","design-pass"]},"cline":{"ask":"text","session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register","code-graph-refresh"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress","telemetry-flush"],"stop":["chat-history","verify-before-complete","self-repair","session-register","roadmap-progress","design-pass-stop"],"user_prompt_submit":["chat-history","verify-before-complete","minimal-safe-diff","language-mirror","git-authorization","session-canary","self-repair","session-register"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","push-settle","orchestration-record","telemetry-usage","mcp-usage-observation","tool-result-bytes","edit-shape","comment-discipline","design-pass"]},"windsurf":{"ask":"text","session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","profile-staleness","wrapper-freshness","surface-probe","session-register","code-graph-refresh"],"stop":["chat-history","verify-before-complete","self-repair","session-register","design-pass-stop"],"user_prompt_submit":["chat-history","verify-before-complete","language-mirror","git-authorization","session-canary","self-repair","session-register"]},"gemini":{"ask":"text","session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register","code-graph-refresh"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress","telemetry-flush"],"stop":["chat-history","verify-before-complete","self-repair","session-register","roadmap-progress","design-pass-stop"],"user_prompt_submit":["chat-history","verify-before-complete","minimal-safe-diff","language-mirror","git-authorization","session-canary","self-repair","session-register"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","push-settle","orchestration-record","telemetry-usage","mcp-usage-observation","tool-result-bytes","edit-shape","comment-discipline","design-pass"]},"copilot":{"ask":"text","fallback_only":true}},"native_event_aliases":{"augment":{"SessionStart":"session_start","SessionEnd":"session_end","Stop":"stop","PostToolUse":"post_tool_use","PreToolUse":"pre_tool_use"},"claude":{"SessionStart":"session_start","SessionEnd":"session_end","Stop":"stop","UserPromptSubmit":"user_prompt_submit","PostToolUse":"post_tool_use","PostToolUseFailure":"post_tool_use","PreToolUse":"pre_tool_use","PreCompact":"pre_compact","SubagentStart":"subagent_start","SubagentStop":"subagent_stop","InstructionsLoaded":"instructions_loaded","StopFailure":"agent_error"},"cowork":{"SessionStart":"session_start","SessionEnd":"session_end","Stop":"stop","UserPromptSubmit":"user_prompt_submit","PostToolUse":"post_tool_use","PreToolUse":"pre_tool_use","PreCompact":"pre_compact","SubagentStart":"subagent_start","SubagentStop":"subagent_stop"},"cursor":{"sessionStart":"session_start","sessionEnd":"session_end","stop":"stop","beforeSubmitPrompt":"user_prompt_submit","postToolUse":"post_tool_use","preToolUse":"pre_tool_use","preCompact":"pre_compact"},"cline":{"TaskStart":"session_start","TaskResume":"session_start","TaskComplete":"session_end","TaskCancel":"stop","UserPromptSubmit":"user_prompt_submit","PostToolUse":"post_tool_use","PreToolUse":"pre_tool_use","PreCompact":"pre_compact"},"windsurf":{"pre_user_prompt":"user_prompt_submit","post_cascade_response":"stop","post_setup_worktree":"session_start"},"gemini":{"SessionStart":"session_start","SessionEnd":"session_end","BeforeAgent":"user_prompt_submit","AfterAgent":"stop","BeforeTool":"pre_tool_use","AfterTool":"post_tool_use"}}}}
|
|
1
|
+
{"fingerprint":"a1ea34a86eaabc4536ff7758681c8a89249dec6925148e96721b677b4d9de34b:111522","body_fingerprint":"6729962557eee79c6c7cda21ee5d245da8d52a4c22fbce12bdba960996db322e:21553","manifest":{"schema_version":1,"concerns":{"chat-history":{"script":"src/scripts/chat_history.ts","args":["hook-dispatch"],"fail_closed":false,"severity":"advisory","effect":"telemetry","needs_payload_bodies":["result"]},"hot-context":{"script":"src/scripts/hot_context_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"memory"},"handoff-context":{"script":"src/scripts/handoff_context_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"context"},"roadmap-progress":{"script":"src/scripts/roadmap_progress_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"formatting","needs_payload_bodies":["input"]},"onboarding-gate":{"script":"src/scripts/onboarding_gate_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification"},"context-hygiene":{"script":"src/scripts/context_hygiene_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"verify-before-complete":{"script":"src/scripts/before_complete_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","needs_payload_bodies":["input","result"]},"ship-diff-volume":{"script":"src/scripts/hooks/ship_diff_volume_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","needs_payload_bodies":["input"]},"minimal-safe-diff":{"script":"src/scripts/minimal_safe_diff_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","needs_payload_bodies":["input"]},"injection-scan":{"script":"src/scripts/injection_scan_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","needs_payload_bodies":["input","result"]},"block-no-verify":{"script":"src/scripts/hooks/block_no_verify.ts","args":[],"fail_closed":true,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"block-kernel-rule-writes":{"script":"src/scripts/hooks/block_kernel_rule_writes.ts","args":[],"fail_closed":true,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"block-plumbing-writes":{"script":"src/scripts/hooks/block_plumbing_writes.ts","args":[],"fail_closed":true,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"one-question-per-ask":{"script":"src/scripts/hooks/one_question_per_ask_hook.ts","args":[],"fail_closed":false,"severity":"blocking","effect":"permission","tools":["AskUserQuestion","AskQuestion","UserQuestion","ask_user_question","ask_question","user_question"],"needs_payload_bodies":["input"]},"block-speaking-inbox-dir":{"script":"src/scripts/hooks/block_speaking_inbox_dir.ts","args":[],"fail_closed":false,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"block-credential-reads":{"script":"src/scripts/hooks/block_credential_reads.ts","args":[],"fail_closed":false,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"block-config-weakening":{"script":"src/scripts/hooks/block_config_weakening.ts","args":[],"fail_closed":false,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"rtk-wrap":{"script":"src/scripts/hooks/rtk_wrap_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"formatting","needs_payload_bodies":["input"]},"design-slop":{"script":"src/scripts/hooks/design_slop_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","needs_payload_bodies":["input"]},"design-pass":{"script":"src/scripts/hooks/design_pass_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification","needs_payload_bodies":["input"]},"design-pass-stop":{"script":"src/scripts/hooks/design_pass_hook.ts","args":["--slot","stop"],"fail_closed":false,"severity":"advisory","effect":"notification"},"ui-route-nudge":{"script":"src/scripts/hooks/ui_route_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification","needs_payload_bodies":["input"]},"suggestion-capture":{"script":"src/scripts/hooks/suggestion_capture_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"chain-nudge":{"script":"src/scripts/hooks/chain_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification","needs_payload_bodies":["input"]},"code-graph-context":{"script":"src/scripts/hooks/code_graph_context_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"context","tools":["Grep","Glob","Read","Bash"],"needs_payload_bodies":["input"]},"memory-learn":{"script":"src/scripts/memory_learn_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"memory"},"first-run-gate":{"script":"src/scripts/first_run_gate_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification"},"profile-staleness":{"script":"src/scripts/profile_staleness_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification"},"wrapper-freshness":{"script":"src/scripts/wrapper_freshness_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification"},"update-notice":{"script":"src/scripts/update_notice_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification"},"surface-probe":{"script":"src/scripts/surface_probe_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"team-review-gate":{"script":"src/scripts/team_review_gate_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification"},"pr-url-reminder":{"script":"src/scripts/pr_url_reminder_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification","needs_payload_bodies":["input","result"]},"push-settle":{"script":"src/scripts/hooks/push_settle_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","needs_payload_bodies":["input","result"]},"language-mirror":{"script":"src/scripts/language_mirror_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"context"},"git-authorization":{"script":"src/scripts/git_authorization_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification"},"evidence-independence":{"script":"src/scripts/hooks/evidence_independence.ts","args":[],"fail_closed":false,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"session-canary":{"script":"src/scripts/session_canary_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"context"},"council-availability":{"script":"src/scripts/council_availability_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification"},"telemetry-disclosure":{"script":"src/scripts/telemetry_disclosure_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification"},"telemetry-flush":{"script":"src/scripts/hooks/telemetry_flush_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"self-repair":{"script":"src/scripts/self_repair_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"session-register":{"script":"src/scripts/session_register_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"orchestration-record":{"script":"src/scripts/hooks/orchestration_record_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry","tools":["Agent","Task"],"needs_payload_bodies":["input","result"]},"telemetry-usage":{"script":"src/scripts/hooks/telemetry_usage_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry","tools":["Skill"],"needs_payload_bodies":["input"]},"mcp-usage-observation":{"script":"src/scripts/hooks/mcp_usage_observation_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"delegation-nudge":{"script":"src/scripts/hooks/delegation_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification","nudge_rank":1},"skill-route":{"script":"src/scripts/hooks/skill_route_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"context","nudge_rank":2},"rule-inject":{"script":"src/scripts/hooks/rule_inject_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"context","needs_payload_bodies":["input"]},"obligation-settle":{"script":"src/scripts/hooks/obligation_settle_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification"},"end-review-nudge":{"script":"src/scripts/hooks/end_review_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification","skip_on_refusal_retry":true},"review-baseline":{"script":"src/scripts/hooks/review_baseline_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"turn-end-gate":{"script":"src/scripts/hooks/turn_end_gate_hook.ts","args":[],"fail_closed":false,"severity":"blocking","effect":"permission"},"comment-discipline":{"script":"src/scripts/hooks/comment_discipline_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","tools":["Write","Edit"],"needs_payload_bodies":["input"]},"edit-shape":{"script":"src/scripts/hooks/edit_shape_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","tools":["Write"],"needs_payload_bodies":["input"]},"reread-guard":{"script":"src/scripts/hooks/reread_guard_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","tools":["Read","Edit","Write"],"needs_payload_bodies":["input"]},"memory-recall":{"script":"src/scripts/hooks/memory_recall_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"memory","tools":["Bash","Edit","Write","MultiEdit","str-replace-editor","save-file","launch-process"],"needs_payload_bodies":["input"]},"session-eol":{"script":"src/scripts/hooks/session_eol_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification"},"interruption-ledger":{"script":"src/scripts/hooks/interruption_ledger_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry","skip_on_refusal_retry":true},"instructions-observer":{"script":"src/scripts/hooks/instructions_observer_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"code-graph-refresh":{"script":"src/scripts/hooks/code_graph_refresh_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"execution"},"subagent-ledger":{"script":"src/scripts/hooks/subagent_ledger_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"tool-result-bytes":{"script":"src/scripts/hooks/tool_result_bytes_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"spawn-guard-shadow":{"script":"src/scripts/hooks/spawn_guard_shadow_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry","tools":["Agent","Task","SendMessage"],"needs_payload_bodies":["input","result"],"payload_fields":["name","subagent_type","to","recipient_kind","agentId"]},"host-rate-marker":{"script":"src/scripts/hooks/host_rate_marker_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"source-first-gate":{"script":"src/scripts/hooks/source_first_gate_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry","needs_payload_bodies":["input"]},"journal-record":{"script":"src/scripts/hooks/journal_record_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"}},"roles":{"worker":{"drop":["delegation-nudge","skill-route","end-review-nudge","review-baseline","council-availability","team-review-gate","self-repair","session-eol","interruption-ledger"]}},"platforms":{"augment":{"ask":"text","session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register","code-graph-refresh"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress","telemetry-flush"],"stop":["chat-history","verify-before-complete","self-repair","session-register","roadmap-progress","design-pass-stop"],"pre_tool_use":["block-no-verify","evidence-independence","block-kernel-rule-writes","block-plumbing-writes","block-config-weakening","block-speaking-inbox-dir","block-credential-reads","rtk-wrap","design-slop","ui-route-nudge","code-graph-context","chain-nudge","ship-diff-volume","reread-guard","memory-recall"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","push-settle","orchestration-record","telemetry-usage","mcp-usage-observation","tool-result-bytes","edit-shape","comment-discipline","design-pass"]},"claude":{"ask":"native","session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","update-notice","surface-probe","session-register","review-baseline","journal-record","rule-inject","code-graph-refresh"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress","telemetry-flush","journal-record"],"stop":["chat-history","verify-before-complete","team-review-gate","end-review-nudge","obligation-settle","turn-end-gate","self-repair","session-register","session-eol","interruption-ledger","roadmap-progress","design-pass-stop","suggestion-capture","journal-record"],"user_prompt_submit":["chat-history","verify-before-complete","minimal-safe-diff","language-mirror","delegation-nudge","skill-route","git-authorization","session-canary","self-repair","session-register","rule-inject","suggestion-capture","journal-record"],"pre_tool_use":["block-no-verify","evidence-independence","block-kernel-rule-writes","block-plumbing-writes","block-config-weakening","block-speaking-inbox-dir","block-credential-reads","one-question-per-ask","rtk-wrap","design-slop","ui-route-nudge","code-graph-context","chain-nudge","ship-diff-volume","reread-guard","spawn-guard-shadow","source-first-gate","memory-recall"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","push-settle","orchestration-record","telemetry-usage","mcp-usage-observation","tool-result-bytes","edit-shape","comment-discipline","language-mirror","design-pass","journal-record","spawn-guard-shadow"],"pre_compact":["language-mirror","rule-inject","journal-record"],"subagent_start":["subagent-ledger","journal-record"],"subagent_stop":["subagent-ledger","journal-record"],"agent_error":["host-rate-marker"],"instructions_loaded":["instructions-observer"]},"cowork":{"ask":"text","session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register","code-graph-refresh"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress","telemetry-flush"],"stop":["chat-history","verify-before-complete","self-repair","session-register","roadmap-progress","design-pass-stop"],"user_prompt_submit":["chat-history","verify-before-complete","minimal-safe-diff","language-mirror","git-authorization","session-canary","self-repair","session-register"],"pre_tool_use":["block-no-verify","evidence-independence","block-kernel-rule-writes","block-plumbing-writes","block-config-weakening","block-speaking-inbox-dir","block-credential-reads","rtk-wrap","design-slop","ui-route-nudge","code-graph-context","chain-nudge","ship-diff-volume","reread-guard","spawn-guard-shadow","source-first-gate","memory-recall"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","push-settle","orchestration-record","telemetry-usage","mcp-usage-observation","tool-result-bytes","edit-shape","comment-discipline","design-pass","spawn-guard-shadow"],"subagent_start":["subagent-ledger"],"subagent_stop":["subagent-ledger"]},"cursor":{"ask":"text","session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register","code-graph-refresh"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress","telemetry-flush"],"stop":["chat-history","verify-before-complete","self-repair","session-register","roadmap-progress","design-pass-stop"],"user_prompt_submit":["chat-history","verify-before-complete","minimal-safe-diff","language-mirror","git-authorization","session-canary","self-repair","session-register"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","push-settle","orchestration-record","telemetry-usage","mcp-usage-observation","tool-result-bytes","edit-shape","comment-discipline","design-pass"]},"cline":{"ask":"text","session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register","code-graph-refresh"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress","telemetry-flush"],"stop":["chat-history","verify-before-complete","self-repair","session-register","roadmap-progress","design-pass-stop"],"user_prompt_submit":["chat-history","verify-before-complete","minimal-safe-diff","language-mirror","git-authorization","session-canary","self-repair","session-register"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","push-settle","orchestration-record","telemetry-usage","mcp-usage-observation","tool-result-bytes","edit-shape","comment-discipline","design-pass"]},"windsurf":{"ask":"text","session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","profile-staleness","wrapper-freshness","surface-probe","session-register","code-graph-refresh"],"stop":["chat-history","verify-before-complete","self-repair","session-register","design-pass-stop"],"user_prompt_submit":["chat-history","verify-before-complete","language-mirror","git-authorization","session-canary","self-repair","session-register"]},"gemini":{"ask":"text","session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register","code-graph-refresh"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress","telemetry-flush"],"stop":["chat-history","verify-before-complete","self-repair","session-register","roadmap-progress","design-pass-stop"],"user_prompt_submit":["chat-history","verify-before-complete","minimal-safe-diff","language-mirror","git-authorization","session-canary","self-repair","session-register"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","push-settle","orchestration-record","telemetry-usage","mcp-usage-observation","tool-result-bytes","edit-shape","comment-discipline","design-pass"]},"copilot":{"ask":"text","fallback_only":true}},"native_event_aliases":{"augment":{"SessionStart":"session_start","SessionEnd":"session_end","Stop":"stop","PostToolUse":"post_tool_use","PreToolUse":"pre_tool_use"},"claude":{"SessionStart":"session_start","SessionEnd":"session_end","Stop":"stop","UserPromptSubmit":"user_prompt_submit","PostToolUse":"post_tool_use","PostToolUseFailure":"post_tool_use","PreToolUse":"pre_tool_use","PreCompact":"pre_compact","SubagentStart":"subagent_start","SubagentStop":"subagent_stop","InstructionsLoaded":"instructions_loaded","StopFailure":"agent_error"},"cowork":{"SessionStart":"session_start","SessionEnd":"session_end","Stop":"stop","UserPromptSubmit":"user_prompt_submit","PostToolUse":"post_tool_use","PreToolUse":"pre_tool_use","PreCompact":"pre_compact","SubagentStart":"subagent_start","SubagentStop":"subagent_stop"},"cursor":{"sessionStart":"session_start","sessionEnd":"session_end","stop":"stop","beforeSubmitPrompt":"user_prompt_submit","postToolUse":"post_tool_use","preToolUse":"pre_tool_use","preCompact":"pre_compact"},"cline":{"TaskStart":"session_start","TaskResume":"session_start","TaskComplete":"session_end","TaskCancel":"stop","UserPromptSubmit":"user_prompt_submit","PostToolUse":"post_tool_use","PreToolUse":"pre_tool_use","PreCompact":"pre_compact"},"windsurf":{"pre_user_prompt":"user_prompt_submit","post_cascade_response":"stop","post_setup_worktree":"session_start"},"gemini":{"SessionStart":"session_start","SessionEnd":"session_end","BeforeAgent":"user_prompt_submit","AfterAgent":"stop","BeforeTool":"pre_tool_use","AfterTool":"post_tool_use"}}}}
|
|
@@ -630,22 +630,25 @@ concerns:
|
|
|
630
630
|
fail_closed: false
|
|
631
631
|
severity: advisory
|
|
632
632
|
effect: notification
|
|
633
|
-
#
|
|
634
|
-
#
|
|
635
|
-
# refused
|
|
636
|
-
# (agents/evidence/council/lazy-concern-authority-expansion-20261020.md)
|
|
637
|
-
#
|
|
638
|
-
#
|
|
639
|
-
#
|
|
640
|
-
#
|
|
641
|
-
#
|
|
642
|
-
#
|
|
643
|
-
#
|
|
644
|
-
#
|
|
645
|
-
#
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
633
|
+
# Tells the user, at session start, that their global install is behind or
|
|
634
|
+
# has just moved. It installs nothing and starts nothing: a 2026-10-20
|
|
635
|
+
# council refused it 2/2 while it could spawn `upgrade --unattended`
|
|
636
|
+
# (agents/evidence/council/lazy-concern-authority-expansion-20261020.md),
|
|
637
|
+
# and that capability was removed rather than the effect widened (D13).
|
|
638
|
+
# Its writes are its own bookkeeping — a day stamp and the last version it
|
|
639
|
+
# reported, user-global, read by no other module (a CI assertion).
|
|
640
|
+
# Bound on `claude` alone: its text goes out through the user channel
|
|
641
|
+
# (`hooks/user_notice.ts`, `systemMessage`), which is UI-only, and claude is
|
|
642
|
+
# the one host with a verified field of that kind. Every other host keeps
|
|
643
|
+
# the CLI banner. Day-throttled, file reads only, loaded from its own chunk.
|
|
644
|
+
# Kill switches: `AGENT_CONFIG_NO_UPDATE_CHECK=1`, `update.mode: off`.
|
|
645
|
+
# `update-auto-invite` (step 4.3) is not registered.
|
|
646
|
+
update-notice:
|
|
647
|
+
script: src/scripts/update_notice_hook.ts
|
|
648
|
+
args: []
|
|
649
|
+
fail_closed: false
|
|
650
|
+
severity: advisory
|
|
651
|
+
effect: notification
|
|
649
652
|
# road-to-install-path-convergence Phase 4 — duplicate-surface probe.
|
|
650
653
|
# Reads src/config/surface-matrix.yml, existence-checks declared duplicate
|
|
651
654
|
# classes, nudges ONCE per day (state: agents/runtime/state/
|
|
@@ -1616,7 +1619,7 @@ platforms:
|
|
|
1616
1619
|
|
|
1617
1620
|
claude:
|
|
1618
1621
|
ask: native
|
|
1619
|
-
session_start: [chat-history, hot-context, handoff-context, session-canary, council-availability, telemetry-disclosure, first-run-gate, onboarding-gate, verify-before-complete, minimal-safe-diff, profile-staleness, wrapper-freshness, surface-probe, session-register, review-baseline, journal-record, rule-inject, code-graph-refresh]
|
|
1622
|
+
session_start: [chat-history, hot-context, handoff-context, session-canary, council-availability, telemetry-disclosure, first-run-gate, onboarding-gate, verify-before-complete, minimal-safe-diff, profile-staleness, wrapper-freshness, update-notice, surface-probe, session-register, review-baseline, journal-record, rule-inject, code-graph-refresh]
|
|
1620
1623
|
# `rule-inject` is bound here for ONE source: `compact`
|
|
1621
1624
|
# (road-to-a-rule-carrier-that-works-outside-the-repo step 1.6). The concern
|
|
1622
1625
|
# returns before reading anything on `startup`, `resume`, `clear` and
|
|
@@ -42,12 +42,12 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
|
42
42
|
|
|
43
43
|
import { hardenedSpawnEnv } from '../_lib/spawn_env.js';
|
|
44
44
|
import { usableCli } from '../code_graph/refresh_cli.js';
|
|
45
|
-
import {
|
|
45
|
+
import { hasProjectHome, projectHome } from '../code_graph/graph_home.js';
|
|
46
|
+
import { isStale, recordRefreshIn } from '../code_graph/refresh_lock.js';
|
|
46
47
|
import { EXIT_ALLOW } from './exit_codes.js';
|
|
47
48
|
import { readHookStdin } from './hook_stdin.js';
|
|
48
49
|
import { is_replay_mode } from './state_io.js';
|
|
49
50
|
|
|
50
|
-
export const CACHE_REL = path.join('agents', 'runtime', 'state', 'code-graph-v1.json');
|
|
51
51
|
export const REFRESH_ARGS = ['code-graph', 'refresh', '--single-flight', '--map', '--budget-seconds', '60'];
|
|
52
52
|
|
|
53
53
|
export type RefreshOutcome =
|
|
@@ -109,15 +109,18 @@ export function refreshFor(cwd: string, spawnFn: typeof spawn = spawn): RefreshO
|
|
|
109
109
|
if (process.platform === 'win32') return 'unsupported';
|
|
110
110
|
if (is_replay_mode()) return 'replay';
|
|
111
111
|
const root = repoRoot(cwd);
|
|
112
|
-
|
|
112
|
+
// `auto-refresh on` refuses a root without a project home (ADR-299).
|
|
113
|
+
if (root === null || !hasProjectHome(root)) return 'not-opted-in';
|
|
114
|
+
const home = projectHome(root);
|
|
115
|
+
if (!fs.existsSync(home.autoRefreshPath)) return 'not-opted-in';
|
|
113
116
|
// A repository-committed opt-in is refused before anything is written into the tree.
|
|
114
|
-
if (anyTracked(root, [
|
|
117
|
+
if (anyTracked(root, [home.autoRefreshPath, home.cachePath].map((p) => path.relative(root, p)))) return 'tracked';
|
|
115
118
|
const done = (outcome: RefreshOutcome, detail?: string): RefreshOutcome => {
|
|
116
|
-
|
|
119
|
+
recordRefreshIn(home.stateDir, { by: 'session-start', outcome, detail });
|
|
117
120
|
return outcome;
|
|
118
121
|
};
|
|
119
|
-
if (!fs.existsSync(
|
|
120
|
-
const lock =
|
|
122
|
+
if (!fs.existsSync(home.cachePath)) return done('no-cache');
|
|
123
|
+
const lock = home.lockPath;
|
|
121
124
|
if (fs.existsSync(lock) && !isStale(lock)) return done('locked');
|
|
122
125
|
const verdict = usableCli(root);
|
|
123
126
|
if ('reason' in verdict) return done(verdict.reason, (verdict as { cli?: string }).cli);
|