archctx 0.9.4 → 0.11.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/bin/archctx.mjs CHANGED
@@ -173,6 +173,22 @@ var init_architecture = __esm(() => {
173
173
  ];
174
174
  });
175
175
 
176
+ // packages/contracts/src/architecture-history.ts
177
+ function decodeArchitectureHistoryState(value) {
178
+ if (!object(value))
179
+ return;
180
+ if (value.nodes === null && value.edges === null && value.structure === null && error(value.error))
181
+ return value;
182
+ if (value.error === undefined && list(value.nodes, node) && list(value.edges, edge) && list(value.structure, structure))
183
+ return value;
184
+ return;
185
+ }
186
+ var ARCHITECTURE_HISTORY_SCHEMA_VERSION = "archcontext.architecture-history/v1", ARCHITECTURE_HISTORY_MERMAID_SCHEMA_VERSION = "archcontext.architecture-history-mermaid/v1", ARCHITECTURE_HISTORY_DERIVATION_VERSION = "v3", object = (v) => typeof v === "object" && v !== null && !Array.isArray(v), string = (v) => typeof v === "string", edge = (v) => object(v) && string(v.source) && string(v.target), kind = (v) => v === "capability" || v === "module" || v === "component", item = (v) => object(v) && string(v.id) && kind(v.kind) && (v.capability === null || string(v.capability)) && (v.kind !== "capability" || v.capability === v.id), structure = (v) => item(v) && object(v) && string(v.name), node = (v) => object(v) && string(v.id) && string(v.name) && (v.domain === null || string(v.domain)), errors, error = (v) => object(v) && string(v.code) && errors.includes(v.code) && (v.path === undefined || string(v.path) && isRepoRelativePosixPath(v.path)), list = (v, check) => Array.isArray(v) && v.every(check);
187
+ var init_architecture_history = __esm(() => {
188
+ init_schema();
189
+ errors = ["history-model-layout-unsupported", "history-model-missing", "history-model-invalid", "history-model-too-large"];
190
+ });
191
+
176
192
  // packages/contracts/src/architecture-debt.ts
177
193
  function architectureDebtReportIssues(report) {
178
194
  const issues = [];
@@ -1961,6 +1977,450 @@ var init_projection = __esm(() => {
1961
1977
  ISO_INSTANT = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?Z$/;
1962
1978
  });
1963
1979
 
1980
+ // packages/contracts/src/projection-manifest.ts
1981
+ function isRuntimeTopologyTargetType(type) {
1982
+ return typeof type === "string" && RUNTIME_TOPOLOGY_TARGET_TYPES.includes(type);
1983
+ }
1984
+ function architectureDocsProjectionManifestIssues(value) {
1985
+ const issues = [];
1986
+ const manifest = record2(value);
1987
+ if (!manifest)
1988
+ return ["manifest must be an object"];
1989
+ issues.push(...exactKeys(manifest, ["schemaVersion", "rendererVersion", "profile", "layoutVersion", "generatedFrom", "semanticBaseline", "targets"], ["minimumRendererVersion", "minimumProtocolVersion"], "manifest"));
1990
+ if (manifest.schemaVersion !== ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSION)
1991
+ issues.push("manifest.schemaVersion is unsupported");
1992
+ if (!isNonEmptyString(manifest.rendererVersion))
1993
+ issues.push("manifest.rendererVersion must be a non-empty string");
1994
+ for (const [key, family] of [["minimumRendererVersion", "archcontext.docs-renderer/v"], ["minimumProtocolVersion", "archcontext.projection-request/v"]]) {
1995
+ if (Object.hasOwn(manifest, key) && versionNumber(manifest[key], family) === undefined)
1996
+ issues.push(`manifest.${key} must name a supported version family`);
1997
+ }
1998
+ if (!ARCHITECTURE_DOCS_PROJECTION_PROFILES.includes(manifest.profile))
1999
+ issues.push("manifest.profile is unsupported");
2000
+ if (manifest.layoutVersion !== ARCHITECTURE_DOCS_LAYOUT_VERSION_V1)
2001
+ issues.push("manifest.layoutVersion is unsupported");
2002
+ issues.push(...generatedFromIssues(manifest.generatedFrom, "manifest.generatedFrom"));
2003
+ const baseline = record2(manifest.semanticBaseline);
2004
+ if (!baseline)
2005
+ issues.push("manifest.semanticBaseline must be an object");
2006
+ else {
2007
+ issues.push(...exactKeys(baseline, ["modelDigest", "capabilities"], [], "manifest.semanticBaseline"));
2008
+ if (!isDigest(baseline.modelDigest))
2009
+ issues.push("manifest.semanticBaseline.modelDigest must be a SHA-256 digest");
2010
+ issues.push(...capabilityEntriesIssues(baseline.capabilities, "manifest.semanticBaseline.capabilities", true));
2011
+ }
2012
+ const targets = record2(manifest.targets);
2013
+ if (!targets) {
2014
+ issues.push("manifest.targets must be an object keyed by targetId");
2015
+ return issues;
2016
+ }
2017
+ const paths = new Set;
2018
+ const stampOwners = new Map;
2019
+ let topologyStamps;
2020
+ for (const [targetId, row] of Object.entries(targets)) {
2021
+ const prefix = `manifest.targets[${JSON.stringify(targetId)}]`;
2022
+ if (!isNonEmptyString(targetId))
2023
+ issues.push("manifest.targets keys must be non-empty targetIds");
2024
+ issues.push(...manifestTargetIssues(row, prefix));
2025
+ const path = record2(row)?.path;
2026
+ if (typeof path === "string") {
2027
+ if (paths.has(path))
2028
+ issues.push(`${prefix}.path is recorded by another target`);
2029
+ paths.add(path);
2030
+ }
2031
+ const stamps = record2(record2(row)?.sourceStamps) ?? {};
2032
+ if (isRuntimeTopologyTargetType(record2(row)?.type)) {
2033
+ const serialized = JSON.stringify(Object.keys(stamps).sort(compareStrings).map((nodeId) => [nodeId, stamps[nodeId]]));
2034
+ if (topologyStamps === undefined)
2035
+ topologyStamps = { targetId, stamps: serialized };
2036
+ else if (topologyStamps.stamps !== serialized)
2037
+ issues.push(`${prefix}.sourceStamps must equal the sourceStamps of ${topologyStamps.targetId}`);
2038
+ for (const nodeId of Object.keys(stamps)) {
2039
+ const owner = stampOwners.get(nodeId);
2040
+ if (owner !== undefined && !isRuntimeTopologyTargetType(record2(targets[owner])?.type))
2041
+ issues.push(`${prefix}.sourceStamps.${nodeId} is already stamped on ${owner}`);
2042
+ else if (owner === undefined)
2043
+ stampOwners.set(nodeId, targetId);
2044
+ }
2045
+ continue;
2046
+ }
2047
+ for (const nodeId of Object.keys(stamps)) {
2048
+ const owner = stampOwners.get(nodeId);
2049
+ if (owner !== undefined)
2050
+ issues.push(`${prefix}.sourceStamps.${nodeId} is already stamped on ${owner}`);
2051
+ else
2052
+ stampOwners.set(nodeId, targetId);
2053
+ }
2054
+ }
2055
+ return issues;
2056
+ }
2057
+ function architectureDocsProjectionManifestSchemaVersion(body) {
2058
+ let parsed;
2059
+ try {
2060
+ parsed = JSON.parse(body);
2061
+ } catch {
2062
+ return;
2063
+ }
2064
+ const schemaVersion = record2(parsed)?.schemaVersion;
2065
+ return typeof schemaVersion === "string" ? schemaVersion : undefined;
2066
+ }
2067
+ function isSupersededArchitectureDocsProjectionManifestSchemaVersion(schemaVersion) {
2068
+ return SUPERSEDED_ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSIONS.includes(schemaVersion);
2069
+ }
2070
+ function serializeArchitectureDocsProjectionManifest(manifest) {
2071
+ const capabilities = [...manifest.semanticBaseline.capabilities].sort((left, right) => compareStrings(left.capabilityId, right.capabilityId)).map(canonicalCapability);
2072
+ const capabilityBlock = JSON.stringify(capabilities, null, 2).split(`
2073
+ `).map((line, index) => index === 0 ? line : ` ${line}`).join(`
2074
+ `);
2075
+ const targetIds = Object.keys(manifest.targets).sort(compareStrings);
2076
+ const targetLines = targetIds.length === 0 ? [' "targets": {}'] : [
2077
+ ' "targets": {',
2078
+ ...targetIds.flatMap((targetId, index) => [
2079
+ ` ${JSON.stringify(targetId)}:`,
2080
+ ` ${JSON.stringify(canonicalTargetRow(manifest.targets[targetId]))}${index === targetIds.length - 1 ? "" : ","}`
2081
+ ]),
2082
+ " }"
2083
+ ];
2084
+ return [
2085
+ "{",
2086
+ ` "schemaVersion": ${JSON.stringify(manifest.schemaVersion)},`,
2087
+ ` "rendererVersion": ${JSON.stringify(manifest.rendererVersion)},`,
2088
+ ...manifest.minimumRendererVersion === undefined ? [] : [` "minimumRendererVersion": ${JSON.stringify(manifest.minimumRendererVersion)},`],
2089
+ ...manifest.minimumProtocolVersion === undefined ? [] : [` "minimumProtocolVersion": ${JSON.stringify(manifest.minimumProtocolVersion)},`],
2090
+ ` "profile": ${JSON.stringify(manifest.profile)},`,
2091
+ ` "layoutVersion": ${JSON.stringify(manifest.layoutVersion)},`,
2092
+ ` "generatedFrom": ${JSON.stringify({ codeGraphPackage: manifest.generatedFrom.codeGraphPackage, codeGraphVersion: manifest.generatedFrom.codeGraphVersion })},`,
2093
+ ' "semanticBaseline": {',
2094
+ ` "modelDigest": ${JSON.stringify(manifest.semanticBaseline.modelDigest)},`,
2095
+ ` "capabilities": ${capabilityBlock}`,
2096
+ " },",
2097
+ ...targetLines,
2098
+ "}",
2099
+ ""
2100
+ ].join(`
2101
+ `);
2102
+ }
2103
+ function architectureDocsProjectionManifestSemanticState(manifest) {
2104
+ return architectureSemanticStateFromCapabilities(manifest.semanticBaseline.capabilities.map(({ selectorEvidenceDigest: _selectorEvidenceDigest, ...capability }) => capability));
2105
+ }
2106
+ function architectureSemanticStateFromCapabilities(capabilities) {
2107
+ const sorted = [...capabilities].sort((left, right) => compareStrings(left.capabilityId, right.capabilityId));
2108
+ return {
2109
+ schemaVersion: ARCHITECTURE_SEMANTIC_STATE_SCHEMA_VERSION,
2110
+ capabilities: sorted,
2111
+ semanticFingerprint: digestJson(sorted.map(({ capabilityId, semanticFingerprint }) => ({ capabilityId, semanticFingerprint }))),
2112
+ flowProofFingerprint: digestJson(sorted.map(({ capabilityId, flowProofFingerprint }) => ({ capabilityId, flowProofFingerprint })))
2113
+ };
2114
+ }
2115
+ function architectureDocsProjectionManifestSourceStamps(manifest) {
2116
+ const stamps = {};
2117
+ for (const row of Object.values(manifest.targets))
2118
+ Object.assign(stamps, row.sourceStamps ?? {});
2119
+ return stamps;
2120
+ }
2121
+ function architectureDocsProjectionManifestProofEvidence(manifest) {
2122
+ return {
2123
+ rendererVersion: manifest.rendererVersion,
2124
+ selectorEvidenceDigests: Object.fromEntries(manifest.semanticBaseline.capabilities.map((capability) => [capability.capabilityId, capability.selectorEvidenceDigest])),
2125
+ sourceStamps: architectureDocsProjectionManifestSourceStamps(manifest)
2126
+ };
2127
+ }
2128
+ function architectureSourceStampsDigest(stamps) {
2129
+ return digestJson({
2130
+ schemaVersion: "archcontext.architecture-source-stamps/v1",
2131
+ stamps: Object.keys(stamps).sort(compareStrings).map((nodeId) => ({ nodeId, digest: stamps[nodeId] }))
2132
+ });
2133
+ }
2134
+ function architectureProjectionOutputsDigest(input) {
2135
+ return digestJson({
2136
+ schemaVersion: "archcontext.architecture-projection-outputs/v1",
2137
+ rendererVersion: input.rendererVersion,
2138
+ profile: input.profile,
2139
+ outputs: Object.keys(input.outputDigests).sort(compareStrings).map((targetId) => ({ targetId, outputDigest: input.outputDigests[targetId] }))
2140
+ });
2141
+ }
2142
+ function architectureDocsProjectionManifestDigests(manifest) {
2143
+ return {
2144
+ modelDigest: manifest.semanticBaseline.modelDigest,
2145
+ sourceTreeDigest: architectureSourceStampsDigest(architectureDocsProjectionManifestSourceStamps(manifest)),
2146
+ flowProofDigest: architectureDocsProjectionManifestSemanticState(manifest).flowProofFingerprint,
2147
+ projectionDigest: architectureProjectionOutputsDigest({
2148
+ rendererVersion: manifest.rendererVersion,
2149
+ profile: manifest.profile,
2150
+ outputDigests: Object.fromEntries(Object.entries(manifest.targets).map(([targetId, row]) => [targetId, row.outputDigest]))
2151
+ })
2152
+ };
2153
+ }
2154
+ function architectureDocsProjectionProvenanceIssues(value, prefix = "provenance") {
2155
+ const provenance = record2(value);
2156
+ if (!provenance)
2157
+ return [`${prefix} must be an object`];
2158
+ const issues = exactKeys(provenance, ["schemaVersion", "sourceTreeDigest", "modelDigest", "projectionInputDigest", "rendererVersion", "layoutVersion", "generatedFrom"], [], prefix);
2159
+ if (provenance.schemaVersion !== ARCHITECTURE_DOCS_PROJECTION_PROVENANCE_SCHEMA_VERSION)
2160
+ issues.push(`${prefix}.schemaVersion is unsupported`);
2161
+ for (const field of ["sourceTreeDigest", "modelDigest", "projectionInputDigest"]) {
2162
+ if (!isDigest(provenance[field]))
2163
+ issues.push(`${prefix}.${field} must be a SHA-256 digest`);
2164
+ }
2165
+ if (provenance.rendererVersion !== ARCHITECTURE_DOCS_RENDERER_VERSION)
2166
+ issues.push(`${prefix}.rendererVersion must be ${ARCHITECTURE_DOCS_RENDERER_VERSION}`);
2167
+ if (provenance.layoutVersion !== ARCHITECTURE_DOCS_LAYOUT_VERSION_V1)
2168
+ issues.push(`${prefix}.layoutVersion is unsupported`);
2169
+ issues.push(...generatedFromIssues(provenance.generatedFrom, `${prefix}.generatedFrom`));
2170
+ return issues;
2171
+ }
2172
+ function capabilityEntriesIssues(value, prefix, withSelectorEvidence) {
2173
+ if (!Array.isArray(value))
2174
+ return [`${prefix} must be an array`];
2175
+ const issues = [];
2176
+ const ids = value.map((entry) => record2(entry)?.capabilityId);
2177
+ if (!isSortedUniqueStrings(ids))
2178
+ issues.push(`${prefix} must be sorted and unique by capabilityId`);
2179
+ value.forEach((entry, index) => {
2180
+ const entryPrefix = `${prefix}[${index}]`;
2181
+ const capability = record2(entry);
2182
+ if (!capability) {
2183
+ issues.push(`${entryPrefix} must be an object`);
2184
+ return;
2185
+ }
2186
+ const required = ["capabilityId", "memberNodeIds", "semanticFingerprint", "flowProofFingerprint", "proofStatus", "facets", ...withSelectorEvidence ? ["selectorEvidenceDigest"] : []];
2187
+ issues.push(...exactKeys(capability, required, [], entryPrefix));
2188
+ if (!isNonEmptyString(capability.capabilityId))
2189
+ issues.push(`${entryPrefix}.capabilityId must be a non-empty string`);
2190
+ if (!Array.isArray(capability.memberNodeIds) || !isSortedUniqueStrings(capability.memberNodeIds))
2191
+ issues.push(`${entryPrefix}.memberNodeIds must be sorted and unique`);
2192
+ if (!isDigest(capability.semanticFingerprint))
2193
+ issues.push(`${entryPrefix}.semanticFingerprint must be a SHA-256 digest`);
2194
+ if (!isDigest(capability.flowProofFingerprint))
2195
+ issues.push(`${entryPrefix}.flowProofFingerprint must be a SHA-256 digest`);
2196
+ if (withSelectorEvidence && !isDigest(capability.selectorEvidenceDigest))
2197
+ issues.push(`${entryPrefix}.selectorEvidenceDigest must be a SHA-256 digest`);
2198
+ if (!isArchitectureCapabilityProofStatus(capability.proofStatus))
2199
+ issues.push(`${entryPrefix}.proofStatus must be a P1/P2 proof status`);
2200
+ const facets = record2(capability.facets);
2201
+ if (!facets)
2202
+ issues.push(`${entryPrefix}.facets must be an object`);
2203
+ else {
2204
+ issues.push(...exactKeys(facets, [...ARCHITECTURE_SEMANTIC_FACETS], [], `${entryPrefix}.facets`));
2205
+ for (const facet of ARCHITECTURE_SEMANTIC_FACETS) {
2206
+ if (!isDigest(facets[facet]))
2207
+ issues.push(`${entryPrefix}.facets.${facet} must be a SHA-256 digest`);
2208
+ }
2209
+ }
2210
+ });
2211
+ return issues;
2212
+ }
2213
+ function generatedFromIssues(value, prefix) {
2214
+ const generatedFrom = record2(value);
2215
+ if (!generatedFrom)
2216
+ return [`${prefix} must be an object`];
2217
+ const issues = exactKeys(generatedFrom, ["codeGraphPackage", "codeGraphVersion"], [], prefix);
2218
+ for (const field of ["codeGraphPackage", "codeGraphVersion"]) {
2219
+ if (!isNonEmptyString(generatedFrom[field]))
2220
+ issues.push(`${prefix}.${field} must be a non-empty string`);
2221
+ }
2222
+ return issues;
2223
+ }
2224
+ function canonicalCapability(capability) {
2225
+ return {
2226
+ capabilityId: capability.capabilityId,
2227
+ memberNodeIds: [...capability.memberNodeIds],
2228
+ semanticFingerprint: capability.semanticFingerprint,
2229
+ flowProofFingerprint: capability.flowProofFingerprint,
2230
+ proofStatus: { p1: capability.proofStatus.p1, p2: capability.proofStatus.p2 },
2231
+ facets: Object.fromEntries(Object.keys(capability.facets).sort(compareStrings).map((facet) => [facet, capability.facets[facet]])),
2232
+ selectorEvidenceDigest: capability.selectorEvidenceDigest
2233
+ };
2234
+ }
2235
+ function canonicalTargetRow(row) {
2236
+ return {
2237
+ type: row.type,
2238
+ scope: {
2239
+ kind: row.scope.kind,
2240
+ ...row.scope.id !== undefined ? { id: row.scope.id } : {},
2241
+ ...row.scope.entityKind !== undefined ? { entityKind: row.scope.entityKind } : {}
2242
+ },
2243
+ path: row.path,
2244
+ ownership: row.ownership,
2245
+ format: row.format,
2246
+ outputDigest: row.outputDigest,
2247
+ ...row.sourceStamps !== undefined ? { sourceStamps: Object.fromEntries(Object.keys(row.sourceStamps).sort(compareStrings).map((nodeId) => [nodeId, row.sourceStamps[nodeId]])) } : {},
2248
+ ...row.scale !== undefined ? {
2249
+ scale: {
2250
+ fileCountBucket: { lower: row.scale.fileCountBucket.lower, upper: row.scale.fileCountBucket.upper },
2251
+ lineCountBucket: { lower: row.scale.lineCountBucket.lower, upper: row.scale.lineCountBucket.upper }
2252
+ }
2253
+ } : {}
2254
+ };
2255
+ }
2256
+ function isArchitectureScaleBucket(value) {
2257
+ const bucket = record2(value);
2258
+ if (!bucket || Object.keys(bucket).length !== 2)
2259
+ return false;
2260
+ const { lower, upper } = bucket;
2261
+ if (typeof lower !== "number" || typeof upper !== "number" || !Number.isSafeInteger(lower) || !Number.isSafeInteger(upper))
2262
+ return false;
2263
+ if (lower === 0)
2264
+ return upper === 1;
2265
+ let magnitude = 1;
2266
+ while (magnitude * 10 <= lower)
2267
+ magnitude *= 10;
2268
+ const mantissa = lower / magnitude;
2269
+ if (mantissa === 1)
2270
+ return upper === 2 * magnitude;
2271
+ if (mantissa === 2)
2272
+ return upper === 5 * magnitude;
2273
+ if (mantissa === 5)
2274
+ return upper === 10 * magnitude;
2275
+ return false;
2276
+ }
2277
+ function manifestTargetIssues(value, prefix) {
2278
+ const target = record2(value);
2279
+ if (!target)
2280
+ return [`${prefix} must be an object`];
2281
+ const issues = exactKeys(target, ["type", "scope", "path", "ownership", "format", "outputDigest"], ["sourceStamps", "scale"], prefix);
2282
+ if (typeof target.type !== "string" || !Object.hasOwn(TARGET_TYPES, target.type))
2283
+ issues.push(`${prefix}.type is unsupported`);
2284
+ const scope = record2(target.scope);
2285
+ if (!scope || typeof scope.kind !== "string" || !Object.hasOwn(SCOPE_KINDS, scope.kind))
2286
+ issues.push(`${prefix}.scope.kind is unsupported`);
2287
+ else {
2288
+ issues.push(...exactKeys(scope, ["kind"], ["id", "entityKind"], `${prefix}.scope`));
2289
+ for (const field of ["id", "entityKind"]) {
2290
+ if (scope[field] !== undefined && typeof scope[field] !== "string")
2291
+ issues.push(`${prefix}.scope.${field} must be a string`);
2292
+ }
2293
+ }
2294
+ if (typeof target.path !== "string" || !isRepoRelativePosixPath(target.path))
2295
+ issues.push(`${prefix}.path must be a repository-relative POSIX path`);
2296
+ if (typeof target.ownership !== "string" || !Object.hasOwn(OWNERSHIPS, target.ownership))
2297
+ issues.push(`${prefix}.ownership is unsupported`);
2298
+ if (typeof target.format !== "string" || !Object.hasOwn(FORMATS, target.format))
2299
+ issues.push(`${prefix}.format is unsupported`);
2300
+ if (!isDigest(target.outputDigest))
2301
+ issues.push(`${prefix}.outputDigest must be a SHA-256 digest`);
2302
+ if (target.sourceStamps !== undefined && target.type !== "entity-summary" && !isRuntimeTopologyTargetType(target.type)) {
2303
+ issues.push(`${prefix}.sourceStamps are only allowed on entity-summary and runtime topology targets`);
2304
+ }
2305
+ if (target.scale !== undefined && target.type !== "entity-summary")
2306
+ issues.push(`${prefix}.scale is only allowed on entity-summary targets`);
2307
+ if (target.sourceStamps !== undefined) {
2308
+ const stamps = record2(target.sourceStamps);
2309
+ if (!stamps || Object.keys(stamps).length === 0)
2310
+ issues.push(`${prefix}.sourceStamps must be a non-empty object keyed by node id`);
2311
+ else {
2312
+ for (const [nodeId, digest] of Object.entries(stamps)) {
2313
+ if (!isNonEmptyString(nodeId))
2314
+ issues.push(`${prefix}.sourceStamps keys must be non-empty node ids`);
2315
+ if (!isDigest(digest))
2316
+ issues.push(`${prefix}.sourceStamps.${nodeId} must be a SHA-256 digest`);
2317
+ }
2318
+ }
2319
+ }
2320
+ const ownNodeId = scope?.id;
2321
+ const stampsOwnNode = typeof ownNodeId === "string" && record2(target.sourceStamps) !== undefined && Object.hasOwn(record2(target.sourceStamps), ownNodeId);
2322
+ if (stampsOwnNode !== (target.scale !== undefined))
2323
+ issues.push(`${prefix}.scale must be present exactly when sourceStamps stamps the target's own node`);
2324
+ if (target.scale !== undefined) {
2325
+ const scale = record2(target.scale);
2326
+ if (!scale)
2327
+ issues.push(`${prefix}.scale must be an object`);
2328
+ else {
2329
+ issues.push(...exactKeys(scale, ["fileCountBucket", "lineCountBucket"], [], `${prefix}.scale`));
2330
+ for (const field of ["fileCountBucket", "lineCountBucket"]) {
2331
+ if (!isArchitectureScaleBucket(scale[field]))
2332
+ issues.push(`${prefix}.scale.${field} must be a 1-2-5 magnitude bucket`);
2333
+ }
2334
+ }
2335
+ }
2336
+ return issues;
2337
+ }
2338
+ function record2(value) {
2339
+ return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
2340
+ }
2341
+ function exactKeys(value, required, optional, prefix) {
2342
+ const issues = required.filter((key) => !(key in value)).map((key) => `${prefix}.${key} is required`);
2343
+ const allowed = new Set([...required, ...optional]);
2344
+ for (const key of Object.keys(value))
2345
+ if (!allowed.has(key))
2346
+ issues.push(`${prefix}.${key} is not allowed`);
2347
+ return issues;
2348
+ }
2349
+ function isDigest(value) {
2350
+ return typeof value === "string" && SHA256.test(value);
2351
+ }
2352
+ function isNonEmptyString(value) {
2353
+ return typeof value === "string" && value.trim() !== "";
2354
+ }
2355
+ function isSortedUniqueStrings(values) {
2356
+ return values.every((value, index) => typeof value === "string" && (index === 0 || values[index - 1] < value));
2357
+ }
2358
+ function compareStrings(left, right) {
2359
+ return left < right ? -1 : left > right ? 1 : 0;
2360
+ }
2361
+ function versionNumber(value, family) {
2362
+ if (typeof value !== "string" || !value.startsWith(family))
2363
+ return;
2364
+ const suffix = value.slice(family.length);
2365
+ if (!/^[1-9][0-9]*$/.test(suffix))
2366
+ return;
2367
+ const version = Number(suffix);
2368
+ return Number.isSafeInteger(version) ? version : undefined;
2369
+ }
2370
+ function architectureDocsProjectionCompatibilityIssues(value, engine = {
2371
+ rendererVersion: ARCHITECTURE_DOCS_RENDERER_VERSION,
2372
+ protocolVersion: PROJECTION_REQUEST_SCHEMA_VERSION
2373
+ }) {
2374
+ const manifest = record2(value);
2375
+ if (!manifest)
2376
+ return [];
2377
+ const issues = [];
2378
+ if (["minimumRendererVersion", "minimumProtocolVersion"].some((key) => Object.hasOwn(manifest, key)) && manifest.schemaVersion !== ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSION)
2379
+ issues.push("projection manifest floors require the current schema");
2380
+ if (typeof manifest.schemaVersion === "string" && manifest.schemaVersion !== ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSION && !isSupersededArchitectureDocsProjectionManifestSchemaVersion(manifest.schemaVersion))
2381
+ issues.push("projection manifest schema is unsupported by this engine");
2382
+ for (const [key, family, current] of [
2383
+ ["minimumRendererVersion", "archcontext.docs-renderer/v", engine.rendererVersion],
2384
+ ["minimumProtocolVersion", "archcontext.projection-request/v", engine.protocolVersion]
2385
+ ]) {
2386
+ if (!Object.hasOwn(manifest, key))
2387
+ continue;
2388
+ const required = versionNumber(manifest[key], family);
2389
+ const supported = versionNumber(current, family);
2390
+ if (required === undefined || supported === undefined || supported < required)
2391
+ issues.push(`projection manifest ${key} is unsupported by this engine`);
2392
+ }
2393
+ return issues;
2394
+ }
2395
+ var ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSION = "archcontext.architecture-docs-projection-manifest/v3", SUPERSEDED_ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSIONS, ARCHITECTURE_DOCS_PROJECTION_MANIFEST_UPGRADE_COMMAND = "archctx docs apply --approved --profile <default|repo-harness/v1>", ARCHITECTURE_DOCS_PROJECTION_MANIFEST_MIGRATION_GUIDE = "docs/runbooks/architecture-documentation-projections.md", PROJECTION_MANIFEST_UPGRADE_REQUIRED = "projection-manifest-upgrade-required", PROJECTION_MANIFEST_INVALID = "projection-manifest-invalid", PROJECTION_FOOTPRINT_UNCOVERED = "projection-footprint-uncovered", ARCHITECTURE_DOCS_PROJECTION_PROVENANCE_SCHEMA_VERSION = "archcontext.architecture-docs-projection-provenance/v3", ARCHITECTURE_DOCS_LAYOUT_VERSION_V1 = "archcontext.docs-layout/v1", ARCHITECTURE_SEMANTIC_STATE_SCHEMA_VERSION = "archcontext.architecture-semantic-state/v1", ARCHITECTURE_DOCS_PROJECTION_PROFILES, SHA256, TARGET_TYPES, RUNTIME_TOPOLOGY_TARGET_TYPES, SCOPE_KINDS, OWNERSHIPS, FORMATS;
2396
+ var init_projection_manifest = __esm(() => {
2397
+ init_projection();
2398
+ init_schema();
2399
+ SUPERSEDED_ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSIONS = [
2400
+ "archcontext.architecture-docs-projection-manifest/v1",
2401
+ "archcontext.architecture-docs-projection-manifest/v2"
2402
+ ];
2403
+ ARCHITECTURE_DOCS_PROJECTION_PROFILES = ["default", "repo-harness/v1"];
2404
+ SHA256 = /^sha256:[a-f0-9]{64}$/;
2405
+ TARGET_TYPES = {
2406
+ "architecture-index": true,
2407
+ "entity-summary": true,
2408
+ "relation-summary": true,
2409
+ "decision-index": true,
2410
+ "architecture-changelog": true,
2411
+ "diagram-mermaid": true,
2412
+ "diagram-structurizr": true,
2413
+ "diagram-likec4": true,
2414
+ "diagram-runtime-topology": true,
2415
+ "runtime-topology-summary": true,
2416
+ "agent-context": true
2417
+ };
2418
+ RUNTIME_TOPOLOGY_TARGET_TYPES = ["diagram-runtime-topology", "runtime-topology-summary"];
2419
+ SCOPE_KINDS = { repository: true, entity: true, relation: true, decision: true, diagram: true, changelog: true };
2420
+ OWNERSHIPS = { generated: true, mixed: true };
2421
+ FORMATS = { markdown: true, mermaid: true, "structurizr-json": true, likec4: true };
2422
+ });
2423
+
1964
2424
  // packages/contracts/src/projection-recovery.ts
1965
2425
  function jsonDataCopy(input, maximum) {
1966
2426
  let measured = 0;
@@ -2085,7 +2545,7 @@ var init_projection_recovery = __esm(() => {
2085
2545
  // packages/contracts/src/failure.ts
2086
2546
  import { isNativeError } from "node:util/types";
2087
2547
  function ownData(input, key) {
2088
- if (!record2(input))
2548
+ if (!record3(input))
2089
2549
  throw new Error("Failure metadata must be an object");
2090
2550
  const descriptor = Object.getOwnPropertyDescriptor(input, key);
2091
2551
  if (!descriptor) {
@@ -2133,7 +2593,7 @@ function detailsFor(policy, input) {
2133
2593
  if (policy.facts)
2134
2594
  return localFactsFor(policy.facts, input);
2135
2595
  const result = {};
2136
- if (!record2(input))
2596
+ if (!record3(input))
2137
2597
  throw new Error("Failure details must be an object");
2138
2598
  let omitted = 0;
2139
2599
  for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(input))) {
@@ -2159,7 +2619,7 @@ function detailsFor(policy, input) {
2159
2619
  return result;
2160
2620
  }
2161
2621
  function dataRecord(value) {
2162
- if (!record2(value))
2622
+ if (!record3(value))
2163
2623
  throw new Error("Facts must be a plain record");
2164
2624
  const proto = Object.getPrototypeOf(value), keys = Reflect.ownKeys(value);
2165
2625
  if (proto !== Object.prototype && proto !== null || keys.length > 16 || Object.keys(value).length !== keys.length || keys.some((key) => typeof key !== "string"))
@@ -2284,7 +2744,7 @@ function nativeFactsFor(policy, input) {
2284
2744
  let omitted = 0, characters = 0;
2285
2745
  const omit = (value) => {
2286
2746
  omitted++;
2287
- const strings = (v) => typeof v === "string" ? v.length : Array.isArray(v) ? v.reduce((n, item) => n + strings(item), 0) : record2(v) ? Object.values(v).reduce((n, item) => n + strings(item), 0) : 0;
2747
+ const strings = (v) => typeof v === "string" ? v.length : Array.isArray(v) ? v.reduce((n, item) => n + strings(item), 0) : record3(v) ? Object.values(v).reduce((n, item) => n + strings(item), 0) : 0;
2288
2748
  characters += strings(value);
2289
2749
  };
2290
2750
  const text = (value) => {
@@ -2423,7 +2883,7 @@ function budgetIssues(value, depth = 0, maxStringBytes = 256) {
2423
2883
  return Number.isFinite(value) ? [] : ["detail number is not finite"];
2424
2884
  if (Array.isArray(value))
2425
2885
  return value.length <= 32 ? value.flatMap((item) => budgetIssues(item, depth + 1, maxStringBytes)) : ["detail list exceeds 32"];
2426
- if (record2(value))
2886
+ if (record3(value))
2427
2887
  return Object.keys(value).length <= 16 ? Object.values(value).flatMap((item) => budgetIssues(item, depth + 1, maxStringBytes)) : ["detail object exceeds 16 fields"];
2428
2888
  return value === null || typeof value === "boolean" ? [] : ["detail value is not JSON"];
2429
2889
  }
@@ -2498,7 +2958,7 @@ function toEnvelope(requestId, error, stage) {
2498
2958
  }
2499
2959
  }
2500
2960
  function normalizeFailureResult(result, stage, requestId = "failure") {
2501
- if (!record2(result))
2961
+ if (!record3(result))
2502
2962
  return result;
2503
2963
  try {
2504
2964
  if (ownData(result, "ok") !== false)
@@ -2528,7 +2988,7 @@ function jsonDataSnapshot(value, depth = 0, maxStringBytes = 256) {
2528
2988
  return jsonDataSnapshot(descriptor.value, depth + 1, maxStringBytes);
2529
2989
  });
2530
2990
  }
2531
- if (record2(value)) {
2991
+ if (record3(value)) {
2532
2992
  const prototype = Object.getPrototypeOf(value);
2533
2993
  const keys = Reflect.ownKeys(value);
2534
2994
  if (prototype !== Object.prototype && prototype !== null || keys.length > 16 || Object.keys(value).length !== keys.length || keys.some((key) => typeof key !== "string"))
@@ -2539,7 +2999,7 @@ function jsonDataSnapshot(value, depth = 0, maxStringBytes = 256) {
2539
2999
  }
2540
3000
  function failureIssues(value) {
2541
3001
  try {
2542
- if (!record2(value))
3002
+ if (!record3(value))
2543
3003
  return ["failure must be an object"];
2544
3004
  const fields = ["code", "message", "severity", "retryable", "action", "reasonCode", "details"];
2545
3005
  const keys = Reflect.ownKeys(value);
@@ -2558,10 +3018,12 @@ function failureIssues(value) {
2558
3018
  return ["failure violates its registered contract or budget"];
2559
3019
  }
2560
3020
  }
2561
- var FAILURE_STAGES, ERROR_CLASSES, CODE_FACTS_ISSUE_MESSAGES, policies, FAILURE_POLICIES, catalogDefaults, actions, bytes = (value) => new TextEncoder().encode(value).byteLength, record2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value), finiteNonnegative = (value) => typeof value === "number" && Number.isFinite(value) && value >= 0, criticalKey = (key) => /id$|digest|receipt|binding|readback|lookupkey/i.test(key), localEnums, nativeEnums, nativeDiagnosticKinds, FailureError;
3021
+ var FAILURE_STAGES, ERROR_CLASSES, CODE_FACTS_ISSUE_MESSAGES, policies, FAILURE_POLICIES, catalogDefaults, actions, bytes = (value) => new TextEncoder().encode(value).byteLength, record3 = (value) => value !== null && typeof value === "object" && !Array.isArray(value), finiteNonnegative = (value) => typeof value === "number" && Number.isFinite(value) && value >= 0, criticalKey = (key) => /id$|digest|receipt|binding|readback|lookupkey/i.test(key), localEnums, nativeEnums, nativeDiagnosticKinds, FailureError;
2562
3022
  var init_failure = __esm(() => {
2563
3023
  init_changeset_recovery();
2564
3024
  init_ports();
3025
+ init_projection();
3026
+ init_projection_manifest();
2565
3027
  init_projection_recovery();
2566
3028
  init_schema();
2567
3029
  FAILURE_STAGES = Object.freeze(["debt", "complete", "practice-checkpoint", "cli", "mcp", "hook-checkpoint", "failure-metadata", "public-operation", "native-export", "docs-anchors", "flows-check"]);
@@ -2576,6 +3038,7 @@ var init_failure = __esm(() => {
2576
3038
  "pending-source-changes": "CodeGraph repository index has pending or unreported source changes"
2577
3039
  });
2578
3040
  policies = {
3041
+ "history-shallow-repository": { code: "AC_PRECONDITION_FAILED", message: "Architecture history requires a complete Git repository.", action: "unshallow-repository" },
2579
3042
  "code-facts-read-not-ready": { code: "AC_CODE_FACTS_UNAVAILABLE", message: "The existing CodeGraph index does not attest to the current source population.", facts: { issues: "codeFactsIssues" }, action: "codegraph-sync", retryable: false },
2580
3043
  "code-facts-snapshot-changed": { code: "AC_CODE_FACTS_UNAVAILABLE", message: "Source or index inputs changed while reading the private snapshot.", action: "retry-read", retryable: true, facts: {} },
2581
3044
  "code-facts-snapshot-limit-exceeded": { code: "AC_CODE_FACTS_UNAVAILABLE", message: "The private CodeGraph snapshot exceeds its 512 MiB or 100000 entry limit.", action: "reduce-snapshot-size", retryable: false, facts: {} },
@@ -2589,7 +3052,7 @@ var init_failure = __esm(() => {
2589
3052
  "model-missing": { code: "AC_MODEL_ADOPTION_REQUIRED", message: "Architecture debt requires an adopted model.", fields: ["checks"] },
2590
3053
  "changed-path-invalid": { code: "AC_SCHEMA_INVALID", message: "Changed paths must be an array of repository-relative POSIX paths.", fields: ["checks"] },
2591
3054
  "debt-report-invalid": { code: "AC_SCHEMA_INVALID", message: "Architecture debt evidence violates its contract.", fields: ["checks"] },
2592
- "projection-manifest-upgrade-required": { code: "AC_PRECONDITION_FAILED", message: "The committed projection manifest requires supported re-baselining. First restore the original model if missing; the manifest digest cannot recover it. With the reviewed model available, follow docs/runbooks/architecture-documentation-projections.md before running archctx docs apply --approved --profile <default|repo-harness/v1>." },
3055
+ "projection-manifest-upgrade-required": { code: "AC_PRECONDITION_FAILED", message: `The committed projection manifest requires supported re-baselining. First restore the original model if missing; the manifest digest cannot recover it. With the reviewed model available, follow ${ARCHITECTURE_DOCS_PROJECTION_MANIFEST_MIGRATION_GUIDE} before running ${ARCHITECTURE_DOCS_PROJECTION_MANIFEST_UPGRADE_COMMAND}.`, facts: { manifestPath: "optional:projectionManifestPath", foundSchemaVersion: "optional:projectionManifestSchemaVersion", supportedSchemaVersion: "optional:projectionManifestSchemaVersion", upgradeCommand: "optional:projectionManifestUpgradeCommand", migrationGuide: "optional:projectionManifestMigrationGuide" } },
2593
3056
  "projection-manifest-invalid": { code: "AC_PRECONDITION_FAILED", message: "The committed projection manifest violates its contract." },
2594
3057
  "architecture-model-ignored": { code: "AC_PRECONDITION_FAILED", action: "commit-architecture-model", message: "Git ignore rules exclude architecture model paths, so the model cannot be committed and a manifest digest cannot rebuild it. Remove or narrow the rule, commit the model, then retry adoption. The diagnostic command prints each deciding rule.", facts: { pathCount: "uint", paths: "optional:diagnosticPaths", commands: "optional:diagnosticCommands", omittedPathCount: "uint" } },
2595
3058
  "projection-footprint-uncovered": { code: "AC_PRECONDITION_FAILED", message: "Declared source footprints lack a projection target." },
@@ -2850,6 +3313,10 @@ var init_failure = __esm(() => {
2850
3313
  upgradeAction: ["upgrade-archctx-runtime"],
2851
3314
  upgradeCommand: ["archctx daemon upgrade"],
2852
3315
  ownershipAction: ["remove-whole-file-outputs-and-reapply"],
3316
+ projectionManifestPath: [ARCHITECTURE_DOCS_PROJECTION_MANIFEST_PATH],
3317
+ projectionManifestSchemaVersion: [...SUPERSEDED_ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSIONS, ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSION],
3318
+ projectionManifestUpgradeCommand: [ARCHITECTURE_DOCS_PROJECTION_MANIFEST_UPGRADE_COMMAND],
3319
+ projectionManifestMigrationGuide: [ARCHITECTURE_DOCS_PROJECTION_MANIFEST_MIGRATION_GUIDE],
2853
3320
  ledgerModeField: ["rolloutMode", "readMode", "writeMode"],
2854
3321
  depsField: ["from", "into", "importNodeLimit", "edgeLimit"],
2855
3322
  depsIssue: ["unknown-node", "invalid-limit", "missing-value"],
@@ -2974,6 +3441,7 @@ var init_failure = __esm(() => {
2974
3441
  ],
2975
3442
  operation: [
2976
3443
  "rev-parse",
3444
+ "log",
2977
3445
  "ls-tree",
2978
3446
  "ls-files",
2979
3447
  "cat-file"
@@ -3566,450 +4034,6 @@ var PRACTICE_SCHEMA_VERSION = "archcontext.practice/v1", PRACTICE_PROFILE_SCHEMA
3566
4034
  var PROJECTION_PUBLISH_RUN_SCHEMA_VERSION = "archcontext.projection-publish-run/v1", PROJECTION_PUBLISH_STATUS_SCHEMA_VERSION = "archcontext.projection-publish-status/v1", PROJECTION_PR_VERIFICATION_SCHEMA_VERSION = "archcontext.projection-pr-verification/v1", PROJECTION_WRITER_BRANCH_PREFIX = "archctx/", PROJECTION_WRITER_DEFAULT_BRANCH = "archctx/projection";
3567
4035
  var init_projection_writer = () => {};
3568
4036
 
3569
- // packages/contracts/src/projection-manifest.ts
3570
- function isRuntimeTopologyTargetType(type) {
3571
- return typeof type === "string" && RUNTIME_TOPOLOGY_TARGET_TYPES.includes(type);
3572
- }
3573
- function architectureDocsProjectionManifestIssues(value) {
3574
- const issues = [];
3575
- const manifest = record3(value);
3576
- if (!manifest)
3577
- return ["manifest must be an object"];
3578
- issues.push(...exactKeys(manifest, ["schemaVersion", "rendererVersion", "profile", "layoutVersion", "generatedFrom", "semanticBaseline", "targets"], ["minimumRendererVersion", "minimumProtocolVersion"], "manifest"));
3579
- if (manifest.schemaVersion !== ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSION)
3580
- issues.push("manifest.schemaVersion is unsupported");
3581
- if (!isNonEmptyString(manifest.rendererVersion))
3582
- issues.push("manifest.rendererVersion must be a non-empty string");
3583
- for (const [key, family] of [["minimumRendererVersion", "archcontext.docs-renderer/v"], ["minimumProtocolVersion", "archcontext.projection-request/v"]]) {
3584
- if (Object.hasOwn(manifest, key) && versionNumber(manifest[key], family) === undefined)
3585
- issues.push(`manifest.${key} must name a supported version family`);
3586
- }
3587
- if (!ARCHITECTURE_DOCS_PROJECTION_PROFILES.includes(manifest.profile))
3588
- issues.push("manifest.profile is unsupported");
3589
- if (manifest.layoutVersion !== ARCHITECTURE_DOCS_LAYOUT_VERSION_V1)
3590
- issues.push("manifest.layoutVersion is unsupported");
3591
- issues.push(...generatedFromIssues(manifest.generatedFrom, "manifest.generatedFrom"));
3592
- const baseline = record3(manifest.semanticBaseline);
3593
- if (!baseline)
3594
- issues.push("manifest.semanticBaseline must be an object");
3595
- else {
3596
- issues.push(...exactKeys(baseline, ["modelDigest", "capabilities"], [], "manifest.semanticBaseline"));
3597
- if (!isDigest(baseline.modelDigest))
3598
- issues.push("manifest.semanticBaseline.modelDigest must be a SHA-256 digest");
3599
- issues.push(...capabilityEntriesIssues(baseline.capabilities, "manifest.semanticBaseline.capabilities", true));
3600
- }
3601
- const targets = record3(manifest.targets);
3602
- if (!targets) {
3603
- issues.push("manifest.targets must be an object keyed by targetId");
3604
- return issues;
3605
- }
3606
- const paths = new Set;
3607
- const stampOwners = new Map;
3608
- let topologyStamps;
3609
- for (const [targetId, row] of Object.entries(targets)) {
3610
- const prefix = `manifest.targets[${JSON.stringify(targetId)}]`;
3611
- if (!isNonEmptyString(targetId))
3612
- issues.push("manifest.targets keys must be non-empty targetIds");
3613
- issues.push(...manifestTargetIssues(row, prefix));
3614
- const path = record3(row)?.path;
3615
- if (typeof path === "string") {
3616
- if (paths.has(path))
3617
- issues.push(`${prefix}.path is recorded by another target`);
3618
- paths.add(path);
3619
- }
3620
- const stamps = record3(record3(row)?.sourceStamps) ?? {};
3621
- if (isRuntimeTopologyTargetType(record3(row)?.type)) {
3622
- const serialized = JSON.stringify(Object.keys(stamps).sort(compareStrings).map((nodeId) => [nodeId, stamps[nodeId]]));
3623
- if (topologyStamps === undefined)
3624
- topologyStamps = { targetId, stamps: serialized };
3625
- else if (topologyStamps.stamps !== serialized)
3626
- issues.push(`${prefix}.sourceStamps must equal the sourceStamps of ${topologyStamps.targetId}`);
3627
- for (const nodeId of Object.keys(stamps)) {
3628
- const owner = stampOwners.get(nodeId);
3629
- if (owner !== undefined && !isRuntimeTopologyTargetType(record3(targets[owner])?.type))
3630
- issues.push(`${prefix}.sourceStamps.${nodeId} is already stamped on ${owner}`);
3631
- else if (owner === undefined)
3632
- stampOwners.set(nodeId, targetId);
3633
- }
3634
- continue;
3635
- }
3636
- for (const nodeId of Object.keys(stamps)) {
3637
- const owner = stampOwners.get(nodeId);
3638
- if (owner !== undefined)
3639
- issues.push(`${prefix}.sourceStamps.${nodeId} is already stamped on ${owner}`);
3640
- else
3641
- stampOwners.set(nodeId, targetId);
3642
- }
3643
- }
3644
- return issues;
3645
- }
3646
- function architectureDocsProjectionManifestSchemaVersion(body) {
3647
- let parsed;
3648
- try {
3649
- parsed = JSON.parse(body);
3650
- } catch {
3651
- return;
3652
- }
3653
- const schemaVersion = record3(parsed)?.schemaVersion;
3654
- return typeof schemaVersion === "string" ? schemaVersion : undefined;
3655
- }
3656
- function isSupersededArchitectureDocsProjectionManifestSchemaVersion(schemaVersion) {
3657
- return SUPERSEDED_ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSIONS.includes(schemaVersion);
3658
- }
3659
- function serializeArchitectureDocsProjectionManifest(manifest) {
3660
- const capabilities = [...manifest.semanticBaseline.capabilities].sort((left, right) => compareStrings(left.capabilityId, right.capabilityId)).map(canonicalCapability);
3661
- const capabilityBlock = JSON.stringify(capabilities, null, 2).split(`
3662
- `).map((line, index) => index === 0 ? line : ` ${line}`).join(`
3663
- `);
3664
- const targetIds = Object.keys(manifest.targets).sort(compareStrings);
3665
- const targetLines = targetIds.length === 0 ? [' "targets": {}'] : [
3666
- ' "targets": {',
3667
- ...targetIds.flatMap((targetId, index) => [
3668
- ` ${JSON.stringify(targetId)}:`,
3669
- ` ${JSON.stringify(canonicalTargetRow(manifest.targets[targetId]))}${index === targetIds.length - 1 ? "" : ","}`
3670
- ]),
3671
- " }"
3672
- ];
3673
- return [
3674
- "{",
3675
- ` "schemaVersion": ${JSON.stringify(manifest.schemaVersion)},`,
3676
- ` "rendererVersion": ${JSON.stringify(manifest.rendererVersion)},`,
3677
- ...manifest.minimumRendererVersion === undefined ? [] : [` "minimumRendererVersion": ${JSON.stringify(manifest.minimumRendererVersion)},`],
3678
- ...manifest.minimumProtocolVersion === undefined ? [] : [` "minimumProtocolVersion": ${JSON.stringify(manifest.minimumProtocolVersion)},`],
3679
- ` "profile": ${JSON.stringify(manifest.profile)},`,
3680
- ` "layoutVersion": ${JSON.stringify(manifest.layoutVersion)},`,
3681
- ` "generatedFrom": ${JSON.stringify({ codeGraphPackage: manifest.generatedFrom.codeGraphPackage, codeGraphVersion: manifest.generatedFrom.codeGraphVersion })},`,
3682
- ' "semanticBaseline": {',
3683
- ` "modelDigest": ${JSON.stringify(manifest.semanticBaseline.modelDigest)},`,
3684
- ` "capabilities": ${capabilityBlock}`,
3685
- " },",
3686
- ...targetLines,
3687
- "}",
3688
- ""
3689
- ].join(`
3690
- `);
3691
- }
3692
- function architectureDocsProjectionManifestSemanticState(manifest) {
3693
- return architectureSemanticStateFromCapabilities(manifest.semanticBaseline.capabilities.map(({ selectorEvidenceDigest: _selectorEvidenceDigest, ...capability }) => capability));
3694
- }
3695
- function architectureSemanticStateFromCapabilities(capabilities) {
3696
- const sorted = [...capabilities].sort((left, right) => compareStrings(left.capabilityId, right.capabilityId));
3697
- return {
3698
- schemaVersion: ARCHITECTURE_SEMANTIC_STATE_SCHEMA_VERSION,
3699
- capabilities: sorted,
3700
- semanticFingerprint: digestJson(sorted.map(({ capabilityId, semanticFingerprint }) => ({ capabilityId, semanticFingerprint }))),
3701
- flowProofFingerprint: digestJson(sorted.map(({ capabilityId, flowProofFingerprint }) => ({ capabilityId, flowProofFingerprint })))
3702
- };
3703
- }
3704
- function architectureDocsProjectionManifestSourceStamps(manifest) {
3705
- const stamps = {};
3706
- for (const row of Object.values(manifest.targets))
3707
- Object.assign(stamps, row.sourceStamps ?? {});
3708
- return stamps;
3709
- }
3710
- function architectureDocsProjectionManifestProofEvidence(manifest) {
3711
- return {
3712
- rendererVersion: manifest.rendererVersion,
3713
- selectorEvidenceDigests: Object.fromEntries(manifest.semanticBaseline.capabilities.map((capability) => [capability.capabilityId, capability.selectorEvidenceDigest])),
3714
- sourceStamps: architectureDocsProjectionManifestSourceStamps(manifest)
3715
- };
3716
- }
3717
- function architectureSourceStampsDigest(stamps) {
3718
- return digestJson({
3719
- schemaVersion: "archcontext.architecture-source-stamps/v1",
3720
- stamps: Object.keys(stamps).sort(compareStrings).map((nodeId) => ({ nodeId, digest: stamps[nodeId] }))
3721
- });
3722
- }
3723
- function architectureProjectionOutputsDigest(input) {
3724
- return digestJson({
3725
- schemaVersion: "archcontext.architecture-projection-outputs/v1",
3726
- rendererVersion: input.rendererVersion,
3727
- profile: input.profile,
3728
- outputs: Object.keys(input.outputDigests).sort(compareStrings).map((targetId) => ({ targetId, outputDigest: input.outputDigests[targetId] }))
3729
- });
3730
- }
3731
- function architectureDocsProjectionManifestDigests(manifest) {
3732
- return {
3733
- modelDigest: manifest.semanticBaseline.modelDigest,
3734
- sourceTreeDigest: architectureSourceStampsDigest(architectureDocsProjectionManifestSourceStamps(manifest)),
3735
- flowProofDigest: architectureDocsProjectionManifestSemanticState(manifest).flowProofFingerprint,
3736
- projectionDigest: architectureProjectionOutputsDigest({
3737
- rendererVersion: manifest.rendererVersion,
3738
- profile: manifest.profile,
3739
- outputDigests: Object.fromEntries(Object.entries(manifest.targets).map(([targetId, row]) => [targetId, row.outputDigest]))
3740
- })
3741
- };
3742
- }
3743
- function architectureDocsProjectionProvenanceIssues(value, prefix = "provenance") {
3744
- const provenance = record3(value);
3745
- if (!provenance)
3746
- return [`${prefix} must be an object`];
3747
- const issues = exactKeys(provenance, ["schemaVersion", "sourceTreeDigest", "modelDigest", "projectionInputDigest", "rendererVersion", "layoutVersion", "generatedFrom"], [], prefix);
3748
- if (provenance.schemaVersion !== ARCHITECTURE_DOCS_PROJECTION_PROVENANCE_SCHEMA_VERSION)
3749
- issues.push(`${prefix}.schemaVersion is unsupported`);
3750
- for (const field of ["sourceTreeDigest", "modelDigest", "projectionInputDigest"]) {
3751
- if (!isDigest(provenance[field]))
3752
- issues.push(`${prefix}.${field} must be a SHA-256 digest`);
3753
- }
3754
- if (provenance.rendererVersion !== ARCHITECTURE_DOCS_RENDERER_VERSION)
3755
- issues.push(`${prefix}.rendererVersion must be ${ARCHITECTURE_DOCS_RENDERER_VERSION}`);
3756
- if (provenance.layoutVersion !== ARCHITECTURE_DOCS_LAYOUT_VERSION_V1)
3757
- issues.push(`${prefix}.layoutVersion is unsupported`);
3758
- issues.push(...generatedFromIssues(provenance.generatedFrom, `${prefix}.generatedFrom`));
3759
- return issues;
3760
- }
3761
- function capabilityEntriesIssues(value, prefix, withSelectorEvidence) {
3762
- if (!Array.isArray(value))
3763
- return [`${prefix} must be an array`];
3764
- const issues = [];
3765
- const ids = value.map((entry) => record3(entry)?.capabilityId);
3766
- if (!isSortedUniqueStrings(ids))
3767
- issues.push(`${prefix} must be sorted and unique by capabilityId`);
3768
- value.forEach((entry, index) => {
3769
- const entryPrefix = `${prefix}[${index}]`;
3770
- const capability = record3(entry);
3771
- if (!capability) {
3772
- issues.push(`${entryPrefix} must be an object`);
3773
- return;
3774
- }
3775
- const required = ["capabilityId", "memberNodeIds", "semanticFingerprint", "flowProofFingerprint", "proofStatus", "facets", ...withSelectorEvidence ? ["selectorEvidenceDigest"] : []];
3776
- issues.push(...exactKeys(capability, required, [], entryPrefix));
3777
- if (!isNonEmptyString(capability.capabilityId))
3778
- issues.push(`${entryPrefix}.capabilityId must be a non-empty string`);
3779
- if (!Array.isArray(capability.memberNodeIds) || !isSortedUniqueStrings(capability.memberNodeIds))
3780
- issues.push(`${entryPrefix}.memberNodeIds must be sorted and unique`);
3781
- if (!isDigest(capability.semanticFingerprint))
3782
- issues.push(`${entryPrefix}.semanticFingerprint must be a SHA-256 digest`);
3783
- if (!isDigest(capability.flowProofFingerprint))
3784
- issues.push(`${entryPrefix}.flowProofFingerprint must be a SHA-256 digest`);
3785
- if (withSelectorEvidence && !isDigest(capability.selectorEvidenceDigest))
3786
- issues.push(`${entryPrefix}.selectorEvidenceDigest must be a SHA-256 digest`);
3787
- if (!isArchitectureCapabilityProofStatus(capability.proofStatus))
3788
- issues.push(`${entryPrefix}.proofStatus must be a P1/P2 proof status`);
3789
- const facets = record3(capability.facets);
3790
- if (!facets)
3791
- issues.push(`${entryPrefix}.facets must be an object`);
3792
- else {
3793
- issues.push(...exactKeys(facets, [...ARCHITECTURE_SEMANTIC_FACETS], [], `${entryPrefix}.facets`));
3794
- for (const facet of ARCHITECTURE_SEMANTIC_FACETS) {
3795
- if (!isDigest(facets[facet]))
3796
- issues.push(`${entryPrefix}.facets.${facet} must be a SHA-256 digest`);
3797
- }
3798
- }
3799
- });
3800
- return issues;
3801
- }
3802
- function generatedFromIssues(value, prefix) {
3803
- const generatedFrom = record3(value);
3804
- if (!generatedFrom)
3805
- return [`${prefix} must be an object`];
3806
- const issues = exactKeys(generatedFrom, ["codeGraphPackage", "codeGraphVersion"], [], prefix);
3807
- for (const field of ["codeGraphPackage", "codeGraphVersion"]) {
3808
- if (!isNonEmptyString(generatedFrom[field]))
3809
- issues.push(`${prefix}.${field} must be a non-empty string`);
3810
- }
3811
- return issues;
3812
- }
3813
- function canonicalCapability(capability) {
3814
- return {
3815
- capabilityId: capability.capabilityId,
3816
- memberNodeIds: [...capability.memberNodeIds],
3817
- semanticFingerprint: capability.semanticFingerprint,
3818
- flowProofFingerprint: capability.flowProofFingerprint,
3819
- proofStatus: { p1: capability.proofStatus.p1, p2: capability.proofStatus.p2 },
3820
- facets: Object.fromEntries(Object.keys(capability.facets).sort(compareStrings).map((facet) => [facet, capability.facets[facet]])),
3821
- selectorEvidenceDigest: capability.selectorEvidenceDigest
3822
- };
3823
- }
3824
- function canonicalTargetRow(row) {
3825
- return {
3826
- type: row.type,
3827
- scope: {
3828
- kind: row.scope.kind,
3829
- ...row.scope.id !== undefined ? { id: row.scope.id } : {},
3830
- ...row.scope.entityKind !== undefined ? { entityKind: row.scope.entityKind } : {}
3831
- },
3832
- path: row.path,
3833
- ownership: row.ownership,
3834
- format: row.format,
3835
- outputDigest: row.outputDigest,
3836
- ...row.sourceStamps !== undefined ? { sourceStamps: Object.fromEntries(Object.keys(row.sourceStamps).sort(compareStrings).map((nodeId) => [nodeId, row.sourceStamps[nodeId]])) } : {},
3837
- ...row.scale !== undefined ? {
3838
- scale: {
3839
- fileCountBucket: { lower: row.scale.fileCountBucket.lower, upper: row.scale.fileCountBucket.upper },
3840
- lineCountBucket: { lower: row.scale.lineCountBucket.lower, upper: row.scale.lineCountBucket.upper }
3841
- }
3842
- } : {}
3843
- };
3844
- }
3845
- function isArchitectureScaleBucket(value) {
3846
- const bucket = record3(value);
3847
- if (!bucket || Object.keys(bucket).length !== 2)
3848
- return false;
3849
- const { lower, upper } = bucket;
3850
- if (typeof lower !== "number" || typeof upper !== "number" || !Number.isSafeInteger(lower) || !Number.isSafeInteger(upper))
3851
- return false;
3852
- if (lower === 0)
3853
- return upper === 1;
3854
- let magnitude = 1;
3855
- while (magnitude * 10 <= lower)
3856
- magnitude *= 10;
3857
- const mantissa = lower / magnitude;
3858
- if (mantissa === 1)
3859
- return upper === 2 * magnitude;
3860
- if (mantissa === 2)
3861
- return upper === 5 * magnitude;
3862
- if (mantissa === 5)
3863
- return upper === 10 * magnitude;
3864
- return false;
3865
- }
3866
- function manifestTargetIssues(value, prefix) {
3867
- const target = record3(value);
3868
- if (!target)
3869
- return [`${prefix} must be an object`];
3870
- const issues = exactKeys(target, ["type", "scope", "path", "ownership", "format", "outputDigest"], ["sourceStamps", "scale"], prefix);
3871
- if (typeof target.type !== "string" || !Object.hasOwn(TARGET_TYPES, target.type))
3872
- issues.push(`${prefix}.type is unsupported`);
3873
- const scope = record3(target.scope);
3874
- if (!scope || typeof scope.kind !== "string" || !Object.hasOwn(SCOPE_KINDS, scope.kind))
3875
- issues.push(`${prefix}.scope.kind is unsupported`);
3876
- else {
3877
- issues.push(...exactKeys(scope, ["kind"], ["id", "entityKind"], `${prefix}.scope`));
3878
- for (const field of ["id", "entityKind"]) {
3879
- if (scope[field] !== undefined && typeof scope[field] !== "string")
3880
- issues.push(`${prefix}.scope.${field} must be a string`);
3881
- }
3882
- }
3883
- if (typeof target.path !== "string" || !isRepoRelativePosixPath(target.path))
3884
- issues.push(`${prefix}.path must be a repository-relative POSIX path`);
3885
- if (typeof target.ownership !== "string" || !Object.hasOwn(OWNERSHIPS, target.ownership))
3886
- issues.push(`${prefix}.ownership is unsupported`);
3887
- if (typeof target.format !== "string" || !Object.hasOwn(FORMATS, target.format))
3888
- issues.push(`${prefix}.format is unsupported`);
3889
- if (!isDigest(target.outputDigest))
3890
- issues.push(`${prefix}.outputDigest must be a SHA-256 digest`);
3891
- if (target.sourceStamps !== undefined && target.type !== "entity-summary" && !isRuntimeTopologyTargetType(target.type)) {
3892
- issues.push(`${prefix}.sourceStamps are only allowed on entity-summary and runtime topology targets`);
3893
- }
3894
- if (target.scale !== undefined && target.type !== "entity-summary")
3895
- issues.push(`${prefix}.scale is only allowed on entity-summary targets`);
3896
- if (target.sourceStamps !== undefined) {
3897
- const stamps = record3(target.sourceStamps);
3898
- if (!stamps || Object.keys(stamps).length === 0)
3899
- issues.push(`${prefix}.sourceStamps must be a non-empty object keyed by node id`);
3900
- else {
3901
- for (const [nodeId, digest] of Object.entries(stamps)) {
3902
- if (!isNonEmptyString(nodeId))
3903
- issues.push(`${prefix}.sourceStamps keys must be non-empty node ids`);
3904
- if (!isDigest(digest))
3905
- issues.push(`${prefix}.sourceStamps.${nodeId} must be a SHA-256 digest`);
3906
- }
3907
- }
3908
- }
3909
- const ownNodeId = scope?.id;
3910
- const stampsOwnNode = typeof ownNodeId === "string" && record3(target.sourceStamps) !== undefined && Object.hasOwn(record3(target.sourceStamps), ownNodeId);
3911
- if (stampsOwnNode !== (target.scale !== undefined))
3912
- issues.push(`${prefix}.scale must be present exactly when sourceStamps stamps the target's own node`);
3913
- if (target.scale !== undefined) {
3914
- const scale = record3(target.scale);
3915
- if (!scale)
3916
- issues.push(`${prefix}.scale must be an object`);
3917
- else {
3918
- issues.push(...exactKeys(scale, ["fileCountBucket", "lineCountBucket"], [], `${prefix}.scale`));
3919
- for (const field of ["fileCountBucket", "lineCountBucket"]) {
3920
- if (!isArchitectureScaleBucket(scale[field]))
3921
- issues.push(`${prefix}.scale.${field} must be a 1-2-5 magnitude bucket`);
3922
- }
3923
- }
3924
- }
3925
- return issues;
3926
- }
3927
- function record3(value) {
3928
- return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
3929
- }
3930
- function exactKeys(value, required, optional, prefix) {
3931
- const issues = required.filter((key) => !(key in value)).map((key) => `${prefix}.${key} is required`);
3932
- const allowed = new Set([...required, ...optional]);
3933
- for (const key of Object.keys(value))
3934
- if (!allowed.has(key))
3935
- issues.push(`${prefix}.${key} is not allowed`);
3936
- return issues;
3937
- }
3938
- function isDigest(value) {
3939
- return typeof value === "string" && SHA256.test(value);
3940
- }
3941
- function isNonEmptyString(value) {
3942
- return typeof value === "string" && value.trim() !== "";
3943
- }
3944
- function isSortedUniqueStrings(values) {
3945
- return values.every((value, index) => typeof value === "string" && (index === 0 || values[index - 1] < value));
3946
- }
3947
- function compareStrings(left, right) {
3948
- return left < right ? -1 : left > right ? 1 : 0;
3949
- }
3950
- function versionNumber(value, family) {
3951
- if (typeof value !== "string" || !value.startsWith(family))
3952
- return;
3953
- const suffix = value.slice(family.length);
3954
- if (!/^[1-9][0-9]*$/.test(suffix))
3955
- return;
3956
- const version = Number(suffix);
3957
- return Number.isSafeInteger(version) ? version : undefined;
3958
- }
3959
- function architectureDocsProjectionCompatibilityIssues(value, engine = {
3960
- rendererVersion: ARCHITECTURE_DOCS_RENDERER_VERSION,
3961
- protocolVersion: PROJECTION_REQUEST_SCHEMA_VERSION
3962
- }) {
3963
- const manifest = record3(value);
3964
- if (!manifest)
3965
- return [];
3966
- const issues = [];
3967
- if (["minimumRendererVersion", "minimumProtocolVersion"].some((key) => Object.hasOwn(manifest, key)) && manifest.schemaVersion !== ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSION)
3968
- issues.push("projection manifest floors require the current schema");
3969
- if (typeof manifest.schemaVersion === "string" && manifest.schemaVersion !== ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSION && !isSupersededArchitectureDocsProjectionManifestSchemaVersion(manifest.schemaVersion))
3970
- issues.push("projection manifest schema is unsupported by this engine");
3971
- for (const [key, family, current] of [
3972
- ["minimumRendererVersion", "archcontext.docs-renderer/v", engine.rendererVersion],
3973
- ["minimumProtocolVersion", "archcontext.projection-request/v", engine.protocolVersion]
3974
- ]) {
3975
- if (!Object.hasOwn(manifest, key))
3976
- continue;
3977
- const required = versionNumber(manifest[key], family);
3978
- const supported = versionNumber(current, family);
3979
- if (required === undefined || supported === undefined || supported < required)
3980
- issues.push(`projection manifest ${key} is unsupported by this engine`);
3981
- }
3982
- return issues;
3983
- }
3984
- var ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSION = "archcontext.architecture-docs-projection-manifest/v3", SUPERSEDED_ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSIONS, PROJECTION_MANIFEST_UPGRADE_REQUIRED = "projection-manifest-upgrade-required", PROJECTION_MANIFEST_INVALID = "projection-manifest-invalid", PROJECTION_FOOTPRINT_UNCOVERED = "projection-footprint-uncovered", ARCHITECTURE_DOCS_PROJECTION_PROVENANCE_SCHEMA_VERSION = "archcontext.architecture-docs-projection-provenance/v3", ARCHITECTURE_DOCS_LAYOUT_VERSION_V1 = "archcontext.docs-layout/v1", ARCHITECTURE_SEMANTIC_STATE_SCHEMA_VERSION = "archcontext.architecture-semantic-state/v1", ARCHITECTURE_DOCS_PROJECTION_PROFILES, SHA256, TARGET_TYPES, RUNTIME_TOPOLOGY_TARGET_TYPES, SCOPE_KINDS, OWNERSHIPS, FORMATS;
3985
- var init_projection_manifest = __esm(() => {
3986
- init_projection();
3987
- init_schema();
3988
- SUPERSEDED_ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSIONS = [
3989
- "archcontext.architecture-docs-projection-manifest/v1",
3990
- "archcontext.architecture-docs-projection-manifest/v2"
3991
- ];
3992
- ARCHITECTURE_DOCS_PROJECTION_PROFILES = ["default", "repo-harness/v1"];
3993
- SHA256 = /^sha256:[a-f0-9]{64}$/;
3994
- TARGET_TYPES = {
3995
- "architecture-index": true,
3996
- "entity-summary": true,
3997
- "relation-summary": true,
3998
- "decision-index": true,
3999
- "architecture-changelog": true,
4000
- "diagram-mermaid": true,
4001
- "diagram-structurizr": true,
4002
- "diagram-likec4": true,
4003
- "diagram-runtime-topology": true,
4004
- "runtime-topology-summary": true,
4005
- "agent-context": true
4006
- };
4007
- RUNTIME_TOPOLOGY_TARGET_TYPES = ["diagram-runtime-topology", "runtime-topology-summary"];
4008
- SCOPE_KINDS = { repository: true, entity: true, relation: true, decision: true, diagram: true, changelog: true };
4009
- OWNERSHIPS = { generated: true, mixed: true };
4010
- FORMATS = { markdown: true, mermaid: true, "structurizr-json": true, likec4: true };
4011
- });
4012
-
4013
4037
  // packages/contracts/src/product-version.ts
4014
4038
  function productVersionManifest() {
4015
4039
  return {
@@ -4095,7 +4119,7 @@ function compareVersionTriples(left, right) {
4095
4119
  }
4096
4120
  return 0;
4097
4121
  }
4098
- var ARCHCONTEXT_PRODUCT_NAME = "archctx", ARCHCONTEXT_PRODUCT_VERSION = "0.9.4", ARCHCONTEXT_PACKAGE_MANAGER = "bun@1.4.3", ARCHCONTEXT_NODE_RANGE = ">=22.22 <26", LOCAL_RUNTIME_RPC_SCHEMA_VERSION = "archcontext.runtime-rpc/v2", ARCHCONTEXT_SCHEMA_SET_VERSION = "2026-07-11.explorer-view-v2";
4122
+ var ARCHCONTEXT_PRODUCT_NAME = "archctx", ARCHCONTEXT_PRODUCT_VERSION = "0.11.0", ARCHCONTEXT_PACKAGE_MANAGER = "bun@1.4.3", ARCHCONTEXT_NODE_RANGE = ">=22.22 <26", LOCAL_RUNTIME_RPC_SCHEMA_VERSION = "archcontext.runtime-rpc/v2", ARCHCONTEXT_SCHEMA_SET_VERSION = "2026-07-11.explorer-view-v2";
4099
4123
 
4100
4124
  // packages/contracts/src/refactor.ts
4101
4125
  function refactorNamespaceIssues(value, label = "product.id") {
@@ -5188,6 +5212,7 @@ var init_refactor = __esm(() => {
5188
5212
  var init_src = __esm(() => {
5189
5213
  init_control_plane_routes();
5190
5214
  init_architecture();
5215
+ init_architecture_history();
5191
5216
  init_architecture_debt();
5192
5217
  init_docs_anchors();
5193
5218
  init_github_governance();
@@ -15651,7 +15676,7 @@ import { basename, posix, resolve as resolve6 } from "node:path";
15651
15676
  var composer = require_composer();
15652
15677
  var Document = require_Document();
15653
15678
  var Schema = require_Schema();
15654
- var errors = require_errors();
15679
+ var errors2 = require_errors();
15655
15680
  var Alias = require_Alias();
15656
15681
  var identity = require_identity();
15657
15682
  var Pair = require_Pair();
@@ -15667,9 +15692,9 @@ var visit2 = require_visit();
15667
15692
  var $Composer = composer.Composer;
15668
15693
  var $Document = Document.Document;
15669
15694
  var $Schema = Schema.Schema;
15670
- var $YAMLError = errors.YAMLError;
15671
- var $YAMLParseError = errors.YAMLParseError;
15672
- var $YAMLWarning = errors.YAMLWarning;
15695
+ var $YAMLError = errors2.YAMLError;
15696
+ var $YAMLParseError = errors2.YAMLParseError;
15697
+ var $YAMLWarning = errors2.YAMLWarning;
15673
15698
  var $Alias = Alias.Alias;
15674
15699
  var $isAlias = identity.isAlias;
15675
15700
  var $isCollection = identity.isCollection;
@@ -16013,6 +16038,114 @@ function sourceIncludeAnchors(patterns) {
16013
16038
  });
16014
16039
  return [...new Set(anchors)].sort(nativeByteCompare);
16015
16040
  }
16041
+ // packages/core/projection-engine/src/architecture-history.ts
16042
+ init_src();
16043
+ var ARCHITECTURE_HISTORY_PATH = "docs/architecture/history.md";
16044
+ var HISTORY_DETAIL_EDGE_LIMIT = 20;
16045
+ var capabilityDomain = (id) => id === null ? null : /^capability\.([a-z0-9]+(?:-[a-z0-9]+)*)\.([a-z0-9]+(?:-[a-z0-9]+)*)$/.exec(id)?.[1] ?? null;
16046
+ var compare2 = (a, b) => a < b ? -1 : a > b ? 1 : 0;
16047
+ function renderHistoryMermaid(milestone, mode = "full") {
16048
+ if (!milestone.nodes)
16049
+ return null;
16050
+ const removed = mode === "changes" ? milestone.delta.removed.filter((node) => node.kind === "capability") : [];
16051
+ const nodes = mode === "changes" ? [...milestone.nodes, ...removed.map((node) => ({
16052
+ id: node.id,
16053
+ name: node.id,
16054
+ domain: capabilityDomain(node.id)
16055
+ }))].sort((a, b) => compare2(a.id, b.id)) : milestone.nodes;
16056
+ const keys = new Map(nodes.map((node, index) => [node.id, `n${index}`]));
16057
+ const label = (node) => ` ${keys.get(node.id)}["${node.name.replaceAll('"', "#quot;")}"]`;
16058
+ const domains = [...new Set(nodes.flatMap((node) => node.domain === null ? [] : [node.domain]))].sort();
16059
+ const lines = ["flowchart LR"];
16060
+ for (const domain of domains) {
16061
+ lines.push(` subgraph ${JSON.stringify(domain)}`);
16062
+ lines.push(...nodes.filter((node) => node.domain === domain).map((node) => ` ${label(node)}`));
16063
+ lines.push(" end");
16064
+ }
16065
+ lines.push(...nodes.filter((node) => node.domain === null).map(label));
16066
+ const added = mode === "changes" ? milestone.delta.edgesChanged.added : milestone.edges;
16067
+ lines.push(...added.map((edge) => ` ${keys.get(edge.source)} --> ${keys.get(edge.target)}`));
16068
+ if (mode === "changes")
16069
+ lines.push(...milestone.delta.edgesChanged.removed.map((edge) => ` ${keys.get(edge.source)} -.-> ${keys.get(edge.target)}`));
16070
+ if (removed.length) {
16071
+ lines.push(...removed.map((node) => ` class ${keys.get(node.id)} removed`));
16072
+ lines.push(" classDef removed stroke-dasharray: 4 4");
16073
+ }
16074
+ return lines.join(`
16075
+ `);
16076
+ }
16077
+ function renderHistoryDomainOverview(milestone) {
16078
+ if (!milestone.nodes)
16079
+ return null;
16080
+ const counts = new Map;
16081
+ const ensure = (domain) => {
16082
+ if (!counts.has(domain))
16083
+ counts.set(domain, 0);
16084
+ };
16085
+ for (const node of milestone.nodes) {
16086
+ const domain = node.domain ?? "ungrouped";
16087
+ counts.set(domain, (counts.get(domain) ?? 0) + 1);
16088
+ }
16089
+ const changed = new Set;
16090
+ for (const item of [...milestone.delta.added, ...milestone.delta.removed, ...milestone.delta.renamed]) {
16091
+ const domain = capabilityDomain(item.capability) ?? "ungrouped";
16092
+ ensure(domain);
16093
+ changed.add(domain);
16094
+ }
16095
+ const pairs = new Map;
16096
+ for (const [kind, edges] of [["added", milestone.delta.edgesChanged.added], ["removed", milestone.delta.edgesChanged.removed]]) {
16097
+ for (const edge of edges) {
16098
+ const source = capabilityDomain(edge.source) ?? "ungrouped", target = capabilityDomain(edge.target) ?? "ungrouped";
16099
+ ensure(source);
16100
+ ensure(target);
16101
+ changed.add(source);
16102
+ changed.add(target);
16103
+ if (source === target)
16104
+ continue;
16105
+ const key = JSON.stringify([source, target]);
16106
+ const pair = pairs.get(key) ?? { source, target, added: 0, removed: 0 };
16107
+ pair[kind]++;
16108
+ pairs.set(key, pair);
16109
+ }
16110
+ }
16111
+ const domains = [...counts.keys()].sort();
16112
+ const keys = new Map(domains.map((domain, index) => [domain, `d${index}`]));
16113
+ const lines = ["flowchart LR", ...domains.map((domain) => ` ${keys.get(domain)}["${domain} (${counts.get(domain)})"]`)];
16114
+ for (const pair of [...pairs.values()].sort((a, b) => compare2(a.source, b.source) || compare2(a.target, b.target))) {
16115
+ const arrow = pair.added === 0 ? "-.->" : "-->";
16116
+ lines.push(` ${keys.get(pair.source)} ${arrow}|+${pair.added} −${pair.removed}| ${keys.get(pair.target)}`);
16117
+ }
16118
+ if (changed.size) {
16119
+ lines.push(...domains.filter((domain) => changed.has(domain)).map((domain) => ` class ${keys.get(domain)} changed`));
16120
+ lines.push(" classDef changed stroke-width:3px");
16121
+ }
16122
+ return { mermaid: lines.join(`
16123
+ `), pairCount: pairs.size };
16124
+ }
16125
+ function projectHistoryMermaid(history) {
16126
+ return { schemaVersion: ARCHITECTURE_HISTORY_MERMAID_SCHEMA_VERSION, head: history.head, total: history.total, offset: history.offset, limit: history.limit, diagrams: history.milestones.map((milestone) => ({ rev: milestone.rev, mermaid: renderHistoryMermaid(milestone) })) };
16127
+ }
16128
+ function renderHistoryMarkdown(history) {
16129
+ const lines = ["<!-- Generated by ArchContext (archctx history). Do not edit by hand. -->", "", `Architecture history contains ${history.total} milestones. Run \`archctx history\` for the full list.`, ""];
16130
+ for (const milestone of [...history.milestones].reverse()) {
16131
+ lines.push(`## ${milestone.date.slice(0, 10)} · ${milestone.rev.slice(0, 12)}`, "", milestone.subject, "");
16132
+ if (milestone.error)
16133
+ lines.push(milestone.error.code, "");
16134
+ else {
16135
+ const delta = milestone.delta;
16136
+ const overview = renderHistoryDomainOverview(milestone);
16137
+ const edgeCount = delta.edgesChanged.added.length + delta.edgesChanged.removed.length;
16138
+ lines.push(`Added ${delta.added.length} · Removed ${delta.removed.length} · Renamed ${delta.renamed.length} · Edges +${delta.edgesChanged.added.length} −${delta.edgesChanged.removed.length}`, "", "```mermaid", overview.mermaid, "```", "");
16139
+ if (edgeCount <= HISTORY_DETAIL_EDGE_LIMIT)
16140
+ lines.push("```mermaid", renderHistoryMermaid(milestone, "changes"), "```", "");
16141
+ else
16142
+ lines.push(`${edgeCount} changed edges across ${overview.pairCount} domain pairs; run archctx history --ref ${milestone.rev.slice(0, 12)} --format mermaid for the full shape.`, "");
16143
+ }
16144
+ }
16145
+ return `${lines.join(`
16146
+ `)}
16147
+ `;
16148
+ }
16016
16149
 
16017
16150
  // packages/core/projection-engine/src/index.ts
16018
16151
  init_src();
@@ -18071,12 +18204,13 @@ function resolveArchitectureDocumentationLayout(input) {
18071
18204
  });
18072
18205
  const relationTargets = (profile === REPO_HARNESS_PROJECTION_PROFILE ? [] : input.relations).map((relation) => layoutTarget(`projection_target.relation.${stableId(relation.id)}`, "relation-summary", { kind: "relation", id: relation.id }, `docs/architecture/relations/${pathSegment(relation.id)}.md`, "mixed", "markdown"));
18073
18206
  const topologyTargets = hasRuntimeTopologyNodes(input.nodes) ? RUNTIME_TOPOLOGY_TARGETS : [];
18074
- const targets = [FIXED_TARGETS[0], ...entityTargets, ...relationTargets, ...FIXED_TARGETS.slice(1), ...topologyTargets].map((target) => ({ ...target, path: requiredPath(target.path, target.targetId) }));
18207
+ const targets = (profile === REPO_HARNESS_PROJECTION_PROFILE ? [...entityTargets, ...topologyTargets] : [FIXED_TARGETS[0], ...entityTargets, ...relationTargets, ...FIXED_TARGETS.slice(1), ...topologyTargets]).map((target) => ({ ...target, path: requiredPath(target.path, target.targetId) }));
18075
18208
  assertUniqueTargets(targets);
18076
18209
  return {
18077
18210
  profile,
18078
18211
  targets,
18079
18212
  expectedPaths: [...new Set([...targets.map((target) => target.path), "docs/architecture/.projection-manifest.json"])].sort(),
18213
+ retiredTargetPaths: profile === REPO_HARNESS_PROJECTION_PROFILE ? FIXED_TARGETS.map((target) => target.path) : [],
18080
18214
  orphanRoots: ["docs/architecture/modules", "docs/architecture/relations"],
18081
18215
  entityPathByNodeId: new Map(entityTargets.map((target, index) => [targetNodes[index].id, target.path]))
18082
18216
  };
@@ -18124,7 +18258,10 @@ function loadArchitectureFilesForLayout(root, layout) {
18124
18258
  }
18125
18259
  if (paths.has(ARCHITECTURE_DOCS_PROJECTION_MANIFEST_PATH)) {
18126
18260
  const manifest = readProjectionOwnedFile(resolve5(root, ARCHITECTURE_DOCS_PROJECTION_MANIFEST_PATH), ARCHITECTURE_DOCS_PROJECTION_MANIFEST_PATH);
18127
- for (const output of committedGeneratedOutputs(currentFormatManifest(manifest.body))) {
18261
+ const retired = new Set(layout.retiredTargetPaths);
18262
+ for (const output of committedProjectionOutputs(currentFormatManifest(manifest.body))) {
18263
+ if (output.ownership !== "generated" && !retired.has(output.path))
18264
+ continue;
18128
18265
  if (resolveSafeRegularPath(root, output.path, false))
18129
18266
  paths.add(output.path);
18130
18267
  }
@@ -18132,17 +18269,20 @@ function loadArchitectureFilesForLayout(root, layout) {
18132
18269
  return [...paths].sort().map((path) => readProjectionOwnedFile(resolve5(root, path), path));
18133
18270
  }
18134
18271
  var OUTPUT_DIGEST_PATTERN = /^sha256:[a-f0-9]{64}$/;
18135
- function committedGeneratedOutputs(manifest) {
18272
+ function committedProjectionOutputs(manifest) {
18136
18273
  if (manifest === undefined)
18137
18274
  return [];
18138
18275
  const outputs = [];
18139
18276
  for (const [targetId, row] of Object.entries(manifest.targets)) {
18140
- if (row.ownership !== "generated" || !OUTPUT_DIGEST_PATTERN.test(row.outputDigest) || !isRepoRelativePosixPath(row.path) || !row.path.startsWith("docs/architecture/") || row.path === ARCHITECTURE_DOCS_PROJECTION_MANIFEST_PATH)
18277
+ if (!OUTPUT_DIGEST_PATTERN.test(row.outputDigest) || !isRepoRelativePosixPath(row.path) || !row.path.startsWith("docs/architecture/") || row.path === ARCHITECTURE_DOCS_PROJECTION_MANIFEST_PATH)
18141
18278
  continue;
18142
- outputs.push({ targetId, path: row.path, outputDigest: row.outputDigest });
18279
+ outputs.push({ targetId, path: row.path, ownership: row.ownership, outputDigest: row.outputDigest });
18143
18280
  }
18144
18281
  return outputs;
18145
18282
  }
18283
+ function committedGeneratedOutputs(manifest) {
18284
+ return committedProjectionOutputs(manifest).filter((output) => output.ownership === "generated").map(({ targetId, path, outputDigest }) => ({ targetId, path, outputDigest }));
18285
+ }
18146
18286
  function currentFormatManifest(body) {
18147
18287
  let parsed;
18148
18288
  try {
@@ -20034,9 +20174,17 @@ class ProjectionPreconditionError extends Error {
20034
20174
  class ProjectionManifestUpgradeRequiredError extends ProjectionPreconditionError {
20035
20175
  schemaVersion;
20036
20176
  reasonCode = PROJECTION_MANIFEST_UPGRADE_REQUIRED;
20177
+ details;
20037
20178
  constructor(schemaVersion) {
20038
- super(`${PROJECTION_MANIFEST_UPGRADE_REQUIRED}: ${ARCHITECTURE_DOCS_PROJECTION_MANIFEST_PATH} is ${schemaVersion}, and this archctx reads only ${ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSION}; reach a clean projection on the earlier release first, then re-baseline once with archctx docs apply --approved --profile <default|repo-harness/v1>; if that apply names whole-file outputs the earlier release wrote, remove them with git rm and run it again`);
20179
+ super(`${PROJECTION_MANIFEST_UPGRADE_REQUIRED}: ${ARCHITECTURE_DOCS_PROJECTION_MANIFEST_PATH} is ${schemaVersion}, and this archctx reads only ${ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSION}; reach a clean projection on the earlier release first, then re-baseline once with ${ARCHITECTURE_DOCS_PROJECTION_MANIFEST_UPGRADE_COMMAND}; if that apply names whole-file outputs the earlier release wrote, remove them with git rm and run it again; ${ARCHITECTURE_DOCS_PROJECTION_MANIFEST_MIGRATION_GUIDE} lists the model and release preconditions`);
20039
20180
  this.schemaVersion = schemaVersion;
20181
+ this.details = isSupersededArchitectureDocsProjectionManifestSchemaVersion(schemaVersion) ? {
20182
+ manifestPath: ARCHITECTURE_DOCS_PROJECTION_MANIFEST_PATH,
20183
+ foundSchemaVersion: schemaVersion,
20184
+ supportedSchemaVersion: ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSION,
20185
+ upgradeCommand: ARCHITECTURE_DOCS_PROJECTION_MANIFEST_UPGRADE_COMMAND,
20186
+ migrationGuide: ARCHITECTURE_DOCS_PROJECTION_MANIFEST_MIGRATION_GUIDE
20187
+ } : {};
20040
20188
  }
20041
20189
  }
20042
20190
 
@@ -22177,7 +22325,7 @@ function sameOwners(left, right) {
22177
22325
 
22178
22326
  // packages/core/module-statistics/src/index.ts
22179
22327
  function evaluateDependencyConstraints(input) {
22180
- const constraints = [...input.constraints].sort((left, right) => compare2(left.id, right.id));
22328
+ const constraints = [...input.constraints].sort((left, right) => compare3(left.id, right.id));
22181
22329
  const certification = certifyCodeFacts(input.codeFacts, input.worktreeDigest, input.truncated, input.importNodeLimitExceeded ?? false);
22182
22330
  if (constraints.length === 0) {
22183
22331
  return {
@@ -22255,7 +22403,7 @@ function evaluateDependencyConstraints(input) {
22255
22403
  reasonCodes.add("unresolved-import");
22256
22404
  if (input.workspacePackagesResolved === false)
22257
22405
  reasonCodes.add("workspace-resolution-failed");
22258
- const sortedViolations = [...violations.values()].sort((left, right) => compare2(left.constraintId, right.constraintId) || compare2(left.fromPath, right.fromPath) || compare2(left.toPath, right.toPath));
22406
+ const sortedViolations = [...violations.values()].sort((left, right) => compare3(left.constraintId, right.constraintId) || compare3(left.fromPath, right.fromPath) || compare3(left.toPath, right.toPath));
22259
22407
  return {
22260
22408
  schemaVersion: "archcontext.dependency-constraint-evaluation/v1",
22261
22409
  status: sortedViolations.length > 0 ? "violated" : reasonCodes.size > 0 ? "undetermined" : "pass",
@@ -22332,7 +22480,7 @@ function measureCapabilityDependencies(input) {
22332
22480
  const cellKey = JSON.stringify([from.capability, to.capability]);
22333
22481
  let cell = cells.get(cellKey);
22334
22482
  if (cell === undefined) {
22335
- const relationIds = [...new Set(declaringRelations.get(cellKey) ?? [])].sort(compare2);
22483
+ const relationIds = [...new Set(declaringRelations.get(cellKey) ?? [])].sort(compare3);
22336
22484
  cell = { from: from.capability, to: to.capability, imports: 0, calls: null, declared: from.capability === to.capability || relationIds.length > 0, relationIds };
22337
22485
  cells.set(cellKey, cell);
22338
22486
  }
@@ -22340,14 +22488,14 @@ function measureCapabilityDependencies(input) {
22340
22488
  attributedEdges.push({ fromPath: edge.from, toPath: edge.to, fromCapability: from.capability, toCapability: to.capability });
22341
22489
  }
22342
22490
  const edgeLimit = input.edgeLimit ?? CAPABILITY_DEPENDENCIES_EDGE_LIMIT;
22343
- attributedEdges.sort((left, right) => compare2(left.fromPath, right.fromPath) || compare2(left.toPath, right.toPath));
22491
+ attributedEdges.sort((left, right) => compare3(left.fromPath, right.fromPath) || compare3(left.toPath, right.toPath));
22344
22492
  const listed = attributedEdges.slice(0, edgeLimit);
22345
22493
  return {
22346
22494
  schemaVersion: CAPABILITY_DEPENDENCIES_SCHEMA_VERSION,
22347
22495
  ownershipRule: "parent-chain",
22348
22496
  filter: { from: input.from ?? null, into: input.into ?? null },
22349
- capabilities: input.nodes.filter((node) => node.kind === "capability").map((node) => node.id).sort(compare2),
22350
- matrix: [...cells.values()].sort((left, right) => compare2(left.from, right.from) || compare2(left.to, right.to)),
22497
+ capabilities: input.nodes.filter((node) => node.kind === "capability").map((node) => node.id).sort(compare3),
22498
+ matrix: [...cells.values()].sort((left, right) => compare3(left.from, right.from) || compare3(left.to, right.to)),
22351
22499
  imports: {
22352
22500
  coverage: certification.coverage,
22353
22501
  reasonCodes: [...certification.reasonCodes].sort(),
@@ -22383,7 +22531,7 @@ function isRepositoryLocalSpecifier(specifier, workspacePackages) {
22383
22531
  return true;
22384
22532
  return workspacePackages.some((workspacePackage) => specifier === workspacePackage.name || specifier.startsWith(`${workspacePackage.name}/`));
22385
22533
  }
22386
- function compare2(left, right) {
22534
+ function compare3(left, right) {
22387
22535
  return left < right ? -1 : left > right ? 1 : 0;
22388
22536
  }
22389
22537
  function measureModuleStatistics(input) {
@@ -22468,7 +22616,7 @@ function modelDigest(model, constraints) {
22468
22616
  nodes: [...model.nodes].sort((left, right) => left.id < right.id ? -1 : left.id > right.id ? 1 : 0),
22469
22617
  relations: [...model.relations].sort((left, right) => left.id < right.id ? -1 : left.id > right.id ? 1 : 0),
22470
22618
  flows: [...model.flows ?? []].sort((left, right) => left.id < right.id ? -1 : left.id > right.id ? 1 : 0),
22471
- ...constraints.length === 0 ? {} : { constraints: [...constraints].sort((left, right) => compare2(left.id, right.id)) }
22619
+ ...constraints.length === 0 ? {} : { constraints: [...constraints].sort((left, right) => compare3(left.id, right.id)) }
22472
22620
  });
22473
22621
  }
22474
22622
  function countViolationsByNode(evaluation) {
@@ -23097,17 +23245,21 @@ function assertNativeGitRevision(ref) {
23097
23245
  throw new NativeContextError("native-context-ref-unsafe", { selector: "ref" });
23098
23246
  }
23099
23247
  function readOnlyGit(root, operation, args, options = {}) {
23100
- if (!["rev-parse", "ls-tree", "ls-files", "cat-file"].includes(operation))
23248
+ if (!["rev-parse", "ls-tree", "ls-files", "cat-file", "log"].includes(operation))
23101
23249
  throw new NativeContextError("native-context-git-read-failed", { category: "unsupported-operation" });
23102
23250
  const unsafeArguments = () => {
23103
23251
  throw new NativeContextError("native-context-git-read-failed", { operation, category: "unsupported-read-arguments" });
23104
23252
  };
23105
23253
  if (operation === "rev-parse") {
23106
- if (args.length === 1 && args[0] === "--show-toplevel") {} else if (args.length === 1 && isGitRevisionArgument(args[0])) {} else if (args.length === 3 && args[0] === "--verify" && args[1] === "--end-of-options")
23254
+ if (args.length === 1 && ["--show-toplevel", "--is-shallow-repository"].includes(args[0])) {} else if (args.length === 1 && isGitRevisionArgument(args[0])) {} else if (args.length === 3 && args[0] === "--verify" && args[1] === "--end-of-options")
23107
23255
  assertNativeGitRevision(args[2]);
23108
23256
  else
23109
23257
  unsafeArguments();
23110
23258
  }
23259
+ if (operation === "log") {
23260
+ if (args.length !== 8 || args[0] !== "--first-parent" || args[1] !== "--reverse" || args[2] !== "-z" || args[3] !== "--format=%H%x00%cI%x00%s" || !OBJECT_ID.test(args[4]) || args[5] !== "--" || args[6] !== ".archcontext/model" || args[7] !== ".archcontext/manifest.yaml")
23261
+ unsafeArguments();
23262
+ }
23111
23263
  if (operation === "ls-tree") {
23112
23264
  const flags = args.slice(0, -1);
23113
23265
  if (!flags.includes("-r") || !flags.includes("-z") || flags.some((flag) => !["-r", "-z", "-t", "-l"].includes(flag)) || new Set(flags).size !== flags.length)
@@ -23133,7 +23285,7 @@ function readOnlyGit(root, operation, args, options = {}) {
23133
23285
  const env = { ...process.env, LC_ALL: "C", GIT_NO_REPLACE_OBJECTS: "1", GIT_NO_LAZY_FETCH: "1", GIT_OPTIONAL_LOCKS: "0", GIT_PAGER: "cat", GIT_ALLOW_PROTOCOL: "", GIT_TERMINAL_PROMPT: "0" };
23134
23286
  for (const key of ["GIT_DIR", "GIT_WORK_TREE", "GIT_COMMON_DIR", "GIT_INDEX_FILE", "GIT_OBJECT_DIRECTORY", "GIT_ALTERNATE_OBJECT_DIRECTORIES", "GIT_NAMESPACE"])
23135
23287
  delete env[key];
23136
- const result = spawnSync("git", ["--no-pager", "--no-replace-objects", "-c", "core.fsmonitor=false", operation, ...args], {
23288
+ const result = spawnSync("git", ["--no-pager", "--no-replace-objects", "-c", "core.fsmonitor=false", ...operation === "log" ? ["-c", "log.showSignature=false"] : [], operation, ...args], {
23137
23289
  cwd: root,
23138
23290
  env,
23139
23291
  input: options.input,
@@ -23811,10 +23963,10 @@ function record5(value) {
23811
23963
  function text(value) {
23812
23964
  return typeof value === "string" && value.length > 0;
23813
23965
  }
23814
- function node(value) {
23966
+ function node2(value) {
23815
23967
  return record5(value) && ["id", "kind", "name", "qualifiedName", "filePath", "language"].every((key) => typeof value[key] === "string") && text(value.id) && ["startLine", "endLine", "startColumn", "endColumn", "updatedAt"].every((key) => typeof value[key] === "number" && Number.isFinite(value[key]));
23816
23968
  }
23817
- function edge(value) {
23969
+ function edge2(value) {
23818
23970
  return record5(value) && text(value.source) && text(value.target) && (value.kind === "calls" || value.kind === "references") && (value.line === undefined || typeof value.line === "number" && Number.isFinite(value.line)) && (value.column === undefined || typeof value.column === "number" && Number.isFinite(value.column)) && (value.metadata === undefined || record5(value.metadata));
23819
23971
  }
23820
23972
  function fileRecord(value) {
@@ -23861,12 +24013,12 @@ function decodeReader(output, root, request) {
23861
24013
  }
23862
24014
  return result;
23863
24015
  };
23864
- const names = table(wire.names, (value) => rows(value, node));
24016
+ const names = table(wire.names, (value) => rows(value, node2));
23865
24017
  sameKeys(names, request.names);
23866
24018
  for (const [name, nodes] of names)
23867
24019
  if (nodes.some((item) => item.name !== name))
23868
24020
  unavailable();
23869
- const filesByPath = table(wire.filesByPath, (value) => rows(value, node));
24021
+ const filesByPath = table(wire.filesByPath, (value) => rows(value, node2));
23870
24022
  const sources = new Map;
23871
24023
  const sourcePaths = new Set(request.sources.map((source) => source.path));
23872
24024
  for (const source of request.sources) {
@@ -23880,7 +24032,7 @@ function decodeReader(output, root, request) {
23880
24032
  }
23881
24033
  }
23882
24034
  sameKeys(filesByPath, sourcePaths);
23883
- const outgoing = table(wire.outgoing, (value) => rows(value, edge));
24035
+ const outgoing = table(wire.outgoing, (value) => rows(value, edge2));
23884
24036
  sameKeys(outgoing, sources.keys());
23885
24037
  const targetIds = new Set;
23886
24038
  for (const [id, edges] of outgoing)
@@ -23890,7 +24042,7 @@ function decodeReader(output, root, request) {
23890
24042
  targetIds.add(item.target);
23891
24043
  }
23892
24044
  const targets = table(wire.targets, (value) => {
23893
- if (++items > MAX_ITEMS || value !== null && !node(value))
24045
+ if (++items > MAX_ITEMS || value !== null && !node2(value))
23894
24046
  return unavailable();
23895
24047
  return value;
23896
24048
  });
@@ -25459,6 +25611,8 @@ function architectureDeltaTask(git) {
25459
25611
  var CODEGRAPH_IMPORT_NODE_READ_LIMIT = 50000;
25460
25612
  var CODEGRAPH_IMPORT_NODE_OUTPUT_BYTES = 4 * 1024;
25461
25613
  function prepareArchitectureDocumentationProjectionSnapshot(root, model, options = {}) {
25614
+ if (codeGraphIndexAvailable(root))
25615
+ assertRepositoryCodeFactsReady(root, options.binary ? { binary: options.binary } : {});
25462
25616
  const baseHeadSha = readProjectionHeadSha(root);
25463
25617
  const sourceFiles = listGitVisibleFiles(root);
25464
25618
  const worktreeDigest = architectureDocumentationProjectionWorktreeDigest(root, model, sourceFiles);
@@ -25603,7 +25757,33 @@ function prepareProjectionCodeFacts(root, model, options) {
25603
25757
  }
25604
25758
  };
25605
25759
  }
25760
+
25761
+ class CodeGraphIndexBuildInProgressError extends Error {
25762
+ constructor() {
25763
+ super("CodeGraph index build is in progress");
25764
+ this.name = "CodeGraphIndexBuildInProgressError";
25765
+ }
25766
+ }
25767
+ function codeGraphIndexBuildInProgress(workspaceRoot) {
25768
+ let raw;
25769
+ try {
25770
+ raw = readFileSync7(join3(workspaceRoot, ".codegraph", "codegraph.lock"), "utf8").trim();
25771
+ } catch {
25772
+ return false;
25773
+ }
25774
+ const pid = Number.parseInt(raw, 10);
25775
+ if (!Number.isSafeInteger(pid) || pid <= 0 || String(pid) !== raw)
25776
+ return false;
25777
+ try {
25778
+ process.kill(pid, 0);
25779
+ return true;
25780
+ } catch (error) {
25781
+ return error.code === "EPERM";
25782
+ }
25783
+ }
25606
25784
  function readProjectionCodeGraphStatus(invocation, root, timeout, envOverrides) {
25785
+ if (codeGraphIndexBuildInProgress(root))
25786
+ throw new CodeGraphIndexBuildInProgressError;
25607
25787
  const output = runProjectionCodeGraph(invocation, root, ["status", "-j", root], timeout, envOverrides);
25608
25788
  try {
25609
25789
  return JSON.parse(output);
@@ -25922,8 +26102,9 @@ function mirrorCodeGraphInputs(root, gitDir, commonDir, destination) {
25922
26102
  var CODEGRAPH_NO_DOWNLOAD_ENV = { CODEGRAPH_NO_DOWNLOAD: "1" };
25923
26103
  function inspectRepositoryCodeFacts(root, options = {}) {
25924
26104
  const schemaVersion = "archcontext.repository-code-facts/v1";
25925
- let codeGraphVersion;
26105
+ let codeGraphVersion = "";
25926
26106
  let status;
26107
+ let indexBuildInProgress = false;
25927
26108
  const indexPresent = codeGraphIndexAvailable(root);
25928
26109
  try {
25929
26110
  const invocation = options.binary ? codeGraphCliInvocation(options.binary, root, "") : packagedCodeGraphCliInvocation();
@@ -25931,18 +26112,37 @@ function inspectRepositoryCodeFacts(root, options = {}) {
25931
26112
  if (indexPresent)
25932
26113
  status = readProjectionCodeGraphStatus(invocation, root, options.timeouts?.statusMs ?? 1e4, CODEGRAPH_NO_DOWNLOAD_ENV);
25933
26114
  } catch (error) {
25934
- return {
25935
- schemaVersion,
25936
- state: "unavailable",
25937
- requiredVersion: REQUIRED_CODEGRAPH_VERSION,
25938
- reasonCode: "codegraph-unavailable",
25939
- message: (error instanceof Error ? error.message : String(error)).replace(/\s+/g, " ").trim().slice(0, 400)
25940
- };
26115
+ if (!(error instanceof CodeGraphIndexBuildInProgressError)) {
26116
+ return {
26117
+ schemaVersion,
26118
+ state: "unavailable",
26119
+ requiredVersion: REQUIRED_CODEGRAPH_VERSION,
26120
+ reasonCode: "codegraph-unavailable",
26121
+ message: (error instanceof Error ? error.message : String(error)).replace(/\s+/g, " ").trim().slice(0, 400)
26122
+ };
26123
+ }
26124
+ indexBuildInProgress = true;
25941
26125
  }
25942
26126
  const versionIssues = codeGraphVersion === REQUIRED_CODEGRAPH_VERSION ? [] : [{ code: "version-mismatch", message: CODE_FACTS_ISSUE_MESSAGES["version-mismatch"] }];
25943
26127
  if (!indexPresent) {
25944
26128
  return { schemaVersion, state: "index-missing", indexPresent: false, requiredVersion: REQUIRED_CODEGRAPH_VERSION, codeGraphVersion, issues: versionIssues };
25945
26129
  }
26130
+ if (indexBuildInProgress) {
26131
+ return {
26132
+ schemaVersion,
26133
+ state: "not-ready",
26134
+ indexPresent: true,
26135
+ requiredVersion: REQUIRED_CODEGRAPH_VERSION,
26136
+ codeGraphVersion,
26137
+ indexBuiltWithVersion: null,
26138
+ extractionVersion: { builtWith: null, current: null },
26139
+ indexState: null,
26140
+ reindexRecommended: null,
26141
+ pendingRefs: null,
26142
+ pendingChanges: null,
26143
+ issues: [...versionIssues, { code: "index-incomplete", message: CODE_FACTS_ISSUE_MESSAGES["index-incomplete"] }]
26144
+ };
26145
+ }
25946
26146
  if (typeof status !== "object" || status === null || Array.isArray(status)) {
25947
26147
  return {
25948
26148
  schemaVersion,
@@ -26329,6 +26529,8 @@ function selectedProducerFailure(error, stage) {
26329
26529
  const details = stage === "docs-anchors" || stage === "flows-check" ? {} : { checks: ["ownership", "anchors"] };
26330
26530
  return new FailureError(selectedProducerData(error, "code"), selectedProducerData(error, "reasonCode"), details);
26331
26531
  }
26532
+ if (error instanceof ProjectionManifestUpgradeRequiredError)
26533
+ return new FailureError("AC_PRECONDITION_FAILED", selectedProducerData(error, "reasonCode"), selectedProducerData(error, "details"));
26332
26534
  if (error instanceof ProjectionPreconditionError)
26333
26535
  return new FailureError("AC_PRECONDITION_FAILED", selectedProducerData(error, "reasonCode"));
26334
26536
  if (error instanceof ProjectionCodeFactsUnavailableError)
@@ -26346,10 +26548,10 @@ function selectedProducerFailureEnvelope(requestId, error, stage) {
26346
26548
  // packages/local-runtime/runtime-daemon/src/refactor-scan.ts
26347
26549
  init_src();
26348
26550
  init_src();
26349
- import { execFileSync as execFileSync3 } from "node:child_process";
26350
- import { createHash as createHash8 } from "node:crypto";
26351
- import { existsSync as existsSync8, readdirSync as readdirSync6, readFileSync as readFileSync9 } from "node:fs";
26352
- import { join as join5 } from "node:path";
26551
+ import { execFileSync as execFileSync4 } from "node:child_process";
26552
+ import { createHash as createHash9 } from "node:crypto";
26553
+ import { existsSync as existsSync8, readdirSync as readdirSync7, readFileSync as readFileSync10 } from "node:fs";
26554
+ import { join as join7 } from "node:path";
26353
26555
 
26354
26556
  // packages/core/refactor-assessment/src/index.ts
26355
26557
  init_src();
@@ -27192,7 +27394,7 @@ function buildObservations(snapshot, structure, model) {
27192
27394
  evidence: evidence.evidenceGap()
27193
27395
  });
27194
27396
  }
27195
- return drafts.map((draft, index) => ({ draft, order: draft.kind === "cycle" ? index : 0 })).sort((left, right) => compare3(left.draft.kind, right.draft.kind) || left.order - right.order || compare3(left.draft.subjectSelectorId, right.draft.subjectSelectorId)).map(({ draft }) => ({
27397
+ return drafts.map((draft, index) => ({ draft, order: draft.kind === "cycle" ? index : 0 })).sort((left, right) => compare4(left.draft.kind, right.draft.kind) || left.order - right.order || compare4(left.draft.subjectSelectorId, right.draft.subjectSelectorId)).map(({ draft }) => ({
27196
27398
  kind: draft.kind,
27197
27399
  subjectSelectorId: draft.subjectSelectorId,
27198
27400
  affectedNodeIds: draft.affectedNodeIds,
@@ -27382,13 +27584,13 @@ function signalIdFor(draft) {
27382
27584
  }
27383
27585
  function modelDigest2(model, constraints) {
27384
27586
  return digestJson({
27385
- nodes: [...model.nodes].sort((left, right) => compare3(left.id, right.id)),
27386
- relations: [...model.relations].sort((left, right) => compare3(left.id, right.id)),
27387
- flows: [...model.flows ?? []].sort((left, right) => compare3(left.id, right.id)),
27388
- ...constraints.length === 0 ? {} : { constraints: [...constraints].sort((left, right) => compare3(left.id, right.id)) }
27587
+ nodes: [...model.nodes].sort((left, right) => compare4(left.id, right.id)),
27588
+ relations: [...model.relations].sort((left, right) => compare4(left.id, right.id)),
27589
+ flows: [...model.flows ?? []].sort((left, right) => compare4(left.id, right.id)),
27590
+ ...constraints.length === 0 ? {} : { constraints: [...constraints].sort((left, right) => compare4(left.id, right.id)) }
27389
27591
  });
27390
27592
  }
27391
- function compare3(left, right) {
27593
+ function compare4(left, right) {
27392
27594
  return left < right ? -1 : left > right ? 1 : 0;
27393
27595
  }
27394
27596
  function isNumber(value) {
@@ -27400,8 +27602,117 @@ function isPresent2(value) {
27400
27602
 
27401
27603
  // packages/local-runtime/model-store-yaml/src/index.ts
27402
27604
  init_src();
27403
- import { existsSync as existsSync7, lstatSync as lstatSync6, mkdirSync as mkdirSync5, readdirSync as readdirSync5, readFileSync as readFileSync8, rmSync as rmSync5 } from "node:fs";
27404
- import { dirname as dirname5, resolve as resolve12 } from "node:path";
27605
+ import { existsSync as existsSync7, lstatSync as lstatSync6, mkdirSync as mkdirSync6, readdirSync as readdirSync6, readFileSync as readFileSync9, rmSync as rmSync5 } from "node:fs";
27606
+ import { dirname as dirname5, resolve as resolve13 } from "node:path";
27607
+
27608
+ // packages/local-runtime/model-store-yaml/src/architecture-history.ts
27609
+ init_src();
27610
+ import { mkdirSync as mkdirSync5, readFileSync as readFileSync8, renameSync as renameSync3, writeFileSync as writeFileSync4 } from "node:fs";
27611
+ import { join as join5 } from "node:path";
27612
+ import { randomUUID } from "node:crypto";
27613
+
27614
+ // packages/local-runtime/runtime-state-paths/src/index.ts
27615
+ import { execFileSync as execFileSync3 } from "node:child_process";
27616
+ import { createHash as createHash6 } from "node:crypto";
27617
+ import { readdirSync as readdirSync5, realpathSync as realpathSync4 } from "node:fs";
27618
+ import { homedir } from "node:os";
27619
+ import { isAbsolute as isAbsolute5, join as join4, resolve as resolve11 } from "node:path";
27620
+ var ARCHCONTEXT_STATE_DIR_ENV = "ARCHCONTEXT_STATE_DIR";
27621
+ var ARCHCONTEXT_LOCAL_STORE_PATH_ENV = "ARCHCONTEXT_LOCAL_STORE_PATH";
27622
+ function defaultArchContextStateRoot(env = process.env, platform = process.platform, home = homedir()) {
27623
+ const override = env[ARCHCONTEXT_STATE_DIR_ENV];
27624
+ if (override)
27625
+ return { path: resolve11(override), source: "environment" };
27626
+ if (platform === "darwin")
27627
+ return { path: join4(home, "Library", "Application Support", "ArchContext"), source: "os-user-data" };
27628
+ if (platform === "win32")
27629
+ return { path: join4(env.LOCALAPPDATA ?? join4(home, "AppData", "Local"), "ArchContext"), source: "os-user-data" };
27630
+ return { path: join4(env.XDG_DATA_HOME ?? join4(home, ".local", "share"), "archcontext"), source: "os-user-data" };
27631
+ }
27632
+ function runtimeStatePaths(root = process.cwd(), env = process.env) {
27633
+ const repositoryRoot = readGitPath(root, ["rev-parse", "--show-toplevel"]) ?? root;
27634
+ const canonicalRepositoryRoot = canonicalPath(repositoryRoot);
27635
+ const gitCommonDir = readGitPath(canonicalRepositoryRoot, ["rev-parse", "--git-common-dir"]);
27636
+ const repositoryAnchor = canonicalPath(gitCommonDir ? resolveMaybeRelative(canonicalRepositoryRoot, gitCommonDir) : canonicalRepositoryRoot);
27637
+ const workspaceAnchor = canonicalRepositoryRoot;
27638
+ const storageRepositoryId = stableStorageId("repo", repositoryAnchor);
27639
+ const storageWorkspaceId = stableStorageId("ws", workspaceAnchor);
27640
+ const stateRoot = defaultArchContextStateRoot(env);
27641
+ const repositoryStateDir = join4(stateRoot.path, REPOSITORIES_DIR, storageRepositoryId);
27642
+ const workspaceStateDir = join4(repositoryStateDir, WORKTREES_DIR, storageWorkspaceId);
27643
+ const legacyControlDir = resolve11(canonicalRepositoryRoot, ".archcontext", ".local");
27644
+ return {
27645
+ schemaVersion: "archcontext.runtime-state-paths/v1",
27646
+ stateRoot: stateRoot.path,
27647
+ source: stateRoot.source,
27648
+ repositoryRoot: canonicalRepositoryRoot,
27649
+ repositoryAnchor,
27650
+ workspaceAnchor,
27651
+ storageRepositoryId,
27652
+ storageWorkspaceId,
27653
+ repositoryId: storageRepositoryId,
27654
+ workspaceId: storageWorkspaceId,
27655
+ repositoryStateDir,
27656
+ workspaceStateDir,
27657
+ sharedCacheDir: join4(repositoryStateDir, "shared", "cache"),
27658
+ localStorePath: env[ARCHCONTEXT_LOCAL_STORE_PATH_ENV] ?? join4(workspaceStateDir, "runtime.sqlite"),
27659
+ ...daemonControlPaths(workspaceStateDir),
27660
+ developerReviewRunStateDir: join4(workspaceStateDir, "developer-review-runs"),
27661
+ legacyControlDir,
27662
+ legacyLocalStorePath: join4(legacyControlDir, "runtime.sqlite")
27663
+ };
27664
+ }
27665
+ var REPOSITORIES_DIR = "repositories";
27666
+ var WORKTREES_DIR = "worktrees";
27667
+ function daemonControlPaths(workspaceStateDir) {
27668
+ return {
27669
+ daemonConnectionPath: join4(workspaceStateDir, "archctxd.json"),
27670
+ daemonLockPath: join4(workspaceStateDir, "archctxd.lock"),
27671
+ daemonLogPath: join4(workspaceStateDir, "archctxd.log")
27672
+ };
27673
+ }
27674
+ function listWorkspaceStateDirs(stateRoot) {
27675
+ return listDirectoryNames(join4(stateRoot, REPOSITORIES_DIR)).flatMap((storageRepositoryId) => listDirectoryNames(join4(stateRoot, REPOSITORIES_DIR, storageRepositoryId, WORKTREES_DIR)).map((storageWorkspaceId) => ({
27676
+ storageRepositoryId,
27677
+ storageWorkspaceId,
27678
+ workspaceStateDir: join4(stateRoot, REPOSITORIES_DIR, storageRepositoryId, WORKTREES_DIR, storageWorkspaceId)
27679
+ })));
27680
+ }
27681
+ function listDirectoryNames(path) {
27682
+ try {
27683
+ return readdirSync5(path, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort();
27684
+ } catch (error) {
27685
+ if (error.code === "ENOENT")
27686
+ return [];
27687
+ throw error;
27688
+ }
27689
+ }
27690
+ function readGitPath(root, args) {
27691
+ try {
27692
+ const value = execFileSync3("git", args, {
27693
+ cwd: root,
27694
+ encoding: "utf8",
27695
+ stdio: ["ignore", "pipe", "ignore"]
27696
+ }).trim();
27697
+ return value.length > 0 ? value : undefined;
27698
+ } catch {
27699
+ return;
27700
+ }
27701
+ }
27702
+ function resolveMaybeRelative(base, path) {
27703
+ return isAbsolute5(path) ? resolve11(path) : resolve11(base, path);
27704
+ }
27705
+ function canonicalPath(path) {
27706
+ const resolved = resolve11(path);
27707
+ try {
27708
+ return realpathSync4.native(resolved);
27709
+ } catch {
27710
+ return resolved;
27711
+ }
27712
+ }
27713
+ function stableStorageId(prefix, value) {
27714
+ return `${prefix}.${createHash6("sha256").update(value).digest("hex").slice(0, 16)}`;
27715
+ }
27405
27716
  // schemas/repo/architecture-node.schema.json
27406
27717
  var architecture_node_schema_default = {
27407
27718
  $schema: "https://json-schema.org/draft/2020-12/schema",
@@ -27522,12 +27833,6 @@ var architecture_node_schema_default = {
27522
27833
  extensions: { type: "object", additionalProperties: true }
27523
27834
  }
27524
27835
  };
27525
-
27526
- // packages/local-runtime/model-store-yaml/src/native-context.ts
27527
- init_src();
27528
- import { createHash as createHash6 } from "node:crypto";
27529
- import { constants, closeSync as closeSync4, fstatSync as fstatSync2, lstatSync as lstatSync5, openSync as openSync4, readSync as readSync2, realpathSync as realpathSync4 } from "node:fs";
27530
- import { join as join4, resolve as resolve11 } from "node:path";
27531
27836
  // schemas/repo/architecture-relation.schema.json
27532
27837
  var architecture_relation_schema_default = {
27533
27838
  $schema: "https://json-schema.org/draft/2020-12/schema",
@@ -27555,6 +27860,185 @@ var architecture_relation_schema_default = {
27555
27860
  extensions: { type: "object", additionalProperties: true }
27556
27861
  }
27557
27862
  };
27863
+
27864
+ // packages/local-runtime/model-store-yaml/src/architecture-history.ts
27865
+ var compare5 = nativeByteCompare;
27866
+ var modelRoot = ".archcontext/model";
27867
+ var failed = (code, path) => ({ nodes: null, edges: null, structure: null, error: { code, ...path ? { path } : {} } });
27868
+ var edgeKey = (e) => JSON.stringify([e.source, e.target]);
27869
+ function stateForRevision(root, rev, parsed) {
27870
+ try {
27871
+ let context;
27872
+ try {
27873
+ context = readGitBlobTree(root, `${rev}:.archcontext`, { sizes: false });
27874
+ } catch (error) {
27875
+ if (!(error instanceof NativeContextError) || error.reasonCode !== "native-context-git-read-failed")
27876
+ throw error;
27877
+ if (readGitBlobTree(root, rev, { sizes: false }).some((entry) => entry.path === ".archcontext" && entry.type === "tree"))
27878
+ throw error;
27879
+ return failed("history-model-missing");
27880
+ }
27881
+ const manifest = context.find((entry) => entry.path === "manifest.yaml");
27882
+ if (manifest && manifest.type !== "blob")
27883
+ return failed("history-model-layout-unsupported");
27884
+ const read = (entry) => {
27885
+ if (!parsed.has(entry.objectId)) {
27886
+ const body = readGitBlobs(root, [entry])[0];
27887
+ try {
27888
+ parsed.set(entry.objectId, { value: parseJsonOrStableYaml(decodeUtf8(body), entry.path) });
27889
+ } catch {
27890
+ parsed.set(entry.objectId, { invalid: true });
27891
+ }
27892
+ }
27893
+ return parsed.get(entry.objectId);
27894
+ };
27895
+ if (manifest) {
27896
+ const data = read(manifest);
27897
+ if (data.value?.schemaVersion !== "archcontext.manifest/v1" || data.value.model?.layout !== "split" || data.value.model.root !== modelRoot)
27898
+ return failed("history-model-layout-unsupported");
27899
+ }
27900
+ if (!context.some((entry) => entry.path === "model" && entry.type === "tree"))
27901
+ return failed("history-model-missing");
27902
+ const all = readGitBlobTree(root, `${rev}:${modelRoot}`, { sizes: false }).map((entry) => ({ ...entry, path: `${modelRoot}/${entry.path}` }));
27903
+ const nodesDir = all.find((entry) => entry.path === `${modelRoot}/nodes` && entry.type === "tree");
27904
+ if (!nodesDir)
27905
+ return failed("history-model-missing");
27906
+ const files = all.filter((entry) => entry.type === "blob" && (entry.path.startsWith(`${modelRoot}/nodes/`) || entry.path.startsWith(`${modelRoot}/relations/`)) && /\.ya?ml$/.test(entry.path)).sort((a, b) => compare5(a.path, b.path));
27907
+ const missing = [...new Map(files.filter((file) => !parsed.has(file.objectId)).map((file) => [file.objectId, file])).values()];
27908
+ const blobs = readGitBlobs(root, missing);
27909
+ missing.forEach((file, index) => {
27910
+ try {
27911
+ parsed.set(file.objectId, { value: parseJsonOrStableYaml(decodeUtf8(blobs[index]), file.path) });
27912
+ } catch {
27913
+ parsed.set(file.objectId, { invalid: true });
27914
+ }
27915
+ });
27916
+ const nodes = [], relations = [];
27917
+ const paths = new Map;
27918
+ for (const file of files) {
27919
+ const result = read(file);
27920
+ const isNode = file.path.startsWith(`${modelRoot}/nodes/`);
27921
+ if (result.invalid || result.value === undefined || !validateJsonSchema(isNode ? architecture_node_schema_default : architecture_relation_schema_default, result.value).valid)
27922
+ return failed("history-model-invalid", file.path);
27923
+ if (isNode) {
27924
+ const value = result.value;
27925
+ if (paths.has(value.id))
27926
+ return failed("history-model-invalid", file.path);
27927
+ paths.set(value.id, file.path);
27928
+ nodes.push(value);
27929
+ } else
27930
+ relations.push(result.value);
27931
+ }
27932
+ const byId = new Map(nodes.map((node) => [node.id, node]));
27933
+ for (const node of nodes) {
27934
+ const visited = new Set;
27935
+ let cursor = node;
27936
+ while (cursor) {
27937
+ if (visited.has(cursor.id))
27938
+ return failed("history-model-invalid", paths.get(node.id));
27939
+ visited.add(cursor.id);
27940
+ cursor = cursor.parent ? byId.get(cursor.parent) : undefined;
27941
+ }
27942
+ }
27943
+ const nearest = (id) => {
27944
+ let node = byId.get(id);
27945
+ while (node) {
27946
+ if (node.kind === "capability")
27947
+ return node.id;
27948
+ node = node.parent ? byId.get(node.parent) : undefined;
27949
+ }
27950
+ return;
27951
+ };
27952
+ const edges = new Map;
27953
+ for (const relation of relations) {
27954
+ const source = nearest(relation.source), target = nearest(relation.target);
27955
+ if (source && target && source !== target) {
27956
+ const edge = { source, target };
27957
+ edges.set(edgeKey(edge), edge);
27958
+ }
27959
+ }
27960
+ return {
27961
+ nodes: nodes.filter((node) => node.kind === "capability").map((node) => ({ id: node.id, name: node.name, domain: /^capability\.([a-z0-9]+(?:-[a-z0-9]+)*)\.([a-z0-9]+(?:-[a-z0-9]+)*)$/.exec(node.id)?.[1] ?? null })).sort((a, b) => compare5(a.id, b.id)),
27962
+ edges: [...edges.values()].sort((a, b) => compare5(a.source, b.source) || compare5(a.target, b.target)),
27963
+ structure: nodes.filter((node) => ["capability", "module", "component"].includes(node.kind)).map((node) => ({ id: node.id, kind: node.kind, name: node.name, capability: nearest(node.id) ?? null })).sort((a, b) => compare5(a.id, b.id))
27964
+ };
27965
+ } catch (error) {
27966
+ if (error instanceof NativeContextError && error.reasonCode === "native-context-limit-exceeded")
27967
+ return failed("history-model-too-large");
27968
+ throw error;
27969
+ }
27970
+ }
27971
+ function difference(before, after, baseRev) {
27972
+ const a = new Map(before.structure.map((node) => [node.id, node])), b = new Map(after.structure.map((node) => [node.id, node]));
27973
+ const ae = new Map(before.edges.map((edge) => [edgeKey(edge), edge])), be = new Map(after.edges.map((edge) => [edgeKey(edge), edge]));
27974
+ return {
27975
+ baseRev,
27976
+ added: after.structure.filter((node) => !a.has(node.id)).map(({ id, kind, capability }) => ({ id, kind, capability })),
27977
+ removed: before.structure.filter((node) => !b.has(node.id)).map(({ id, kind, capability }) => ({ id, kind, capability })),
27978
+ renamed: after.structure.flatMap((node) => {
27979
+ const old = a.get(node.id);
27980
+ return old && old.name !== node.name ? [{ id: node.id, kind: node.kind, capability: node.capability, from: old.name, to: node.name }] : [];
27981
+ }),
27982
+ edgesChanged: { added: after.edges.filter((edge) => !ae.has(edgeKey(edge))), removed: before.edges.filter((edge) => !be.has(edgeKey(edge))) }
27983
+ };
27984
+ }
27985
+ function readArchitectureHistory(cwd, options = {}) {
27986
+ const root = readNativeGitRoot(cwd);
27987
+ if (decodeUtf8(readOnlyGit(root, "rev-parse", ["--is-shallow-repository"])).trim() === "true")
27988
+ throw new FailureError("AC_PRECONDITION_FAILED", "history-shallow-repository");
27989
+ const head = resolveNativeGitSnapshot(root, options.ref ?? "HEAD").commitSha;
27990
+ const output = decodeUtf8(readOnlyGit(root, "log", ["--first-parent", "--reverse", "-z", "--format=%H%x00%cI%x00%s", head, "--", modelRoot, ".archcontext/manifest.yaml"]));
27991
+ const fields = output ? output.split("\x00") : [];
27992
+ if (fields.length && fields.pop() !== "")
27993
+ throw new NativeContextError("native-context-git-read-failed", { operation: "log", category: "malformed-record" });
27994
+ if (fields.length % 3 !== 0)
27995
+ throw new NativeContextError("native-context-git-read-failed", { operation: "log", category: "malformed-record" });
27996
+ for (let i = 0;i < fields.length; i += 3)
27997
+ if (!/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(fields[i]))
27998
+ throw new NativeContextError("native-context-git-read-failed", { operation: "log", category: "malformed-record" });
27999
+ const parsed = new Map;
28000
+ const milestones = [];
28001
+ let previous = { nodes: [], edges: [], structure: [] };
28002
+ let havePrevious = false, priorError, previousMilestone = null;
28003
+ const cacheDir = join5(runtimeStatePaths(root, options.env).sharedCacheDir, "architecture-history", ARCHITECTURE_HISTORY_DERIVATION_VERSION);
28004
+ for (let i = 0;i < fields.length; i += 3) {
28005
+ const [rev, date, subject] = fields.slice(i, i + 3);
28006
+ const cache = join5(cacheDir, `${rev}.json`);
28007
+ let state;
28008
+ try {
28009
+ state = decodeArchitectureHistoryState(JSON.parse(readFileSync8(cache, "utf8")));
28010
+ } catch {}
28011
+ if (!state) {
28012
+ state = stateForRevision(root, rev, parsed);
28013
+ mkdirSync5(cacheDir, { recursive: true });
28014
+ const temporary = `${cache}.${randomUUID()}.tmp`;
28015
+ writeFileSync4(temporary, JSON.stringify(state));
28016
+ renameSync3(temporary, cache);
28017
+ }
28018
+ if (state.error) {
28019
+ if (priorError !== state.error.code)
28020
+ milestones.push({ rev, date, subject, nodes: null, edges: null, delta: null, error: state.error });
28021
+ priorError = state.error.code;
28022
+ continue;
28023
+ }
28024
+ const recovered = priorError !== undefined;
28025
+ priorError = undefined;
28026
+ const delta = difference(previous, state, previousMilestone);
28027
+ if (!havePrevious || recovered || delta.added.length || delta.removed.length || delta.renamed.length || delta.edgesChanged.added.length || delta.edgesChanged.removed.length) {
28028
+ milestones.push({ rev, date, subject, nodes: state.nodes, edges: state.edges, delta });
28029
+ previousMilestone = rev;
28030
+ previous = state;
28031
+ havePrevious = true;
28032
+ }
28033
+ }
28034
+ const offset = options.offset ?? 0, limit = options.limit ?? 200;
28035
+ return { schemaVersion: ARCHITECTURE_HISTORY_SCHEMA_VERSION, head, total: milestones.length, offset, limit, milestones: milestones.slice(offset, offset + limit) };
28036
+ }
28037
+ // packages/local-runtime/model-store-yaml/src/native-context.ts
28038
+ init_src();
28039
+ import { createHash as createHash7 } from "node:crypto";
28040
+ import { constants, closeSync as closeSync4, fstatSync as fstatSync2, lstatSync as lstatSync5, openSync as openSync4, readSync as readSync2, realpathSync as realpathSync5 } from "node:fs";
28041
+ import { join as join6, resolve as resolve12 } from "node:path";
27558
28042
  // schemas/repo/architecture-flow.schema.json
27559
28043
  var architecture_flow_schema_default = {
27560
28044
  $schema: "https://json-schema.org/draft/2020-12/schema",
@@ -27659,7 +28143,7 @@ var SCHEMAS = { node: architecture_node_schema_default, relation: architecture_r
27659
28143
  var MANIFEST = ".archcontext/manifest.yaml";
27660
28144
  var MODEL_KINDS = ["nodes", "relations", "flows"];
27661
28145
  function contentDigest(bytes) {
27662
- return `sha256:${createHash6("sha256").update(bytes).digest("hex")}`;
28146
+ return `sha256:${createHash7("sha256").update(bytes).digest("hex")}`;
27663
28147
  }
27664
28148
  function record6(value) {
27665
28149
  return value !== null && typeof value === "object" && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype ? value : undefined;
@@ -27787,23 +28271,23 @@ function observePath(root, path, directory = false) {
27787
28271
  const segments = path.split("/");
27788
28272
  for (let index = -1;index < segments.length; index += 1) {
27789
28273
  if (index >= 0)
27790
- absolute = join4(absolute, segments[index]);
28274
+ absolute = join6(absolute, segments[index]);
27791
28275
  let stat;
27792
28276
  try {
27793
28277
  stat = lstatSync5(absolute, { bigint: true });
27794
28278
  } catch (error) {
27795
28279
  if (error.code === "ENOENT")
27796
- return { exists: false, identity: identities.join("/") + "/missing", absolute: resolve11(root, path) };
28280
+ return { exists: false, identity: identities.join("/") + "/missing", absolute: resolve12(root, path) };
27797
28281
  throw new NativeContextError("native-context-input-unreadable", { path, category: "stat" });
27798
28282
  }
27799
28283
  const needsDirectory = index < segments.length - 1 || directory;
27800
28284
  if (stat.isSymbolicLink() || (needsDirectory ? !stat.isDirectory() : !stat.isFile()))
27801
28285
  throw new NativeContextError("native-context-entry-kind-unsupported", { path, category: stat.isSymbolicLink() ? "link" : "non-regular" });
27802
- if (index >= 0 && realpathSync4.native(absolute) !== absolute)
28286
+ if (index >= 0 && realpathSync5.native(absolute) !== absolute)
27803
28287
  throw new NativeContextError("native-context-path-unsafe", { path, category: "filesystem-path-alias" });
27804
28288
  if (needsDirectory && index >= 0) {
27805
28289
  try {
27806
- lstatSync5(join4(absolute, ".git"));
28290
+ lstatSync5(join6(absolute, ".git"));
27807
28291
  throw new NativeContextError("native-context-entry-kind-unsupported", { path: segments.slice(0, index + 1).join("/"), category: "nested-repository" });
27808
28292
  } catch (error) {
27809
28293
  if (error instanceof NativeContextError)
@@ -28147,7 +28631,7 @@ function readNativeContext(start, selector, hooks) {
28147
28631
  `, "utf8"));
28148
28632
  return data;
28149
28633
  }
28150
- const worktreeRoot = realpathSync4.native(root);
28634
+ const worktreeRoot = realpathSync5.native(root);
28151
28635
  const head = resolveNativeGitSnapshot(worktreeRoot, "HEAD");
28152
28636
  const snapshot = { source: "worktree", headSha: head.commitSha, headTreeOid: head.treeOid, validation: "stable-read" };
28153
28637
  const first = new WorktreeSource(worktreeRoot, hooks, 1, head.treeOid);
@@ -28183,7 +28667,7 @@ init_src();
28183
28667
 
28184
28668
  // packages/local-runtime/codegraph-adapter/src/ref-impact-facts.ts
28185
28669
  init_src();
28186
- import { createHash as createHash7 } from "node:crypto";
28670
+ import { createHash as createHash8 } from "node:crypto";
28187
28671
  import { createRequire as createRequire3 } from "node:module";
28188
28672
  var nonDeclarations = new Set(["file", "import", "export", "parameter"]);
28189
28673
  var requireFromAdapter2 = createRequire3(import.meta.url);
@@ -28217,7 +28701,7 @@ function bindSnapshotRefImpactFacts(root, model, ref, graph) {
28217
28701
  for (let i = 0;i < files.length; i++) {
28218
28702
  const file = files[i], body = blobs[i];
28219
28703
  const content = decodeUtf8(body);
28220
- if (createHash7("sha256").update(content).digest("hex") !== file.contentHash)
28704
+ if (createHash8("sha256").update(content).digest("hex") !== file.contentHash)
28221
28705
  return;
28222
28706
  lineCounts.set(file.path, content.split(`
28223
28707
  `).length);
@@ -28696,10 +29180,10 @@ function initializeArchContextModel(root, productName = "ArchContext Project") {
28696
29180
  });
28697
29181
  files.push({ path: ".archcontext/projections/targets.json", body: `${JSON.stringify(createDefaultProjectionTargetManifest(), null, 2)}
28698
29182
  ` });
28699
- mkdirSync5(root, { recursive: true });
29183
+ mkdirSync6(root, { recursive: true });
28700
29184
  const existing = files.filter((file) => {
28701
29185
  assertPathHasNoSymlinkSegments(root, file.path);
28702
- return lstatIfExists(resolve12(root, file.path)) !== undefined;
29186
+ return lstatIfExists(resolve13(root, file.path)) !== undefined;
28703
29187
  }).map((file) => file.path);
28704
29188
  if (existing.length > 0)
28705
29189
  throw new ArchContextInitRefusedError(existing);
@@ -28712,7 +29196,7 @@ function initializeArchContextModel(root, productName = "ArchContext Project") {
28712
29196
  rebuildGeneratedProjection(root);
28713
29197
  } catch (error) {
28714
29198
  for (const path of created.reverse())
28715
- rmSync5(resolve12(root, path), { force: true });
29199
+ rmSync5(resolve13(root, path), { force: true });
28716
29200
  throw error;
28717
29201
  }
28718
29202
  }
@@ -28720,7 +29204,7 @@ function rebuildGeneratedProjection(root) {
28720
29204
  for (const operation of planGeneratedProjection(root)) {
28721
29205
  if (operation.operation === "delete_entity") {
28722
29206
  assertPathHasNoSymlinkSegments(root, dirname5(operation.path));
28723
- rmSync5(resolve12(root, operation.path), { force: true });
29207
+ rmSync5(resolve13(root, operation.path), { force: true });
28724
29208
  } else {
28725
29209
  writeFileWithoutFollowingSymlinks({ root, path: operation.path, body: withTrailingNewline(operation.body), expectedHash: operation.expectedHash });
28726
29210
  }
@@ -28728,12 +29212,12 @@ function rebuildGeneratedProjection(root) {
28728
29212
  }
28729
29213
  function planGeneratedProjection(root) {
28730
29214
  const desiredBody = GENERATED_ARCHITECTURE_BODY;
28731
- const desiredAbsolute = resolve12(root, GENERATED_ARCHITECTURE_PATH);
29215
+ const desiredAbsolute = resolve13(root, GENERATED_ARCHITECTURE_PATH);
28732
29216
  const operations = [];
28733
- if (!existsSync7(desiredAbsolute) || readFileSync8(desiredAbsolute, "utf8") !== desiredBody) {
29217
+ if (!existsSync7(desiredAbsolute) || readFileSync9(desiredAbsolute, "utf8") !== desiredBody) {
28734
29218
  operations.push({
28735
29219
  path: GENERATED_ARCHITECTURE_PATH,
28736
- expectedHash: existsSync7(desiredAbsolute) ? digestJson({ body: readFileSync8(desiredAbsolute, "utf8") }) : "missing",
29220
+ expectedHash: existsSync7(desiredAbsolute) ? digestJson({ body: readFileSync9(desiredAbsolute, "utf8") }) : "missing",
28737
29221
  body: desiredBody,
28738
29222
  operation: "render_projection"
28739
29223
  });
@@ -28741,7 +29225,7 @@ function planGeneratedProjection(root) {
28741
29225
  for (const path of collectGeneratedProjectionFiles(root)) {
28742
29226
  if (path === GENERATED_ARCHITECTURE_PATH)
28743
29227
  continue;
28744
- const body = readFileSync8(resolve12(root, path), "utf8");
29228
+ const body = readFileSync9(resolve13(root, path), "utf8");
28745
29229
  operations.push({
28746
29230
  path,
28747
29231
  expectedHash: digestJson({ body }),
@@ -28753,9 +29237,9 @@ function planGeneratedProjection(root) {
28753
29237
  }
28754
29238
  function collectGeneratedProjectionFiles(root) {
28755
29239
  const generatedRoot = ".archcontext/generated";
28756
- if (!existsSync7(resolve12(root, generatedRoot)))
29240
+ if (!existsSync7(resolve13(root, generatedRoot)))
28757
29241
  return [];
28758
- const walk = (relativeDir) => readdirSync5(resolve12(root, relativeDir), { withFileTypes: true }).flatMap((entry) => {
29242
+ const walk = (relativeDir) => readdirSync6(resolve13(root, relativeDir), { withFileTypes: true }).flatMap((entry) => {
28759
29243
  const child = `${relativeDir}/${entry.name}`;
28760
29244
  if (entry.isDirectory())
28761
29245
  return walk(child);
@@ -28766,7 +29250,7 @@ function collectGeneratedProjectionFiles(root) {
28766
29250
 
28767
29251
  class YamlModelStore {
28768
29252
  async loadManifest(workspace) {
28769
- return readFileSync8(resolve12(workspace.root, ".archcontext/manifest.yaml"), "utf8");
29253
+ return readFileSync9(resolve13(workspace.root, ".archcontext/manifest.yaml"), "utf8");
28770
29254
  }
28771
29255
  async loadModel(workspace) {
28772
29256
  return listModelFiles(workspace.root);
@@ -28777,7 +29261,7 @@ class YamlModelStore {
28777
29261
  const nodeSchemaErrors = [];
28778
29262
  for (const required of [".archcontext/manifest.yaml", ".archcontext/product.yaml"]) {
28779
29263
  try {
28780
- readFileSync8(resolve12(workspace.root, required), "utf8");
29264
+ readFileSync9(resolve13(workspace.root, required), "utf8");
28781
29265
  } catch {
28782
29266
  const error = `missing ${required}`;
28783
29267
  errors.push(error);
@@ -28874,7 +29358,7 @@ function listModelFiles(root) {
28874
29358
  "docs/adr"
28875
29359
  ]);
28876
29360
  return paths.map((path) => {
28877
- const body = readFileSync8(resolve12(root, path), "utf8");
29361
+ const body = readFileSync9(resolve13(root, path), "utf8");
28878
29362
  return {
28879
29363
  path,
28880
29364
  body,
@@ -28886,7 +29370,7 @@ function listModelFiles(root) {
28886
29370
  function collectArchContextFiles(root, entries) {
28887
29371
  const files = [];
28888
29372
  for (const entry of entries) {
28889
- const absolute = resolve12(root, entry);
29373
+ const absolute = resolve13(root, entry);
28890
29374
  if (!existsSync7(absolute))
28891
29375
  continue;
28892
29376
  const stat = readdirOrFile(absolute);
@@ -28900,8 +29384,8 @@ function collectArchContextFiles(root, entries) {
28900
29384
  return [...new Set(files)].sort();
28901
29385
  function walk(relativeDir) {
28902
29386
  const out = [];
28903
- const dir = resolve12(root, relativeDir);
28904
- for (const entry of readdirSync5(dir, { withFileTypes: true })) {
29387
+ const dir = resolve13(root, relativeDir);
29388
+ for (const entry of readdirSync6(dir, { withFileTypes: true })) {
28905
29389
  const child = `${relativeDir}/${entry.name}`;
28906
29390
  if (entry.isDirectory())
28907
29391
  out.push(...walk(child));
@@ -28918,7 +29402,7 @@ function isCollectableModelFile(path) {
28918
29402
  }
28919
29403
  function readdirOrFile(path) {
28920
29404
  try {
28921
- readdirSync5(path);
29405
+ readdirSync6(path);
28922
29406
  return "directory";
28923
29407
  } catch {
28924
29408
  return "file";
@@ -32381,10 +32865,10 @@ function evaluateWorktreeDependencyConstraints(input) {
32381
32865
  });
32382
32866
  }
32383
32867
  function reviewWorkspacePackages(root) {
32384
- if (!existsSync8(join5(root, "package.json")))
32868
+ if (!existsSync8(join7(root, "package.json")))
32385
32869
  return { packages: [], resolved: true };
32386
32870
  try {
32387
- const manifest = JSON.parse(readFileSync9(join5(root, "package.json"), "utf8"));
32871
+ const manifest = JSON.parse(readFileSync10(join7(root, "package.json"), "utf8"));
32388
32872
  const declared = Array.isArray(manifest.workspaces) ? manifest.workspaces : manifest.workspaces?.packages ?? [];
32389
32873
  if (!Array.isArray(declared))
32390
32874
  throw new Error("workspaces must be a list");
@@ -32397,10 +32881,10 @@ function reviewWorkspacePackages(root) {
32397
32881
  const parent = /^([^*?[\]{}!]+)\/\*$/.exec(pattern)?.[1];
32398
32882
  if (parent === undefined)
32399
32883
  throw new Error(`unsupported workspace pattern: ${entry}`);
32400
- return readdirSync6(join5(root, parent), { withFileTypes: true }).filter((child) => child.isDirectory() && existsSync8(join5(root, parent, child.name, "package.json"))).map((child) => `${parent}/${child.name}`);
32884
+ return readdirSync7(join7(root, parent), { withFileTypes: true }).filter((child) => child.isDirectory() && existsSync8(join7(root, parent, child.name, "package.json"))).map((child) => `${parent}/${child.name}`);
32401
32885
  });
32402
32886
  const packages = directories.flatMap((directory) => {
32403
- const packageManifest = JSON.parse(readFileSync9(join5(root, ...directory.split("/"), "package.json"), "utf8"));
32887
+ const packageManifest = JSON.parse(readFileSync10(join7(root, ...directory.split("/"), "package.json"), "utf8"));
32404
32888
  if (typeof packageManifest.name !== "string")
32405
32889
  return [];
32406
32890
  const exports = typeof packageManifest.exports === "string" ? { ".": packageManifest.exports } : Object.fromEntries(Object.entries(packageManifest.exports ?? {}).filter((entry) => typeof entry[1] === "string"));
@@ -32426,7 +32910,7 @@ function modelNodes(files) {
32426
32910
  function readWorktreeFiles(root) {
32427
32911
  let output;
32428
32912
  try {
32429
- output = execFileSync3("git", ["ls-files", "--cached", "--others", "--exclude-standard", "-z"], {
32913
+ output = execFileSync4("git", ["ls-files", "--cached", "--others", "--exclude-standard", "-z"], {
32430
32914
  cwd: root,
32431
32915
  encoding: "utf8",
32432
32916
  stdio: ["ignore", "pipe", "pipe"],
@@ -32442,7 +32926,7 @@ function countFilesOutsideHead(root) {
32442
32926
  return readWorktreeFiles(root).filter((path) => !head.has(path)).length;
32443
32927
  }
32444
32928
  function declaredWorkspacePackages(root) {
32445
- return existsSync8(join5(root, "package.json")) ? readWorkspacePackages(root) : [];
32929
+ return existsSync8(join7(root, "package.json")) ? readWorkspacePackages(root) : [];
32446
32930
  }
32447
32931
  function assertRequestedStateIsCurrent(request, worktree) {
32448
32932
  if (request.expectedHeadSha !== undefined && request.expectedHeadSha !== worktree.headSha) {
@@ -32454,13 +32938,13 @@ function assertRequestedStateIsCurrent(request, worktree) {
32454
32938
  }
32455
32939
  var REFACTOR_NAMESPACE_MANIFEST_PATH = ".archcontext/manifest.yaml";
32456
32940
  function readRefactorNamespace(root) {
32457
- const path = join5(root, REFACTOR_NAMESPACE_MANIFEST_PATH);
32941
+ const path = join7(root, REFACTOR_NAMESPACE_MANIFEST_PATH);
32458
32942
  if (!existsSync8(path)) {
32459
32943
  throw new RefactorScanError("AC_MODEL_ADOPTION_REQUIRED", `${REFACTOR_NAMESPACE_MANIFEST_PATH} is missing; refactor recommendations are scoped by its product.id; run archctx init`, "product-id-missing");
32460
32944
  }
32461
32945
  let manifest;
32462
32946
  try {
32463
- manifest = parseJsonOrStableYaml(readFileSync9(path, "utf8"), REFACTOR_NAMESPACE_MANIFEST_PATH);
32947
+ manifest = parseJsonOrStableYaml(readFileSync10(path, "utf8"), REFACTOR_NAMESPACE_MANIFEST_PATH);
32464
32948
  } catch (error) {
32465
32949
  throw new RefactorScanError("AC_SCHEMA_INVALID", `${REFACTOR_NAMESPACE_MANIFEST_PATH} is unreadable: ${error instanceof Error ? error.message : String(error)}`, "product-id-invalid");
32466
32950
  }
@@ -32502,7 +32986,7 @@ function readCodeFacts(root, worktreeDigest, edgeLimit) {
32502
32986
  }
32503
32987
  function attestCodeGraphBinary(root) {
32504
32988
  const invocation = codeGraphCliInvocation(CODEGRAPH_BINARY, root);
32505
- const version = execFileSync3(invocation.command, [...invocation.argsPrefix, "--version"], {
32989
+ const version = execFileSync4(invocation.command, [...invocation.argsPrefix, "--version"], {
32506
32990
  cwd: root,
32507
32991
  encoding: "utf8",
32508
32992
  stdio: ["ignore", "pipe", "pipe"],
@@ -32511,7 +32995,7 @@ function attestCodeGraphBinary(root) {
32511
32995
  const binaryPath = invocation.argsPrefix[0] ?? invocation.command;
32512
32996
  return {
32513
32997
  version,
32514
- binaryDigest: `sha256:${createHash8("sha256").update(readFileSync9(binaryPath)).digest("hex")}`
32998
+ binaryDigest: `sha256:${createHash9("sha256").update(readFileSync10(binaryPath)).digest("hex")}`
32515
32999
  };
32516
33000
  }
32517
33001
 
@@ -32608,8 +33092,8 @@ function unavailable2(reasons) {
32608
33092
  // packages/local-runtime/runtime-daemon/src/docs-anchors.ts
32609
33093
  init_src();
32610
33094
  import { spawnSync as spawnSync5 } from "node:child_process";
32611
- import { readFileSync as readFileSync12 } from "node:fs";
32612
- import { resolve as resolve15 } from "node:path";
33095
+ import { readFileSync as readFileSync13 } from "node:fs";
33096
+ import { resolve as resolve16 } from "node:path";
32613
33097
 
32614
33098
  // packages/local-runtime/runtime-daemon/src/projection-service.ts
32615
33099
  init_src();
@@ -33886,8 +34370,8 @@ class ChangeSetRecoveryUnresolvedError extends FailureError {
33886
34370
 
33887
34371
  // packages/local-runtime/runtime-daemon/src/projection-freshness.ts
33888
34372
  init_src();
33889
- import { readFileSync as readFileSync10 } from "node:fs";
33890
- import { posix as posix3, resolve as resolve13 } from "node:path";
34373
+ import { readFileSync as readFileSync11 } from "node:fs";
34374
+ import { posix as posix3, resolve as resolve14 } from "node:path";
33891
34375
  function evaluateProjectionFreshness(input) {
33892
34376
  const { model, profile, manifest, sourceFootprints, scope } = input;
33893
34377
  return scope.kind === "tree" ? evaluateArchitectureProjectionSnapshotFreshness({ model, profile, manifest, sourceFootprints, currentSourceTreeDigest: scope.currentSourceTreeDigest }) : evaluateArchitectureProjectionFreshness({ model, profile, manifest, sourceFootprints, nodeIds: scope.nodeIds });
@@ -33912,7 +34396,7 @@ function measureProjectionFreshness(root, options = {}) {
33912
34396
  assertProjectionFreshnessChangedPaths(options.changedPaths);
33913
34397
  const manifest = options.manifest ?? loadArchitectureProjectionManifestStamps(root);
33914
34398
  if (manifest.status === "manifest-unreadable") {
33915
- assertArchitectureDocsProjectionManifestAccepted(readFileSync10(resolve13(root, ARCHITECTURE_DOCS_PROJECTION_MANIFEST_PATH), "utf8"));
34399
+ assertArchitectureDocsProjectionManifestAccepted(readFileSync11(resolve14(root, ARCHITECTURE_DOCS_PROJECTION_MANIFEST_PATH), "utf8"));
33916
34400
  }
33917
34401
  const model = loadNativeModelFromArchContext(root);
33918
34402
  const profile = manifest.status === "present" ? loadArchitectureDocumentationProfile(root) : undefined;
@@ -34030,6 +34514,8 @@ function publicOperationFailure(error) {
34030
34514
  failure = toEnvelope("public.operation", undefined, "public-operation").error;
34031
34515
  } else if (error instanceof GitVisibleFilesUnavailableError)
34032
34516
  failure = knownFailure(own2(error, "code"), own2(error, "reasonCode"));
34517
+ else if (error instanceof ProjectionManifestUpgradeRequiredError)
34518
+ failure = knownFailure("AC_PRECONDITION_FAILED", own2(error, "reasonCode"), own2(error, "details"));
34033
34519
  else if (error instanceof ProjectionPreconditionError)
34034
34520
  failure = knownFailure("AC_PRECONDITION_FAILED", own2(error, "reasonCode"));
34035
34521
  else if (error instanceof ProjectionCodeFactsUnavailableError)
@@ -34056,15 +34542,15 @@ function publicOperationResult(requestId, result) {
34056
34542
  }
34057
34543
 
34058
34544
  // packages/local-runtime/runtime-daemon/src/projection-service.ts
34059
- import { existsSync as existsSync9, readFileSync as readFileSync11 } from "node:fs";
34060
- import { resolve as resolve14 } from "node:path";
34545
+ import { existsSync as existsSync9, readFileSync as readFileSync12 } from "node:fs";
34546
+ import { resolve as resolve15 } from "node:path";
34061
34547
 
34062
34548
  // packages/local-runtime/runtime-daemon/src/projection-inputs.ts
34063
- import { execFileSync as execFileSync4 } from "node:child_process";
34549
+ import { execFileSync as execFileSync5 } from "node:child_process";
34064
34550
  init_src();
34065
34551
  function readCurrentBranch(root) {
34066
34552
  try {
34067
- const branch = execFileSync4("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
34553
+ const branch = execFileSync5("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
34068
34554
  cwd: root,
34069
34555
  encoding: "utf8",
34070
34556
  stdio: ["ignore", "pipe", "ignore"]
@@ -34380,7 +34866,7 @@ function architectureModelIgnoredEnvelope(requestId, root) {
34380
34866
  });
34381
34867
  }
34382
34868
  function committedArchitectureDocsProfile(root) {
34383
- return existsSync9(resolve14(root, ARCHITECTURE_DOCS_PROJECTION_MANIFEST_PATH)) ? loadArchitectureDocumentationProfile(root) : "default";
34869
+ return existsSync9(resolve15(root, ARCHITECTURE_DOCS_PROJECTION_MANIFEST_PATH)) ? loadArchitectureDocumentationProfile(root) : "default";
34384
34870
  }
34385
34871
  function withProjectionMetadata(envelope, provenance, runtimeSnapshot, majorChange, refreshSignals, receiptDigest) {
34386
34872
  if (!envelope.ok)
@@ -34794,8 +35280,8 @@ function runProjectionCheckCommandUnchecked(request, root) {
34794
35280
  return publicFailureEnvelope("projection.run", "AC_SCHEMA_INVALID", "projection-check-mode-invalid");
34795
35281
  }
34796
35282
  const manifestPath = ".archcontext/manifest.yaml";
34797
- if (existsSync9(resolve14(root, manifestPath))) {
34798
- const diagnostics = manifestDecisionDiagnostics([{ path: manifestPath, body: readFileSync11(resolve14(root, manifestPath), "utf8") }]);
35283
+ if (existsSync9(resolve15(root, manifestPath))) {
35284
+ const diagnostics = manifestDecisionDiagnostics([{ path: manifestPath, body: readFileSync12(resolve15(root, manifestPath), "utf8") }]);
34799
35285
  if (diagnostics.length)
34800
35286
  return publicFailureEnvelope("projection.run", "AC_SCHEMA_INVALID", "native-context-model-invalid", { path: manifestPath, invariant: diagnostics[0] });
34801
35287
  }
@@ -35685,7 +36171,7 @@ function fileContentReader(root) {
35685
36171
  return (path) => {
35686
36172
  let content = cache.get(path);
35687
36173
  if (content === undefined) {
35688
- content = readFileSync12(resolve15(root, path), "utf8").replace(/\r\n/g, `
36174
+ content = readFileSync13(resolve16(root, path), "utf8").replace(/\r\n/g, `
35689
36175
  `);
35690
36176
  cache.set(path, content);
35691
36177
  }
@@ -35753,7 +36239,7 @@ function proseAnchorSymbols(reader, files, contents) {
35753
36239
 
35754
36240
  // packages/local-runtime/runtime-daemon/src/architecture-debt.ts
35755
36241
  import { existsSync as existsSync10 } from "node:fs";
35756
- import { join as join6 } from "node:path";
36242
+ import { join as join8 } from "node:path";
35757
36243
  function readArchitectureDebt(root, input = {}) {
35758
36244
  try {
35759
36245
  const { evidence } = readArchitectureDebtEvidence(root, input);
@@ -35779,7 +36265,7 @@ function readArchitectureDebtEvidence(root, input) {
35779
36265
  const changedPaths = [...new Set(input.changedPaths ?? [])].sort();
35780
36266
  if (changedPaths.some((path) => !isRepoRelativePosixPath(path)))
35781
36267
  throw new ArchitectureDebtReadError("AC_SCHEMA_INVALID", "changedPaths must contain repository-relative POSIX paths", "changed-path-invalid");
35782
- if (!existsSync10(join6(root, ".archcontext/manifest.yaml")))
36268
+ if (!existsSync10(join8(root, ".archcontext/manifest.yaml")))
35783
36269
  throw new ArchitectureDebtReadError("AC_MODEL_ADOPTION_REQUIRED", "Architecture debt requires an adopted architecture model", "model-missing");
35784
36270
  const model = loadNativeModelFromArchContext(root);
35785
36271
  const files = listGitVisibleFiles(root);
@@ -35922,7 +36408,7 @@ function runNativeContextCommand(args, cwd, reader = exportNativeContext) {
35922
36408
  // packages/surfaces/cli/src/ref-impact.ts
35923
36409
  init_src();
35924
36410
  import { openSync as openSync5, closeSync as closeSync5, readSync as readSync3 } from "node:fs";
35925
- import { resolve as resolve16 } from "node:path";
36411
+ import { resolve as resolve17 } from "node:path";
35926
36412
  var invalid2 = (category) => {
35927
36413
  throw new NativeContextError("native-context-arguments-invalid", { category });
35928
36414
  };
@@ -35965,7 +36451,7 @@ function runRefImpactCommand(args, cwd, reader = readRefImpact) {
35965
36451
  let text;
35966
36452
  let fd;
35967
36453
  try {
35968
- fd = path === "-" ? 0 : openSync5(resolve16(cwd, path), "r");
36454
+ fd = path === "-" ? 0 : openSync5(resolve17(cwd, path), "r");
35969
36455
  const bytes = Buffer.alloc(REF_IMPACT_LIMITS.diffBytes + 1);
35970
36456
  let length = 0;
35971
36457
  while (length < bytes.length) {
@@ -36001,6 +36487,31 @@ function runRefImpactCommand(args, cwd, reader = readRefImpact) {
36001
36487
  }
36002
36488
  }
36003
36489
 
36490
+ // packages/surfaces/cli/src/architecture-history.ts
36491
+ init_src();
36492
+ function runArchitectureHistoryCommand(args, cwd) {
36493
+ if (args.includes("--help") || args.includes("-h"))
36494
+ return okEnvelope("history", { usage: "archctx history [--ref <rev>] [--format json|mermaid] [--offset <n>] [--limit <n>] --json" });
36495
+ const values = new Map;
36496
+ for (let i = 0;i < args.length; i++) {
36497
+ const flag = args[i];
36498
+ if (flag === "--json")
36499
+ continue;
36500
+ if (!["--ref", "--format", "--offset", "--limit"].includes(flag) || values.has(flag) || args[i + 1] === undefined)
36501
+ return errorEnvelope("history", "AC_SCHEMA_INVALID", "Invalid history arguments", "cli-input-invalid");
36502
+ values.set(flag, args[++i]);
36503
+ }
36504
+ const format = values.get("--format") ?? "json", offsetText = values.get("--offset") ?? "0", limitText = values.get("--limit") ?? "200";
36505
+ if (!/^[0-9]+$/.test(offsetText) || !/^[0-9]+$/.test(limitText) || !Number.isSafeInteger(Number(offsetText)) || !Number.isSafeInteger(Number(limitText)) || Number(limitText) > 1000 || !["json", "mermaid"].includes(format))
36506
+ return errorEnvelope("history", "AC_SCHEMA_INVALID", "Invalid history arguments", "cli-input-invalid");
36507
+ try {
36508
+ const history = readArchitectureHistory(cwd, { ref: values.get("--ref"), offset: Number(offsetText), limit: Number(limitText) });
36509
+ return okEnvelope("history", format === "mermaid" ? projectHistoryMermaid(history) : history);
36510
+ } catch (error) {
36511
+ return toEnvelope("history", error, "cli");
36512
+ }
36513
+ }
36514
+
36004
36515
  // packages/local-runtime/runtime-daemon/src/index.ts
36005
36516
  init_src();
36006
36517
 
@@ -36037,7 +36548,7 @@ async function exportChangeSetReceipt(store, root, journalId) {
36037
36548
  // packages/local-runtime/runtime-daemon/src/architecture-debt.ts
36038
36549
  init_src();
36039
36550
  import { existsSync as existsSync11 } from "node:fs";
36040
- import { join as join7 } from "node:path";
36551
+ import { join as join9 } from "node:path";
36041
36552
  function readArchitectureDebt2(root, input = {}) {
36042
36553
  try {
36043
36554
  const { evidence } = readArchitectureDebtEvidence2(root, input);
@@ -36051,7 +36562,7 @@ function readArchitectureDebt2(root, input = {}) {
36051
36562
  }
36052
36563
  function readCompleteTaskArchitectureDebt(root, practices) {
36053
36564
  try {
36054
- if (!existsSync11(join7(root, ".archcontext/manifest.yaml"))) {
36565
+ if (!existsSync11(join9(root, ".archcontext/manifest.yaml"))) {
36055
36566
  return checkedDebt2({
36056
36567
  scope: { kind: "repository", changedPaths: [], capabilityIds: [] },
36057
36568
  unavailable: Object.fromEntries(ARCHITECTURE_DEBT_CHECKS.map((check) => [check, ["model-not-adopted"]]))
@@ -36083,7 +36594,7 @@ function readArchitectureDebtEvidence2(root, input) {
36083
36594
  const changedPaths = [...new Set(input.changedPaths ?? [])].sort();
36084
36595
  if (changedPaths.some((path) => !isRepoRelativePosixPath(path)))
36085
36596
  throw new ArchitectureDebtReadError2("AC_SCHEMA_INVALID", "changedPaths must contain repository-relative POSIX paths", "changed-path-invalid");
36086
- if (!existsSync11(join7(root, ".archcontext/manifest.yaml")))
36597
+ if (!existsSync11(join9(root, ".archcontext/manifest.yaml")))
36087
36598
  throw new ArchitectureDebtReadError2("AC_MODEL_ADOPTION_REQUIRED", "Architecture debt requires an adopted architecture model", "model-missing");
36088
36599
  const model = loadNativeModelFromArchContext(root);
36089
36600
  const files = listGitVisibleFiles(root);
@@ -37716,8 +38227,8 @@ function validateRuntimeAgentProposalPlan(input) {
37716
38227
  }
37717
38228
 
37718
38229
  // packages/local-runtime/runtime-daemon/src/external-documentation.ts
37719
- import { existsSync as existsSync14, readdirSync as readdirSync9, readFileSync as readFileSync15, statSync as statSync4 } from "node:fs";
37720
- import { resolve as resolve19 } from "node:path";
38230
+ import { existsSync as existsSync14, readdirSync as readdirSync10, readFileSync as readFileSync16, statSync as statSync4 } from "node:fs";
38231
+ import { resolve as resolve20 } from "node:path";
37721
38232
 
37722
38233
  // packages/core/context-compiler/src/index.ts
37723
38234
  init_src();
@@ -37725,11 +38236,11 @@ init_src();
37725
38236
  // packages/core/practice-catalog/src/index.ts
37726
38237
  init_src();
37727
38238
  init_src();
37728
- import { existsSync as existsSync12, lstatSync as lstatSync7, readdirSync as readdirSync7, readFileSync as readFileSync13, realpathSync as realpathSync5 } from "node:fs";
37729
- import { dirname as dirname6, relative as relative5, resolve as resolve17, sep as sep3 } from "node:path";
38239
+ import { existsSync as existsSync12, lstatSync as lstatSync7, readdirSync as readdirSync8, readFileSync as readFileSync14, realpathSync as realpathSync6 } from "node:fs";
38240
+ import { dirname as dirname6, relative as relative5, resolve as resolve18, sep as sep3 } from "node:path";
37730
38241
  import { fileURLToPath } from "node:url";
37731
38242
  var PRACTICE_CATALOG_VERSION = "2026.06.0";
37732
- var BUILTIN_PRACTICE_ASSETS_DIR = resolve17(dirname6(fileURLToPath(import.meta.url)), "../assets");
38243
+ var BUILTIN_PRACTICE_ASSETS_DIR = resolve18(dirname6(fileURLToPath(import.meta.url)), "../assets");
37733
38244
  var ALLOWED_CHECK_IDS = new Set([
37734
38245
  "compatibility-contract-required",
37735
38246
  "no-new-cycle",
@@ -37781,13 +38292,13 @@ var PRACTICE_ROOT_KEYS = new Set([
37781
38292
  "overlay"
37782
38293
  ]);
37783
38294
  function loadPracticeCatalog(options = {}) {
37784
- const root = options.root ? resolve17(options.root) : process.cwd();
38295
+ const root = options.root ? resolve18(options.root) : process.cwd();
37785
38296
  const builtInAssetsDir = options.builtInAssetsDir ?? BUILTIN_PRACTICE_ASSETS_DIR;
37786
38297
  const errors = [];
37787
38298
  const warnings = [];
37788
- const builtIn = loadAssetFiles(resolve17(builtInAssetsDir, "practices"), "curated-static", errors);
37789
- const profiles = loadProfileFiles(resolve17(builtInAssetsDir, "profiles"), errors);
37790
- const sources = loadSourceFiles(resolve17(builtInAssetsDir, "sources"), errors);
38299
+ const builtIn = loadAssetFiles(resolve18(builtInAssetsDir, "practices"), "curated-static", errors);
38300
+ const profiles = loadProfileFiles(resolve18(builtInAssetsDir, "profiles"), errors);
38301
+ const sources = loadSourceFiles(resolve18(builtInAssetsDir, "sources"), errors);
37791
38302
  const overlays = options.includeRepoOverlay === false ? [] : loadRepoOverlayAssets(root, errors);
37792
38303
  const merged = mergeCatalogAssets(builtIn, overlays, errors, options.now ?? new Date().toISOString());
37793
38304
  const sourceIds = new Set(sources.map((source) => source.id));
@@ -37973,7 +38484,7 @@ function loadProfileFiles(dir, errors) {
37973
38484
  return profiles.sort((a, b) => a.id.localeCompare(b.id));
37974
38485
  }
37975
38486
  function loadRepoOverlayAssets(root, errors) {
37976
- const overlayRoot = resolve17(root, ".archcontext/practices");
38487
+ const overlayRoot = resolve18(root, ".archcontext/practices");
37977
38488
  if (!existsSync12(overlayRoot))
37978
38489
  return [];
37979
38490
  const out = [];
@@ -38336,8 +38847,8 @@ function listDataFiles(dir, allowedRoot, errors) {
38336
38847
  return;
38337
38848
  }
38338
38849
  if (stat.isDirectory()) {
38339
- for (const entry of readdirSync7(current, { withFileTypes: true }))
38340
- walk(resolve17(current, entry.name));
38850
+ for (const entry of readdirSync8(current, { withFileTypes: true }))
38851
+ walk(resolve18(current, entry.name));
38341
38852
  return;
38342
38853
  }
38343
38854
  if (!/\.(ya?ml|json)$/.test(current))
@@ -38352,7 +38863,7 @@ function listDataFiles(dir, allowedRoot, errors) {
38352
38863
  }
38353
38864
  function parseDataFile(path, errors) {
38354
38865
  try {
38355
- const body = readFileSync13(path, "utf8").replace(/^\uFEFF/, "").trim();
38866
+ const body = readFileSync14(path, "utf8").replace(/^\uFEFF/, "").trim();
38356
38867
  const withoutDocumentMarker = body.startsWith("---") ? body.replace(/^---\s*/, "").trim() : body;
38357
38868
  return JSON.parse(withoutDocumentMarker);
38358
38869
  } catch (error) {
@@ -38379,14 +38890,14 @@ function assertRealChild(root, path) {
38379
38890
  }
38380
38891
  function safeRealpath(path) {
38381
38892
  try {
38382
- return realpathSync5.native(path);
38893
+ return realpathSync6.native(path);
38383
38894
  } catch {
38384
- return resolve17(path);
38895
+ return resolve18(path);
38385
38896
  }
38386
38897
  }
38387
38898
  function isRealChild(rootReal, pathReal) {
38388
38899
  const rel = relative5(rootReal, pathReal);
38389
- return rel === "" || !rel.startsWith("..") && !rel.includes(`..${sep3}`) && !resolve17(rel).startsWith("..");
38900
+ return rel === "" || !rel.startsWith("..") && !rel.includes(`..${sep3}`) && !resolve18(rel).startsWith("..");
38390
38901
  }
38391
38902
  function displayPath(path) {
38392
38903
  return path.split(sep3).join("/");
@@ -38950,8 +39461,8 @@ function checkResult(input, result) {
38950
39461
  }
38951
39462
  // packages/core/practice-engine/src/enforcement.ts
38952
39463
  init_src();
38953
- import { existsSync as existsSync13, lstatSync as lstatSync8, readdirSync as readdirSync8, readFileSync as readFileSync14 } from "node:fs";
38954
- import { basename as basename4, join as join8, relative as relative6, resolve as resolve18, sep as sep4 } from "node:path";
39464
+ import { existsSync as existsSync13, lstatSync as lstatSync8, readdirSync as readdirSync9, readFileSync as readFileSync15 } from "node:fs";
39465
+ import { basename as basename4, join as join10, relative as relative6, resolve as resolve19, sep as sep4 } from "node:path";
38955
39466
  var ENFORCEMENT_RANK = { advisory: 0, checkpoint: 1, complete: 2 };
38956
39467
  var POLICY_MODES = new Set(["advisory", "active", "fail-open", "fail-closed"]);
38957
39468
  var DEFAULT_POLICY = {
@@ -38974,7 +39485,7 @@ function shouldEvaluatePracticeEnforcement(policy) {
38974
39485
  return practiceEnforcementPolicyMode(policy) !== "advisory";
38975
39486
  }
38976
39487
  function loadPracticeEnforcementPolicy(root) {
38977
- const path = resolve18(root, ".archcontext/policies/practices.yaml");
39488
+ const path = resolve19(root, ".archcontext/policies/practices.yaml");
38978
39489
  if (!existsSync13(path))
38979
39490
  return defaultPracticeEnforcementPolicy();
38980
39491
  assertRepoPolicyFile(root, path, ".archcontext/policies/practices.yaml");
@@ -38982,7 +39493,7 @@ function loadPracticeEnforcementPolicy(root) {
38982
39493
  return validatePracticeEnforcementPolicy(parsed, ".archcontext/policies/practices.yaml");
38983
39494
  }
38984
39495
  function loadPracticeWaivers(root) {
38985
- const dir = resolve18(root, ".archcontext/waivers");
39496
+ const dir = resolve19(root, ".archcontext/waivers");
38986
39497
  if (!existsSync13(dir))
38987
39498
  return [];
38988
39499
  const stat = lstatSync8(dir);
@@ -38992,10 +39503,10 @@ function loadPracticeWaivers(root) {
38992
39503
  throw new Error("practice-waiver-path-not-directory");
38993
39504
  const waivers = [];
38994
39505
  const ownerRegistry = loadPracticeWaiverOwnerRegistry(root);
38995
- for (const entry of readdirSync8(dir, { withFileTypes: true })) {
39506
+ for (const entry of readdirSync9(dir, { withFileTypes: true })) {
38996
39507
  if (!entry.isFile() || !/\.(?:ya?ml|json)$/.test(entry.name))
38997
39508
  continue;
38998
- const path = join8(dir, entry.name);
39509
+ const path = join10(dir, entry.name);
38999
39510
  const relativePath = `.archcontext/waivers/${entry.name}`;
39000
39511
  assertRepoPolicyFile(root, path, relativePath);
39001
39512
  waivers.push(validatePracticeWaiver(parseJsonYamlFile(path), relativePath, { allowedOwners: ownerRegistry.owners }));
@@ -39003,17 +39514,17 @@ function loadPracticeWaivers(root) {
39003
39514
  return waivers.sort((left, right) => waiverDigest(left).localeCompare(waiverDigest(right)));
39004
39515
  }
39005
39516
  function loadPracticeWaiverOwnerRegistry(root) {
39006
- const modelDir = resolve18(root, ".archcontext/model/nodes");
39517
+ const modelDir = resolve19(root, ".archcontext/model/nodes");
39007
39518
  const sources = [];
39008
39519
  const subjects = [];
39009
39520
  if (existsSync13(modelDir)) {
39010
39521
  if (lstatSync8(modelDir).isSymbolicLink())
39011
39522
  throw new Error("practice-owner-registry-symlink-denied");
39012
39523
  for (const path of collectFiles(root, ".archcontext/model/nodes")) {
39013
- const absolute = resolve18(root, path);
39524
+ const absolute = resolve19(root, path);
39014
39525
  if (lstatSync8(absolute).isSymbolicLink())
39015
39526
  throw new Error(`practice-owner-registry-symlink-denied: ${path}`);
39016
- const body = readFileSync14(absolute, "utf8");
39527
+ const body = readFileSync15(absolute, "utf8");
39017
39528
  const lifecycleOwners = extractOwnershipOwners(body, "lifecycle");
39018
39529
  const dataOwners = extractOwnershipOwners(body, "data");
39019
39530
  for (const kind of ["lifecycle", "data"]) {
@@ -39288,14 +39799,14 @@ function isVagueReason(reason) {
39288
39799
  return /^(temporary|cleanup later|todo|tbd|later|just in case)$/i.test(trimmed);
39289
39800
  }
39290
39801
  function parseJsonYamlFile(path) {
39291
- const body = readFileSync14(path, "utf8").replace(/^\uFEFF/, "").trim();
39802
+ const body = readFileSync15(path, "utf8").replace(/^\uFEFF/, "").trim();
39292
39803
  const withoutDocumentMarker = body.startsWith("---") ? body.replace(/^---\s*/, "").trim() : body;
39293
39804
  return JSON.parse(withoutDocumentMarker);
39294
39805
  }
39295
39806
  function collectFiles(root, relativeDir) {
39296
- const dir = resolve18(root, relativeDir);
39807
+ const dir = resolve19(root, relativeDir);
39297
39808
  const out = [];
39298
- for (const entry of readdirSync8(dir, { withFileTypes: true })) {
39809
+ for (const entry of readdirSync9(dir, { withFileTypes: true })) {
39299
39810
  const child = `${relativeDir}/${entry.name}`;
39300
39811
  if (entry.isDirectory())
39301
39812
  out.push(...collectFiles(root, child));
@@ -39381,8 +39892,8 @@ function assertRepoPolicyFile(root, path, relativePath) {
39381
39892
  assertRepoRelativePath(relativePath);
39382
39893
  if (lstatSync8(path).isSymbolicLink())
39383
39894
  throw new Error(`practice-policy-symlink-denied: ${relativePath}`);
39384
- const rootResolved = resolve18(root);
39385
- const pathResolved = resolve18(path);
39895
+ const rootResolved = resolve19(root);
39896
+ const pathResolved = resolve19(path);
39386
39897
  const rel = relative6(rootResolved, pathResolved);
39387
39898
  if (rel === "" || rel.startsWith("..") || rel.includes(`..${sep4}`))
39388
39899
  throw new Error(`practice-policy-path-escape: ${relativePath}`);
@@ -40742,7 +41253,7 @@ function readExactPackageVersion(root, packageName) {
40742
41253
  return;
40743
41254
  }
40744
41255
  function readPackageLockExactVersion(root, packageName) {
40745
- const lock = readJsonFile(resolve19(root, "package-lock.json"));
41256
+ const lock = readJsonFile(resolve20(root, "package-lock.json"));
40746
41257
  if (!lock || typeof lock !== "object" || Array.isArray(lock))
40747
41258
  return;
40748
41259
  const packages = lock.packages;
@@ -40760,7 +41271,7 @@ function readPackageLockExactVersion(root, packageName) {
40760
41271
  return;
40761
41272
  }
40762
41273
  function packageManifestPaths(root) {
40763
- const paths = [resolve19(root, "package.json")];
41274
+ const paths = [resolve20(root, "package.json")];
40764
41275
  const rootManifest = readJsonFile(paths[0]);
40765
41276
  for (const pattern of workspacePatternsFromManifest(rootManifest)) {
40766
41277
  for (const path of expandWorkspacePackageJson(root, pattern))
@@ -40783,15 +41294,15 @@ function expandWorkspacePackageJson(root, pattern) {
40783
41294
  if (pattern.includes("**") || pattern.startsWith("/") || pattern.includes("\\"))
40784
41295
  return [];
40785
41296
  if (!pattern.includes("*")) {
40786
- const path = resolve19(root, pattern, "package.json");
41297
+ const path = resolve20(root, pattern, "package.json");
40787
41298
  return existsSync14(path) ? [path] : [];
40788
41299
  }
40789
41300
  if (!pattern.endsWith("/*"))
40790
41301
  return [];
40791
- const base = resolve19(root, pattern.slice(0, -2));
41302
+ const base = resolve20(root, pattern.slice(0, -2));
40792
41303
  if (!existsSync14(base) || !statSync4(base).isDirectory())
40793
41304
  return [];
40794
- return readdirSync9(base, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => resolve19(base, entry.name, "package.json")).filter((path) => existsSync14(path));
41305
+ return readdirSync10(base, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => resolve20(base, entry.name, "package.json")).filter((path) => existsSync14(path));
40795
41306
  }
40796
41307
  function exactVersionFromManifest(manifest, packageName) {
40797
41308
  if (!manifest || typeof manifest !== "object" || Array.isArray(manifest))
@@ -40810,7 +41321,7 @@ function readJsonFile(path) {
40810
41321
  if (!existsSync14(path))
40811
41322
  return;
40812
41323
  try {
40813
- return JSON.parse(readFileSync15(path, "utf8"));
41324
+ return JSON.parse(readFileSync16(path, "utf8"));
40814
41325
  } catch {
40815
41326
  return;
40816
41327
  }
@@ -40833,7 +41344,7 @@ function readContext7LockfileState(root) {
40833
41344
  expectedHash: "missing"
40834
41345
  };
40835
41346
  }
40836
- const body = readFileSync15(path, "utf8");
41347
+ const body = readFileSync16(path, "utf8");
40837
41348
  const parsed = JSON.parse(body);
40838
41349
  if (parsed.schemaVersion !== CONTEXT7_LOCKFILE_SCHEMA_VERSION || parsed.provider !== "context7" || !Array.isArray(parsed.libraries)) {
40839
41350
  throw new Error("Invalid Context7 lockfile");
@@ -40869,7 +41380,7 @@ function writeContext7Lockfile(root, lock, expectedHash) {
40869
41380
 
40870
41381
  // packages/core/application/src/index.ts
40871
41382
  import { existsSync as existsSync15, statSync as statSync5 } from "node:fs";
40872
- import { extname, resolve as resolve20 } from "node:path";
41383
+ import { extname, resolve as resolve21 } from "node:path";
40873
41384
  init_src();
40874
41385
  async function prepareTask(input) {
40875
41386
  const confidence = computeRefactorConfidence({
@@ -41062,7 +41573,7 @@ function classifyCheckpointPath(root, path) {
41062
41573
  return "ignored";
41063
41574
  if (isGeneratedCheckpointPath(path))
41064
41575
  return "generated";
41065
- const absolute = resolve20(root, path);
41576
+ const absolute = resolve21(root, path);
41066
41577
  if (!existsSync15(absolute))
41067
41578
  return "deleted";
41068
41579
  try {
@@ -41360,14 +41871,14 @@ function parsePracticeCheckpointBaselineState(state, repositoryId, taskSessionId
41360
41871
  init_src();
41361
41872
  init_src();
41362
41873
  import { randomBytes as randomBytes2 } from "node:crypto";
41363
- import { chmodSync as chmodSync3, existsSync as existsSync18, lstatSync as lstatSync9, mkdirSync as mkdirSync6, mkdtempSync as mkdtempSync3, readdirSync as readdirSync11, readFileSync as readFileSync17, rmSync as rmSync8, writeFileSync as writeFileSync5 } from "node:fs";
41874
+ import { chmodSync as chmodSync3, existsSync as existsSync18, lstatSync as lstatSync9, mkdirSync as mkdirSync7, mkdtempSync as mkdtempSync3, readdirSync as readdirSync11, readFileSync as readFileSync18, rmSync as rmSync8, writeFileSync as writeFileSync6 } from "node:fs";
41364
41875
  import { tmpdir as tmpdir3 } from "node:os";
41365
- import { basename as basename5, dirname as dirname7, join as join12, resolve as resolve22, sep as sep5 } from "node:path";
41876
+ import { basename as basename5, dirname as dirname7, join as join13, resolve as resolve22, sep as sep5 } from "node:path";
41366
41877
 
41367
41878
  // packages/local-runtime/control-file-security/src/index.ts
41368
- import { execFileSync as execFileSync5 } from "node:child_process";
41369
- import { closeSync as closeSync6, constants as constants2, existsSync as existsSync16, fstatSync as fstatSync3, openSync as openSync6, readFileSync as readFileSync16, rmSync as rmSync6, writeFileSync as writeFileSync4 } from "node:fs";
41370
- import { join as join10 } from "node:path";
41879
+ import { execFileSync as execFileSync6 } from "node:child_process";
41880
+ import { closeSync as closeSync6, constants as constants2, existsSync as existsSync16, fstatSync as fstatSync3, openSync as openSync6, readFileSync as readFileSync17, rmSync as rmSync6, writeFileSync as writeFileSync5 } from "node:fs";
41881
+ import { join as join12 } from "node:path";
41371
41882
  import { setTimeout as sleep } from "node:timers/promises";
41372
41883
  var WINDOWS_CREATE_TIMEOUT_MS = 60000;
41373
41884
  var WINDOWS_READ_TIMEOUT_MS = 1e4;
@@ -41451,7 +41962,7 @@ function windowsControlFile(operation, path, body) {
41451
41962
  let output;
41452
41963
  const startedAt = performance.now();
41453
41964
  try {
41454
- output = execFileSync5(join10(systemRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe"), [
41965
+ output = execFileSync6(join12(systemRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe"), [
41455
41966
  "-NoLogo",
41456
41967
  "-NoProfile",
41457
41968
  "-NonInteractive",
@@ -41506,7 +42017,7 @@ function createPrivateControlFile(path, body) {
41506
42017
  }
41507
42018
  const fd = openSync6(path, "wx", 384);
41508
42019
  try {
41509
- writeFileSync4(fd, body, "utf8");
42020
+ writeFileSync5(fd, body, "utf8");
41510
42021
  } catch (error) {
41511
42022
  rmSync6(path, { force: true });
41512
42023
  throw error;
@@ -41526,7 +42037,7 @@ function readPrivateControlFile(path) {
41526
42037
  const stat = fstatSync3(fd);
41527
42038
  if (!stat.isFile() || (stat.mode & 63) !== 0)
41528
42039
  return;
41529
- return readFileSync16(fd, "utf8");
42040
+ return readFileSync17(fd, "utf8");
41530
42041
  } finally {
41531
42042
  closeSync6(fd);
41532
42043
  }
@@ -41603,7 +42114,7 @@ function rpcRequiredBoolean(params, index, context, label) {
41603
42114
  function rpcOptionalString(params, index, context, label) {
41604
42115
  const value = params[index];
41605
42116
  if (value === undefined || value === null)
41606
- return value;
42117
+ return;
41607
42118
  if (typeof value !== "string")
41608
42119
  throw rpcInputInvalid(context, `${label} must be a string`);
41609
42120
  return value;
@@ -41611,7 +42122,7 @@ function rpcOptionalString(params, index, context, label) {
41611
42122
  function rpcOptionalNumber(params, index, context, label) {
41612
42123
  const value = params[index];
41613
42124
  if (value === undefined || value === null)
41614
- return value;
42125
+ return;
41615
42126
  if (typeof value !== "number" || !Number.isFinite(value))
41616
42127
  throw rpcInputInvalid(context, `${label} must be a number`);
41617
42128
  return value;
@@ -41619,7 +42130,7 @@ function rpcOptionalNumber(params, index, context, label) {
41619
42130
  function rpcOptionalStringArray(params, index, context, label) {
41620
42131
  const value = params[index];
41621
42132
  if (value === undefined || value === null)
41622
- return value;
42133
+ return;
41623
42134
  if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string"))
41624
42135
  throw rpcInputInvalid(context, `${label} must be an array of strings`);
41625
42136
  return value;
@@ -41636,7 +42147,7 @@ function rpcRequiredObject(params, index, context, label) {
41636
42147
  function rpcOptionalObject(params, index, context, label) {
41637
42148
  const value = params[index];
41638
42149
  if (value === undefined || value === null)
41639
- return value;
42150
+ return;
41640
42151
  if (!isPlainRpcObject(value))
41641
42152
  throw rpcInputInvalid(context, `${label} must be an object`);
41642
42153
  return value;
@@ -42063,111 +42574,6 @@ function daemonReadiness(root) {
42063
42574
 
42064
42575
  // packages/local-runtime/runtime-daemon/src/daemon-control.ts
42065
42576
  import { existsSync as existsSync17, openSync as openSync7, rmSync as rmSync7 } from "node:fs";
42066
-
42067
- // packages/local-runtime/runtime-state-paths/src/index.ts
42068
- import { execFileSync as execFileSync6 } from "node:child_process";
42069
- import { createHash as createHash9 } from "node:crypto";
42070
- import { readdirSync as readdirSync10, realpathSync as realpathSync6 } from "node:fs";
42071
- import { homedir } from "node:os";
42072
- import { isAbsolute as isAbsolute5, join as join11, resolve as resolve21 } from "node:path";
42073
- var ARCHCONTEXT_STATE_DIR_ENV = "ARCHCONTEXT_STATE_DIR";
42074
- var ARCHCONTEXT_LOCAL_STORE_PATH_ENV = "ARCHCONTEXT_LOCAL_STORE_PATH";
42075
- function defaultArchContextStateRoot(env = process.env, platform = process.platform, home = homedir()) {
42076
- const override = env[ARCHCONTEXT_STATE_DIR_ENV];
42077
- if (override)
42078
- return { path: resolve21(override), source: "environment" };
42079
- if (platform === "darwin")
42080
- return { path: join11(home, "Library", "Application Support", "ArchContext"), source: "os-user-data" };
42081
- if (platform === "win32")
42082
- return { path: join11(env.LOCALAPPDATA ?? join11(home, "AppData", "Local"), "ArchContext"), source: "os-user-data" };
42083
- return { path: join11(env.XDG_DATA_HOME ?? join11(home, ".local", "share"), "archcontext"), source: "os-user-data" };
42084
- }
42085
- function runtimeStatePaths(root = process.cwd(), env = process.env) {
42086
- const repositoryRoot = readGitPath(root, ["rev-parse", "--show-toplevel"]) ?? root;
42087
- const canonicalRepositoryRoot = canonicalPath(repositoryRoot);
42088
- const gitCommonDir = readGitPath(canonicalRepositoryRoot, ["rev-parse", "--git-common-dir"]);
42089
- const repositoryAnchor = canonicalPath(gitCommonDir ? resolveMaybeRelative(canonicalRepositoryRoot, gitCommonDir) : canonicalRepositoryRoot);
42090
- const workspaceAnchor = canonicalRepositoryRoot;
42091
- const storageRepositoryId = stableStorageId("repo", repositoryAnchor);
42092
- const storageWorkspaceId = stableStorageId("ws", workspaceAnchor);
42093
- const stateRoot = defaultArchContextStateRoot(env);
42094
- const repositoryStateDir = join11(stateRoot.path, REPOSITORIES_DIR, storageRepositoryId);
42095
- const workspaceStateDir = join11(repositoryStateDir, WORKTREES_DIR, storageWorkspaceId);
42096
- const legacyControlDir = resolve21(canonicalRepositoryRoot, ".archcontext", ".local");
42097
- return {
42098
- schemaVersion: "archcontext.runtime-state-paths/v1",
42099
- stateRoot: stateRoot.path,
42100
- source: stateRoot.source,
42101
- repositoryRoot: canonicalRepositoryRoot,
42102
- repositoryAnchor,
42103
- workspaceAnchor,
42104
- storageRepositoryId,
42105
- storageWorkspaceId,
42106
- repositoryId: storageRepositoryId,
42107
- workspaceId: storageWorkspaceId,
42108
- repositoryStateDir,
42109
- workspaceStateDir,
42110
- sharedCacheDir: join11(repositoryStateDir, "shared", "cache"),
42111
- localStorePath: env[ARCHCONTEXT_LOCAL_STORE_PATH_ENV] ?? join11(workspaceStateDir, "runtime.sqlite"),
42112
- ...daemonControlPaths(workspaceStateDir),
42113
- developerReviewRunStateDir: join11(workspaceStateDir, "developer-review-runs"),
42114
- legacyControlDir,
42115
- legacyLocalStorePath: join11(legacyControlDir, "runtime.sqlite")
42116
- };
42117
- }
42118
- var REPOSITORIES_DIR = "repositories";
42119
- var WORKTREES_DIR = "worktrees";
42120
- function daemonControlPaths(workspaceStateDir) {
42121
- return {
42122
- daemonConnectionPath: join11(workspaceStateDir, "archctxd.json"),
42123
- daemonLockPath: join11(workspaceStateDir, "archctxd.lock"),
42124
- daemonLogPath: join11(workspaceStateDir, "archctxd.log")
42125
- };
42126
- }
42127
- function listWorkspaceStateDirs(stateRoot) {
42128
- return listDirectoryNames(join11(stateRoot, REPOSITORIES_DIR)).flatMap((storageRepositoryId) => listDirectoryNames(join11(stateRoot, REPOSITORIES_DIR, storageRepositoryId, WORKTREES_DIR)).map((storageWorkspaceId) => ({
42129
- storageRepositoryId,
42130
- storageWorkspaceId,
42131
- workspaceStateDir: join11(stateRoot, REPOSITORIES_DIR, storageRepositoryId, WORKTREES_DIR, storageWorkspaceId)
42132
- })));
42133
- }
42134
- function listDirectoryNames(path) {
42135
- try {
42136
- return readdirSync10(path, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort();
42137
- } catch (error) {
42138
- if (error.code === "ENOENT")
42139
- return [];
42140
- throw error;
42141
- }
42142
- }
42143
- function readGitPath(root, args) {
42144
- try {
42145
- const value = execFileSync6("git", args, {
42146
- cwd: root,
42147
- encoding: "utf8",
42148
- stdio: ["ignore", "pipe", "ignore"]
42149
- }).trim();
42150
- return value.length > 0 ? value : undefined;
42151
- } catch {
42152
- return;
42153
- }
42154
- }
42155
- function resolveMaybeRelative(base, path) {
42156
- return isAbsolute5(path) ? resolve21(path) : resolve21(base, path);
42157
- }
42158
- function canonicalPath(path) {
42159
- const resolved = resolve21(path);
42160
- try {
42161
- return realpathSync6.native(resolved);
42162
- } catch {
42163
- return resolved;
42164
- }
42165
- }
42166
- function stableStorageId(prefix, value) {
42167
- return `${prefix}.${createHash9("sha256").update(value).digest("hex").slice(0, 16)}`;
42168
- }
42169
-
42170
- // packages/local-runtime/runtime-daemon/src/daemon-control.ts
42171
42577
  function defaultDeveloperReviewRunStateDir(root = process.cwd()) {
42172
42578
  return runtimeStatePaths(root).developerReviewRunStateDir;
42173
42579
  }
@@ -42380,9 +42786,9 @@ class DeveloperReviewRunService {
42380
42786
  challengeId: input.challenge.challengeId,
42381
42787
  tempRoot: input.tempRoot
42382
42788
  });
42383
- mkdirSync6(paths.stateDir, { recursive: true });
42384
- mkdirSync6(paths.runRoot, { recursive: true });
42385
- mkdirSync6(paths.worktreeTempRoot, { recursive: true });
42789
+ mkdirSync7(paths.stateDir, { recursive: true });
42790
+ mkdirSync7(paths.runRoot, { recursive: true });
42791
+ mkdirSync7(paths.worktreeTempRoot, { recursive: true });
42386
42792
  const createdAt = this.clock();
42387
42793
  writeDeveloperReviewRunOwnerMarker({
42388
42794
  runRoot: paths.runRoot,
@@ -42506,7 +42912,7 @@ class DeveloperReviewRunService {
42506
42912
  this.assertRunning();
42507
42913
  const sourceRoot = findRepositoryRoot(input.repositoryRoot);
42508
42914
  const safeChallengeId = safeControlFileSegment(input.challengeId);
42509
- const manifestPath = join12(defaultDeveloperReviewRunStateDir(sourceRoot), `${safeChallengeId}.json`);
42915
+ const manifestPath = join13(defaultDeveloperReviewRunStateDir(sourceRoot), `${safeChallengeId}.json`);
42510
42916
  const manifest = readDeveloperReviewRunManifest(manifestPath);
42511
42917
  if (!manifest)
42512
42918
  throw developerReviewRunNotOwned("persisted-manifest-missing");
@@ -42533,7 +42939,7 @@ class DeveloperReviewRunService {
42533
42939
  for (const entry of readdirSync11(stateDir).sort()) {
42534
42940
  if (!entry.endsWith(".json"))
42535
42941
  continue;
42536
- const manifestPath = join12(stateDir, entry);
42942
+ const manifestPath = join13(stateDir, entry);
42537
42943
  const stats = lstatIfExists2(manifestPath);
42538
42944
  if (!stats || !stats.isFile()) {
42539
42945
  recovery.rejected.push(`${entry}: not-a-regular-file`);
@@ -42561,7 +42967,7 @@ class DeveloperReviewRunService {
42561
42967
  for (const entry of readdirSync11(stateDir).sort()) {
42562
42968
  if (!entry.endsWith(".lock"))
42563
42969
  continue;
42564
- const lockPath = join12(stateDir, entry);
42970
+ const lockPath = join13(stateDir, entry);
42565
42971
  const stats = lstatIfExists2(lockPath);
42566
42972
  if (!stats || !stats.isFile()) {
42567
42973
  recovery.rejected.push(`${entry}: not-a-regular-file`);
@@ -42590,15 +42996,15 @@ function createDeveloperReviewRunPaths(input) {
42590
42996
  const runId = `${safeChallengeId}-${randomBytes2(6).toString("hex")}`;
42591
42997
  const stateDir = defaultDeveloperReviewRunStateDir(input.sourceRoot);
42592
42998
  const tempParent = input.tempRoot ? resolve22(input.tempRoot) : tmpdir3();
42593
- mkdirSync6(tempParent, { recursive: true });
42594
- const runRoot = mkdtempSync3(join12(tempParent, `${DEVELOPER_REVIEW_RUN_ROOT_PREFIX}${safeChallengeId.slice(0, 32)}-`));
42999
+ mkdirSync7(tempParent, { recursive: true });
43000
+ const runRoot = mkdtempSync3(join13(tempParent, `${DEVELOPER_REVIEW_RUN_ROOT_PREFIX}${safeChallengeId.slice(0, 32)}-`));
42595
43001
  return {
42596
43002
  runId,
42597
43003
  stateDir,
42598
43004
  runRoot,
42599
- worktreeTempRoot: join12(runRoot, "worktrees"),
42600
- manifestPath: join12(stateDir, `${safeChallengeId}.json`),
42601
- lockPath: join12(stateDir, `${safeChallengeId}.lock`)
43005
+ worktreeTempRoot: join13(runRoot, "worktrees"),
43006
+ manifestPath: join13(stateDir, `${safeChallengeId}.json`),
43007
+ lockPath: join13(stateDir, `${safeChallengeId}.lock`)
42602
43008
  };
42603
43009
  }
42604
43010
  function writeDeveloperReviewRunOwnerMarker(input) {
@@ -42612,7 +43018,7 @@ function writeDeveloperReviewRunOwnerMarker(input) {
42612
43018
  pid: process.pid,
42613
43019
  createdAt: input.createdAt
42614
43020
  };
42615
- writePrivateJson(join12(input.runRoot, DEVELOPER_REVIEW_RUN_OWNER_MARKER_FILE), marker, "wx");
43021
+ writePrivateJson(join13(input.runRoot, DEVELOPER_REVIEW_RUN_OWNER_MARKER_FILE), marker, "wx");
42616
43022
  }
42617
43023
  function readDeveloperReviewRunOwnerMarker(path) {
42618
43024
  const stats = lstatIfExists2(path);
@@ -42636,8 +43042,8 @@ function resolveOwnedDeveloperReviewRunTargets(run) {
42636
43042
  if (!runIdSuffix || !DEVELOPER_REVIEW_RUN_ID_SUFFIX.test(runIdSuffix))
42637
43043
  throw developerReviewRunNotOwned("run-id");
42638
43044
  const stateDir = defaultDeveloperReviewRunStateDir(run.sourceRoot);
42639
- const manifestPath = join12(stateDir, `${safeChallengeId}.json`);
42640
- const lockPath = join12(stateDir, `${safeChallengeId}.lock`);
43045
+ const manifestPath = join13(stateDir, `${safeChallengeId}.json`);
43046
+ const lockPath = join13(stateDir, `${safeChallengeId}.lock`);
42641
43047
  if (resolve22(run.manifestPath) !== manifestPath)
42642
43048
  throw developerReviewRunNotOwned("manifest-path");
42643
43049
  if (resolve22(run.lockPath) !== lockPath)
@@ -42659,7 +43065,7 @@ function resolveOwnedDeveloperReviewRunTargets(run) {
42659
43065
  if (!runRootName.startsWith(runRootPrefix) || !DEVELOPER_REVIEW_RUN_ROOT_SUFFIX.test(runRootName.slice(runRootPrefix.length))) {
42660
43066
  throw developerReviewRunNotOwned("run-root-name");
42661
43067
  }
42662
- const worktreeTempRoot = join12(runRoot, "worktrees");
43068
+ const worktreeTempRoot = join13(runRoot, "worktrees");
42663
43069
  if (resolve22(run.worktreeTempRoot) !== worktreeTempRoot)
42664
43070
  throw developerReviewRunNotOwned("worktree-temp-root");
42665
43071
  if (resolve22(run.codeGraphTemporaryState.root) !== runRoot)
@@ -42669,7 +43075,7 @@ function resolveOwnedDeveloperReviewRunTargets(run) {
42669
43075
  return { stateDir, manifestPath, lockPath };
42670
43076
  if (!runRootStats.isDirectory())
42671
43077
  throw developerReviewRunNotOwned("run-root-not-a-directory");
42672
- const marker = readDeveloperReviewRunOwnerMarker(join12(runRoot, DEVELOPER_REVIEW_RUN_OWNER_MARKER_FILE));
43078
+ const marker = readDeveloperReviewRunOwnerMarker(join13(runRoot, DEVELOPER_REVIEW_RUN_OWNER_MARKER_FILE));
42673
43079
  if (!marker)
42674
43080
  throw developerReviewRunNotOwned("run-root-owner-marker-missing");
42675
43081
  if (marker.runId !== run.runId || marker.challengeId !== run.challengeId)
@@ -42706,8 +43112,8 @@ function writeDeveloperReviewRunManifest(manifest) {
42706
43112
  writePrivateJson(manifest.manifestPath, manifest);
42707
43113
  }
42708
43114
  function writePrivateJson(path, value, flag = "w") {
42709
- mkdirSync6(dirname7(path), { recursive: true });
42710
- writeFileSync5(path, JSON.stringify(value, null, 2), { mode: 384, flag });
43115
+ mkdirSync7(dirname7(path), { recursive: true });
43116
+ writeFileSync6(path, JSON.stringify(value, null, 2), { mode: 384, flag });
42711
43117
  chmodSync3(path, 384);
42712
43118
  }
42713
43119
  function readDeveloperReviewRunManifest(path) {
@@ -42719,7 +43125,7 @@ function readDeveloperReviewRunManifest(path) {
42719
43125
  }
42720
43126
  function readJsonObject(path) {
42721
43127
  try {
42722
- const parsed = JSON.parse(readFileSync17(path, "utf8"));
43128
+ const parsed = JSON.parse(readFileSync18(path, "utf8"));
42723
43129
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : undefined;
42724
43130
  } catch {
42725
43131
  return;
@@ -44316,8 +44722,8 @@ function uniqueStrings2(values) {
44316
44722
  // packages/local-runtime/runtime-daemon/src/ledger-admin.ts
44317
44723
  init_src();
44318
44724
  init_src();
44319
- import { existsSync as existsSync20, readFileSync as readFileSync19 } from "node:fs";
44320
- import { join as join14, resolve as resolve24 } from "node:path";
44725
+ import { existsSync as existsSync20, readFileSync as readFileSync20 } from "node:fs";
44726
+ import { join as join15, resolve as resolve24 } from "node:path";
44321
44727
 
44322
44728
  // packages/core/reconcile-engine/src/index.ts
44323
44729
  function reconcileArchitectureLedgerDrift(input) {
@@ -44394,11 +44800,11 @@ init_src();
44394
44800
 
44395
44801
  // packages/local-runtime/local-store-sqlite/src/index.ts
44396
44802
  init_src();
44397
- import { createHash as createHash10, randomUUID } from "node:crypto";
44398
- import { chmodSync as chmodSync4, closeSync as closeSync7, copyFileSync, existsSync as existsSync19, fsyncSync as fsyncSync3, lstatSync as lstatSync10, mkdirSync as mkdirSync7, openSync as openSync8, readFileSync as readFileSync18, readSync as readSync4, realpathSync as realpathSync7, renameSync as renameSync3, rmSync as rmSync9, statfsSync, statSync as statSync7, writeFileSync as writeFileSync6 } from "node:fs";
44803
+ import { createHash as createHash10, randomUUID as randomUUID2 } from "node:crypto";
44804
+ import { chmodSync as chmodSync4, closeSync as closeSync7, copyFileSync, existsSync as existsSync19, fsyncSync as fsyncSync3, lstatSync as lstatSync10, mkdirSync as mkdirSync8, openSync as openSync8, readFileSync as readFileSync19, readSync as readSync4, realpathSync as realpathSync7, renameSync as renameSync4, rmSync as rmSync9, statfsSync, statSync as statSync7, writeFileSync as writeFileSync7 } from "node:fs";
44399
44805
  import { readdir, readFile } from "node:fs/promises";
44400
44806
  import { createRequire as createRequire4 } from "node:module";
44401
- import { dirname as dirname8, isAbsolute as isAbsolute6, join as join13, relative as relative7, resolve as resolve23 } from "node:path";
44807
+ import { dirname as dirname8, isAbsolute as isAbsolute6, join as join14, relative as relative7, resolve as resolve23 } from "node:path";
44402
44808
  init_src();
44403
44809
  // schemas/runtime/explorer-projection-v2.schema.json
44404
44810
  var explorer_projection_v2_schema_default = {
@@ -45815,8 +46221,8 @@ function migrateLegacyLocalStoreIfNeeded(root = process.cwd(), env = process.env
45815
46221
  }
45816
46222
  assertTrustedLegacyLocalStoreSource(paths);
45817
46223
  const lock = acquireLegacyMigrationLock(paths);
45818
- const stagingDir = join13(paths.workspaceStateDir, `.runtime.sqlite.migration-${process.pid}-${randomUUID()}`);
45819
- const stagingPath = join13(stagingDir, "runtime.sqlite");
46224
+ const stagingDir = join14(paths.workspaceStateDir, `.runtime.sqlite.migration-${process.pid}-${randomUUID2()}`);
46225
+ const stagingPath = join14(stagingDir, "runtime.sqlite");
45820
46226
  try {
45821
46227
  if (targetExists)
45822
46228
  quarantinedFiles.push(...quarantineExistingLocalStore(paths));
@@ -45908,7 +46314,7 @@ class SqliteLocalStore {
45908
46314
  }
45909
46315
  async beginSnapshot(snapshot) {
45910
46316
  const db = await this.database();
45911
- const snapshotId = `snapshot_${randomUUID()}`;
46317
+ const snapshotId = `snapshot_${randomUUID2()}`;
45912
46318
  db.prepare(`INSERT INTO snapshots
45913
46319
  (id, repository_id, head_sha, worktree_digest, state, created_at)
45914
46320
  VALUES (?, ?, ?, ?, ?, ?)`).run(snapshotId, snapshot.repositoryId, snapshot.headSha, snapshot.worktreeDigest, "pending", nowIso());
@@ -46246,7 +46652,7 @@ class SqliteLocalStore {
46246
46652
  }
46247
46653
  async beginChangeSet(root, draft) {
46248
46654
  const db = await this.database();
46249
- const journalId = `changeset_${randomUUID()}`;
46655
+ const journalId = `changeset_${randomUUID2()}`;
46250
46656
  db.prepare(`INSERT INTO changeset_journal
46251
46657
  (journal_id, changeset_id, root, status, metadata_json, files_json, created_at, updated_at)
46252
46658
  VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(journalId, draft.id, root, "pending", stableJson(changeSetMetadata(draft)), "[]", nowIso(), nowIso());
@@ -49170,7 +49576,7 @@ function ftsMatchKind(query, doc) {
49170
49576
  function recordArchitectureLedgerOperation(db, input) {
49171
49577
  db.prepare(`INSERT INTO architecture_ledger_operations
49172
49578
  (operation_id, storage_repository_id, storage_workspace_id, operation_kind, duration_ms, row_count, rebuild_reason, created_at)
49173
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(`ledger_operation_${randomUUID()}`, input.scope.repository.storageRepositoryId, architectureLedgerWorkspaceKey(input.scope.worktree), input.operationKind, Math.max(0, Math.trunc(input.durationMs)), input.rowCount, input.rebuildReason, nowIso());
49579
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(`ledger_operation_${randomUUID2()}`, input.scope.repository.storageRepositoryId, architectureLedgerWorkspaceKey(input.scope.worktree), input.operationKind, Math.max(0, Math.trunc(input.durationMs)), input.rowCount, input.rebuildReason, nowIso());
49174
49580
  }
49175
49581
  function stableLedgerId(prefix, ...parts) {
49176
49582
  return `${prefix}.${createHash10("sha256").update(parts.join("\x00")).digest("hex").slice(0, 24)}`;
@@ -49738,7 +50144,7 @@ function publishStagedLocalStore(stagingPath, targetPath) {
49738
50144
  if (existsSync19(path))
49739
50145
  throw new Error(`Cannot publish migrated SQLite over existing target file: ${path}`);
49740
50146
  }
49741
- renameSync3(stagingPath, targetPath);
50147
+ renameSync4(stagingPath, targetPath);
49742
50148
  makePrivateFile(targetPath);
49743
50149
  fsyncDirectory2(dirname8(targetPath));
49744
50150
  }
@@ -49759,7 +50165,7 @@ function acquireLegacyMigrationLock(paths) {
49759
50165
  ensurePrivateDir(dirname8(lockPath));
49760
50166
  try {
49761
50167
  const fd = openSync8(lockPath, "wx", 384);
49762
- writeFileSync6(fd, JSON.stringify({
50168
+ writeFileSync7(fd, JSON.stringify({
49763
50169
  schemaVersion: "archcontext.legacy-local-store-migration-lock/v1",
49764
50170
  pid: process.pid,
49765
50171
  root: paths.repositoryRoot,
@@ -49785,7 +50191,7 @@ function releaseLegacyMigrationLock(lock) {
49785
50191
  }
49786
50192
  function isStaleMigrationLock(lockPath) {
49787
50193
  try {
49788
- const parsed = JSON.parse(readFileSync18(lockPath, "utf8"));
50194
+ const parsed = JSON.parse(readFileSync19(lockPath, "utf8"));
49789
50195
  if (typeof parsed.pid !== "number" || parsed.pid <= 0)
49790
50196
  return true;
49791
50197
  return !isProcessAlive(parsed.pid);
@@ -49836,7 +50242,7 @@ function acquireLocalStoreWriterOwnership(databasePath) {
49836
50242
  throw error;
49837
50243
  }
49838
50244
  makePrivateFile(lockPath);
49839
- const token = randomUUID();
50245
+ const token = randomUUID2();
49840
50246
  writeOwnerRecord(recordPath, { pid: process.pid, databasePath, acquiredAt: nowIso(), token });
49841
50247
  let released = false;
49842
50248
  return {
@@ -49870,17 +50276,17 @@ function sleepSync(ms) {
49870
50276
  Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
49871
50277
  }
49872
50278
  function writeOwnerRecord(recordPath, record) {
49873
- const tempPath = `${recordPath}.${process.pid}-${randomUUID()}.tmp`;
50279
+ const tempPath = `${recordPath}.${process.pid}-${randomUUID2()}.tmp`;
49874
50280
  try {
49875
- writeFileSync6(tempPath, JSON.stringify(record, null, 2), { encoding: "utf8", mode: 384, flag: "wx" });
49876
- renameSync3(tempPath, recordPath);
50281
+ writeFileSync7(tempPath, JSON.stringify(record, null, 2), { encoding: "utf8", mode: 384, flag: "wx" });
50282
+ renameSync4(tempPath, recordPath);
49877
50283
  } catch {
49878
50284
  rmSync9(tempPath, { force: true });
49879
50285
  }
49880
50286
  }
49881
50287
  function readOwnerRecord(recordPath) {
49882
50288
  try {
49883
- const parsed = JSON.parse(readFileSync18(recordPath, "utf8"));
50289
+ const parsed = JSON.parse(readFileSync19(recordPath, "utf8"));
49884
50290
  return parsed && typeof parsed === "object" ? parsed : undefined;
49885
50291
  } catch {
49886
50292
  return;
@@ -49888,7 +50294,7 @@ function readOwnerRecord(recordPath) {
49888
50294
  }
49889
50295
  function readLegacyOwnerLockPid(legacyPath) {
49890
50296
  try {
49891
- const pid = JSON.parse(readFileSync18(legacyPath, "utf8"))?.pid;
50297
+ const pid = JSON.parse(readFileSync19(legacyPath, "utf8"))?.pid;
49892
50298
  return typeof pid === "number" && Number.isInteger(pid) && pid > 0 ? pid : undefined;
49893
50299
  } catch {
49894
50300
  return;
@@ -49903,21 +50309,21 @@ function changeSetJournalRecoveryErrorMessage(metadataJson) {
49903
50309
  return "pending ChangeSet journal without a recorded recovery error";
49904
50310
  }
49905
50311
  function quarantineExistingLocalStore(paths) {
49906
- const quarantineDir = join13(paths.workspaceStateDir, "quarantine", `runtime.sqlite-${Date.now()}-${randomUUID()}`);
50312
+ const quarantineDir = join14(paths.workspaceStateDir, "quarantine", `runtime.sqlite-${Date.now()}-${randomUUID2()}`);
49907
50313
  ensurePrivateDir(quarantineDir);
49908
50314
  const quarantinedFiles = [];
49909
50315
  for (const suffix of SQLITE_SIDECAR_SUFFIXES) {
49910
50316
  const source = `${paths.localStorePath}${suffix}`;
49911
50317
  if (!existsSync19(source))
49912
50318
  continue;
49913
- const target = join13(quarantineDir, `runtime.sqlite${suffix}`);
49914
- renameSync3(source, target);
50319
+ const target = join14(quarantineDir, `runtime.sqlite${suffix}`);
50320
+ renameSync4(source, target);
49915
50321
  quarantinedFiles.push(target);
49916
50322
  }
49917
50323
  const markerPath = legacyMigrationMarkerPath(paths);
49918
50324
  if (existsSync19(markerPath)) {
49919
- const target = join13(quarantineDir, LEGACY_MIGRATION_MARKER_FILE);
49920
- renameSync3(markerPath, target);
50325
+ const target = join14(quarantineDir, LEGACY_MIGRATION_MARKER_FILE);
50326
+ renameSync4(markerPath, target);
49921
50327
  quarantinedFiles.push(target);
49922
50328
  }
49923
50329
  fsyncDirectory2(quarantineDir);
@@ -49925,16 +50331,16 @@ function quarantineExistingLocalStore(paths) {
49925
50331
  return quarantinedFiles;
49926
50332
  }
49927
50333
  function legacyMigrationMarkerPath(paths) {
49928
- return join13(paths.workspaceStateDir, LEGACY_MIGRATION_MARKER_FILE);
50334
+ return join14(paths.workspaceStateDir, LEGACY_MIGRATION_MARKER_FILE);
49929
50335
  }
49930
50336
  function legacyMigrationLockPath(paths) {
49931
- return join13(paths.workspaceStateDir, LEGACY_MIGRATION_LOCK_FILE);
50337
+ return join14(paths.workspaceStateDir, LEGACY_MIGRATION_LOCK_FILE);
49932
50338
  }
49933
50339
  function writePrivateJson2(path, value) {
49934
50340
  ensurePrivateDir(dirname8(path));
49935
50341
  const fd = openSync8(path, "w", 384);
49936
50342
  try {
49937
- writeFileSync6(fd, JSON.stringify(value, null, 2), "utf8");
50343
+ writeFileSync7(fd, JSON.stringify(value, null, 2), "utf8");
49938
50344
  fsyncSync3(fd);
49939
50345
  } finally {
49940
50346
  closeSync7(fd);
@@ -49943,7 +50349,7 @@ function writePrivateJson2(path, value) {
49943
50349
  fsyncDirectory2(dirname8(path));
49944
50350
  }
49945
50351
  function ensurePrivateDir(path) {
49946
- mkdirSync7(path, { recursive: true, mode: 448 });
50352
+ mkdirSync8(path, { recursive: true, mode: 448 });
49947
50353
  if (process.platform !== "win32") {
49948
50354
  try {
49949
50355
  chmodSync4(path, 448);
@@ -50306,7 +50712,7 @@ function recoverJournalFiles(root, files) {
50306
50712
  try {
50307
50713
  const stat = lstatSync10(absolute);
50308
50714
  if (stat.isFile() && !stat.isSymbolicLink()) {
50309
- const bytes = readFileSync18(absolute), body = bytes.toString("utf8");
50715
+ const bytes = readFileSync19(absolute), body = bytes.toString("utf8");
50310
50716
  if (Buffer.from(body, "utf8").equals(bytes))
50311
50717
  current = digestJson({ body });
50312
50718
  }
@@ -50325,7 +50731,7 @@ function recoverJournalFiles(root, files) {
50325
50731
  if (file.existed) {
50326
50732
  if (file.backupPath && existsSync19(file.backupPath)) {
50327
50733
  rmSync9(absolute, { recursive: true, force: true });
50328
- renameSync3(file.backupPath, absolute);
50734
+ renameSync4(file.backupPath, absolute);
50329
50735
  } else if (!existsSync19(absolute) && firstExistedByPath.get(pathKey(absolute)) === true) {
50330
50736
  missing.push(file.path);
50331
50737
  continue;
@@ -50383,7 +50789,7 @@ async function readRelationFiles(root, relationsDir) {
50383
50789
  for (const entry of entries) {
50384
50790
  if (!entry.isFile() || !/\.(json|ya?ml)$/.test(entry.name))
50385
50791
  continue;
50386
- const relativePath = join13(relationsDir, entry.name).split("\\").join("/");
50792
+ const relativePath = join14(relationsDir, entry.name).split("\\").join("/");
50387
50793
  relations.push(parseCrossRepoRelationFile(await readFile(resolve23(root, relativePath), "utf8"), relativePath));
50388
50794
  }
50389
50795
  return relations.sort((a, b) => a.id.localeCompare(b.id));
@@ -50515,7 +50921,7 @@ class LedgerAdminService {
50515
50921
  }
50516
50922
  const paths = runtimeStatePaths(repositoryRoot);
50517
50923
  const backupCreatedAt = this.context.clock();
50518
- const backupPath = uniqueRuntimeBackupPath(join14(paths.workspaceStateDir, "backups", "ledger-migrate", safePathSegment(backupCreatedAt), "runtime.sqlite"));
50924
+ const backupPath = uniqueRuntimeBackupPath(join15(paths.workspaceStateDir, "backups", "ledger-migrate", safePathSegment(backupCreatedAt), "runtime.sqlite"));
50519
50925
  const backup = await this.context.localStore.backupArchitectureLedger({ backupPath });
50520
50926
  const append = await this.context.appendArchitectureEventsWithFeed(repositoryRoot, {
50521
50927
  writer: "runtime-daemon",
@@ -51014,7 +51420,7 @@ function obsoleteManagedProjectionPaths(currentFiles, projectedFiles) {
51014
51420
  }
51015
51421
  function expectedFileHash(root, path) {
51016
51422
  const absolute = resolve24(root, path);
51017
- return existsSync20(absolute) ? digestJson({ body: readFileSync19(absolute, "utf8") }) : "missing";
51423
+ return existsSync20(absolute) ? digestJson({ body: readFileSync20(absolute, "utf8") }) : "missing";
51018
51424
  }
51019
51425
  function architectureProjectionRollbackBackup(files, options = {}) {
51020
51426
  const manifest = {
@@ -51069,12 +51475,12 @@ function isEmptyArchitectureLedgerState(state) {
51069
51475
  // packages/local-runtime/runtime-daemon/src/architecture-book.ts
51070
51476
  init_src();
51071
51477
  import { existsSync as existsSync22 } from "node:fs";
51072
- import { join as join16 } from "node:path";
51478
+ import { join as join17 } from "node:path";
51073
51479
 
51074
51480
  // packages/local-runtime/runtime-daemon/src/refactor-decisions.ts
51075
51481
  init_src();
51076
- import { existsSync as existsSync21, lstatSync as lstatSync11, readdirSync as readdirSync12, readFileSync as readFileSync20 } from "node:fs";
51077
- import { join as join15 } from "node:path";
51482
+ import { existsSync as existsSync21, lstatSync as lstatSync11, readdirSync as readdirSync12, readFileSync as readFileSync21 } from "node:fs";
51483
+ import { join as join16 } from "node:path";
51078
51484
  var REFACTOR_DECISION_SET_SCHEMA_VERSION = "archcontext.refactor-decision-set/v1";
51079
51485
  var REFACTOR_DECISION_FILE_NAME = /^recommendation\.[a-f0-9]{16}\.json$/;
51080
51486
  var CHANGESET_TRANSIENT_DECISION_NAME = /^recommendation\.[a-f0-9]{16}\.json\.(archctx-backup|archctx-tmp-[0-9]+-[0-9]+)$/;
@@ -51113,11 +51519,11 @@ function readRefactorDecisionSet(root) {
51113
51519
  const name = path.slice(prefix.length);
51114
51520
  if (name.includes("/"))
51115
51521
  throw decisionReadError(`${path} must sit directly in ${REFACTOR_DECISION_DIRECTORY}`);
51116
- if (!lstatSync11(join15(absoluteDirectory, name)).isFile())
51522
+ if (!lstatSync11(join16(absoluteDirectory, name)).isFile())
51117
51523
  throw decisionReadError(`${path} must be a regular file, not a directory or symlink`);
51118
51524
  let decision;
51119
51525
  try {
51120
- decision = parseRefactorDecisionFile(path, readFileSync20(join15(absoluteDirectory, name), "utf8"));
51526
+ decision = parseRefactorDecisionFile(path, readFileSync21(join16(absoluteDirectory, name), "utf8"));
51121
51527
  } catch (error) {
51122
51528
  throw decisionReadError(error instanceof Error ? error.message : String(error));
51123
51529
  }
@@ -51206,7 +51612,7 @@ function buildRefactorDecision(input) {
51206
51612
  function refactorDecisionWrite(root, decision) {
51207
51613
  const path = refactorDecisionPath(decision.recommendationId);
51208
51614
  const absolute = assertPathHasNoSymlinkSegments(root, path);
51209
- const expectedHash = existsSync21(absolute) ? digestJson({ body: readFileSync20(absolute, "utf8") }) : "missing";
51615
+ const expectedHash = existsSync21(absolute) ? digestJson({ body: readFileSync21(absolute, "utf8") }) : "missing";
51210
51616
  return { path, expectedHash, body: serializeRefactorDecision(decision) };
51211
51617
  }
51212
51618
  function refactorDecisionIdentityIssues(decision, namespace) {
@@ -51396,7 +51802,7 @@ class ArchitectureBookService {
51396
51802
  const gitScope = await this.context.architectureLedgerGitScope(root);
51397
51803
  let refactorDecisionStatuses = new Map;
51398
51804
  const repositoryRoot = findRepositoryRoot(root);
51399
- if (replay.events.some(eventCarriesRefactorRecommendation) || existsSync22(join16(repositoryRoot, REFACTOR_DECISION_DIRECTORY))) {
51805
+ if (replay.events.some(eventCarriesRefactorRecommendation) || existsSync22(join17(repositoryRoot, REFACTOR_DECISION_DIRECTORY))) {
51400
51806
  try {
51401
51807
  const decisions = readRefactorDecisionSet(repositoryRoot);
51402
51808
  refactorDecisionStatuses = new Map(decisions.decisions.map((decision) => [decision.recommendationId, decision.status]));
@@ -51752,8 +52158,8 @@ init_src();
51752
52158
  init_src();
51753
52159
  import { randomBytes as randomBytes4 } from "node:crypto";
51754
52160
  import { execFileSync as execFileSync7 } from "node:child_process";
51755
- import { chmodSync as chmodSync5, existsSync as existsSync23, lstatSync as lstatSync12, mkdirSync as mkdirSync8, readFileSync as readFileSync21, renameSync as renameSync4, rmSync as rmSync10, writeFileSync as writeFileSync7 } from "node:fs";
51756
- import { basename as basename6, dirname as dirname9, join as join17 } from "node:path";
52161
+ import { chmodSync as chmodSync5, existsSync as existsSync23, lstatSync as lstatSync12, mkdirSync as mkdirSync9, readFileSync as readFileSync22, renameSync as renameSync5, rmSync as rmSync10, writeFileSync as writeFileSync8 } from "node:fs";
52162
+ import { basename as basename6, dirname as dirname9, join as join18 } from "node:path";
51757
52163
 
51758
52164
  // packages/local-runtime/runtime-daemon/src/investigation-transport.ts
51759
52165
  import { spawn } from "node:child_process";
@@ -51995,7 +52401,7 @@ var AUDIT_EGRESS_POLICY_DIGEST = digestJson(AUDIT_EGRESS_POLICY);
51995
52401
  function auditConsentBinding(root, env) {
51996
52402
  const paths = runtimeStatePaths(root, env);
51997
52403
  return {
51998
- path: join17(paths.repositoryStateDir, AUDIT_CONSENT_FILE),
52404
+ path: join18(paths.repositoryStateDir, AUDIT_CONSENT_FILE),
51999
52405
  storageRepositoryId: paths.storageRepositoryId,
52000
52406
  repositoryAnchor: paths.repositoryAnchor,
52001
52407
  origin: readSanitizedOrigin(paths.repositoryRoot)
@@ -52043,7 +52449,7 @@ function readAuditConsentUnchecked(root, env = process.env) {
52043
52449
  try {
52044
52450
  if (!lstatSync12(binding.path).isFile())
52045
52451
  return { granted: false, path: binding.path, reason: "unreadable" };
52046
- record = JSON.parse(readFileSync21(binding.path, "utf8"));
52452
+ record = JSON.parse(readFileSync22(binding.path, "utf8"));
52047
52453
  } catch {
52048
52454
  return { granted: false, path: binding.path, reason: "unreadable" };
52049
52455
  }
@@ -52081,13 +52487,13 @@ function grantAuditConsentUnchecked(root, env = process.env, now = new Date().to
52081
52487
  }
52082
52488
  function writePrivateJsonAtomically(path, value) {
52083
52489
  const directory = dirname9(path);
52084
- mkdirSync8(directory, { recursive: true, mode: 448 });
52085
- const tempPath = join17(directory, `.${basename6(path)}.${process.pid}.${randomBytes4(6).toString("hex")}.tmp`);
52490
+ mkdirSync9(directory, { recursive: true, mode: 448 });
52491
+ const tempPath = join18(directory, `.${basename6(path)}.${process.pid}.${randomBytes4(6).toString("hex")}.tmp`);
52086
52492
  try {
52087
- writeFileSync7(tempPath, `${JSON.stringify(value, null, 2)}
52493
+ writeFileSync8(tempPath, `${JSON.stringify(value, null, 2)}
52088
52494
  `, { encoding: "utf8", mode: 384, flag: "wx" });
52089
52495
  chmodSync5(tempPath, 384);
52090
- renameSync4(tempPath, path);
52496
+ renameSync5(tempPath, path);
52091
52497
  } catch (error) {
52092
52498
  rmSync10(tempPath, { force: true });
52093
52499
  throw error;
@@ -52120,9 +52526,9 @@ function auditConsentRequiredEnvelope(requestId, reason) {
52120
52526
 
52121
52527
  // packages/local-runtime/runtime-daemon/src/github-issue-executor.ts
52122
52528
  import { execFile } from "node:child_process";
52123
- import { mkdtempSync as mkdtempSync4, rmSync as rmSync11, writeFileSync as writeFileSync8 } from "node:fs";
52529
+ import { mkdtempSync as mkdtempSync4, rmSync as rmSync11, writeFileSync as writeFileSync9 } from "node:fs";
52124
52530
  import { tmpdir as tmpdir4 } from "node:os";
52125
- import { join as join18 } from "node:path";
52531
+ import { join as join19 } from "node:path";
52126
52532
  var DEFAULT_GH_EXECUTOR_TIMEOUT_MS = 30000;
52127
52533
  var GITHUB_ISSUE_LIST_LIMIT = 100;
52128
52534
  function createNodeGithubIssueExecutor(options = {}) {
@@ -52187,10 +52593,10 @@ function runGh(args, env, timeoutMs) {
52187
52593
  });
52188
52594
  }
52189
52595
  async function withGithubIssueBodyFile(body, fn, deps = {}) {
52190
- const writeFile = deps.writeFile ?? writeFileSync8;
52191
- const dir = mkdtempSync4(join18(tmpdir4(), "archctx-gh-issue-body-"));
52596
+ const writeFile = deps.writeFile ?? writeFileSync9;
52597
+ const dir = mkdtempSync4(join19(tmpdir4(), "archctx-gh-issue-body-"));
52192
52598
  try {
52193
- const bodyFile = join18(dir, "body.md");
52599
+ const bodyFile = join19(dir, "body.md");
52194
52600
  writeFile(bodyFile, body, { mode: 384 });
52195
52601
  return await fn(bodyFile);
52196
52602
  } finally {
@@ -53174,10 +53580,10 @@ function runtimeProjectionOwnedOutputDigest(projection) {
53174
53580
  }
53175
53581
  // packages/local-runtime/runtime-daemon/src/projection-writer.ts
53176
53582
  import { execFile as execFile2, spawnSync as spawnSync6 } from "node:child_process";
53177
- import { createHash as createHash11, randomUUID as randomUUID2 } from "node:crypto";
53178
- import { closeSync as closeSync8, existsSync as existsSync24, mkdirSync as mkdirSync9, mkdtempSync as mkdtempSync5, openSync as openSync9, readFileSync as readFileSync22, readSync as readSync5, realpathSync as realpathSync8, renameSync as renameSync5, rmSync as rmSync12, writeFileSync as writeFileSync9 } from "node:fs";
53583
+ import { createHash as createHash11, randomUUID as randomUUID3 } from "node:crypto";
53584
+ import { closeSync as closeSync8, existsSync as existsSync24, mkdirSync as mkdirSync10, mkdtempSync as mkdtempSync5, openSync as openSync9, readFileSync as readFileSync23, readSync as readSync5, realpathSync as realpathSync8, renameSync as renameSync6, rmSync as rmSync12, writeFileSync as writeFileSync10 } from "node:fs";
53179
53585
  import { tmpdir as tmpdir5 } from "node:os";
53180
- import { extname as extname2, join as join19, resolve as resolve25 } from "node:path";
53586
+ import { extname as extname2, join as join20, resolve as resolve25 } from "node:path";
53181
53587
  init_src();
53182
53588
  var PROJECTION_PUBLISH_REQUEST_ID = "projection.publish";
53183
53589
  var PROJECTION_PUBLISH_STATUS_REQUEST_ID = "projection.publish-status";
@@ -53190,6 +53596,10 @@ var PROJECTION_WRITER_MAX_ITERATIONS = 3;
53190
53596
  var PROJECTION_WRITER_TARGETS = ["agent-context", "architecture-docs"];
53191
53597
  var PUBLISHER_TIMEOUT_MS = 120000;
53192
53598
  var PR_BODY_MAX_LISTED_PATHS = 200;
53599
+ function renderRecentHistory(root, ref, env) {
53600
+ const { total } = readArchitectureHistory(root, { ref, limit: 0, env });
53601
+ return renderHistoryMarkdown(readArchitectureHistory(root, { ref, offset: Math.max(0, total - 20), limit: 20, env }));
53602
+ }
53193
53603
 
53194
53604
  class ProjectionWriterFailure extends Error {
53195
53605
  code;
@@ -53207,8 +53617,8 @@ class ProjectionWriterFailure extends Error {
53207
53617
  }
53208
53618
  function projectionWriterPaths(repositoryRoot, remote, base, env = process.env) {
53209
53619
  const key = createHash11("sha256").update(`${remote}\x00${base}`, "utf8").digest("hex").slice(0, 16);
53210
- const dir = join19(runtimeStatePaths(repositoryRoot, env).repositoryStateDir, "projection-writer", key);
53211
- return { dir, baseRef: `refs/archctx/projection-writer/${key}/base`, worktree: join19(dir, "worktree"), state: join19(dir, "state.json"), lock: join19(dir, "lock") };
53620
+ const dir = join20(runtimeStatePaths(repositoryRoot, env).repositoryStateDir, "projection-writer", key);
53621
+ return { dir, baseRef: `refs/archctx/projection-writer/${key}/base`, worktree: join20(dir, "worktree"), state: join20(dir, "state.json"), lock: join20(dir, "lock") };
53212
53622
  }
53213
53623
  async function runProjectionPublishCommand(options) {
53214
53624
  const env = options.env ?? process.env;
@@ -53253,7 +53663,7 @@ async function runProjectionPublishCommand(options) {
53253
53663
  });
53254
53664
  let lock;
53255
53665
  try {
53256
- mkdirSync9(paths.dir, { recursive: true, mode: 448 });
53666
+ mkdirSync10(paths.dir, { recursive: true, mode: 448 });
53257
53667
  lock = acquireProjectionWriterLock(paths.lock, startedAt);
53258
53668
  } catch (error) {
53259
53669
  const failure = asWriterFailure(error);
@@ -53362,6 +53772,12 @@ async function runLockedProjectionPublish(input) {
53362
53772
  if (!["noop", "applied", "applied-partial"].includes(projectionStatus)) {
53363
53773
  throw new ProjectionWriterFailure("AC_PRECONDITION_FAILED", "projection-apply-status-unsupported", `projection apply ended with status ${projectionStatus}; the writer publishes only noop, applied and applied-partial results`);
53364
53774
  }
53775
+ const historyBody = renderRecentHistory(paths.worktree, baseSha, options.env);
53776
+ const historyPath = join20(paths.worktree, ARCHITECTURE_HISTORY_PATH);
53777
+ mkdirSync10(join20(paths.worktree, "docs/architecture"), { recursive: true });
53778
+ const historyTemp = `${historyPath}.${randomUUID3()}.tmp`;
53779
+ writeFileSync10(historyTemp, historyBody);
53780
+ renameSync6(historyTemp, historyPath);
53365
53781
  const changed = worktreeChangedPaths(paths.worktree);
53366
53782
  if (changed.length === 0) {
53367
53783
  const tip = lsRemoteBranch(repositoryRoot, pushRemote, base, env);
@@ -53373,6 +53789,7 @@ async function runLockedProjectionPublish(input) {
53373
53789
  return finish("up-to-date", { projectionStatus });
53374
53790
  }
53375
53791
  const written = new Set(result.files.filter((file) => file.action !== "unchanged").map((file) => file.path));
53792
+ written.add(ARCHITECTURE_HISTORY_PATH);
53376
53793
  const offending = changed.filter((path) => !written.has(path) || !isProjectionOwnedPath(path, ownedPatterns));
53377
53794
  if (offending.length > 0) {
53378
53795
  return failed(new ProjectionWriterFailure("AC_POLICY_VIOLATION", "projection-writer-non-owned-change", `projection apply changed paths the writer may not publish: ${offending.join(", ")}`), { projectionStatus });
@@ -53475,10 +53892,10 @@ function projectionPublishBody(input) {
53475
53892
  async function publishPullRequest(publisher, input) {
53476
53893
  if (publisher.kind === "none")
53477
53894
  return { ok: true, pullRequest: null };
53478
- const dir = mkdtempSync5(join19(tmpdir5(), "archctx-projection-pr-body-"));
53895
+ const dir = mkdtempSync5(join20(tmpdir5(), "archctx-projection-pr-body-"));
53479
53896
  try {
53480
- const bodyFile = join19(dir, "body.md");
53481
- writeFileSync9(bodyFile, projectionPublishBody(input), { mode: 384 });
53897
+ const bodyFile = join20(dir, "body.md");
53898
+ writeFileSync10(bodyFile, projectionPublishBody(input), { mode: 384 });
53482
53899
  const pullRequest = await publisher.ensurePullRequest({
53483
53900
  worktree: input.worktree,
53484
53901
  remote: input.remote,
@@ -53617,11 +54034,13 @@ function runProjectionVerifyPrCommand(options) {
53617
54034
  } catch {
53618
54035
  agentContextDiffering = [...classified.agentContextPaths];
53619
54036
  }
54037
+ const historyDiffering = changedPaths.includes(ARCHITECTURE_HISTORY_PATH) && readFileAtRevision(root, headSha, ARCHITECTURE_HISTORY_PATH) !== renderRecentHistory(root, headSha) ? [ARCHITECTURE_HISTORY_PATH] : [];
53620
54038
  const differingPaths = [...new Set([
53621
54039
  ...result.files.filter((file) => file.action !== "unchanged").map((file) => file.path),
53622
- ...agentContextDiffering
54040
+ ...agentContextDiffering,
54041
+ ...historyDiffering
53623
54042
  ])].sort();
53624
- const renderEquivalent = result.status === "noop" && agentContextDiffering.length === 0;
54043
+ const renderEquivalent = result.status === "noop" && agentContextDiffering.length === 0 && historyDiffering.length === 0;
53625
54044
  return verification({
53626
54045
  verdict: renderEquivalent ? "generated-only-render-equivalent" : "generated-only-not-render-equivalent",
53627
54046
  generatedOnly: true,
@@ -53640,7 +54059,7 @@ function classifyPullRequestPaths(root, mergeBase, headSha, changedPaths) {
53640
54059
  const humanEdited = [];
53641
54060
  const agentContext = [];
53642
54061
  for (const path of changedPaths) {
53643
- if (path === ARCHITECTURE_DOCS_PROJECTION_MANIFEST_PATH)
54062
+ if (path === ARCHITECTURE_DOCS_PROJECTION_MANIFEST_PATH || path === ARCHITECTURE_HISTORY_PATH)
53644
54063
  continue;
53645
54064
  const atBase = baseTargets.get(path);
53646
54065
  const atHead = headTargets.get(path);
@@ -53979,7 +54398,7 @@ function acquireProjectionWriterLock(lockPath, startedAt) {
53979
54398
  return { kind: "busy", pid: holder.pid };
53980
54399
  }
53981
54400
  rmSync12(lockPath, { force: true });
53982
- const record = JSON.stringify({ pid: process.pid, startedAt, token: randomUUID2() }, null, 2);
54401
+ const record = JSON.stringify({ pid: process.pid, startedAt, token: randomUUID3() }, null, 2);
53983
54402
  createPrivateControlFile(lockPath, record);
53984
54403
  return { kind: "acquired", record, release() {
53985
54404
  try {
@@ -54035,7 +54454,7 @@ function readProjectionWriterState(path, remote, base) {
54035
54454
  return emptyProjectionWriterState(remote, base);
54036
54455
  let value;
54037
54456
  try {
54038
- value = JSON.parse(readFileSync22(path, "utf8"));
54457
+ value = JSON.parse(readFileSync23(path, "utf8"));
54039
54458
  } catch (error) {
54040
54459
  throw new ProjectionWriterFailure("AC_PRECONDITION_FAILED", "projection-writer-state-invalid", `projection writer state is unreadable at ${path}: ${errorMessage(error)}`);
54041
54460
  }
@@ -54057,9 +54476,9 @@ function readProjectionWriterState(path, remote, base) {
54057
54476
  }
54058
54477
  function writeProjectionWriterState(path, state) {
54059
54478
  const temporary = `${path}.${process.pid}.tmp`;
54060
- writeFileSync9(temporary, `${JSON.stringify(state, null, 2)}
54479
+ writeFileSync10(temporary, `${JSON.stringify(state, null, 2)}
54061
54480
  `, { encoding: "utf8", mode: 384 });
54062
- renameSync5(temporary, path);
54481
+ renameSync6(temporary, path);
54063
54482
  }
54064
54483
  function prepareProjectionWriterWorktree(repositoryRoot, worktree, sha) {
54065
54484
  git(repositoryRoot, ["worktree", "prune"]);
@@ -54072,7 +54491,7 @@ function prepareProjectionWriterWorktree(repositoryRoot, worktree, sha) {
54072
54491
  git(worktree, ["clean", "-ffdq"]);
54073
54492
  }
54074
54493
  function isRegisteredWorktree(repositoryRoot, worktree) {
54075
- if (!existsSync24(join19(worktree, ".git")))
54494
+ if (!existsSync24(join20(worktree, ".git")))
54076
54495
  return false;
54077
54496
  const wanted = canonical(worktree);
54078
54497
  return git(repositoryRoot, ["worktree", "list", "--porcelain", "-z"]).split("\x00").filter((line) => line.startsWith("worktree ")).some((line) => canonical(line.slice("worktree ".length)) === wanted);
@@ -54324,7 +54743,7 @@ function runFlowSelectorCheckCommand(cwd, options = {}) {
54324
54743
  }
54325
54744
  // packages/local-runtime/runtime-daemon/src/recommendations.ts
54326
54745
  import { existsSync as existsSync25 } from "node:fs";
54327
- import { join as join20 } from "node:path";
54746
+ import { join as join21 } from "node:path";
54328
54747
 
54329
54748
  // packages/local-runtime/runtime-daemon/src/refactor-verify.ts
54330
54749
  init_src();
@@ -54926,7 +55345,7 @@ class RecommendationsService {
54926
55345
  });
54927
55346
  }
54928
55347
  readGitOnlyDecision(repositoryRoot, recommendationId, surface) {
54929
- if (!existsSync25(join20(repositoryRoot, REFACTOR_DECISION_DIRECTORY)))
55348
+ if (!existsSync25(join21(repositoryRoot, REFACTOR_DECISION_DIRECTORY)))
54930
55349
  return;
54931
55350
  let decisions;
54932
55351
  try {
@@ -55596,7 +56015,7 @@ function lifecycleEnvelope(input) {
55596
56015
  });
55597
56016
  }
55598
56017
  function refactorDecisionsInPlay(repositoryRoot, records) {
55599
- return records.some(isRefactorRecommendation) || existsSync25(join20(repositoryRoot, REFACTOR_DECISION_DIRECTORY));
56018
+ return records.some(isRefactorRecommendation) || existsSync25(join21(repositoryRoot, REFACTOR_DECISION_DIRECTORY));
55600
56019
  }
55601
56020
  function ledgerAuditDecisionRefused(surface, record, recommendations, decisions) {
55602
56021
  let head = record.recommendationId;
@@ -55718,14 +56137,14 @@ function recommendationActorKind(input) {
55718
56137
  init_src();
55719
56138
  init_src();
55720
56139
  init_src();
55721
- import { existsSync as existsSync26, readFileSync as readFileSync24 } from "node:fs";
56140
+ import { existsSync as existsSync26, readFileSync as readFileSync25 } from "node:fs";
55722
56141
  import { resolve as resolve27 } from "node:path";
55723
56142
  init_src();
55724
56143
 
55725
56144
  // packages/local-runtime/runtime-daemon/src/committed-change-acceptance.ts
55726
56145
  init_src();
55727
56146
  import { execFileSync as execFileSync9 } from "node:child_process";
55728
- import { closeSync as closeSync9, constants as fsConstants3, fstatSync as fstatSync4, lstatSync as lstatSync13, openSync as openSync10, readdirSync as readdirSync13, readFileSync as readFileSync23 } from "node:fs";
56147
+ import { closeSync as closeSync9, constants as fsConstants3, fstatSync as fstatSync4, lstatSync as lstatSync13, openSync as openSync10, readdirSync as readdirSync13, readFileSync as readFileSync24 } from "node:fs";
55729
56148
  import { resolve as resolve26 } from "node:path";
55730
56149
  init_src();
55731
56150
  var SEMANTIC_MODEL_DIRECTORIES = ["nodes", "relations", "flows"];
@@ -55804,7 +56223,7 @@ function readRegularFileBytes(absolute, path) {
55804
56223
  try {
55805
56224
  if (!fstatSync4(fd).isFile())
55806
56225
  throw new FailureError("AC_PRECONDITION_FAILED", "semantic-model-entry-not-regular");
55807
- return readFileSync23(fd);
56226
+ return readFileSync24(fd);
55808
56227
  } finally {
55809
56228
  closeSync9(fd);
55810
56229
  }
@@ -56307,7 +56726,7 @@ class ChangeSetAuthorityService {
56307
56726
  const absolute = resolve27(session.workspace.root, path);
56308
56727
  const body = `${JSON.stringify(waiver, null, 2)}
56309
56728
  `;
56310
- const expectedHash = existsSync26(absolute) ? digestJson({ body: readFileSync24(absolute, "utf8") }) : "missing";
56729
+ const expectedHash = existsSync26(absolute) ? digestJson({ body: readFileSync25(absolute, "utf8") }) : "missing";
56311
56730
  const draft = this.changeSetEngine.plan({
56312
56731
  id: input.id ?? `changeset.practice-waiver-${waiverId.replace(/[^A-Za-z0-9_-]/g, "-")}`,
56313
56732
  base: {
@@ -56747,7 +57166,7 @@ function architectureLedgerWriteAppendsEvents(mode) {
56747
57166
  // packages/local-runtime/runtime-daemon/src/rpc-server.ts
56748
57167
  init_src();
56749
57168
  import { createServer as createServer2 } from "node:http";
56750
- import { closeSync as closeSync10, existsSync as existsSync27, mkdirSync as mkdirSync10 } from "node:fs";
57169
+ import { closeSync as closeSync10, existsSync as existsSync27, mkdirSync as mkdirSync11 } from "node:fs";
56751
57170
  import { dirname as dirname10 } from "node:path";
56752
57171
  import { randomBytes as randomBytes5 } from "node:crypto";
56753
57172
  var DEFAULT_DAEMON_IDLE_TIMEOUT_MS = 30 * 60000;
@@ -56818,8 +57237,8 @@ class ArchctxRuntimeRpcServer {
56818
57237
  const root = this.options.root ?? process.cwd();
56819
57238
  const connectionPath = this.options.connectionPath ?? defaultDaemonConnectionPath(root);
56820
57239
  const lockPath = this.options.lockPath ?? defaultDaemonLockPath(root);
56821
- mkdirSync10(dirname10(connectionPath), { recursive: true });
56822
- mkdirSync10(dirname10(lockPath), { recursive: true });
57240
+ mkdirSync11(dirname10(connectionPath), { recursive: true });
57241
+ mkdirSync11(dirname10(lockPath), { recursive: true });
56823
57242
  this.lockFd = acquireDaemonLock(lockPath, root);
56824
57243
  const token = this.options.token ?? randomBytes5(18).toString("base64url");
56825
57244
  const server = createServer2((request, response) => {
@@ -57138,7 +57557,7 @@ async function readRpcRequestBody(request, limits) {
57138
57557
  }
57139
57558
 
57140
57559
  // packages/local-runtime/runtime-daemon/src/index.ts
57141
- import { existsSync as existsSync28, readFileSync as readFileSync25 } from "node:fs";
57560
+ import { existsSync as existsSync28, readFileSync as readFileSync26 } from "node:fs";
57142
57561
  import { resolve as resolve28 } from "node:path";
57143
57562
  init_src();
57144
57563
 
@@ -57333,7 +57752,7 @@ class ArchctxDaemon {
57333
57752
  const model = loadNativeModelFromArchContext(root);
57334
57753
  const canonical = renderAgentContextProjection({ model, sourceDigest: digestJson({ model }), existingFiles: loadAgentContextProjectionFiles(root, model) });
57335
57754
  const canonicalBody = canonical.files.find((candidate) => candidate.path === file.path)?.body;
57336
- if (canonicalBody === undefined || projectionOwnedWriteBody(canonicalBody, readFileSync25(resolve28(root, file.path), "utf8")) !== file.body) {
57755
+ if (canonicalBody === undefined || projectionOwnedWriteBody(canonicalBody, readFileSync26(resolve28(root, file.path), "utf8")) !== file.body) {
57337
57756
  throw new Error(`Root contract requires canonical marker-only content: ${file.path}`);
57338
57757
  }
57339
57758
  }
@@ -58651,8 +59070,8 @@ function isArchContextGeneratedProjectionPath2(path) {
58651
59070
 
58652
59071
  // packages/surfaces/cli/src/github-review-state.ts
58653
59072
  init_src();
58654
- import { chmodSync as chmodSync6, existsSync as existsSync29, mkdirSync as mkdirSync11, readFileSync as readFileSync26, rmSync as rmSync13, writeFileSync as writeFileSync10 } from "node:fs";
58655
- import { dirname as dirname11, join as join22 } from "node:path";
59073
+ import { chmodSync as chmodSync6, existsSync as existsSync29, mkdirSync as mkdirSync12, readFileSync as readFileSync27, rmSync as rmSync13, writeFileSync as writeFileSync11 } from "node:fs";
59074
+ import { dirname as dirname11, join as join23 } from "node:path";
58656
59075
  var text2 = { type: "string", minLength: 1 };
58657
59076
  var digest2 = { type: "string", pattern: "^sha256:[0-9a-f]{64}$" };
58658
59077
  var record7 = (properties, required = Object.keys(properties)) => ({ type: "object", additionalProperties: false, properties, required });
@@ -58683,7 +59102,7 @@ var stateSchema = record7({
58683
59102
  }, ["schemaVersion", "status", "challenge", "challengeDigest", "updatedAt"]);
58684
59103
  function defaultGithubDeveloperReviewStatePath(cwd, pullRequestNumber) {
58685
59104
  const suffix = pullRequestNumber ? `github-developer-review-pr-${pullRequestNumber}.json` : "github-developer-review.json";
58686
- return join22(runtimeStatePaths(cwd).workspaceStateDir, suffix);
59105
+ return join23(runtimeStatePaths(cwd).workspaceStateDir, suffix);
58687
59106
  }
58688
59107
  function metadata(state) {
58689
59108
  const { submission, ...rest } = state;
@@ -58737,8 +59156,8 @@ async function writeGithubDeveloperReviewState(cwd, state, secrets = []) {
58737
59156
  assertNoCliSecretMaterial(state.submission);
58738
59157
  assertNoReviewSecrets(state.submission, secrets);
58739
59158
  }
58740
- mkdirSync11(dirname11(path), { recursive: true });
58741
- writeFileSync10(path, serialized, { mode: 384 });
59159
+ mkdirSync12(dirname11(path), { recursive: true });
59160
+ writeFileSync11(path, serialized, { mode: 384 });
58742
59161
  if (process.platform !== "win32")
58743
59162
  chmodSync6(path, 384);
58744
59163
  return { state: { ...validated, ...state.submission === undefined ? {} : { submission: state.submission } }, path };
@@ -58748,7 +59167,7 @@ function readGithubDeveloperReviewState(path) {
58748
59167
  return;
58749
59168
  let parsed;
58750
59169
  try {
58751
- parsed = JSON.parse(readFileSync26(path, "utf8"));
59170
+ parsed = JSON.parse(readFileSync27(path, "utf8"));
58752
59171
  } catch {
58753
59172
  throw new Error("github-review-state-metadata-invalid");
58754
59173
  }
@@ -58763,7 +59182,7 @@ function discardLegacyGithubDeveloperReviewState(path) {
58763
59182
  return false;
58764
59183
  let parsed;
58765
59184
  try {
58766
- parsed = JSON.parse(readFileSync26(path, "utf8"));
59185
+ parsed = JSON.parse(readFileSync27(path, "utf8"));
58767
59186
  } catch {
58768
59187
  throw new Error("github-review-state-metadata-invalid");
58769
59188
  }
@@ -58865,13 +59284,14 @@ function localEgressStatus2(env = process.env, live = {}) {
58865
59284
 
58866
59285
  // packages/surfaces/cli/src/main.ts
58867
59286
  import { spawn as spawn2, spawnSync as spawnSync9 } from "child_process";
58868
- import { accessSync as accessSync3, closeSync as closeSync14, constants as constants3, existsSync as existsSync35, mkdirSync as mkdirSync16, openSync as openSync14, readFileSync as readFileSync33, rmSync as rmSync18, statSync as statSync12 } from "fs";
58869
- import { dirname as dirname16, join as join27, parse, resolve as resolve37 } from "path";
59287
+ import { accessSync as accessSync3, closeSync as closeSync14, constants as constants3, existsSync as existsSync35, mkdirSync as mkdirSync17, openSync as openSync14, readFileSync as readFileSync34, rmSync as rmSync18, statSync as statSync12 } from "fs";
59288
+ import { dirname as dirname16, join as join28, parse, resolve as resolve37 } from "path";
58870
59289
  import { fileURLToPath as fileURLToPath2 } from "url";
58871
59290
 
58872
59291
  // packages/contracts/src/index.ts
58873
59292
  init_control_plane_routes();
58874
59293
  init_architecture();
59294
+ init_architecture_history();
58875
59295
  init_architecture_debt();
58876
59296
  init_docs_anchors();
58877
59297
  init_github_governance();
@@ -58893,12 +59313,12 @@ init_changeset_recovery();
58893
59313
 
58894
59314
  // packages/core/changeset-engine/src/index.ts
58895
59315
  init_src();
58896
- import { chmodSync as chmodSync7, closeSync as closeSync11, existsSync as existsSync30, fsyncSync as fsyncSync4, lstatSync as lstatSync14, mkdirSync as mkdirSync12, openSync as openSync11, readFileSync as readFileSync27, renameSync as renameSync6, rmSync as rmSync14, writeFileSync as writeFileSync11 } from "node:fs";
59316
+ import { chmodSync as chmodSync7, closeSync as closeSync11, existsSync as existsSync30, fsyncSync as fsyncSync4, lstatSync as lstatSync14, mkdirSync as mkdirSync13, openSync as openSync11, readFileSync as readFileSync28, renameSync as renameSync7, rmSync as rmSync14, writeFileSync as writeFileSync12 } from "node:fs";
58897
59317
  import { dirname as dirname12, isAbsolute as isAbsolute7, relative as relative8, resolve as resolve29, sep as sep6 } from "node:path";
58898
59318
  var EMPTY_PATH_SET2 = new Set;
58899
59319
  function planManifestFieldsOperation(root, fields) {
58900
59320
  const absolute = assertPathHasNoSymlinkSegments2(root, MANIFEST_UPDATE_PATH);
58901
- const body = readFileSync27(absolute, "utf8");
59321
+ const body = readFileSync28(absolute, "utf8");
58902
59322
  const operation = { op: "update_manifest_fields", path: MANIFEST_UPDATE_PATH, expectedHash: digestJson({ body }), fields };
58903
59323
  assertManifestUpdateOperation(operation);
58904
59324
  renderManifestFieldsUpdate(body, fields);
@@ -59006,7 +59426,7 @@ function assertAllowedArchContextPath2(root, relativePath, scope) {
59006
59426
 
59007
59427
  // packages/core/architecture-domain/src/index.ts
59008
59428
  import { createHash as createHash12 } from "node:crypto";
59009
- import { readFileSync as readFileSync28, realpathSync as realpathSync10, statSync as statSync8 } from "node:fs";
59429
+ import { readFileSync as readFileSync29, realpathSync as realpathSync10, statSync as statSync8 } from "node:fs";
59010
59430
  import { resolve as resolve31 } from "node:path";
59011
59431
  init_src();
59012
59432
  var DEFAULT_IGNORES2 = new Set([
@@ -59059,7 +59479,7 @@ function computeWorktreeDigest2(root, files, options = {}) {
59059
59479
  return {
59060
59480
  path,
59061
59481
  size: statSync8(absolute).size,
59062
- digest: createHash12("sha256").update(readFileSync28(absolute)).digest("hex")
59482
+ digest: createHash12("sha256").update(readFileSync29(absolute)).digest("hex")
59063
59483
  };
59064
59484
  });
59065
59485
  return digestJson(payload);
@@ -59374,7 +59794,7 @@ var UNTRUSTED_TOOL_ESCAPE_KEYS2 = new Set([
59374
59794
  ]);
59375
59795
 
59376
59796
  // packages/cloud/hardening/src/index.ts
59377
- import { readdirSync as readdirSync14, readFileSync as readFileSync29, statSync as statSync9 } from "node:fs";
59797
+ import { readdirSync as readdirSync14, readFileSync as readFileSync30, statSync as statSync9 } from "node:fs";
59378
59798
  import { resolve as resolve32 } from "node:path";
59379
59799
  init_src2();
59380
59800
  init_src();
@@ -59422,7 +59842,7 @@ function uninstallMarker(content, host) {
59422
59842
  `).trim();
59423
59843
  }
59424
59844
  function dependencyAudit(root) {
59425
- const packageJson = JSON.parse(readFileSync29(resolve32(root, "package.json"), "utf8"));
59845
+ const packageJson = JSON.parse(readFileSync30(resolve32(root, "package.json"), "utf8"));
59426
59846
  const issues = [];
59427
59847
  if (packageJson.engines?.node !== ARCHCONTEXT_NODE_RANGE) {
59428
59848
  issues.push(`node engine must equal ${ARCHCONTEXT_NODE_RANGE}`);
@@ -59436,7 +59856,7 @@ function secretScan(root) {
59436
59856
  continue;
59437
59857
  if (file === "packages/cloud/hardening/src/index.ts" || file.includes("/test/"))
59438
59858
  continue;
59439
- const body = readFileSync29(resolve32(root, file), "utf8");
59859
+ const body = readFileSync30(resolve32(root, file), "utf8");
59440
59860
  if (/(sk-[A-Za-z0-9]{20,}|ghp_[A-Za-z0-9]{20,}|BEGIN PRIVATE KEY)/.test(body))
59441
59861
  findings.push(file);
59442
59862
  }
@@ -59485,10 +59905,10 @@ function listFiles(root) {
59485
59905
 
59486
59906
  // packages/local-runtime/local-store-sqlite/src/index.ts
59487
59907
  init_src();
59488
- import { createHash as createHash14, randomUUID as randomUUID3 } from "node:crypto";
59489
- import { chmodSync as chmodSync8, closeSync as closeSync12, copyFileSync as copyFileSync2, existsSync as existsSync32, fsyncSync as fsyncSync5, lstatSync as lstatSync15, mkdirSync as mkdirSync13, openSync as openSync12, readFileSync as readFileSync30, readSync as readSync6, realpathSync as realpathSync11, renameSync as renameSync7, rmSync as rmSync15, statfsSync as statfsSync2, statSync as statSync10, writeFileSync as writeFileSync12 } from "node:fs";
59908
+ import { createHash as createHash14, randomUUID as randomUUID4 } from "node:crypto";
59909
+ import { chmodSync as chmodSync8, closeSync as closeSync12, copyFileSync as copyFileSync2, existsSync as existsSync32, fsyncSync as fsyncSync5, lstatSync as lstatSync15, mkdirSync as mkdirSync14, openSync as openSync12, readFileSync as readFileSync31, readSync as readSync6, realpathSync as realpathSync11, renameSync as renameSync8, rmSync as rmSync15, statfsSync as statfsSync2, statSync as statSync10, writeFileSync as writeFileSync13 } from "node:fs";
59490
59910
  import { createRequire as createRequire5 } from "node:module";
59491
- import { dirname as dirname13, isAbsolute as isAbsolute9, join as join23, relative as relative10, resolve as resolve33 } from "node:path";
59911
+ import { dirname as dirname13, isAbsolute as isAbsolute9, join as join24, relative as relative10, resolve as resolve33 } from "node:path";
59492
59912
  init_src();
59493
59913
  var runtimeRequire2 = createRequire5(import.meta.url);
59494
59914
  var SQLITE_SIDECAR_SUFFIXES2 = ["", "-wal", "-shm"];
@@ -60407,8 +60827,8 @@ function recoverRuntimeStateTarget(input) {
60407
60827
  }
60408
60828
  assertRuntimeStateRecoveryDaemonStopped(paths);
60409
60829
  const lock = acquireLegacyMigrationLock2(paths);
60410
- const stagingDir = join23(paths.workspaceStateDir, `.runtime.sqlite.recovery-${process.pid}-${randomUUID3()}`);
60411
- const stagingPath = join23(stagingDir, "runtime.sqlite");
60830
+ const stagingDir = join24(paths.workspaceStateDir, `.runtime.sqlite.recovery-${process.pid}-${randomUUID4()}`);
60831
+ const stagingPath = join24(stagingDir, "runtime.sqlite");
60412
60832
  let quarantineDirectory;
60413
60833
  let quarantineFiles = [];
60414
60834
  let receiptPath;
@@ -60427,7 +60847,7 @@ function recoverRuntimeStateTarget(input) {
60427
60847
  throw new Error(`runtime-state-recovery-target-fingerprint-mismatch:${lockedSnapshot.fingerprint}`);
60428
60848
  }
60429
60849
  assertRuntimeStateRecoveryDiskBudget(inspection.availableBytes, inspection.requiredFreeBytes);
60430
- quarantineDirectory = join23(paths.workspaceStateDir, "quarantine", `runtime-state-recovery-${Date.now()}-${randomUUID3()}`);
60850
+ quarantineDirectory = join24(paths.workspaceStateDir, "quarantine", `runtime-state-recovery-${Date.now()}-${randomUUID4()}`);
60431
60851
  ensurePrivateDir2(quarantineDirectory);
60432
60852
  assertRuntimeStateRecoveryPrivatePermissions(quarantineDirectory, 448);
60433
60853
  quarantineFiles = copyRuntimeStateRecoveryFiles(lockedSnapshot.files, quarantineDirectory);
@@ -60440,7 +60860,7 @@ function recoverRuntimeStateTarget(input) {
60440
60860
  assertRuntimeStateRecoveryPrivatePermissions(stagingDir, 448);
60441
60861
  migrateSqliteDatabaseSync2(stagingPath);
60442
60862
  const stagingIntegrity = assertCurrentLocalStore2(stagingPath);
60443
- receiptPath = join23(quarantineDirectory, RUNTIME_STATE_RECOVERY_RECEIPT_FILE);
60863
+ receiptPath = join24(quarantineDirectory, RUNTIME_STATE_RECOVERY_RECEIPT_FILE);
60444
60864
  writeRuntimeStateRecoveryReceipt(receiptPath, {
60445
60865
  status: "quarantine-verified",
60446
60866
  paths,
@@ -60504,7 +60924,7 @@ function completeRuntimeStateRecovery(input) {
60504
60924
  if (resolve33(input.recovery.receiptPath) !== expectedReceiptPath) {
60505
60925
  throw new Error("runtime-state-recovery-completion-receipt-path-mismatch");
60506
60926
  }
60507
- const parsed = JSON.parse(readFileSync30(expectedReceiptPath, "utf8"));
60927
+ const parsed = JSON.parse(readFileSync31(expectedReceiptPath, "utf8"));
60508
60928
  if (parsed.schemaVersion !== "archcontext.runtime-state-recovery-receipt/v1" || parsed.status !== "target-published-rebuild-required" || parsed.targetFingerprint !== input.recovery.targetFingerprintBefore || parsed.expectedWorktreeDigest !== input.recovery.expectedWorktreeDigest) {
60509
60929
  throw new Error("runtime-state-recovery-completion-receipt-mismatch");
60510
60930
  }
@@ -60558,8 +60978,8 @@ function migrateLegacyLocalStoreIfNeeded2(root = process.cwd(), env = process.en
60558
60978
  }
60559
60979
  assertTrustedLegacyLocalStoreSource2(paths);
60560
60980
  const lock = acquireLegacyMigrationLock2(paths);
60561
- const stagingDir = join23(paths.workspaceStateDir, `.runtime.sqlite.migration-${process.pid}-${randomUUID3()}`);
60562
- const stagingPath = join23(stagingDir, "runtime.sqlite");
60981
+ const stagingDir = join24(paths.workspaceStateDir, `.runtime.sqlite.migration-${process.pid}-${randomUUID4()}`);
60982
+ const stagingPath = join24(stagingDir, "runtime.sqlite");
60563
60983
  try {
60564
60984
  if (targetExists)
60565
60985
  quarantinedFiles.push(...quarantineExistingLocalStore2(paths));
@@ -61295,13 +61715,13 @@ function runtimeStateRecoveryInspection(paths, migration, status, reasonCode, fi
61295
61715
  };
61296
61716
  }
61297
61717
  function runtimeStateRecoveryStartupProbe(paths, sourceFiles) {
61298
- const probeDirectory = join23(paths.workspaceStateDir, `.runtime.sqlite.recovery-probe-${process.pid}-${randomUUID3()}`);
61299
- const probePath = join23(probeDirectory, "runtime.sqlite");
61718
+ const probeDirectory = join24(paths.workspaceStateDir, `.runtime.sqlite.recovery-probe-${process.pid}-${randomUUID4()}`);
61719
+ const probePath = join24(probeDirectory, "runtime.sqlite");
61300
61720
  try {
61301
61721
  ensurePrivateDir2(probeDirectory);
61302
61722
  assertRuntimeStateRecoveryPrivatePermissions(probeDirectory, 448);
61303
61723
  for (const source of sourceFiles.filter((file) => file.name.startsWith("runtime.sqlite") && file.name !== LEGACY_MIGRATION_MARKER_FILE2)) {
61304
- const target = join23(probeDirectory, source.name);
61724
+ const target = join24(probeDirectory, source.name);
61305
61725
  copyFileSync2(source.path, target);
61306
61726
  makePrivateFile2(target);
61307
61727
  }
@@ -61393,7 +61813,7 @@ function runtimeStateRecoveryAvailableBytes(path) {
61393
61813
  }
61394
61814
  function copyRuntimeStateRecoveryFiles(sourceFiles, quarantineDirectory) {
61395
61815
  return sourceFiles.map((source) => {
61396
- const target = join23(quarantineDirectory, source.name);
61816
+ const target = join24(quarantineDirectory, source.name);
61397
61817
  copyFileSync2(source.path, target);
61398
61818
  makePrivateFile2(target);
61399
61819
  assertRuntimeStateRecoveryPrivatePermissions(target, 384);
@@ -61439,7 +61859,7 @@ function removeRuntimeStateRecoveryTargetFamily(paths) {
61439
61859
  }
61440
61860
  function restoreRuntimeStateRecoveryFiles(files, paths) {
61441
61861
  for (const file of files) {
61442
- const target = file.name === LEGACY_MIGRATION_MARKER_FILE2 ? legacyMigrationMarkerPath2(paths) : join23(dirname13(paths.localStorePath), file.name);
61862
+ const target = file.name === LEGACY_MIGRATION_MARKER_FILE2 ? legacyMigrationMarkerPath2(paths) : join24(dirname13(paths.localStorePath), file.name);
61443
61863
  copyFileSync2(file.path, target);
61444
61864
  makePrivateFile2(target);
61445
61865
  fsyncFile2(target);
@@ -61607,7 +62027,7 @@ function publishStagedLocalStore2(stagingPath, targetPath) {
61607
62027
  if (existsSync32(path))
61608
62028
  throw new Error(`Cannot publish migrated SQLite over existing target file: ${path}`);
61609
62029
  }
61610
- renameSync7(stagingPath, targetPath);
62030
+ renameSync8(stagingPath, targetPath);
61611
62031
  makePrivateFile2(targetPath);
61612
62032
  fsyncDirectory3(dirname13(targetPath));
61613
62033
  }
@@ -61628,7 +62048,7 @@ function acquireLegacyMigrationLock2(paths) {
61628
62048
  ensurePrivateDir2(dirname13(lockPath));
61629
62049
  try {
61630
62050
  const fd = openSync12(lockPath, "wx", 384);
61631
- writeFileSync12(fd, JSON.stringify({
62051
+ writeFileSync13(fd, JSON.stringify({
61632
62052
  schemaVersion: "archcontext.legacy-local-store-migration-lock/v1",
61633
62053
  pid: process.pid,
61634
62054
  root: paths.repositoryRoot,
@@ -61654,7 +62074,7 @@ function releaseLegacyMigrationLock2(lock) {
61654
62074
  }
61655
62075
  function isStaleMigrationLock2(lockPath) {
61656
62076
  try {
61657
- const parsed = JSON.parse(readFileSync30(lockPath, "utf8"));
62077
+ const parsed = JSON.parse(readFileSync31(lockPath, "utf8"));
61658
62078
  if (typeof parsed.pid !== "number" || parsed.pid <= 0)
61659
62079
  return true;
61660
62080
  return !isProcessAlive(parsed.pid);
@@ -61664,21 +62084,21 @@ function isStaleMigrationLock2(lockPath) {
61664
62084
  }
61665
62085
  var LOCAL_STORE_WRITER_OWNED_ERROR = "local-store-writer-owned";
61666
62086
  function quarantineExistingLocalStore2(paths) {
61667
- const quarantineDir = join23(paths.workspaceStateDir, "quarantine", `runtime.sqlite-${Date.now()}-${randomUUID3()}`);
62087
+ const quarantineDir = join24(paths.workspaceStateDir, "quarantine", `runtime.sqlite-${Date.now()}-${randomUUID4()}`);
61668
62088
  ensurePrivateDir2(quarantineDir);
61669
62089
  const quarantinedFiles = [];
61670
62090
  for (const suffix of SQLITE_SIDECAR_SUFFIXES2) {
61671
62091
  const source = `${paths.localStorePath}${suffix}`;
61672
62092
  if (!existsSync32(source))
61673
62093
  continue;
61674
- const target = join23(quarantineDir, `runtime.sqlite${suffix}`);
61675
- renameSync7(source, target);
62094
+ const target = join24(quarantineDir, `runtime.sqlite${suffix}`);
62095
+ renameSync8(source, target);
61676
62096
  quarantinedFiles.push(target);
61677
62097
  }
61678
62098
  const markerPath = legacyMigrationMarkerPath2(paths);
61679
62099
  if (existsSync32(markerPath)) {
61680
- const target = join23(quarantineDir, LEGACY_MIGRATION_MARKER_FILE2);
61681
- renameSync7(markerPath, target);
62100
+ const target = join24(quarantineDir, LEGACY_MIGRATION_MARKER_FILE2);
62101
+ renameSync8(markerPath, target);
61682
62102
  quarantinedFiles.push(target);
61683
62103
  }
61684
62104
  fsyncDirectory3(quarantineDir);
@@ -61686,16 +62106,16 @@ function quarantineExistingLocalStore2(paths) {
61686
62106
  return quarantinedFiles;
61687
62107
  }
61688
62108
  function legacyMigrationMarkerPath2(paths) {
61689
- return join23(paths.workspaceStateDir, LEGACY_MIGRATION_MARKER_FILE2);
62109
+ return join24(paths.workspaceStateDir, LEGACY_MIGRATION_MARKER_FILE2);
61690
62110
  }
61691
62111
  function legacyMigrationLockPath2(paths) {
61692
- return join23(paths.workspaceStateDir, LEGACY_MIGRATION_LOCK_FILE2);
62112
+ return join24(paths.workspaceStateDir, LEGACY_MIGRATION_LOCK_FILE2);
61693
62113
  }
61694
62114
  function writePrivateJson3(path, value) {
61695
62115
  ensurePrivateDir2(dirname13(path));
61696
62116
  const fd = openSync12(path, "w", 384);
61697
62117
  try {
61698
- writeFileSync12(fd, JSON.stringify(value, null, 2), "utf8");
62118
+ writeFileSync13(fd, JSON.stringify(value, null, 2), "utf8");
61699
62119
  fsyncSync5(fd);
61700
62120
  } finally {
61701
62121
  closeSync12(fd);
@@ -61704,7 +62124,7 @@ function writePrivateJson3(path, value) {
61704
62124
  fsyncDirectory3(dirname13(path));
61705
62125
  }
61706
62126
  function ensurePrivateDir2(path) {
61707
- mkdirSync13(path, { recursive: true, mode: 448 });
62127
+ mkdirSync14(path, { recursive: true, mode: 448 });
61708
62128
  if (process.platform !== "win32") {
61709
62129
  try {
61710
62130
  chmodSync8(path, 448);
@@ -61750,8 +62170,8 @@ function isIgnorableDirectoryFsyncError3(error) {
61750
62170
 
61751
62171
  // packages/local-runtime/git-adapter/src/index.ts
61752
62172
  import { execFileSync as execFileSync10, spawnSync as spawnSync7 } from "node:child_process";
61753
- import { existsSync as existsSync33, lstatSync as lstatSync16, mkdirSync as mkdirSync14, mkdtempSync as mkdtempSync6, readdirSync as readdirSync15, readFileSync as readFileSync31, rmSync as rmSync16 } from "node:fs";
61754
- import { dirname as dirname14, join as join24, resolve as resolve34 } from "node:path";
62173
+ import { existsSync as existsSync33, lstatSync as lstatSync16, mkdirSync as mkdirSync15, mkdtempSync as mkdtempSync6, readdirSync as readdirSync15, readFileSync as readFileSync32, rmSync as rmSync16 } from "node:fs";
62174
+ import { dirname as dirname14, join as join25, resolve as resolve34 } from "node:path";
61755
62175
  init_src();
61756
62176
  var GIT_CAT_FILE_MAX_BYTES2 = 512 * 1024 * 1024;
61757
62177
  function findRepositoryRoot2(start) {
@@ -61801,7 +62221,7 @@ function listGitVisibleFiles2(root, pathspec) {
61801
62221
  }
61802
62222
  return [...new Set(output.split("\x00").filter(Boolean))].filter((path) => {
61803
62223
  try {
61804
- return lstatSync16(join24(root, path)).isFile();
62224
+ return lstatSync16(join25(root, path)).isFile();
61805
62225
  } catch {
61806
62226
  return false;
61807
62227
  }
@@ -61821,14 +62241,14 @@ function readHeadSha2(root) {
61821
62241
 
61822
62242
  // packages/local-runtime/runtime-state-paths/src/index.ts
61823
62243
  import { readdirSync as readdirSync16, realpathSync as realpathSync12 } from "node:fs";
61824
- import { isAbsolute as isAbsolute10, join as join25, resolve as resolve35 } from "node:path";
62244
+ import { isAbsolute as isAbsolute10, join as join26, resolve as resolve35 } from "node:path";
61825
62245
  var REPOSITORIES_DIR2 = "repositories";
61826
62246
  var WORKTREES_DIR2 = "worktrees";
61827
62247
  function listWorkspaceStateDirs2(stateRoot) {
61828
- return listDirectoryNames2(join25(stateRoot, REPOSITORIES_DIR2)).flatMap((storageRepositoryId) => listDirectoryNames2(join25(stateRoot, REPOSITORIES_DIR2, storageRepositoryId, WORKTREES_DIR2)).map((storageWorkspaceId) => ({
62248
+ return listDirectoryNames2(join26(stateRoot, REPOSITORIES_DIR2)).flatMap((storageRepositoryId) => listDirectoryNames2(join26(stateRoot, REPOSITORIES_DIR2, storageRepositoryId, WORKTREES_DIR2)).map((storageWorkspaceId) => ({
61829
62249
  storageRepositoryId,
61830
62250
  storageWorkspaceId,
61831
- workspaceStateDir: join25(stateRoot, REPOSITORIES_DIR2, storageRepositoryId, WORKTREES_DIR2, storageWorkspaceId)
62251
+ workspaceStateDir: join26(stateRoot, REPOSITORIES_DIR2, storageRepositoryId, WORKTREES_DIR2, storageWorkspaceId)
61832
62252
  })));
61833
62253
  }
61834
62254
  function listDirectoryNames2(path) {
@@ -61844,9 +62264,9 @@ function listDirectoryNames2(path) {
61844
62264
  // packages/local-runtime/codegraph-adapter/src/index.ts
61845
62265
  init_src();
61846
62266
  import { execFileSync as execFileSync11, spawnSync as spawnSync8 } from "node:child_process";
61847
- import { accessSync as accessSync2, closeSync as closeSync13, constants as fsConstants4, existsSync as existsSync34, lstatSync as lstatSync17, mkdirSync as mkdirSync15, mkdtempSync as mkdtempSync7, openSync as openSync13, readFileSync as readFileSync32, readdirSync as readdirSync17, readSync as readSync7, realpathSync as realpathSync13, rmSync as rmSync17, statSync as statSync11, writeFileSync as writeFileSync13 } from "node:fs";
62267
+ import { accessSync as accessSync2, closeSync as closeSync13, constants as fsConstants4, existsSync as existsSync34, lstatSync as lstatSync17, mkdirSync as mkdirSync16, mkdtempSync as mkdtempSync7, openSync as openSync13, readFileSync as readFileSync33, readdirSync as readdirSync17, readSync as readSync7, realpathSync as realpathSync13, rmSync as rmSync17, statSync as statSync11, writeFileSync as writeFileSync14 } from "node:fs";
61848
62268
  import { createRequire as createRequire6 } from "node:module";
61849
- import { basename as basename7, delimiter as delimiter2, dirname as dirname15, isAbsolute as isAbsolute11, join as join26, posix as posix4, relative as relative11, resolve as resolve36 } from "node:path";
62269
+ import { basename as basename7, delimiter as delimiter2, dirname as dirname15, isAbsolute as isAbsolute11, join as join27, posix as posix4, relative as relative11, resolve as resolve36 } from "node:path";
61850
62270
  init_src();
61851
62271
  var REQUIRED_CODEGRAPH_PACKAGE2 = "@colbymchenry/codegraph";
61852
62272
  var REQUIRED_CODEGRAPH_VERSION2 = productVersionManifest().runtime.codeGraph.requiredVersion;
@@ -61883,13 +62303,13 @@ function codeGraphCliInvocation2(binary, cwd, pathValue = process.env.PATH ?? ""
61883
62303
  }
61884
62304
  function resolveExecutable2(binary, cwd, pathValue) {
61885
62305
  if (binary.includes("/") || binary.includes("\\")) {
61886
- const path = isAbsolute11(binary) ? binary : join26(cwd, binary);
62306
+ const path = isAbsolute11(binary) ? binary : join27(cwd, binary);
61887
62307
  return existsSync34(path) ? realpathSync13.native(path) : undefined;
61888
62308
  }
61889
62309
  for (const dir of pathValue.split(delimiter2)) {
61890
62310
  if (!dir)
61891
62311
  continue;
61892
- const path = join26(dir, binary);
62312
+ const path = join27(dir, binary);
61893
62313
  if (isExecutablePath2(path))
61894
62314
  return realpathSync13.native(path);
61895
62315
  }
@@ -61909,7 +62329,7 @@ function isExecutablePath2(path) {
61909
62329
  function resolvePackagedCodeGraphShim2() {
61910
62330
  try {
61911
62331
  const manifestPath = requireFromAdapter3.resolve(`${REQUIRED_CODEGRAPH_PACKAGE2}/package.json`);
61912
- const manifest = JSON.parse(readFileSync32(manifestPath, "utf8"));
62332
+ const manifest = JSON.parse(readFileSync33(manifestPath, "utf8"));
61913
62333
  const relativeBin = manifest.bin?.codegraph;
61914
62334
  if (manifest.version !== REQUIRED_CODEGRAPH_VERSION2 || !relativeBin)
61915
62335
  return;
@@ -61940,7 +62360,32 @@ function readFilePrefix2(path, length) {
61940
62360
  }
61941
62361
  }
61942
62362
  var CODEGRAPH_IMPORT_NODE_OUTPUT_BYTES2 = 4 * 1024;
62363
+ class CodeGraphIndexBuildInProgressError2 extends Error {
62364
+ constructor() {
62365
+ super("CodeGraph index build is in progress");
62366
+ this.name = "CodeGraphIndexBuildInProgressError";
62367
+ }
62368
+ }
62369
+ function codeGraphIndexBuildInProgress2(workspaceRoot) {
62370
+ let raw;
62371
+ try {
62372
+ raw = readFileSync33(join27(workspaceRoot, ".codegraph", "codegraph.lock"), "utf8").trim();
62373
+ } catch {
62374
+ return false;
62375
+ }
62376
+ const pid = Number.parseInt(raw, 10);
62377
+ if (!Number.isSafeInteger(pid) || pid <= 0 || String(pid) !== raw)
62378
+ return false;
62379
+ try {
62380
+ process.kill(pid, 0);
62381
+ return true;
62382
+ } catch (error) {
62383
+ return error.code === "EPERM";
62384
+ }
62385
+ }
61943
62386
  function readProjectionCodeGraphStatus2(invocation, root, timeout, envOverrides) {
62387
+ if (codeGraphIndexBuildInProgress2(root))
62388
+ throw new CodeGraphIndexBuildInProgressError2;
61944
62389
  const output = runProjectionCodeGraph2(invocation, root, ["status", "-j", root], timeout, envOverrides);
61945
62390
  try {
61946
62391
  return JSON.parse(output);
@@ -62011,8 +62456,9 @@ var CODEGRAPH_SNAPSHOT_MAX_BYTES2 = 512 * 1024 * 1024;
62011
62456
  var CODEGRAPH_NO_DOWNLOAD_ENV2 = { CODEGRAPH_NO_DOWNLOAD: "1" };
62012
62457
  function inspectRepositoryCodeFacts2(root, options = {}) {
62013
62458
  const schemaVersion = "archcontext.repository-code-facts/v1";
62014
- let codeGraphVersion;
62459
+ let codeGraphVersion = "";
62015
62460
  let status;
62461
+ let indexBuildInProgress = false;
62016
62462
  const indexPresent = codeGraphIndexAvailable2(root);
62017
62463
  try {
62018
62464
  const invocation = options.binary ? codeGraphCliInvocation2(options.binary, root, "") : packagedCodeGraphCliInvocation2();
@@ -62020,18 +62466,37 @@ function inspectRepositoryCodeFacts2(root, options = {}) {
62020
62466
  if (indexPresent)
62021
62467
  status = readProjectionCodeGraphStatus2(invocation, root, options.timeouts?.statusMs ?? 1e4, CODEGRAPH_NO_DOWNLOAD_ENV2);
62022
62468
  } catch (error) {
62023
- return {
62024
- schemaVersion,
62025
- state: "unavailable",
62026
- requiredVersion: REQUIRED_CODEGRAPH_VERSION2,
62027
- reasonCode: "codegraph-unavailable",
62028
- message: (error instanceof Error ? error.message : String(error)).replace(/\s+/g, " ").trim().slice(0, 400)
62029
- };
62469
+ if (!(error instanceof CodeGraphIndexBuildInProgressError2)) {
62470
+ return {
62471
+ schemaVersion,
62472
+ state: "unavailable",
62473
+ requiredVersion: REQUIRED_CODEGRAPH_VERSION2,
62474
+ reasonCode: "codegraph-unavailable",
62475
+ message: (error instanceof Error ? error.message : String(error)).replace(/\s+/g, " ").trim().slice(0, 400)
62476
+ };
62477
+ }
62478
+ indexBuildInProgress = true;
62030
62479
  }
62031
62480
  const versionIssues = codeGraphVersion === REQUIRED_CODEGRAPH_VERSION2 ? [] : [{ code: "version-mismatch", message: CODE_FACTS_ISSUE_MESSAGES["version-mismatch"] }];
62032
62481
  if (!indexPresent) {
62033
62482
  return { schemaVersion, state: "index-missing", indexPresent: false, requiredVersion: REQUIRED_CODEGRAPH_VERSION2, codeGraphVersion, issues: versionIssues };
62034
62483
  }
62484
+ if (indexBuildInProgress) {
62485
+ return {
62486
+ schemaVersion,
62487
+ state: "not-ready",
62488
+ indexPresent: true,
62489
+ requiredVersion: REQUIRED_CODEGRAPH_VERSION2,
62490
+ codeGraphVersion,
62491
+ indexBuiltWithVersion: null,
62492
+ extractionVersion: { builtWith: null, current: null },
62493
+ indexState: null,
62494
+ reindexRecommended: null,
62495
+ pendingRefs: null,
62496
+ pendingChanges: null,
62497
+ issues: [...versionIssues, { code: "index-incomplete", message: CODE_FACTS_ISSUE_MESSAGES["index-incomplete"] }]
62498
+ };
62499
+ }
62035
62500
  if (typeof status !== "object" || status === null || Array.isArray(status)) {
62036
62501
  return {
62037
62502
  schemaVersion,
@@ -62065,7 +62530,7 @@ function inspectRepositoryCodeFacts2(root, options = {}) {
62065
62530
  };
62066
62531
  }
62067
62532
  function codeGraphIndexAvailable2(workspaceRoot) {
62068
- return existsSync34(join26(workspaceRoot, ".codegraph"));
62533
+ return existsSync34(join27(workspaceRoot, ".codegraph"));
62069
62534
  }
62070
62535
  var NON_DECLARATION_KINDS2 = new Set(["file", "import", "export", "parameter"]);
62071
62536
  var RUNTIME_BUILTIN_CALL_NAMES2 = new Set([
@@ -63146,6 +63611,7 @@ var CLI_COMMAND_FLAGS = {
63146
63611
  repo: { value: ["--name", "--repository-id", "--root"], boolean: [] },
63147
63612
  resolve: { value: ["--path", "--paths-from"], boolean: [] },
63148
63613
  impact: { value: ["--base", "--head", "--depth", "--paths-from"], boolean: [] },
63614
+ history: { value: ["--ref", "--format", "--offset", "--limit"], boolean: [] },
63149
63615
  review: { value: ["--head-sha", "--posture", "--task", "--task-session-id"], boolean: [] },
63150
63616
  state: { value: ["--expected-target-fingerprint", "--expected-worktree-digest"], boolean: ["--accept-external-projection", "--dry-run", "--from-git", "--write"] },
63151
63617
  status: { value: [], boolean: [] },
@@ -63413,6 +63879,8 @@ function runCapabilitiesCommand() {
63413
63879
  async function runCliUnchecked(command = "help", args = [], cwd, deps = {}) {
63414
63880
  if (command === "impact")
63415
63881
  return runRefImpactCommand(args, cwd);
63882
+ if (command === "history")
63883
+ return runArchitectureHistoryCommand(args, cwd);
63416
63884
  if (command === "export" && args[0] === "native")
63417
63885
  return runNativeContextCommand(args.slice(1), cwd);
63418
63886
  const preflight = preflightCliArguments(command, args);
@@ -63727,7 +64195,7 @@ async function runCliUnchecked(command = "help", args = [], cwd, deps = {}) {
63727
64195
  ok: true,
63728
64196
  requestId: "help",
63729
64197
  data: {
63730
- commands: ["capabilities", "projection", "init", "sync", "validate", "context", "status", "daemon", "state", "repo", "landscape", "ledger", "book", "recommendations", "refactor", "explore", "prepare", "practices", "checkpoint", "hook", "hooks", "investigate", "agents", "jobs", "audit", "plan", "apply", "hash", "review", "complete", "github", "manifest", "config", "mcp", "install", "uninstall", "doctor", "update", "paths", "privacy-audit", "export", "import", "resolve", "impact", "tunnel", "flows", "deps", "constraints", "debt"],
64198
+ commands: ["capabilities", "projection", "init", "sync", "validate", "context", "status", "daemon", "state", "repo", "landscape", "ledger", "book", "recommendations", "refactor", "explore", "prepare", "practices", "checkpoint", "hook", "hooks", "investigate", "agents", "jobs", "audit", "plan", "apply", "hash", "review", "complete", "github", "manifest", "config", "mcp", "install", "uninstall", "doctor", "update", "paths", "privacy-audit", "export", "import", "resolve", "impact", "history", "tunnel", "flows", "deps", "constraints", "debt"],
63731
64199
  examples: CLI_HELP_EXAMPLES
63732
64200
  }
63733
64201
  };
@@ -65121,7 +65589,7 @@ function auditGithubIssuesEnabled(cwd) {
65121
65589
  return false;
65122
65590
  let raw;
65123
65591
  try {
65124
- raw = readFileSync33(manifestPath, "utf8");
65592
+ raw = readFileSync34(manifestPath, "utf8");
65125
65593
  } catch {
65126
65594
  return false;
65127
65595
  }
@@ -65694,7 +66162,7 @@ async function digestReviewChallenge(challenge) {
65694
66162
  return reviewChallengeV2Digest(challenge);
65695
66163
  }
65696
66164
  function defaultGithubConnectionPath(cwd) {
65697
- return join27(dirname16(defaultDaemonConnectionPath(cwd)), "github-connection.json");
66165
+ return join28(dirname16(defaultDaemonConnectionPath(cwd)), "github-connection.json");
65698
66166
  }
65699
66167
  function sanitizeGithubConnection(record, connectionPath) {
65700
66168
  return {
@@ -65718,7 +66186,7 @@ async function readReviewChallengeV2Arg(args, cwd, commandName = "github verify-
65718
66186
  if (!inline && !challengePath)
65719
66187
  return { ok: false, message: `${commandName} requires --challenge-json or --challenge-path` };
65720
66188
  try {
65721
- const raw = inline ?? readFileSync33(resolve37(cwd, challengePath), "utf8");
66189
+ const raw = inline ?? readFileSync34(resolve37(cwd, challengePath), "utf8");
65722
66190
  const parsed = JSON.parse(raw);
65723
66191
  const attestation = await Promise.resolve().then(() => (init_src6(), {}));
65724
66192
  const assertReviewChallengeV2 = assertReviewChallengeV22;
@@ -66032,7 +66500,7 @@ async function doctorReport(cwd, args = []) {
66032
66500
  function doctorManifest(root) {
66033
66501
  const path = ".archcontext/manifest.yaml";
66034
66502
  try {
66035
- return { warnings: manifestDecisionDiagnostics2([{ path, body: readFileSync33(resolve37(root, path), "utf8") }]) };
66503
+ return { warnings: manifestDecisionDiagnostics2([{ path, body: readFileSync34(resolve37(root, path), "utf8") }]) };
66036
66504
  } catch {
66037
66505
  return { warnings: [] };
66038
66506
  }
@@ -66230,8 +66698,8 @@ function runtimePathsReport(cwd) {
66230
66698
  ...paths,
66231
66699
  legacyLocalStore: inspectLegacyLocalStoreMigration(cwd),
66232
66700
  runtimeRepositoryId: repositoryFingerprint2(paths.repositoryRoot),
66233
- repositoryTruthDir: join27(paths.repositoryRoot, ".archcontext"),
66234
- codeGraphIndexDir: join27(paths.repositoryRoot, ".codegraph"),
66701
+ repositoryTruthDir: join28(paths.repositoryRoot, ".archcontext"),
66702
+ codeGraphIndexDir: join28(paths.repositoryRoot, ".codegraph"),
66235
66703
  npmGlobalInstallState: "forbidden",
66236
66704
  overrides: {
66237
66705
  stateRootEnv: "ARCHCONTEXT_STATE_DIR",
@@ -66520,8 +66988,8 @@ async function startBackgroundDaemon(args, cwd) {
66520
66988
  const recovery = discovered.recovery;
66521
66989
  const connectionPath = defaultDaemonConnectionPath(cwd);
66522
66990
  const controlDir = dirname16(connectionPath);
66523
- const logPath = join27(controlDir, "archctxd.log");
66524
- mkdirSync16(controlDir, { recursive: true });
66991
+ const logPath = join28(controlDir, "archctxd.log");
66992
+ mkdirSync17(controlDir, { recursive: true });
66525
66993
  const logFd = openSync14(logPath, "a", 384);
66526
66994
  try {
66527
66995
  let childExit;
@@ -66845,7 +67313,7 @@ function sleep2(ms) {
66845
67313
  }
66846
67314
  function readFileTail(path, maxBytes = 4096) {
66847
67315
  try {
66848
- const content = readFileSync33(path, "utf8");
67316
+ const content = readFileSync34(path, "utf8");
66849
67317
  return content.slice(Math.max(0, content.length - maxBytes)).replace(/\s+/g, " ").trim();
66850
67318
  } catch {
66851
67319
  return "<unavailable>";
@@ -66947,7 +67415,7 @@ function cliArgumentFailure(requestId, message) {
66947
67415
  };
66948
67416
  }
66949
67417
  function loadResolveModel(cwd) {
66950
- if (!existsSync35(join27(cwd, ".archcontext/manifest.yaml"))) {
67418
+ if (!existsSync35(join28(cwd, ".archcontext/manifest.yaml"))) {
66951
67419
  throw new NativeContextError("native-context-model-missing", { path: ".archcontext/manifest.yaml" });
66952
67420
  }
66953
67421
  let model;
@@ -67003,7 +67471,7 @@ async function readResolvePathsFrom(args, cwd, deps) {
67003
67471
  return { problem: "resolve --paths-from requires a file path or - for stdin" };
67004
67472
  let content;
67005
67473
  try {
67006
- content = source === "-" ? await (deps.readStdin ? deps.readStdin() : readFileSync33(0, "utf8")) : readFileSync33(resolve37(cwd, source), "utf8");
67474
+ content = source === "-" ? await (deps.readStdin ? deps.readStdin() : readFileSync34(0, "utf8")) : readFileSync34(resolve37(cwd, source), "utf8");
67007
67475
  } catch (error) {
67008
67476
  return { problem: `resolve --paths-from ${source} is not readable: ${error instanceof Error ? error.message : String(error)}` };
67009
67477
  }
@@ -67091,7 +67559,7 @@ function readRepositoryInputFile(cwd, flag, file) {
67091
67559
  const absolute = assertPathHasNoSymlinkSegments2(cwd, file);
67092
67560
  if (!statSync12(absolute).isFile())
67093
67561
  return { problem: `plan ${flag} ${file} is not a regular file` };
67094
- return { content: readFileSync33(absolute, "utf8") };
67562
+ return { content: readFileSync34(absolute, "utf8") };
67095
67563
  } catch (error) {
67096
67564
  return { problem: `plan ${flag} ${file} is not readable: ${error instanceof Error ? error.message : String(error)}` };
67097
67565
  }
@@ -67112,7 +67580,7 @@ function runHashCommand(args, cwd) {
67112
67580
  if (!existsSync35(absolute) || !statSync12(absolute).isFile()) {
67113
67581
  return errorEnvelope("hash", "AC_SCHEMA_INVALID", `hash --path is not an existing file: ${path}`);
67114
67582
  }
67115
- return okEnvelope("hash", { path, hash: digestJson({ body: readFileSync33(absolute, "utf8") }) });
67583
+ return okEnvelope("hash", { path, hash: digestJson({ body: readFileSync34(absolute, "utf8") }) });
67116
67584
  }
67117
67585
  async function readCliPlanOperations(args, cwd, deps) {
67118
67586
  if (args.includes("--operations-file")) {
@@ -67122,7 +67590,7 @@ async function readCliPlanOperations(args, cwd, deps) {
67122
67590
  const file = readFlag(args, "--operations-file");
67123
67591
  if (!file)
67124
67592
  return "plan --operations-file requires a path";
67125
- const read = file === "-" ? { content: await (deps.readStdin ? deps.readStdin() : readFileSync33(0, "utf8")) } : readRepositoryInputFile(cwd, "--operations-file", file);
67593
+ const read = file === "-" ? { content: await (deps.readStdin ? deps.readStdin() : readFileSync34(0, "utf8")) } : readRepositoryInputFile(cwd, "--operations-file", file);
67126
67594
  if ("problem" in read)
67127
67595
  return read.problem;
67128
67596
  let parsed;
@@ -67184,7 +67652,7 @@ async function readCliPlanBody(args, cwd, deps) {
67184
67652
  return { problem: "plan --body requires a value (use - to read stdin)" };
67185
67653
  if (inline !== "-")
67186
67654
  return inline;
67187
- return deps.readStdin ? deps.readStdin() : readFileSync33(0, "utf8");
67655
+ return deps.readStdin ? deps.readStdin() : readFileSync34(0, "utf8");
67188
67656
  }
67189
67657
  function readFlag(args, flag) {
67190
67658
  const index = args.indexOf(flag);