instar 1.3.471 → 1.3.473
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/dist/config/ConfigDefaults.d.ts.map +1 -1
- package/dist/config/ConfigDefaults.js +20 -0
- package/dist/config/ConfigDefaults.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +9 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/SessionManager.d.ts +7 -2
- package/dist/core/SessionManager.d.ts.map +1 -1
- package/dist/core/SessionManager.js +33 -10
- package/dist/core/SessionManager.js.map +1 -1
- package/dist/core/StandardEnforcementExtractor.d.ts +44 -0
- package/dist/core/StandardEnforcementExtractor.d.ts.map +1 -0
- package/dist/core/StandardEnforcementExtractor.js +98 -0
- package/dist/core/StandardEnforcementExtractor.js.map +1 -0
- package/dist/core/StandardsEnforcementAuditor.d.ts +78 -0
- package/dist/core/StandardsEnforcementAuditor.d.ts.map +1 -0
- package/dist/core/StandardsEnforcementAuditor.js +295 -0
- package/dist/core/StandardsEnforcementAuditor.js.map +1 -0
- package/dist/core/StandardsRegistryParser.d.ts +7 -0
- package/dist/core/StandardsRegistryParser.d.ts.map +1 -1
- package/dist/core/StandardsRegistryParser.js +7 -0
- package/dist/core/StandardsRegistryParser.js.map +1 -1
- package/dist/core/componentCategories.d.ts.map +1 -1
- package/dist/core/componentCategories.js +6 -0
- package/dist/core/componentCategories.js.map +1 -1
- package/dist/server/CapabilityIndex.d.ts.map +1 -1
- package/dist/server/CapabilityIndex.js +3 -1
- package/dist/server/CapabilityIndex.js.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +80 -0
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/scripts/standards-coverage.mjs +279 -0
- package/src/data/builtin-manifest.json +64 -64
- package/upgrades/1.3.473.md +84 -0
- package/upgrades/side-effects/cartographer-conformance-audit.md +109 -0
- package/upgrades/side-effects/pin-interactive-session-lane.md +47 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StandardEnforcementExtractor — pull the structural enforcement references a
|
|
3
|
+
* constitutional standard NAMES in its prose (cartographer-conformance-audit spec #3,
|
|
4
|
+
* Part A).
|
|
5
|
+
*
|
|
6
|
+
* The constitution declares its own enforcement: nearly every article carries an
|
|
7
|
+
* `**In practice.**` / `**Applied through.**` line naming the mechanism that enforces
|
|
8
|
+
* it — a test ratchet (`tests/unit/no-silent-llm-fallback.test.ts`), a gate marker
|
|
9
|
+
* (`B16_UNVERIFIED_WALL` in `MessagingToneGate`), a route (`POST /spec/conformance-check`),
|
|
10
|
+
* a lint (`scripts/lint-*.js`), or a spec (`docs/specs/*.md`). This module extracts
|
|
11
|
+
* those references so the auditor can VERIFY each one actually resolves on disk.
|
|
12
|
+
*
|
|
13
|
+
* PURE — no I/O. It only recognizes enforcement-shaped tokens; verification (does the
|
|
14
|
+
* file/route/symbol actually exist?) is the auditor's job. Extraction is conservative:
|
|
15
|
+
* a reference is only pulled if it matches a known enforcement shape. Unmatched prose
|
|
16
|
+
* contributes nothing (→ the standard reads as having no NAMED guard, itself a signal).
|
|
17
|
+
*
|
|
18
|
+
* Provenance refs (`#NNN` PR/issue numbers) are deliberately NOT treated as enforcement
|
|
19
|
+
* — they record where a guard was built, not a live guard.
|
|
20
|
+
*/
|
|
21
|
+
// ── Recognizers (the prototype regexes, broadened) ──────────────────────────
|
|
22
|
+
/**
|
|
23
|
+
* Backtick-fenced file paths with a known source/test/script/spec/config extension.
|
|
24
|
+
* Matches `scripts/lint-foo.js`, `tests/unit/x.test.ts`, `docs/specs/y.md`,
|
|
25
|
+
* `src/core/Z.ts`, `.instar/config.json`, a `.sh` hook. The leading char class
|
|
26
|
+
* tolerates a leading `.` (e.g. `.github/...`).
|
|
27
|
+
*/
|
|
28
|
+
const FILE_RE = /`([a-zA-Z0-9_./-]+\.(?:ts|js|mjs|cjs|md|json|sh))`/g;
|
|
29
|
+
/** Backtick-fenced `METHOD /route` tokens (the route table shape). */
|
|
30
|
+
const ROUTE_RE = /`(GET|POST|PUT|DELETE|PATCH)\s+(\/[a-zA-Z0-9/_:-]+)`/g;
|
|
31
|
+
/**
|
|
32
|
+
* CONSTANT_CASE gate markers (e.g. `B16_UNVERIFIED_WALL`, `B17_FALSE_BLOCKER`).
|
|
33
|
+
* Requires at least one underscore so it doesn't sweep up ALL-CAPS prose words
|
|
34
|
+
* (`RLHF`, `CI`, `LLM`), while still catching the real gate-marker shape. Matched
|
|
35
|
+
* with OR without surrounding backticks (the registry uses both).
|
|
36
|
+
*/
|
|
37
|
+
const MARKER_RE = /\b([A-Z][A-Z0-9]{2,}_[A-Z0-9_]{2,})\b/g;
|
|
38
|
+
/**
|
|
39
|
+
* Named class / symbol guards the registry cites in backticks but WITHOUT a file
|
|
40
|
+
* extension or method — `MessagingToneGate`, `IntelligenceRouter.failureSwap`,
|
|
41
|
+
* `FencedLease`, `UserManager`. PascalCase (optionally `.member`), ≥2 segments of
|
|
42
|
+
* casing so it isn't a bare lowercase word. Treated as a `marker` (a symbol the
|
|
43
|
+
* auditor greps src/** for).
|
|
44
|
+
*/
|
|
45
|
+
const SYMBOL_RE = /`([A-Z][a-zA-Z0-9]+(?:\.[a-zA-Z][a-zA-Z0-9]*)?)`/g;
|
|
46
|
+
/** Prefixes that count as a real on-disk enforcement artifact (vs. arbitrary prose). */
|
|
47
|
+
const ENFORCEMENT_PATH_PREFIXES = ['tests/', 'scripts/', 'src/', 'docs/', '.github/', '.instar/', '.husky/'];
|
|
48
|
+
/** True if a path looks like an enforcement artifact (a guard we can verify on disk). */
|
|
49
|
+
function isEnforcementPath(p) {
|
|
50
|
+
return ENFORCEMENT_PATH_PREFIXES.some((pre) => p.startsWith(pre));
|
|
51
|
+
}
|
|
52
|
+
function dedupe(xs) {
|
|
53
|
+
return [...new Set(xs)];
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Extract enforcement references from a single article. Scans both `inPractice` and
|
|
57
|
+
* `appliedThrough` (the two prose lines that name enforcement). Pure + deterministic:
|
|
58
|
+
* same article in → same refs out, in stable (sorted) order.
|
|
59
|
+
*/
|
|
60
|
+
export function extractEnforcementRefs(article) {
|
|
61
|
+
const text = `${article.inPractice ?? ''}\n${article.appliedThrough ?? ''}`;
|
|
62
|
+
const files = [];
|
|
63
|
+
for (const m of text.matchAll(FILE_RE)) {
|
|
64
|
+
const p = m[1];
|
|
65
|
+
if (isEnforcementPath(p))
|
|
66
|
+
files.push(p);
|
|
67
|
+
}
|
|
68
|
+
const routes = [];
|
|
69
|
+
for (const m of text.matchAll(ROUTE_RE)) {
|
|
70
|
+
routes.push(`${m[1].toUpperCase()} ${m[2]}`);
|
|
71
|
+
}
|
|
72
|
+
const markers = [];
|
|
73
|
+
for (const m of text.matchAll(MARKER_RE))
|
|
74
|
+
markers.push(m[1]);
|
|
75
|
+
for (const m of text.matchAll(SYMBOL_RE)) {
|
|
76
|
+
// A `.member` symbol (IntelligenceRouter.failureSwap) → grep the base class name.
|
|
77
|
+
const base = m[1].split('.')[0];
|
|
78
|
+
markers.push(base);
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
files: dedupe(files).sort(),
|
|
82
|
+
routes: dedupe(routes).sort(),
|
|
83
|
+
markers: dedupe(markers).sort(),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/** Flatten an ExtractedRefs into a typed list (auditor convenience). */
|
|
87
|
+
export function flattenRefs(refs) {
|
|
88
|
+
return [
|
|
89
|
+
...refs.files.map((ref) => ({ ref, kind: 'file' })),
|
|
90
|
+
...refs.routes.map((ref) => ({ ref, kind: 'route' })),
|
|
91
|
+
...refs.markers.map((ref) => ({ ref, kind: 'marker' })),
|
|
92
|
+
];
|
|
93
|
+
}
|
|
94
|
+
/** True if the article names ANY enforcement reference at all. */
|
|
95
|
+
export function hasAnyRef(refs) {
|
|
96
|
+
return refs.files.length > 0 || refs.routes.length > 0 || refs.markers.length > 0;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=StandardEnforcementExtractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StandardEnforcementExtractor.js","sourceRoot":"","sources":["../../src/core/StandardEnforcementExtractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StandardsEnforcementAuditor — the registry-wide enforcement-coverage audit
|
|
3
|
+
* (cartographer-conformance-audit spec #3, Parts B + C).
|
|
4
|
+
*
|
|
5
|
+
* For each constitutional standard in `docs/STANDARDS-REGISTRY.md`, it:
|
|
6
|
+
* 1. parses the article (StandardsRegistryParser),
|
|
7
|
+
* 2. extracts the enforcement references its prose NAMES (StandardEnforcementExtractor),
|
|
8
|
+
* 3. VERIFIES each reference resolves against the live repo — a file via
|
|
9
|
+
* `fs.existsSync`, a route via a regex scan of `src/server/routes.ts`, a
|
|
10
|
+
* symbol/marker via a bounded grep of `src/**`,
|
|
11
|
+
* 4. classifies the standard by its STRONGEST verified guard
|
|
12
|
+
* (`ratchet` > `gate` > `lint` > `spec-only` > `documented-only` gap),
|
|
13
|
+
* 5. records DANGLING refs — a guard a standard names that no longer exists on
|
|
14
|
+
* disk (a broken guarantee, the loudest signal).
|
|
15
|
+
*
|
|
16
|
+
* Deterministic + idempotent: two runs over an unchanged registry+repo produce a
|
|
17
|
+
* byte-identical report (refs are sorted; classifiedAt is omitted from the hashable
|
|
18
|
+
* core). A content-hash short-circuit (registry hash + a cheap repo-structure signal)
|
|
19
|
+
* skips recompute when nothing changed — the `docs-coverage.mjs` pattern.
|
|
20
|
+
*
|
|
21
|
+
* Observe-only, non-gating: it NEVER blocks anything. It produces a read-only
|
|
22
|
+
* coverage report. "Signal vs. Authority" — a gap is a signal to build a guard.
|
|
23
|
+
*/
|
|
24
|
+
export type EnforcementKind = 'ratchet' | 'gate' | 'lint' | 'spec-only' | 'documented-only';
|
|
25
|
+
export interface VerifiedGuard {
|
|
26
|
+
/** The reference token (path / `METHOD /route` / symbol). */
|
|
27
|
+
ref: string;
|
|
28
|
+
/** Recognizer kind from extraction. */
|
|
29
|
+
kind: 'file' | 'route' | 'marker';
|
|
30
|
+
/** Did the reference resolve on disk / in the route table / in src? */
|
|
31
|
+
verified: boolean;
|
|
32
|
+
/** The classification weight this guard contributes (only when verified). */
|
|
33
|
+
guardKind?: Exclude<EnforcementKind, 'documented-only'>;
|
|
34
|
+
}
|
|
35
|
+
export interface StandardCoverage {
|
|
36
|
+
standard: string;
|
|
37
|
+
family: string;
|
|
38
|
+
enforcementKind: EnforcementKind;
|
|
39
|
+
guards: VerifiedGuard[];
|
|
40
|
+
/** Refs named in prose but NOT found on disk — broken guarantees (loud signal). */
|
|
41
|
+
danglingRefs: string[];
|
|
42
|
+
classifiedAt: string;
|
|
43
|
+
}
|
|
44
|
+
export interface CoverageSummary {
|
|
45
|
+
total: number;
|
|
46
|
+
byKind: Record<EnforcementKind, number>;
|
|
47
|
+
/** (ratchet + gate + lint) / total — the fraction of standards with a verified structural guard. */
|
|
48
|
+
enforcedRatio: number;
|
|
49
|
+
/** Names of `documented-only` standards (the gaps). */
|
|
50
|
+
gaps: string[];
|
|
51
|
+
/** Total dangling refs across all standards. */
|
|
52
|
+
danglingCount: number;
|
|
53
|
+
}
|
|
54
|
+
export interface CoverageReport {
|
|
55
|
+
generatedAt: string;
|
|
56
|
+
/** Hash of the inputs (registry content + repo-structure signal) — drives the short-circuit. */
|
|
57
|
+
inputHash: string;
|
|
58
|
+
standards: StandardCoverage[];
|
|
59
|
+
summary: CoverageSummary;
|
|
60
|
+
}
|
|
61
|
+
export interface AuditorOptions {
|
|
62
|
+
/** Path to docs/STANDARDS-REGISTRY.md. */
|
|
63
|
+
registryPath: string;
|
|
64
|
+
/** Repo root — all refs resolve relative to this. */
|
|
65
|
+
projectDir: string;
|
|
66
|
+
}
|
|
67
|
+
/** Compute the input hash that drives the recompute short-circuit. */
|
|
68
|
+
export declare function computeInputHash(opts: AuditorOptions): string;
|
|
69
|
+
/**
|
|
70
|
+
* Compute the full enforcement-coverage report. Deterministic: the per-standard order
|
|
71
|
+
* follows the registry parse order; refs within a standard are sorted; the only
|
|
72
|
+
* non-deterministic field is `generatedAt`/`classifiedAt` (a timestamp, excluded from
|
|
73
|
+
* `inputHash`). Pass `prior` to short-circuit when the input hash is unchanged.
|
|
74
|
+
*/
|
|
75
|
+
export declare function computeCoverage(opts: AuditorOptions, prior?: CoverageReport | null): CoverageReport;
|
|
76
|
+
/** A stable, timestamp-free view used to assert determinism (two runs → identical). */
|
|
77
|
+
export declare function stableView(report: CoverageReport): unknown;
|
|
78
|
+
//# sourceMappingURL=StandardsEnforcementAuditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StandardsEnforcementAuditor.d.ts","sourceRoot":"","sources":["../../src/core/StandardsEnforcementAuditor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAQH,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,WAAW,GAAG,iBAAiB,CAAC;AAE5F,MAAM,WAAW,aAAa;IAC5B,6DAA6D;IAC7D,GAAG,EAAE,MAAM,CAAC;IACZ,uCAAuC;IACvC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IAClC,uEAAuE;IACvE,QAAQ,EAAE,OAAO,CAAC;IAClB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,OAAO,CAAC,eAAe,EAAE,iBAAiB,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,eAAe,CAAC;IACjC,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,mFAAmF;IACnF,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;IACxC,oGAAoG;IACpG,aAAa,EAAE,MAAM,CAAC;IACtB,uDAAuD;IACvD,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,gDAAgD;IAChD,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,gGAAgG;IAChG,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,OAAO,EAAE,eAAe,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,0CAA0C;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,UAAU,EAAE,MAAM,CAAC;CACpB;AAiKD,sEAAsE;AACtE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAK7D;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,cAAc,EACpB,KAAK,CAAC,EAAE,cAAc,GAAG,IAAI,GAC5B,cAAc,CA0ChB;AAED,uFAAuF;AACvF,wBAAgB,UAAU,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAY1D"}
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StandardsEnforcementAuditor — the registry-wide enforcement-coverage audit
|
|
3
|
+
* (cartographer-conformance-audit spec #3, Parts B + C).
|
|
4
|
+
*
|
|
5
|
+
* For each constitutional standard in `docs/STANDARDS-REGISTRY.md`, it:
|
|
6
|
+
* 1. parses the article (StandardsRegistryParser),
|
|
7
|
+
* 2. extracts the enforcement references its prose NAMES (StandardEnforcementExtractor),
|
|
8
|
+
* 3. VERIFIES each reference resolves against the live repo — a file via
|
|
9
|
+
* `fs.existsSync`, a route via a regex scan of `src/server/routes.ts`, a
|
|
10
|
+
* symbol/marker via a bounded grep of `src/**`,
|
|
11
|
+
* 4. classifies the standard by its STRONGEST verified guard
|
|
12
|
+
* (`ratchet` > `gate` > `lint` > `spec-only` > `documented-only` gap),
|
|
13
|
+
* 5. records DANGLING refs — a guard a standard names that no longer exists on
|
|
14
|
+
* disk (a broken guarantee, the loudest signal).
|
|
15
|
+
*
|
|
16
|
+
* Deterministic + idempotent: two runs over an unchanged registry+repo produce a
|
|
17
|
+
* byte-identical report (refs are sorted; classifiedAt is omitted from the hashable
|
|
18
|
+
* core). A content-hash short-circuit (registry hash + a cheap repo-structure signal)
|
|
19
|
+
* skips recompute when nothing changed — the `docs-coverage.mjs` pattern.
|
|
20
|
+
*
|
|
21
|
+
* Observe-only, non-gating: it NEVER blocks anything. It produces a read-only
|
|
22
|
+
* coverage report. "Signal vs. Authority" — a gap is a signal to build a guard.
|
|
23
|
+
*/
|
|
24
|
+
import fs from 'node:fs';
|
|
25
|
+
import path from 'node:path';
|
|
26
|
+
import crypto from 'node:crypto';
|
|
27
|
+
import { loadStandardsRegistry } from './StandardsRegistryParser.js';
|
|
28
|
+
import { extractEnforcementRefs, flattenRefs } from './StandardEnforcementExtractor.js';
|
|
29
|
+
const KIND_RANK = {
|
|
30
|
+
ratchet: 4, gate: 3, lint: 2, 'spec-only': 1,
|
|
31
|
+
};
|
|
32
|
+
/** Classify a VERIFIED file ref into its guard weight. */
|
|
33
|
+
function classifyFileGuard(ref) {
|
|
34
|
+
const base = ref.split('/').pop() ?? ref;
|
|
35
|
+
// Ratchet: a CI test that fails on regression — `*.test.ts`, a `no-*` guard, a
|
|
36
|
+
// `*-coverage` script.
|
|
37
|
+
if (/\.test\.(ts|js|mjs)$/.test(base) || base.startsWith('no-') || /-coverage\.(mjs|js)$/.test(base)) {
|
|
38
|
+
return 'ratchet';
|
|
39
|
+
}
|
|
40
|
+
// Lint: a `scripts/lint-*` static check.
|
|
41
|
+
if (ref.startsWith('scripts/') && base.startsWith('lint-'))
|
|
42
|
+
return 'lint';
|
|
43
|
+
// Gate: a precommit/husky hook, or a server/source guard file (a hook script, a
|
|
44
|
+
// gate module under src/). `.husky/*` and `scripts/*-precommit*` count as gates.
|
|
45
|
+
if (ref.startsWith('.husky/') || /precommit/i.test(base))
|
|
46
|
+
return 'gate';
|
|
47
|
+
if (ref.startsWith('scripts/'))
|
|
48
|
+
return 'lint'; // a generic script guard → lint-strength
|
|
49
|
+
// A docs/specs/* reference designed-but-maybe-unenforced → spec-only.
|
|
50
|
+
if (ref.startsWith('docs/specs/'))
|
|
51
|
+
return 'spec-only';
|
|
52
|
+
if (ref.startsWith('docs/'))
|
|
53
|
+
return 'spec-only';
|
|
54
|
+
// A src/** guard file (a gate/marker module) → gate-strength.
|
|
55
|
+
if (ref.startsWith('src/'))
|
|
56
|
+
return 'gate';
|
|
57
|
+
return 'spec-only';
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Build a regex-scannable route token set from the server route files. Routes are
|
|
61
|
+
* registered across `routes.ts` AND several sibling `*Routes.ts` modules
|
|
62
|
+
* (specReviewRoutes, machineRoutes, usherRoutes, …); scanning only routes.ts would
|
|
63
|
+
* report a route registered elsewhere as a (false) dangling ref. We scan every
|
|
64
|
+
* `*.ts` under `src/server/` for the `router.<verb>('…')` pattern.
|
|
65
|
+
*/
|
|
66
|
+
function loadRouteTable(projectDir) {
|
|
67
|
+
const serverDir = path.join(projectDir, 'src', 'server');
|
|
68
|
+
const out = new Set();
|
|
69
|
+
let files;
|
|
70
|
+
try {
|
|
71
|
+
files = fs.readdirSync(serverDir).filter((f) => f.endsWith('.ts') && !f.endsWith('.test.ts'));
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return out;
|
|
75
|
+
}
|
|
76
|
+
const re = /router\.(get|post|put|delete|patch)\s*\(\s*['"`]([^'"`]+)['"`]/g;
|
|
77
|
+
for (const f of files) {
|
|
78
|
+
let content;
|
|
79
|
+
try {
|
|
80
|
+
content = fs.readFileSync(path.join(serverDir, f), 'utf-8');
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
for (const m of content.matchAll(re))
|
|
86
|
+
out.add(`${m[1].toUpperCase()} ${m[2]}`);
|
|
87
|
+
}
|
|
88
|
+
return out;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Bounded grep for a symbol across src/** — returns the set of all symbols found so a
|
|
92
|
+
* batch of marker refs is resolved in ONE walk (not one walk per ref). Skips test
|
|
93
|
+
* files and node_modules; caps total bytes read for safety.
|
|
94
|
+
*/
|
|
95
|
+
function buildSymbolIndex(projectDir, wanted) {
|
|
96
|
+
const found = new Set();
|
|
97
|
+
if (wanted.size === 0)
|
|
98
|
+
return found;
|
|
99
|
+
const srcDir = path.join(projectDir, 'src');
|
|
100
|
+
let exists = false;
|
|
101
|
+
try {
|
|
102
|
+
exists = fs.statSync(srcDir).isDirectory();
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
exists = false;
|
|
106
|
+
}
|
|
107
|
+
if (!exists)
|
|
108
|
+
return found;
|
|
109
|
+
const MAX_TOTAL_BYTES = 64 * 1024 * 1024;
|
|
110
|
+
let readBytes = 0;
|
|
111
|
+
// Pre-compile a single alternation regex over the wanted symbols (word-bounded).
|
|
112
|
+
const escaped = [...wanted].map((s) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
|
|
113
|
+
const re = new RegExp(`\\b(${escaped.join('|')})\\b`, 'g');
|
|
114
|
+
const walk = (dir) => {
|
|
115
|
+
let entries;
|
|
116
|
+
try {
|
|
117
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
for (const e of entries) {
|
|
123
|
+
if (found.size === wanted.size)
|
|
124
|
+
return; // all resolved — stop early
|
|
125
|
+
const full = path.join(dir, e.name);
|
|
126
|
+
if (e.isDirectory()) {
|
|
127
|
+
if (e.name === 'node_modules' || e.name.startsWith('.'))
|
|
128
|
+
continue;
|
|
129
|
+
walk(full);
|
|
130
|
+
}
|
|
131
|
+
else if (/\.(ts|js|mjs|cjs)$/.test(e.name)) {
|
|
132
|
+
if (readBytes > MAX_TOTAL_BYTES)
|
|
133
|
+
return;
|
|
134
|
+
let content;
|
|
135
|
+
try {
|
|
136
|
+
content = fs.readFileSync(full, 'utf-8');
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
readBytes += content.length;
|
|
142
|
+
for (const m of content.matchAll(re))
|
|
143
|
+
found.add(m[1]);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
walk(srcDir);
|
|
148
|
+
return found;
|
|
149
|
+
}
|
|
150
|
+
/** Verify each ref of an article against the prepared lookups. */
|
|
151
|
+
function verifyRefs(refs, projectDir, routeTable, symbolIndex) {
|
|
152
|
+
return refs.map((r) => {
|
|
153
|
+
let verified = false;
|
|
154
|
+
if (r.kind === 'file') {
|
|
155
|
+
// An fs.existsSync that throws (a malformed path, an EACCES) means the referenced
|
|
156
|
+
// guard is NOT resolvable on disk — which IS the correct, complete answer here
|
|
157
|
+
// (verified=false → the standard reads as having a dangling ref, the loud signal
|
|
158
|
+
// this auditor exists to surface). Not a degradation.
|
|
159
|
+
try {
|
|
160
|
+
verified = fs.existsSync(path.join(projectDir, r.ref));
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
verified = false; /* @silent-fallback-ok — unresolvable path = a real dangling-ref finding, not a degraded result */
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
else if (r.kind === 'route') {
|
|
167
|
+
verified = routeTable.has(r.ref);
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
verified = symbolIndex.has(r.ref);
|
|
171
|
+
}
|
|
172
|
+
const g = { ref: r.ref, kind: r.kind, verified };
|
|
173
|
+
if (verified) {
|
|
174
|
+
g.guardKind = r.kind === 'file' ? classifyFileGuard(r.ref) : 'gate'; // route/marker → gate-strength
|
|
175
|
+
}
|
|
176
|
+
return g;
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
/** Classify a standard by its strongest VERIFIED guard. */
|
|
180
|
+
function classifyStandard(guards) {
|
|
181
|
+
let best = null;
|
|
182
|
+
for (const g of guards) {
|
|
183
|
+
if (!g.verified || !g.guardKind)
|
|
184
|
+
continue;
|
|
185
|
+
if (best === null || KIND_RANK[g.guardKind] > KIND_RANK[best])
|
|
186
|
+
best = g.guardKind;
|
|
187
|
+
}
|
|
188
|
+
return best ?? 'documented-only';
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* A cheap repo-structure signal for the short-circuit: a hash over the sorted mtimes
|
|
192
|
+
* + sizes of the directories whose contents the audit reads (the route table source
|
|
193
|
+
* and the top-level src/scripts/tests/docs/.husky trees' immediate listings). Cheap,
|
|
194
|
+
* deterministic on an unchanged tree, and changes when a referenced guard file is
|
|
195
|
+
* added/removed.
|
|
196
|
+
*/
|
|
197
|
+
function repoStructureSignal(projectDir) {
|
|
198
|
+
const hash = crypto.createHash('sha256');
|
|
199
|
+
const probe = (rel) => {
|
|
200
|
+
const full = path.join(projectDir, rel);
|
|
201
|
+
try {
|
|
202
|
+
const st = fs.statSync(full);
|
|
203
|
+
if (st.isDirectory()) {
|
|
204
|
+
const names = fs.readdirSync(full).sort();
|
|
205
|
+
hash.update(`${rel}:${names.join(',')}\n`);
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
hash.update(`${rel}:${st.size}:${Math.floor(st.mtimeMs)}\n`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
catch {
|
|
212
|
+
hash.update(`${rel}:absent\n`);
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
for (const p of [
|
|
216
|
+
'src', 'src/server', 'scripts', 'tests', 'tests/unit', 'docs', 'docs/specs', '.husky',
|
|
217
|
+
'src/server/routes.ts',
|
|
218
|
+
])
|
|
219
|
+
probe(p);
|
|
220
|
+
return hash.digest('hex').slice(0, 16);
|
|
221
|
+
}
|
|
222
|
+
/** Compute the input hash that drives the recompute short-circuit. */
|
|
223
|
+
export function computeInputHash(opts) {
|
|
224
|
+
let registry = '';
|
|
225
|
+
try {
|
|
226
|
+
registry = fs.readFileSync(opts.registryPath, 'utf-8');
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
registry = '';
|
|
230
|
+
}
|
|
231
|
+
const regHash = crypto.createHash('sha256').update(registry).digest('hex').slice(0, 16);
|
|
232
|
+
return `${regHash}.${repoStructureSignal(opts.projectDir)}`;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Compute the full enforcement-coverage report. Deterministic: the per-standard order
|
|
236
|
+
* follows the registry parse order; refs within a standard are sorted; the only
|
|
237
|
+
* non-deterministic field is `generatedAt`/`classifiedAt` (a timestamp, excluded from
|
|
238
|
+
* `inputHash`). Pass `prior` to short-circuit when the input hash is unchanged.
|
|
239
|
+
*/
|
|
240
|
+
export function computeCoverage(opts, prior) {
|
|
241
|
+
const inputHash = computeInputHash(opts);
|
|
242
|
+
if (prior && prior.inputHash === inputHash) {
|
|
243
|
+
// Inputs unchanged → the deterministic report is byte-identical to the prior;
|
|
244
|
+
// return it (only its timestamp would differ on recompute). The short-circuit.
|
|
245
|
+
return prior;
|
|
246
|
+
}
|
|
247
|
+
const articles = loadStandardsRegistry(opts.registryPath);
|
|
248
|
+
const routeTable = loadRouteTable(opts.projectDir);
|
|
249
|
+
// Collect every wanted marker across all articles → ONE bounded src walk.
|
|
250
|
+
const extracted = articles.map((a) => ({ a, refs: extractEnforcementRefs(a) }));
|
|
251
|
+
const wantedMarkers = new Set();
|
|
252
|
+
for (const { refs } of extracted)
|
|
253
|
+
for (const m of refs.markers)
|
|
254
|
+
wantedMarkers.add(m);
|
|
255
|
+
const symbolIndex = buildSymbolIndex(opts.projectDir, wantedMarkers);
|
|
256
|
+
const classifiedAt = new Date().toISOString();
|
|
257
|
+
const standards = extracted.map(({ a, refs }) => {
|
|
258
|
+
const flat = flattenRefs(refs);
|
|
259
|
+
const guards = verifyRefs(flat, opts.projectDir, routeTable, symbolIndex);
|
|
260
|
+
const enforcementKind = classifyStandard(guards);
|
|
261
|
+
const danglingRefs = guards.filter((g) => !g.verified).map((g) => g.ref).sort();
|
|
262
|
+
return { standard: a.name, family: a.family, enforcementKind, guards, danglingRefs, classifiedAt };
|
|
263
|
+
});
|
|
264
|
+
const byKind = {
|
|
265
|
+
ratchet: 0, gate: 0, lint: 0, 'spec-only': 0, 'documented-only': 0,
|
|
266
|
+
};
|
|
267
|
+
for (const s of standards)
|
|
268
|
+
byKind[s.enforcementKind] += 1;
|
|
269
|
+
const total = standards.length;
|
|
270
|
+
const enforced = byKind.ratchet + byKind.gate + byKind.lint;
|
|
271
|
+
const enforcedRatio = total === 0 ? 0 : Number((enforced / total).toFixed(4));
|
|
272
|
+
const gaps = standards.filter((s) => s.enforcementKind === 'documented-only').map((s) => s.standard);
|
|
273
|
+
const danglingCount = standards.reduce((n, s) => n + s.danglingRefs.length, 0);
|
|
274
|
+
return {
|
|
275
|
+
generatedAt: classifiedAt,
|
|
276
|
+
inputHash,
|
|
277
|
+
standards,
|
|
278
|
+
summary: { total, byKind, enforcedRatio, gaps, danglingCount },
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
/** A stable, timestamp-free view used to assert determinism (two runs → identical). */
|
|
282
|
+
export function stableView(report) {
|
|
283
|
+
return {
|
|
284
|
+
inputHash: report.inputHash,
|
|
285
|
+
standards: report.standards.map((s) => ({
|
|
286
|
+
standard: s.standard,
|
|
287
|
+
family: s.family,
|
|
288
|
+
enforcementKind: s.enforcementKind,
|
|
289
|
+
guards: s.guards.map((g) => ({ ref: g.ref, kind: g.kind, verified: g.verified, guardKind: g.guardKind ?? null })),
|
|
290
|
+
danglingRefs: s.danglingRefs,
|
|
291
|
+
})),
|
|
292
|
+
summary: report.summary,
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
//# sourceMappingURL=StandardsEnforcementAuditor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StandardsEnforcementAuditor.js","sourceRoot":"","sources":["../../src/core/StandardsEnforcementAuditor.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,6 +24,13 @@ export interface StandardArticle {
|
|
|
24
24
|
rule: string;
|
|
25
25
|
/** The `**In practice.**` line, when present. */
|
|
26
26
|
inPractice: string;
|
|
27
|
+
/**
|
|
28
|
+
* The `**Applied through.**` line, when present — names the structural guard(s)
|
|
29
|
+
* that enforce the article (a test, lint, gate marker, route, or spec). Additive
|
|
30
|
+
* field (cartographer-conformance-audit spec #3); the enforcement-coverage audit
|
|
31
|
+
* scans `inPractice` + `appliedThrough` for verifiable enforcement references.
|
|
32
|
+
*/
|
|
33
|
+
appliedThrough?: string;
|
|
27
34
|
}
|
|
28
35
|
/**
|
|
29
36
|
* Parse the registry markdown into standards articles. Pure function — no I/O —
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StandardsRegistryParser.d.ts","sourceRoot":"","sources":["../../src/core/StandardsRegistryParser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,MAAM,WAAW,eAAe;IAC9B,2GAA2G;IAC3G,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,UAAU,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"StandardsRegistryParser.d.ts","sourceRoot":"","sources":["../../src/core/StandardsRegistryParser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,MAAM,WAAW,eAAe;IAC9B,2GAA2G;IAC3G,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAkBD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,EAAE,CA+C1E;AAED,kFAAkF;AAClF,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,eAAe,EAAE,CAG7E;AAID,0FAA0F;AAC1F,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAExC;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,MAAM,EAM5C,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,OAAO,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,+DAA+D;AAC/D,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG,oBAAoB,CAWnF"}
|
|
@@ -78,6 +78,13 @@ export function parseStandardsRegistry(markdown) {
|
|
|
78
78
|
cur.inPractice = inPractice;
|
|
79
79
|
continue;
|
|
80
80
|
}
|
|
81
|
+
// Additive (spec #3): capture the `**Applied through.**` line if present. Same
|
|
82
|
+
// `fieldAfter` extraction as Rule/In practice; absent on articles without one.
|
|
83
|
+
const appliedThrough = fieldAfter(line, 'Applied through');
|
|
84
|
+
if (appliedThrough !== null) {
|
|
85
|
+
cur.appliedThrough = appliedThrough;
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
81
88
|
}
|
|
82
89
|
flush();
|
|
83
90
|
return articles;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StandardsRegistryParser.js","sourceRoot":"","sources":["../../src/core/StandardsRegistryParser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"StandardsRegistryParser.js","sourceRoot":"","sources":["../../src/core/StandardsRegistryParser.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"componentCategories.d.ts","sourceRoot":"","sources":["../../src/core/componentCategories.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG,MAAM,GAAG,KAAK,GAAG,WAAW,GAAG,OAAO,CAAC;AAEpF,eAAO,MAAM,oBAAoB,EAAE,aAAa,CAAC,iBAAiB,CAEjE,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,iBAAiB,CAEtE;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,
|
|
1
|
+
{"version":3,"file":"componentCategories.d.ts","sourceRoot":"","sources":["../../src/core/componentCategories.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG,MAAM,GAAG,KAAK,GAAG,WAAW,GAAG,OAAO,CAAC;AAEpF,eAAO,MAAM,oBAAoB,EAAE,aAAa,CAAC,iBAAiB,CAEjE,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,iBAAiB,CAEtE;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAqD1E,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,iBAAiB,CAIrF;AAED,gGAAgG;AAChG,wBAAgB,eAAe,IAAI,MAAM,EAAE,CAE1C"}
|
|
@@ -72,6 +72,12 @@ export const COMPONENT_CATEGORY = {
|
|
|
72
72
|
// this registration guards the categoryForComponent path so a missing entry
|
|
73
73
|
// fails the wiring test rather than silently routing to the default framework.
|
|
74
74
|
CartographerSweep: 'job',
|
|
75
|
+
// The OPTIONAL dark LLM-enrichment path of the standards enforcement-coverage
|
|
76
|
+
// audit (cartographer-conformance-audit spec #3). Category 'job' so an operator
|
|
77
|
+
// can route it OFF Claude via sessions.componentFrameworks.categories.job — the
|
|
78
|
+
// enrichment then never spends Anthropic quota. Only used by the dark
|
|
79
|
+
// llmEnrichment path; the shipped deterministic auditor makes no LLM calls.
|
|
80
|
+
StandardsCoverageEnrichment: 'job',
|
|
75
81
|
};
|
|
76
82
|
/**
|
|
77
83
|
* Resolve a component's category. Strips a trailing "/segment" call-site suffix
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"componentCategories.js","sourceRoot":"","sources":["../../src/core/componentCategories.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,MAAM,CAAC,MAAM,oBAAoB,GAAqC;IACpE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO;CAChD,CAAC;AAEF,MAAM,UAAU,mBAAmB,CAAC,CAAU;IAC5C,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAK,oBAA0C,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC1F,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAgD;IAC7E,uEAAuE;IACvE,aAAa,EAAE,UAAU;IACzB,UAAU,EAAE,UAAU;IACtB,uBAAuB,EAAE,UAAU;IACnC,gBAAgB,EAAE,UAAU;IAC5B,kBAAkB,EAAE,UAAU;IAC9B,aAAa,EAAE,UAAU;IACzB,aAAa,EAAE,UAAU;IACzB,eAAe,EAAE,UAAU;IAC3B,mBAAmB,EAAE,UAAU;IAC/B,wBAAwB,EAAE,UAAU;IACpC,mBAAmB,EAAE,UAAU;IAC/B,eAAe,EAAE,UAAU;IAC3B,mBAAmB,EAAE,UAAU;IAE/B,iDAAiD;IACjD,UAAU,EAAE,MAAM;IAClB,YAAY,EAAE,MAAM;IACpB,eAAe,EAAE,MAAM;IACvB,qBAAqB,EAAE,MAAM;IAC7B,iBAAiB,EAAE,MAAM;IACzB,mBAAmB,EAAE,MAAM;IAC3B,aAAa,EAAE,MAAM;IACrB,iBAAiB,EAAE,MAAM;IACzB,iBAAiB,EAAE,MAAM;IAEzB,gEAAgE;IAChE,YAAY,EAAE,WAAW;IACzB,kBAAkB,EAAE,WAAW;IAC/B,iBAAiB,EAAE,WAAW;IAC9B,UAAU,EAAE,WAAW;IACvB,eAAe,EAAE,WAAW;IAC5B,mBAAmB,EAAE,WAAW;IAChC,mBAAmB,EAAE,WAAW;IAChC,4BAA4B,EAAE,WAAW;IACzC,kBAAkB,EAAE,WAAW;IAE/B,8BAA8B;IAC9B,kBAAkB,EAAE,KAAK;IACzB,8EAA8E;IAC9E,4EAA4E;IAC5E,8EAA8E;IAC9E,4EAA4E;IAC5E,4EAA4E;IAC5E,+EAA+E;IAC/E,iBAAiB,EAAE,KAAK;
|
|
1
|
+
{"version":3,"file":"componentCategories.js","sourceRoot":"","sources":["../../src/core/componentCategories.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,MAAM,CAAC,MAAM,oBAAoB,GAAqC;IACpE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO;CAChD,CAAC;AAEF,MAAM,UAAU,mBAAmB,CAAC,CAAU;IAC5C,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAK,oBAA0C,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC1F,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAgD;IAC7E,uEAAuE;IACvE,aAAa,EAAE,UAAU;IACzB,UAAU,EAAE,UAAU;IACtB,uBAAuB,EAAE,UAAU;IACnC,gBAAgB,EAAE,UAAU;IAC5B,kBAAkB,EAAE,UAAU;IAC9B,aAAa,EAAE,UAAU;IACzB,aAAa,EAAE,UAAU;IACzB,eAAe,EAAE,UAAU;IAC3B,mBAAmB,EAAE,UAAU;IAC/B,wBAAwB,EAAE,UAAU;IACpC,mBAAmB,EAAE,UAAU;IAC/B,eAAe,EAAE,UAAU;IAC3B,mBAAmB,EAAE,UAAU;IAE/B,iDAAiD;IACjD,UAAU,EAAE,MAAM;IAClB,YAAY,EAAE,MAAM;IACpB,eAAe,EAAE,MAAM;IACvB,qBAAqB,EAAE,MAAM;IAC7B,iBAAiB,EAAE,MAAM;IACzB,mBAAmB,EAAE,MAAM;IAC3B,aAAa,EAAE,MAAM;IACrB,iBAAiB,EAAE,MAAM;IACzB,iBAAiB,EAAE,MAAM;IAEzB,gEAAgE;IAChE,YAAY,EAAE,WAAW;IACzB,kBAAkB,EAAE,WAAW;IAC/B,iBAAiB,EAAE,WAAW;IAC9B,UAAU,EAAE,WAAW;IACvB,eAAe,EAAE,WAAW;IAC5B,mBAAmB,EAAE,WAAW;IAChC,mBAAmB,EAAE,WAAW;IAChC,4BAA4B,EAAE,WAAW;IACzC,kBAAkB,EAAE,WAAW;IAE/B,8BAA8B;IAC9B,kBAAkB,EAAE,KAAK;IACzB,8EAA8E;IAC9E,4EAA4E;IAC5E,8EAA8E;IAC9E,4EAA4E;IAC5E,4EAA4E;IAC5E,+EAA+E;IAC/E,iBAAiB,EAAE,KAAK;IACxB,8EAA8E;IAC9E,gFAAgF;IAChF,gFAAgF;IAChF,sEAAsE;IACtE,4EAA4E;IAC5E,2BAA2B,EAAE,KAAK;CACnC,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,SAA6B;IAChE,IAAI,CAAC,SAAS;QAAE,OAAO,OAAO,CAAC;IAC/B,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACpE,OAAO,kBAAkB,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC;AAC7C,CAAC;AAED,gGAAgG;AAChG,MAAM,UAAU,eAAe;IAC7B,OAAO,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,IAAI,EAAE,CAAC;AAChD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CapabilityIndex.d.ts","sourceRoot":"","sources":["../../src/server/CapabilityIndex.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,yEAAyE;AACzE,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,YAAY,CAAC;IAClB,iFAAiF;IACjF,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,kFAAkF;IAClF,UAAU,EAAE,UAAU,CAAC;CACxB;AAED,kEAAkE;AAClE,MAAM,WAAW,eAAe;IAC9B,yEAAyE;IACzE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,kEAAkE;IAClE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,oDAAoD;IACpD,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,OAAO,CAAC;CAC1D;AAID,eAAO,MAAM,gBAAgB,EAAE,SAAS,eAAe,
|
|
1
|
+
{"version":3,"file":"CapabilityIndex.d.ts","sourceRoot":"","sources":["../../src/server/CapabilityIndex.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,yEAAyE;AACzE,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,YAAY,CAAC;IAClB,iFAAiF;IACjF,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,kFAAkF;IAClF,UAAU,EAAE,UAAU,CAAC;CACxB;AAED,kEAAkE;AAClE,MAAM,WAAW,eAAe;IAC9B,yEAAyE;IACzE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,kEAAkE;IAClE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,oDAAoD;IACpD,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,OAAO,CAAC;CAC1D;AAID,eAAO,MAAM,gBAAgB,EAAE,SAAS,eAAe,EA46BtD,CAAC;AAsCF;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,EAAE,aAAa,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAgE/E,CAAC;AAIF;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAUzD;AAED,mEAAmE;AACnE,wBAAgB,sBAAsB,IAAI,GAAG,CAAC,MAAM,CAAC,CAEpD;AAED,sEAAsE;AACtE,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,oBAAoB,GAC1B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAMzB"}
|
|
@@ -770,7 +770,7 @@ export const CAPABILITY_INDEX = [
|
|
|
770
770
|
},
|
|
771
771
|
{
|
|
772
772
|
key: 'cartographer',
|
|
773
|
-
prefixes: ['/cartographer'],
|
|
773
|
+
prefixes: ['/cartographer', '/conformance'],
|
|
774
774
|
description: 'Cartographer doc-tree — semantic codebase map with git-hash staleness',
|
|
775
775
|
build: ({ ctx }) => ({
|
|
776
776
|
enabled: !!ctx.cartographer,
|
|
@@ -781,6 +781,8 @@ export const CAPABILITY_INDEX = [
|
|
|
781
781
|
'GET /cartographer/stale — nodes whose summary has drifted from the code',
|
|
782
782
|
'GET /cartographer/health — node count + staleness + freshness backlog (spec #2)',
|
|
783
783
|
'POST /cartographer/node/refresh {path,summary} — inline-refresh one node\'s summary (spec #2; 503 unless freshnessSweep enabled)',
|
|
784
|
+
'GET /conformance/coverage — per-standard enforcement-coverage of docs/STANDARDS-REGISTRY.md (spec #3; filters ?family=/?kind=/?status=gap; X-Instar-Request:1; 503 unless conformanceAudit enabled)',
|
|
785
|
+
'GET /conformance/coverage/health — coverage summary: counts by enforcementKind, enforced ratio, gap + dangling-ref counts (spec #3)',
|
|
784
786
|
]
|
|
785
787
|
: [],
|
|
786
788
|
}),
|