instar 1.3.1112 → 1.3.1114

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.
Files changed (48) hide show
  1. package/README.md +1 -0
  2. package/dist/core/CartographerRootAuthority.d.ts +143 -0
  3. package/dist/core/CartographerRootAuthority.d.ts.map +1 -0
  4. package/dist/core/CartographerRootAuthority.js +448 -0
  5. package/dist/core/CartographerRootAuthority.js.map +1 -0
  6. package/dist/core/CartographerTree.d.ts +6 -0
  7. package/dist/core/CartographerTree.d.ts.map +1 -1
  8. package/dist/core/CartographerTree.js +6 -1
  9. package/dist/core/CartographerTree.js.map +1 -1
  10. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  11. package/dist/core/PostUpdateMigrator.js +53 -1
  12. package/dist/core/PostUpdateMigrator.js.map +1 -1
  13. package/dist/core/TopicAwareness.d.ts +134 -0
  14. package/dist/core/TopicAwareness.d.ts.map +1 -0
  15. package/dist/core/TopicAwareness.js +454 -0
  16. package/dist/core/TopicAwareness.js.map +1 -0
  17. package/dist/core/TopicIntent.d.ts +25 -1
  18. package/dist/core/TopicIntent.d.ts.map +1 -1
  19. package/dist/core/TopicIntent.js +92 -4
  20. package/dist/core/TopicIntent.js.map +1 -1
  21. package/dist/core/TopicIntentBriefing.d.ts +4 -0
  22. package/dist/core/TopicIntentBriefing.d.ts.map +1 -1
  23. package/dist/core/TopicIntentBriefing.js +37 -2
  24. package/dist/core/TopicIntentBriefing.js.map +1 -1
  25. package/dist/core/TopicIntentCapture.d.ts.map +1 -1
  26. package/dist/core/TopicIntentCapture.js +9 -3
  27. package/dist/core/TopicIntentCapture.js.map +1 -1
  28. package/dist/core/TopicIntentExtractor.d.ts +17 -1
  29. package/dist/core/TopicIntentExtractor.d.ts.map +1 -1
  30. package/dist/core/TopicIntentExtractor.js +115 -12
  31. package/dist/core/TopicIntentExtractor.js.map +1 -1
  32. package/dist/data/standards-guard-index.json +1 -1
  33. package/dist/data/standards-guard-index.meta.json +2 -2
  34. package/dist/data/standards-registry.meta.json +1 -1
  35. package/dist/server/topicIntentRoutes.d.ts.map +1 -1
  36. package/dist/server/topicIntentRoutes.js +16 -2
  37. package/dist/server/topicIntentRoutes.js.map +1 -1
  38. package/package.json +1 -1
  39. package/src/data/builtin-manifest.json +21 -21
  40. package/src/data/standards-guard-index.json +1 -1
  41. package/src/data/standards-guard-index.meta.json +2 -2
  42. package/src/data/standards-registry.meta.json +1 -1
  43. package/src/templates/hooks/compaction-recovery.sh +19 -0
  44. package/src/templates/hooks/telegram-topic-context.sh +3 -2
  45. package/upgrades/1.3.1113.md +54 -0
  46. package/upgrades/1.3.1114.md +46 -0
  47. package/upgrades/side-effects/cartographer-verified-root-authority.md +151 -0
  48. package/upgrades/side-effects/topic-awareness-three-levels.md +303 -0
package/README.md CHANGED
@@ -135,6 +135,7 @@ We didn't just claim it works. We ran controlled experiments — same model, sam
135
135
  | **Slack** | Two-way messaging via Slack adapter. Channel and DM routing, eight HTTP routes, dedicated CLI | [→](https://instar.sh/features/slack/) |
136
136
  | **Lifeline** | Persistent supervisor. Detects crashes, auto-recovers, queues messages, version-skew handling (v1.1.3+) | [→](https://instar.sh/features/lifeline/) |
137
137
  | **Conversational Memory** | Per-topic SQLite with FTS5, rolling summaries, context re-injection | [→](https://instar.sh/features/memory/) |
138
+ | **Three-level Topic Awareness** | Keeps the whole-topic anchor and evolution, latest conversational arc, and current work visible together — each with goal, trend, and themes; stale projections say so | [→](docs/specs/topic-awareness-three-levels.eli16.md) |
138
139
  | **Evolution System** | Proposals, learnings, gap tracking, commitment follow-through | [→](https://instar.sh/features/evolution/) |
139
140
  | **Relationships** | Cross-platform identity resolution, significance scoring, context injection | [→](https://instar.sh/features/relationships/) |
140
141
  | **Safety Gates** | LLM-supervised gate for external operations. Adaptive trust per service | [→](https://instar.sh/features/safety-gates/) |
@@ -0,0 +1,143 @@
1
+ export type CartographerRootKind = 'agent-home' | 'active-project-checkout' | 'instar-source-checkout';
2
+ export type CartographerRootProvenance = {
3
+ source: 'agent-home';
4
+ agentName: string;
5
+ } | {
6
+ source: 'server-project';
7
+ projectName: string;
8
+ } | {
9
+ source: 'topic-binding';
10
+ topicId: number;
11
+ projectName: string;
12
+ } | {
13
+ source: 'operator-binding';
14
+ bindingId: string;
15
+ projectName: string;
16
+ };
17
+ export interface CartographerRootCandidate {
18
+ kind: CartographerRootKind;
19
+ requestedPath: string;
20
+ provenance: CartographerRootProvenance;
21
+ /** Optional repository anchor supplied by the provenance source. */
22
+ expectedRemote?: string;
23
+ /** Optional exact revision anchor, primarily used for revalidation. */
24
+ expectedRevision?: string;
25
+ }
26
+ export type CartographerRootSelectionRequest = {
27
+ kind: 'agent-home';
28
+ agentHome: string;
29
+ agentName: string;
30
+ } | {
31
+ kind: 'active-project-checkout';
32
+ standalone: boolean;
33
+ serverProject?: {
34
+ projectDir: string;
35
+ projectName: string;
36
+ gitRemote?: string;
37
+ };
38
+ topicBinding?: {
39
+ topicId: number;
40
+ projectDir: string;
41
+ projectName: string;
42
+ gitRemote?: string;
43
+ };
44
+ } | {
45
+ kind: 'instar-source-checkout';
46
+ binding: {
47
+ bindingId: string;
48
+ projectDir: string;
49
+ projectName: string;
50
+ gitRemote: string;
51
+ };
52
+ };
53
+ export type CartographerRootSelectionResult = {
54
+ ok: true;
55
+ candidate: CartographerRootCandidate;
56
+ } | {
57
+ ok: false;
58
+ code: 'topic-binding-required' | 'server-project-required' | 'instar-source-binding-required';
59
+ message: string;
60
+ };
61
+ export type CartographerRootTrust = 'verified' | 'structural-only' | 'refused';
62
+ export type CartographerRootReason = 'verified' | 'path-missing' | 'path-not-directory' | 'canonicalize-failed' | 'git-root-unreadable' | 'candidate-not-git-root' | 'head-unreadable' | 'instar-source-expectation-missing' | 'remote-unreadable' | 'remote-mismatch' | 'revision-mismatch' | 'root-identity-mismatch';
63
+ export interface CartographerRootIdentity {
64
+ /** Stable for this checked-out root across revisions. */
65
+ rootId: string;
66
+ /** Stable repository identity derived from an anchored remote or common Git dir. */
67
+ repositoryId: string | null;
68
+ kind: CartographerRootKind;
69
+ canonicalPath: string;
70
+ gitTopLevel: string | null;
71
+ remoteUrl: string | null;
72
+ revision: string | null;
73
+ /** Safe, opaque namespace for stateDir/cartographer/roots/<namespace>. */
74
+ stateNamespace: string;
75
+ }
76
+ export interface CartographerRootAssessment {
77
+ candidate: CartographerRootCandidate;
78
+ trust: CartographerRootTrust;
79
+ reason: CartographerRootReason;
80
+ identity: CartographerRootIdentity | null;
81
+ /** Structural population is zero-egress and survives missing Git identity. */
82
+ structuralPopulationAllowed: boolean;
83
+ /** Paid authoring requires a verified project/source checkout and exact readable revision. */
84
+ paidAuthoringAllowed: boolean;
85
+ }
86
+ export interface CartographerRootDecisionSignals {
87
+ pathState: 'unreadable' | 'file' | 'directory';
88
+ canonicalPath: string | null;
89
+ gitTopLevel: string | null;
90
+ expectedRemote: string | null;
91
+ observedRemotes: string[];
92
+ expectedRevision: string | null;
93
+ observedRevision: string | null;
94
+ }
95
+ /**
96
+ * Structured evidence emitted for every authority outcome. The recorder is a
97
+ * required dependency: a live consumer cannot obtain an allow/degrade/refuse
98
+ * result without also accepting responsibility for its decision trail.
99
+ */
100
+ export interface CartographerRootDecision {
101
+ schemaVersion: 1;
102
+ decidedAt: string;
103
+ operation: 'assess' | 'revalidate';
104
+ context: {
105
+ candidate: CartographerRootCandidate;
106
+ };
107
+ signals: CartographerRootDecisionSignals;
108
+ rule: CartographerRootReason | 'revalidation-not-applicable';
109
+ outcome: {
110
+ trust: CartographerRootTrust;
111
+ structuralPopulationAllowed: boolean;
112
+ paidAuthoringAllowed: boolean;
113
+ rootId: string | null;
114
+ stateNamespace: string | null;
115
+ };
116
+ }
117
+ export interface CartographerRootAuthorityOptions {
118
+ /** Must durably record in a live consumer. Throwing prevents an unlogged outcome. */
119
+ recordDecision: (decision: CartographerRootDecision) => void;
120
+ now?: () => Date;
121
+ }
122
+ /**
123
+ * Select a candidate only from an explicit, typed provenance source.
124
+ *
125
+ * In particular, a standalone active-project request never falls back to the
126
+ * agent home. That fallback is the wrong-root failure this contract exists to
127
+ * remove. Instar source is explicit-only: directory scanning and marker files
128
+ * may corroborate an identity later, but can never select it.
129
+ */
130
+ export declare function selectCartographerRootCandidate(request: CartographerRootSelectionRequest): CartographerRootSelectionResult;
131
+ /** Normalize common HTTPS, SSH, and scp-like Git remote spellings for identity comparison. */
132
+ export declare function normalizeCartographerGitRemote(raw: string): string;
133
+ export declare class CartographerRootAuthority {
134
+ private readonly recordDecision;
135
+ private readonly now;
136
+ constructor(options: CartographerRootAuthorityOptions);
137
+ private decide;
138
+ private evaluate;
139
+ assess(candidate: CartographerRootCandidate): CartographerRootAssessment;
140
+ /** Revalidate the same root identity and exact revision before a trusted operation. */
141
+ revalidate(assessment: CartographerRootAssessment): CartographerRootAssessment;
142
+ }
143
+ //# sourceMappingURL=CartographerRootAuthority.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CartographerRootAuthority.d.ts","sourceRoot":"","sources":["../../src/core/CartographerRootAuthority.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,448 @@
1
+ /**
2
+ * CartographerRootAuthority — inert root-selection and verification substrate.
3
+ *
4
+ * This module deliberately does not wire itself into Cartographer routes or the
5
+ * freshness sweep. It separates three questions that the old projectDir
6
+ * singleton collapsed:
7
+ *
8
+ * 1. Which root did a provenance-bearing source select?
9
+ * 2. What repository identity and revision are actually present there?
10
+ * 3. Which operations are safe at the resulting trust level?
11
+ *
12
+ * A selected directory without a readable Git HEAD remains useful for the
13
+ * zero-cost structural hierarchy, but it is never eligible for paid authoring.
14
+ * Contradictory evidence (for example an expected-remote mismatch) refuses the
15
+ * root entirely. PR 11B-2 is the consumer boundary that will apply this contract
16
+ * to live navigation, reporting, and authoring.
17
+ */
18
+ import crypto from 'node:crypto';
19
+ import fs from 'node:fs';
20
+ import path from 'node:path';
21
+ import { SafeGitExecutor } from './SafeGitExecutor.js';
22
+ const GIT_OP = 'cartographer-root-authority';
23
+ /**
24
+ * Select a candidate only from an explicit, typed provenance source.
25
+ *
26
+ * In particular, a standalone active-project request never falls back to the
27
+ * agent home. That fallback is the wrong-root failure this contract exists to
28
+ * remove. Instar source is explicit-only: directory scanning and marker files
29
+ * may corroborate an identity later, but can never select it.
30
+ */
31
+ export function selectCartographerRootCandidate(request) {
32
+ if (request.kind === 'agent-home') {
33
+ return {
34
+ ok: true,
35
+ candidate: {
36
+ kind: request.kind,
37
+ requestedPath: request.agentHome,
38
+ provenance: { source: 'agent-home', agentName: request.agentName },
39
+ },
40
+ };
41
+ }
42
+ if (request.kind === 'instar-source-checkout') {
43
+ if (!request.binding?.projectDir || !request.binding.gitRemote) {
44
+ return {
45
+ ok: false,
46
+ code: 'instar-source-binding-required',
47
+ message: 'Instar source selection requires an explicit binding with a repository anchor',
48
+ };
49
+ }
50
+ return {
51
+ ok: true,
52
+ candidate: {
53
+ kind: request.kind,
54
+ requestedPath: request.binding.projectDir,
55
+ provenance: {
56
+ source: 'operator-binding',
57
+ bindingId: request.binding.bindingId,
58
+ projectName: request.binding.projectName,
59
+ },
60
+ expectedRemote: request.binding.gitRemote,
61
+ },
62
+ };
63
+ }
64
+ if (request.topicBinding) {
65
+ return {
66
+ ok: true,
67
+ candidate: {
68
+ kind: request.kind,
69
+ requestedPath: request.topicBinding.projectDir,
70
+ provenance: {
71
+ source: 'topic-binding',
72
+ topicId: request.topicBinding.topicId,
73
+ projectName: request.topicBinding.projectName,
74
+ },
75
+ expectedRemote: request.topicBinding.gitRemote,
76
+ },
77
+ };
78
+ }
79
+ if (request.standalone) {
80
+ return {
81
+ ok: false,
82
+ code: 'topic-binding-required',
83
+ message: 'A standalone active-project root requires a topic-project binding',
84
+ };
85
+ }
86
+ if (!request.serverProject) {
87
+ return {
88
+ ok: false,
89
+ code: 'server-project-required',
90
+ message: 'A project-bound active-project root requires the server project declaration',
91
+ };
92
+ }
93
+ return {
94
+ ok: true,
95
+ candidate: {
96
+ kind: request.kind,
97
+ requestedPath: request.serverProject.projectDir,
98
+ provenance: {
99
+ source: 'server-project',
100
+ projectName: request.serverProject.projectName,
101
+ },
102
+ expectedRemote: request.serverProject.gitRemote,
103
+ },
104
+ };
105
+ }
106
+ /** Normalize common HTTPS, SSH, and scp-like Git remote spellings for identity comparison. */
107
+ export function normalizeCartographerGitRemote(raw) {
108
+ let value = raw.trim();
109
+ while (value.endsWith('/'))
110
+ value = value.slice(0, -1);
111
+ if (/\.git$/i.test(value))
112
+ value = value.slice(0, -4);
113
+ const normalizePath = (host, rawPath) => {
114
+ const clean = rawPath
115
+ .replace(/^\/+/, '')
116
+ .replace(/\.git$/i, '')
117
+ .replace(/\/+$/, '');
118
+ // github.com documents repository URLs as case-insensitive. Preserve path
119
+ // case everywhere else: folding an unknown forge's path can collapse two
120
+ // genuinely different repositories into one trusted identity.
121
+ return host === 'github.com' ? clean.toLowerCase() : clean;
122
+ };
123
+ const scp = value.match(/^(?:[^@/]+@)?([^:/]+):(.+)$/);
124
+ if (scp && !value.includes('://')) {
125
+ const host = scp[1].toLowerCase();
126
+ return `${host}/${normalizePath(host, scp[2])}`;
127
+ }
128
+ try {
129
+ const parsed = new URL(value);
130
+ const host = parsed.hostname.toLowerCase();
131
+ const pathname = normalizePath(host, parsed.pathname);
132
+ if (parsed.protocol === 'file:')
133
+ return `file:${pathname}`;
134
+ const defaultPort = (parsed.protocol === 'ssh:' && parsed.port === '22') ||
135
+ (parsed.protocol === 'git:' && parsed.port === '9418') ||
136
+ (parsed.protocol === 'http:' && parsed.port === '80') ||
137
+ (parsed.protocol === 'https:' && parsed.port === '443');
138
+ const authority = parsed.port && !defaultPort ? `${host}:${parsed.port}` : host;
139
+ return `${authority}/${pathname}`;
140
+ }
141
+ catch {
142
+ // Unknown syntax is not safe to case-fold. Equality remains available for
143
+ // byte-equivalent anchors without manufacturing false equivalence.
144
+ return value;
145
+ }
146
+ }
147
+ function digest(value, length = 24) {
148
+ return crypto
149
+ .createHash('sha256')
150
+ .update(value, 'utf8')
151
+ .digest('hex')
152
+ .slice(0, length);
153
+ }
154
+ function provenanceKey(provenance) {
155
+ switch (provenance.source) {
156
+ case 'agent-home':
157
+ return `agent-home:${provenance.agentName}`;
158
+ case 'server-project':
159
+ return `server-project:${provenance.projectName}`;
160
+ case 'topic-binding':
161
+ return `topic-binding:${provenance.topicId}:${provenance.projectName}`;
162
+ case 'operator-binding':
163
+ return `operator-binding:${provenance.bindingId}:${provenance.projectName}`;
164
+ }
165
+ }
166
+ function readGit(cwd, args) {
167
+ try {
168
+ // Root verification must work against the Instar source checkout itself.
169
+ // SafeGitExecutor keeps this opt-in narrow: only its closed read-tier verb
170
+ // allowlist bypasses SourceTreeGuard; a destructive/differently-shaped call
171
+ // still cannot pass through this option.
172
+ const value = SafeGitExecutor.readSync(args, {
173
+ cwd,
174
+ operation: GIT_OP,
175
+ sourceTreeReadOk: true,
176
+ }).trim();
177
+ return value || null;
178
+ }
179
+ catch {
180
+ return null; /* @silent-fallback-ok — unreadable Git evidence becomes a required structured authority decision */
181
+ }
182
+ }
183
+ function readRemotes(cwd) {
184
+ // `remote -v` is on SafeGitExecutor's source-tree read-tier allowlist, while
185
+ // arbitrary config access intentionally is not. Parse fetch identities only:
186
+ // a push-only URL proves write destination, not which repository was checked out.
187
+ const raw = readGit(cwd, ['remote', '-v']);
188
+ if (!raw)
189
+ return [];
190
+ const remotes = [];
191
+ for (const line of raw.split('\n')) {
192
+ const match = line.match(/^(\S+)\s+(.+?)\s+\(fetch\)$/);
193
+ if (!match)
194
+ continue;
195
+ const url = match[2].trim();
196
+ if (!url)
197
+ continue;
198
+ remotes.push({
199
+ name: match[1],
200
+ url,
201
+ normalized: normalizeCartographerGitRemote(url),
202
+ });
203
+ }
204
+ return remotes;
205
+ }
206
+ function canonicalCommonGitDir(cwd) {
207
+ const raw = readGit(cwd, ['rev-parse', '--git-common-dir']);
208
+ if (!raw)
209
+ return null;
210
+ const absolute = path.isAbsolute(raw) ? raw : path.resolve(cwd, raw);
211
+ try {
212
+ return fs.realpathSync(absolute);
213
+ }
214
+ catch {
215
+ return path.resolve(absolute);
216
+ }
217
+ }
218
+ function identityFor(input) {
219
+ const remoteIdentity = input.remoteUrl
220
+ ? `remote:${normalizeCartographerGitRemote(input.remoteUrl)}`
221
+ : null;
222
+ const repositoryBasis = remoteIdentity ??
223
+ (input.commonGitDir ? `common-git-dir:${input.commonGitDir}` : null);
224
+ const repositoryId = repositoryBasis ? digest(repositoryBasis) : null;
225
+ const rootBasis = repositoryId
226
+ ? `${input.candidate.kind}\0${repositoryId}\0${input.canonicalPath}`
227
+ : `${input.candidate.kind}\0structural\0${provenanceKey(input.candidate.provenance)}\0${input.canonicalPath}`;
228
+ const rootId = digest(rootBasis);
229
+ return {
230
+ rootId,
231
+ repositoryId,
232
+ kind: input.candidate.kind,
233
+ canonicalPath: input.canonicalPath,
234
+ gitTopLevel: input.gitTopLevel,
235
+ remoteUrl: input.remoteUrl,
236
+ revision: input.revision,
237
+ stateNamespace: `root-${rootId}`,
238
+ };
239
+ }
240
+ function refused(candidate, reason, identity = null) {
241
+ return {
242
+ candidate,
243
+ trust: 'refused',
244
+ reason,
245
+ identity,
246
+ structuralPopulationAllowed: false,
247
+ paidAuthoringAllowed: false,
248
+ };
249
+ }
250
+ function structuralOnly(candidate, reason, identity) {
251
+ return {
252
+ candidate,
253
+ trust: 'structural-only',
254
+ reason,
255
+ identity,
256
+ structuralPopulationAllowed: true,
257
+ paidAuthoringAllowed: false,
258
+ };
259
+ }
260
+ export class CartographerRootAuthority {
261
+ recordDecision;
262
+ now;
263
+ constructor(options) {
264
+ this.recordDecision = options.recordDecision;
265
+ this.now = options.now ?? (() => new Date());
266
+ }
267
+ decide(assessment, operation, signals, rule = assessment.reason) {
268
+ // Do not return an authority outcome if its required audit sink fails. That
269
+ // keeps the future live consumer from silently acting on an unlogged trust
270
+ // decision and makes recorder availability part of the authority contract.
271
+ this.recordDecision({
272
+ schemaVersion: 1,
273
+ decidedAt: this.now().toISOString(),
274
+ operation,
275
+ context: {
276
+ candidate: {
277
+ ...assessment.candidate,
278
+ provenance: { ...assessment.candidate.provenance },
279
+ },
280
+ },
281
+ signals: { ...signals, observedRemotes: [...signals.observedRemotes] },
282
+ rule,
283
+ outcome: {
284
+ trust: assessment.trust,
285
+ structuralPopulationAllowed: assessment.structuralPopulationAllowed,
286
+ paidAuthoringAllowed: assessment.paidAuthoringAllowed,
287
+ rootId: assessment.identity?.rootId ?? null,
288
+ stateNamespace: assessment.identity?.stateNamespace ?? null,
289
+ },
290
+ });
291
+ return assessment;
292
+ }
293
+ evaluate(candidate, operation, expectedRootId) {
294
+ const signals = {
295
+ pathState: 'unreadable',
296
+ canonicalPath: null,
297
+ gitTopLevel: null,
298
+ expectedRemote: candidate.expectedRemote
299
+ ? normalizeCartographerGitRemote(candidate.expectedRemote)
300
+ : null,
301
+ observedRemotes: [],
302
+ expectedRevision: candidate.expectedRevision ?? null,
303
+ observedRevision: null,
304
+ };
305
+ let stat;
306
+ try {
307
+ stat = fs.statSync(candidate.requestedPath);
308
+ }
309
+ catch {
310
+ return this.decide(refused(candidate, 'path-missing'), operation, signals);
311
+ }
312
+ signals.pathState = stat.isDirectory() ? 'directory' : 'file';
313
+ if (!stat.isDirectory()) {
314
+ return this.decide(refused(candidate, 'path-not-directory'), operation, signals);
315
+ }
316
+ let canonicalPath;
317
+ try {
318
+ canonicalPath = fs.realpathSync(candidate.requestedPath);
319
+ }
320
+ catch {
321
+ return this.decide(refused(candidate, 'canonicalize-failed'), operation, signals);
322
+ }
323
+ signals.canonicalPath = canonicalPath;
324
+ const rawTopLevel = readGit(canonicalPath, [
325
+ 'rev-parse',
326
+ '--show-toplevel',
327
+ ]);
328
+ if (!rawTopLevel) {
329
+ return this.decide(structuralOnly(candidate, 'git-root-unreadable', identityFor({
330
+ candidate,
331
+ canonicalPath,
332
+ gitTopLevel: null,
333
+ remoteUrl: null,
334
+ commonGitDir: null,
335
+ revision: null,
336
+ })), operation, signals);
337
+ }
338
+ let gitTopLevel;
339
+ try {
340
+ gitTopLevel = fs.realpathSync(rawTopLevel);
341
+ }
342
+ catch {
343
+ return this.decide(structuralOnly(candidate, 'git-root-unreadable', identityFor({
344
+ candidate,
345
+ canonicalPath,
346
+ gitTopLevel: null,
347
+ remoteUrl: null,
348
+ commonGitDir: null,
349
+ revision: null,
350
+ })), operation, signals);
351
+ }
352
+ signals.gitTopLevel = gitTopLevel;
353
+ if (gitTopLevel !== canonicalPath) {
354
+ return this.decide(refused(candidate, 'candidate-not-git-root', identityFor({
355
+ candidate,
356
+ canonicalPath,
357
+ gitTopLevel,
358
+ remoteUrl: null,
359
+ commonGitDir: canonicalCommonGitDir(gitTopLevel),
360
+ revision: null,
361
+ })), operation, signals);
362
+ }
363
+ const remotes = readRemotes(canonicalPath);
364
+ signals.observedRemotes = remotes.map((remote) => remote.normalized);
365
+ const expectedRemote = signals.expectedRemote;
366
+ const matchedRemote = expectedRemote
367
+ ? (remotes.find((remote) => remote.normalized === expectedRemote) ?? null)
368
+ : (remotes.find((remote) => remote.name === 'origin') ??
369
+ remotes[0] ??
370
+ null);
371
+ const commonGitDir = canonicalCommonGitDir(canonicalPath);
372
+ const revision = readGit(canonicalPath, ['rev-parse', 'HEAD']);
373
+ signals.observedRevision = revision;
374
+ const provisionalIdentity = identityFor({
375
+ candidate,
376
+ canonicalPath,
377
+ gitTopLevel,
378
+ remoteUrl: matchedRemote?.url ?? null,
379
+ commonGitDir,
380
+ revision,
381
+ });
382
+ if (candidate.kind === 'instar-source-checkout' && !expectedRemote) {
383
+ return this.decide(structuralOnly(candidate, 'instar-source-expectation-missing', provisionalIdentity), operation, signals);
384
+ }
385
+ if (expectedRemote && remotes.length === 0) {
386
+ return this.decide(structuralOnly(candidate, 'remote-unreadable', provisionalIdentity), operation, signals);
387
+ }
388
+ if (expectedRemote && !matchedRemote) {
389
+ const actualIdentity = identityFor({
390
+ candidate,
391
+ canonicalPath,
392
+ gitTopLevel,
393
+ remoteUrl: remotes.find((remote) => remote.name === 'origin')?.url ??
394
+ remotes[0]?.url ??
395
+ null,
396
+ commonGitDir,
397
+ revision,
398
+ });
399
+ return this.decide(refused(candidate, 'remote-mismatch', actualIdentity), operation, signals);
400
+ }
401
+ if (!revision) {
402
+ return this.decide(structuralOnly(candidate, 'head-unreadable', provisionalIdentity), operation, signals);
403
+ }
404
+ if (candidate.expectedRevision && revision !== candidate.expectedRevision) {
405
+ return this.decide(refused(candidate, 'revision-mismatch', provisionalIdentity), operation, signals);
406
+ }
407
+ if (expectedRootId && provisionalIdentity.rootId !== expectedRootId) {
408
+ return this.decide(refused(candidate, 'root-identity-mismatch', provisionalIdentity), operation, signals);
409
+ }
410
+ return this.decide({
411
+ candidate,
412
+ trust: 'verified',
413
+ reason: 'verified',
414
+ identity: provisionalIdentity,
415
+ structuralPopulationAllowed: true,
416
+ // Agent home is an identity/state container, not an active project. Even
417
+ // when it is itself a valid Git repository, selecting it explicitly must
418
+ // not authorize the noisy-home paid sweep that exposed this failure.
419
+ paidAuthoringAllowed: candidate.kind !== 'agent-home',
420
+ }, operation, signals);
421
+ }
422
+ assess(candidate) {
423
+ return this.evaluate(candidate, 'assess');
424
+ }
425
+ /** Revalidate the same root identity and exact revision before a trusted operation. */
426
+ revalidate(assessment) {
427
+ if (assessment.trust !== 'verified' || !assessment.identity?.revision) {
428
+ return this.decide(assessment, 'revalidate', {
429
+ pathState: assessment.identity ? 'directory' : 'unreadable',
430
+ canonicalPath: assessment.identity?.canonicalPath ?? null,
431
+ gitTopLevel: assessment.identity?.gitTopLevel ?? null,
432
+ expectedRemote: assessment.candidate.expectedRemote
433
+ ? normalizeCartographerGitRemote(assessment.candidate.expectedRemote)
434
+ : null,
435
+ observedRemotes: assessment.identity?.remoteUrl
436
+ ? [normalizeCartographerGitRemote(assessment.identity.remoteUrl)]
437
+ : [],
438
+ expectedRevision: assessment.identity?.revision ?? null,
439
+ observedRevision: assessment.identity?.revision ?? null,
440
+ }, 'revalidation-not-applicable');
441
+ }
442
+ return this.evaluate({
443
+ ...assessment.candidate,
444
+ expectedRevision: assessment.identity.revision,
445
+ }, 'revalidate', assessment.identity.rootId);
446
+ }
447
+ }
448
+ //# sourceMappingURL=CartographerRootAuthority.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CartographerRootAuthority.js","sourceRoot":"","sources":["../../src/core/CartographerRootAuthority.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AA6IvD,MAAM,MAAM,GAAG,6BAA6B,CAAC;AAE7C;;;;;;;GAOG;AACH,MAAM,UAAU,+BAA+B,CAC7C,OAAyC;IAEzC,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;QAClC,OAAO;YACL,EAAE,EAAE,IAAI;YACR,SAAS,EAAE;gBACT,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,aAAa,EAAE,OAAO,CAAC,SAAS;gBAChC,UAAU,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE;aACnE;SACF,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,KAAK,wBAAwB,EAAE,CAAC;QAC9C,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,UAAU,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;YAC/D,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,IAAI,EAAE,gCAAgC;gBACtC,OAAO,EACL,+EAA+E;aAClF,CAAC;QACJ,CAAC;QACD,OAAO;YACL,EAAE,EAAE,IAAI;YACR,SAAS,EAAE;gBACT,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,aAAa,EAAE,OAAO,CAAC,OAAO,CAAC,UAAU;gBACzC,UAAU,EAAE;oBACV,MAAM,EAAE,kBAAkB;oBAC1B,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,SAAS;oBACpC,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,WAAW;iBACzC;gBACD,cAAc,EAAE,OAAO,CAAC,OAAO,CAAC,SAAS;aAC1C;SACF,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;QACzB,OAAO;YACL,EAAE,EAAE,IAAI;YACR,SAAS,EAAE;gBACT,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,aAAa,EAAE,OAAO,CAAC,YAAY,CAAC,UAAU;gBAC9C,UAAU,EAAE;oBACV,MAAM,EAAE,eAAe;oBACvB,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,OAAO;oBACrC,WAAW,EAAE,OAAO,CAAC,YAAY,CAAC,WAAW;iBAC9C;gBACD,cAAc,EAAE,OAAO,CAAC,YAAY,CAAC,SAAS;aAC/C;SACF,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACvB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,IAAI,EAAE,wBAAwB;YAC9B,OAAO,EACL,mEAAmE;SACtE,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;QAC3B,OAAO;YACL,EAAE,EAAE,KAAK;YACT,IAAI,EAAE,yBAAyB;YAC/B,OAAO,EACL,6EAA6E;SAChF,CAAC;IACJ,CAAC;IAED,OAAO;QACL,EAAE,EAAE,IAAI;QACR,SAAS,EAAE;YACT,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,aAAa,EAAE,OAAO,CAAC,aAAa,CAAC,UAAU;YAC/C,UAAU,EAAE;gBACV,MAAM,EAAE,gBAAgB;gBACxB,WAAW,EAAE,OAAO,CAAC,aAAa,CAAC,WAAW;aAC/C;YACD,cAAc,EAAE,OAAO,CAAC,aAAa,CAAC,SAAS;SAChD;KACF,CAAC;AACJ,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,8BAA8B,CAAC,GAAW;IACxD,IAAI,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACvB,OAAO,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACvD,IAAI,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAEtD,MAAM,aAAa,GAAG,CAAC,IAAY,EAAE,OAAe,EAAU,EAAE;QAC9D,MAAM,KAAK,GAAG,OAAO;aAClB,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;aACnB,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;aACtB,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACvB,0EAA0E;QAC1E,yEAAyE;QACzE,8DAA8D;QAC9D,OAAO,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;IAC7D,CAAC,CAAC;IAEF,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACvD,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QAClC,OAAO,GAAG,IAAI,IAAI,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAClD,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;QAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;QACtD,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO;YAAE,OAAO,QAAQ,QAAQ,EAAE,CAAC;QAC3D,MAAM,WAAW,GACf,CAAC,MAAM,CAAC,QAAQ,KAAK,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,CAAC;YACpD,CAAC,MAAM,CAAC,QAAQ,KAAK,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC;YACtD,CAAC,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,CAAC;YACrD,CAAC,MAAM,CAAC,QAAQ,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC;QAC1D,MAAM,SAAS,GACb,MAAM,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAChE,OAAO,GAAG,SAAS,IAAI,QAAQ,EAAE,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,0EAA0E;QAC1E,mEAAmE;QACnE,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,MAAM,CAAC,KAAa,EAAE,MAAM,GAAG,EAAE;IACxC,OAAO,MAAM;SACV,UAAU,CAAC,QAAQ,CAAC;SACpB,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC;SACrB,MAAM,CAAC,KAAK,CAAC;SACb,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AACtB,CAAC;AAED,SAAS,aAAa,CAAC,UAAsC;IAC3D,QAAQ,UAAU,CAAC,MAAM,EAAE,CAAC;QAC1B,KAAK,YAAY;YACf,OAAO,cAAc,UAAU,CAAC,SAAS,EAAE,CAAC;QAC9C,KAAK,gBAAgB;YACnB,OAAO,kBAAkB,UAAU,CAAC,WAAW,EAAE,CAAC;QACpD,KAAK,eAAe;YAClB,OAAO,iBAAiB,UAAU,CAAC,OAAO,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC;QACzE,KAAK,kBAAkB;YACrB,OAAO,oBAAoB,UAAU,CAAC,SAAS,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC;IAChF,CAAC;AACH,CAAC;AAED,SAAS,OAAO,CAAC,GAAW,EAAE,IAAuB;IACnD,IAAI,CAAC;QACH,yEAAyE;QACzE,2EAA2E;QAC3E,4EAA4E;QAC5E,yCAAyC;QACzC,MAAM,KAAK,GAAG,eAAe,CAAC,QAAQ,CAAC,IAAI,EAAE;YAC3C,GAAG;YACH,SAAS,EAAE,MAAM;YACjB,gBAAgB,EAAE,IAAI;SACvB,CAAC,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,KAAK,IAAI,IAAI,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC,CAAC,oGAAoG;IACnH,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAClB,GAAW;IAEX,6EAA6E;IAC7E,6EAA6E;IAC7E,kFAAkF;IAClF,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;IAC3C,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IACpB,MAAM,OAAO,GAA6D,EAAE,CAAC;IAC7E,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACxD,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,GAAG;YAAE,SAAS;QACnB,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;YACd,GAAG;YACH,UAAU,EAAE,8BAA8B,CAAC,GAAG,CAAC;SAChD,CAAC,CAAC;IACL,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,qBAAqB,CAAC,GAAW;IACxC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAC5D,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACrE,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,KAOpB;IACC,MAAM,cAAc,GAAG,KAAK,CAAC,SAAS;QACpC,CAAC,CAAC,UAAU,8BAA8B,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE;QAC7D,CAAC,CAAC,IAAI,CAAC;IACT,MAAM,eAAe,GACnB,cAAc;QACd,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,kBAAkB,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACvE,MAAM,YAAY,GAAG,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACtE,MAAM,SAAS,GAAG,YAAY;QAC5B,CAAC,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,KAAK,YAAY,KAAK,KAAK,CAAC,aAAa,EAAE;QACpE,CAAC,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,iBAAiB,aAAa,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,KAAK,CAAC,aAAa,EAAE,CAAC;IAChH,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;IACjC,OAAO;QACL,MAAM;QACN,YAAY;QACZ,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,IAAI;QAC1B,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,cAAc,EAAE,QAAQ,MAAM,EAAE;KACjC,CAAC;AACJ,CAAC;AAED,SAAS,OAAO,CACd,SAAoC,EACpC,MAA8B,EAC9B,WAA4C,IAAI;IAEhD,OAAO;QACL,SAAS;QACT,KAAK,EAAE,SAAS;QAChB,MAAM;QACN,QAAQ;QACR,2BAA2B,EAAE,KAAK;QAClC,oBAAoB,EAAE,KAAK;KAC5B,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CACrB,SAAoC,EACpC,MAA8B,EAC9B,QAAkC;IAElC,OAAO;QACL,SAAS;QACT,KAAK,EAAE,iBAAiB;QACxB,MAAM;QACN,QAAQ;QACR,2BAA2B,EAAE,IAAI;QACjC,oBAAoB,EAAE,KAAK;KAC5B,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,yBAAyB;IACnB,cAAc,CAA+C;IAC7D,GAAG,CAAa;IAEjC,YAAY,OAAyC;QACnD,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;QAC7C,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;IAEO,MAAM,CACZ,UAAsC,EACtC,SAAkC,EAClC,OAAwC,EACxC,OAAyC,UAAU,CAAC,MAAM;QAE1D,4EAA4E;QAC5E,2EAA2E;QAC3E,2EAA2E;QAC3E,IAAI,CAAC,cAAc,CAAC;YAClB,aAAa,EAAE,CAAC;YAChB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;YACnC,SAAS;YACT,OAAO,EAAE;gBACP,SAAS,EAAE;oBACT,GAAG,UAAU,CAAC,SAAS;oBACvB,UAAU,EAAE,EAAE,GAAG,UAAU,CAAC,SAAS,CAAC,UAAU,EAAE;iBACnD;aACF;YACD,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,eAAe,EAAE,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,EAAE;YACtE,IAAI;YACJ,OAAO,EAAE;gBACP,KAAK,EAAE,UAAU,CAAC,KAAK;gBACvB,2BAA2B,EAAE,UAAU,CAAC,2BAA2B;gBACnE,oBAAoB,EAAE,UAAU,CAAC,oBAAoB;gBACrD,MAAM,EAAE,UAAU,CAAC,QAAQ,EAAE,MAAM,IAAI,IAAI;gBAC3C,cAAc,EAAE,UAAU,CAAC,QAAQ,EAAE,cAAc,IAAI,IAAI;aAC5D;SACF,CAAC,CAAC;QACH,OAAO,UAAU,CAAC;IACpB,CAAC;IAEO,QAAQ,CACd,SAAoC,EACpC,SAAkC,EAClC,cAAuB;QAEvB,MAAM,OAAO,GAAoC;YAC/C,SAAS,EAAE,YAAY;YACvB,aAAa,EAAE,IAAI;YACnB,WAAW,EAAE,IAAI;YACjB,cAAc,EAAE,SAAS,CAAC,cAAc;gBACtC,CAAC,CAAC,8BAA8B,CAAC,SAAS,CAAC,cAAc,CAAC;gBAC1D,CAAC,CAAC,IAAI;YACR,eAAe,EAAE,EAAE;YACnB,gBAAgB,EAAE,SAAS,CAAC,gBAAgB,IAAI,IAAI;YACpD,gBAAgB,EAAE,IAAI;SACvB,CAAC;QACF,IAAI,IAAc,CAAC;QACnB,IAAI,CAAC;YACH,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QAC9C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC,MAAM,CAChB,OAAO,CAAC,SAAS,EAAE,cAAc,CAAC,EAClC,SAAS,EACT,OAAO,CACR,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC;QAC9D,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC,MAAM,CAChB,OAAO,CAAC,SAAS,EAAE,oBAAoB,CAAC,EACxC,SAAS,EACT,OAAO,CACR,CAAC;QACJ,CAAC;QAED,IAAI,aAAqB,CAAC;QAC1B,IAAI,CAAC;YACH,aAAa,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QAC3D,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC,MAAM,CAChB,OAAO,CAAC,SAAS,EAAE,qBAAqB,CAAC,EACzC,SAAS,EACT,OAAO,CACR,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,aAAa,GAAG,aAAa,CAAC;QAEtC,MAAM,WAAW,GAAG,OAAO,CAAC,aAAa,EAAE;YACzC,WAAW;YACX,iBAAiB;SAClB,CAAC,CAAC;QACH,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC,MAAM,CAChB,cAAc,CACZ,SAAS,EACT,qBAAqB,EACrB,WAAW,CAAC;gBACV,SAAS;gBACT,aAAa;gBACb,WAAW,EAAE,IAAI;gBACjB,SAAS,EAAE,IAAI;gBACf,YAAY,EAAE,IAAI;gBAClB,QAAQ,EAAE,IAAI;aACf,CAAC,CACH,EACD,SAAS,EACT,OAAO,CACR,CAAC;QACJ,CAAC;QAED,IAAI,WAAmB,CAAC;QACxB,IAAI,CAAC;YACH,WAAW,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;QAC7C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC,MAAM,CAChB,cAAc,CACZ,SAAS,EACT,qBAAqB,EACrB,WAAW,CAAC;gBACV,SAAS;gBACT,aAAa;gBACb,WAAW,EAAE,IAAI;gBACjB,SAAS,EAAE,IAAI;gBACf,YAAY,EAAE,IAAI;gBAClB,QAAQ,EAAE,IAAI;aACf,CAAC,CACH,EACD,SAAS,EACT,OAAO,CACR,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,WAAW,GAAG,WAAW,CAAC;QAElC,IAAI,WAAW,KAAK,aAAa,EAAE,CAAC;YAClC,OAAO,IAAI,CAAC,MAAM,CAChB,OAAO,CACL,SAAS,EACT,wBAAwB,EACxB,WAAW,CAAC;gBACV,SAAS;gBACT,aAAa;gBACb,WAAW;gBACX,SAAS,EAAE,IAAI;gBACf,YAAY,EAAE,qBAAqB,CAAC,WAAW,CAAC;gBAChD,QAAQ,EAAE,IAAI;aACf,CAAC,CACH,EACD,SAAS,EACT,OAAO,CACR,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,WAAW,CAAC,aAAa,CAAC,CAAC;QAC3C,OAAO,CAAC,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACrE,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;QAC9C,MAAM,aAAa,GAAG,cAAc;YAClC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,KAAK,cAAc,CAAC,IAAI,IAAI,CAAC;YAC1E,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC;gBACnD,OAAO,CAAC,CAAC,CAAC;gBACV,IAAI,CAAC,CAAC;QACV,MAAM,YAAY,GAAG,qBAAqB,CAAC,aAAa,CAAC,CAAC;QAC1D,MAAM,QAAQ,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;QAC/D,OAAO,CAAC,gBAAgB,GAAG,QAAQ,CAAC;QAEpC,MAAM,mBAAmB,GAAG,WAAW,CAAC;YACtC,SAAS;YACT,aAAa;YACb,WAAW;YACX,SAAS,EAAE,aAAa,EAAE,GAAG,IAAI,IAAI;YACrC,YAAY;YACZ,QAAQ;SACT,CAAC,CAAC;QAEH,IAAI,SAAS,CAAC,IAAI,KAAK,wBAAwB,IAAI,CAAC,cAAc,EAAE,CAAC;YACnE,OAAO,IAAI,CAAC,MAAM,CAChB,cAAc,CACZ,SAAS,EACT,mCAAmC,EACnC,mBAAmB,CACpB,EACD,SAAS,EACT,OAAO,CACR,CAAC;QACJ,CAAC;QACD,IAAI,cAAc,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3C,OAAO,IAAI,CAAC,MAAM,CAChB,cAAc,CAAC,SAAS,EAAE,mBAAmB,EAAE,mBAAmB,CAAC,EACnE,SAAS,EACT,OAAO,CACR,CAAC;QACJ,CAAC;QACD,IAAI,cAAc,IAAI,CAAC,aAAa,EAAE,CAAC;YACrC,MAAM,cAAc,GAAG,WAAW,CAAC;gBACjC,SAAS;gBACT,aAAa;gBACb,WAAW;gBACX,SAAS,EACP,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,EAAE,GAAG;oBACvD,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG;oBACf,IAAI;gBACN,YAAY;gBACZ,QAAQ;aACT,CAAC,CAAC;YACH,OAAO,IAAI,CAAC,MAAM,CAChB,OAAO,CAAC,SAAS,EAAE,iBAAiB,EAAE,cAAc,CAAC,EACrD,SAAS,EACT,OAAO,CACR,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,IAAI,CAAC,MAAM,CAChB,cAAc,CAAC,SAAS,EAAE,iBAAiB,EAAE,mBAAmB,CAAC,EACjE,SAAS,EACT,OAAO,CACR,CAAC;QACJ,CAAC;QACD,IAAI,SAAS,CAAC,gBAAgB,IAAI,QAAQ,KAAK,SAAS,CAAC,gBAAgB,EAAE,CAAC;YAC1E,OAAO,IAAI,CAAC,MAAM,CAChB,OAAO,CAAC,SAAS,EAAE,mBAAmB,EAAE,mBAAmB,CAAC,EAC5D,SAAS,EACT,OAAO,CACR,CAAC;QACJ,CAAC;QACD,IAAI,cAAc,IAAI,mBAAmB,CAAC,MAAM,KAAK,cAAc,EAAE,CAAC;YACpE,OAAO,IAAI,CAAC,MAAM,CAChB,OAAO,CAAC,SAAS,EAAE,wBAAwB,EAAE,mBAAmB,CAAC,EACjE,SAAS,EACT,OAAO,CACR,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC,MAAM,CAChB;YACE,SAAS;YACT,KAAK,EAAE,UAAU;YACjB,MAAM,EAAE,UAAU;YAClB,QAAQ,EAAE,mBAAmB;YAC7B,2BAA2B,EAAE,IAAI;YACjC,yEAAyE;YACzE,yEAAyE;YACzE,qEAAqE;YACrE,oBAAoB,EAAE,SAAS,CAAC,IAAI,KAAK,YAAY;SACtD,EACD,SAAS,EACT,OAAO,CACR,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,SAAoC;QACzC,OAAO,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC5C,CAAC;IAED,uFAAuF;IACvF,UAAU,CACR,UAAsC;QAEtC,IAAI,UAAU,CAAC,KAAK,KAAK,UAAU,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC;YACtE,OAAO,IAAI,CAAC,MAAM,CAChB,UAAU,EACV,YAAY,EACZ;gBACE,SAAS,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY;gBAC3D,aAAa,EAAE,UAAU,CAAC,QAAQ,EAAE,aAAa,IAAI,IAAI;gBACzD,WAAW,EAAE,UAAU,CAAC,QAAQ,EAAE,WAAW,IAAI,IAAI;gBACrD,cAAc,EAAE,UAAU,CAAC,SAAS,CAAC,cAAc;oBACjD,CAAC,CAAC,8BAA8B,CAC5B,UAAU,CAAC,SAAS,CAAC,cAAc,CACpC;oBACH,CAAC,CAAC,IAAI;gBACR,eAAe,EAAE,UAAU,CAAC,QAAQ,EAAE,SAAS;oBAC7C,CAAC,CAAC,CAAC,8BAA8B,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;oBACjE,CAAC,CAAC,EAAE;gBACN,gBAAgB,EAAE,UAAU,CAAC,QAAQ,EAAE,QAAQ,IAAI,IAAI;gBACvD,gBAAgB,EAAE,UAAU,CAAC,QAAQ,EAAE,QAAQ,IAAI,IAAI;aACxD,EACD,6BAA6B,CAC9B,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC,QAAQ,CAClB;YACE,GAAG,UAAU,CAAC,SAAS;YACvB,gBAAgB,EAAE,UAAU,CAAC,QAAQ,CAAC,QAAQ;SAC/C,EACD,YAAY,EACZ,UAAU,CAAC,QAAQ,CAAC,MAAM,CAC3B,CAAC;IACJ,CAAC;CACF"}
@@ -81,6 +81,12 @@ export interface CartographerConfig {
81
81
  projectDir: string;
82
82
  /** Instar state directory (cartographer state nests under here). */
83
83
  stateDir: string;
84
+ /**
85
+ * Optional verified-root namespace. When supplied, state is isolated under
86
+ * cartographer/roots/<namespace>. Omitted preserves the legacy singleton path
87
+ * exactly; PR 11B-1 adds the inert storage substrate without changing callers.
88
+ */
89
+ stateNamespace?: string;
84
90
  /** Hard cap on descent depth (default 12). */
85
91
  maxDepth?: number;
86
92
  /** File extensions that become leaf nodes (default ts/js/mjs/cjs). */