@holmes-lab/holmes-kit 0.1.7 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +11 -7
  3. package/bin/holmes-mcp.js +0 -0
  4. package/dist/.build-id +1 -1
  5. package/dist/holmes/cli/agents.d.ts +50 -0
  6. package/dist/holmes/cli/ci-gate.d.ts +18 -0
  7. package/dist/holmes/cli/doctor.d.ts +44 -0
  8. package/dist/holmes/cli/gitignore-merge.d.ts +18 -0
  9. package/dist/holmes/cli/governed-precondition.d.ts +27 -0
  10. package/dist/holmes/cli/index.d.ts +14 -0
  11. package/dist/holmes/cli/index.js +23 -1
  12. package/dist/holmes/cli/init.d.ts +69 -0
  13. package/dist/holmes/cli/interactive-prompt.d.ts +9 -0
  14. package/dist/holmes/cli/playbook-skills.d.ts +129 -0
  15. package/dist/holmes/cli/roles-readme.d.ts +12 -0
  16. package/dist/holmes/cli/serve.d.ts +14 -0
  17. package/dist/holmes/cli/serve.js +70 -0
  18. package/dist/holmes/cli/settings-merge.d.ts +66 -0
  19. package/dist/holmes/config/config.d.ts +13 -0
  20. package/dist/holmes/context/bundler.d.ts +40 -0
  21. package/dist/holmes/context/render.d.ts +9 -0
  22. package/dist/holmes/context/tiers.d.ts +54 -0
  23. package/dist/holmes/context/tokens.d.ts +2 -0
  24. package/dist/holmes/cpg/ast-mutation.d.ts +31 -0
  25. package/dist/holmes/cpg/ast-mutation.js +126 -0
  26. package/dist/holmes/cpg/cpg-scanner.d.ts +69 -0
  27. package/dist/holmes/cpg/dynamic-cpg.d.ts +18 -0
  28. package/dist/holmes/cpg/dynamic-cpg.js +82 -0
  29. package/dist/holmes/cpg/hash-cache.d.ts +21 -0
  30. package/dist/holmes/cpg/language-parser-walk.d.ts +31 -0
  31. package/dist/holmes/cpg/language-parser-worker.d.ts +1 -0
  32. package/dist/holmes/cpg/language-parser.d.ts +116 -0
  33. package/dist/holmes/cpg/program-slicing.d.ts +21 -0
  34. package/dist/holmes/cpg/program-slicing.js +123 -0
  35. package/dist/holmes/cpg/scan-cache.d.ts +21 -0
  36. package/dist/holmes/cpg/source-path.d.ts +2 -0
  37. package/dist/holmes/cpg/test-files.d.ts +36 -0
  38. package/dist/holmes/governance/constitution-debt.d.ts +3 -0
  39. package/dist/holmes/governance/constitution-report.d.ts +23 -0
  40. package/dist/holmes/governance/constitution.d.ts +61 -0
  41. package/dist/holmes/governance/identity.d.ts +28 -0
  42. package/dist/holmes/governance/ledger-lock.d.ts +55 -0
  43. package/dist/holmes/governance/ledger-store.conformance.d.ts +11 -0
  44. package/dist/holmes/governance/ledger-store.d.ts +114 -0
  45. package/dist/holmes/governance/progress-ledger.d.ts +25 -0
  46. package/dist/holmes/governance/provenance-chain.d.ts +154 -0
  47. package/dist/holmes/governance/provenance-ledger.d.ts +102 -0
  48. package/dist/holmes/governance/provenance-schema.d.ts +21 -0
  49. package/dist/holmes/governance/replica-id.d.ts +20 -0
  50. package/dist/holmes/governance/role-policy.d.ts +52 -0
  51. package/dist/holmes/governance/trust-score.d.ts +32 -0
  52. package/dist/holmes/guardrail/anchors.d.ts +8 -0
  53. package/dist/holmes/guardrail/blind-spots.d.ts +32 -0
  54. package/dist/holmes/guardrail/decision-ledger.d.ts +29 -0
  55. package/dist/holmes/guardrail/executable-artifact.d.ts +1 -0
  56. package/dist/holmes/guardrail/governance-history.d.ts +15 -0
  57. package/dist/holmes/guardrail/phase.d.ts +27 -0
  58. package/dist/holmes/guardrail/risk-classifier.d.ts +52 -0
  59. package/dist/holmes/guardrail/risk-gate.d.ts +77 -0
  60. package/dist/holmes/guardrail/risk-types.d.ts +48 -0
  61. package/dist/holmes/guardrail/tspec-state.d.ts +71 -0
  62. package/dist/holmes/guardrail/write-target.d.ts +77 -0
  63. package/dist/holmes/hooks/adapters/antigravity.d.ts +42 -0
  64. package/dist/holmes/hooks/pre-tool-use.d.ts +144 -0
  65. package/dist/holmes/hooks/stop.d.ts +91 -0
  66. package/dist/holmes/mcp/basis.d.ts +100 -0
  67. package/dist/holmes/mcp/handlers.d.ts +482 -0
  68. package/dist/holmes/mcp/server.d.ts +2 -0
  69. package/dist/holmes/mcp/stdio-client.d.ts +51 -0
  70. package/dist/holmes/mcp/supervisor.d.ts +48 -0
  71. package/dist/holmes/mcp/tool-schemas.d.ts +12 -0
  72. package/dist/holmes/mcp/validate-args.d.ts +27 -0
  73. package/dist/holmes/messages/registry.d.ts +23 -0
  74. package/dist/holmes/project/baseline.d.ts +66 -0
  75. package/dist/holmes/project/change-source.d.ts +89 -0
  76. package/dist/holmes/project/ignore.d.ts +33 -0
  77. package/dist/holmes/project/root.d.ts +34 -0
  78. package/dist/holmes/reverse/anchor.d.ts +47 -0
  79. package/dist/holmes/reverse/cluster.d.ts +45 -0
  80. package/dist/holmes/reverse/draft.d.ts +33 -0
  81. package/dist/holmes/reverse/dynamic-wiring.d.ts +18 -0
  82. package/dist/holmes/reverse/scan.d.ts +103 -0
  83. package/dist/holmes/reverse/surface.d.ts +91 -0
  84. package/dist/holmes/reverse/test-map.d.ts +91 -0
  85. package/dist/holmes/review/coverage.d.ts +21 -0
  86. package/dist/holmes/review/findings.d.ts +49 -0
  87. package/dist/holmes/review/package.d.ts +26 -0
  88. package/dist/holmes/review/review-targets.d.ts +28 -0
  89. package/dist/holmes/review/scope.d.ts +13 -0
  90. package/dist/holmes/review/test-evidence.d.ts +31 -0
  91. package/dist/holmes/review/test-runner.d.ts +141 -0
  92. package/dist/holmes/rtm/dataflow-taint.d.ts +81 -0
  93. package/dist/holmes/rtm/gap-analyzer.d.ts +28 -0
  94. package/dist/holmes/rtm/git-changes.d.ts +33 -0
  95. package/dist/holmes/rtm/heatmap.d.ts +21 -0
  96. package/dist/holmes/rtm/incremental.d.ts +38 -0
  97. package/dist/holmes/rtm/localize.d.ts +36 -0
  98. package/dist/holmes/rtm/rtm-builder.d.ts +101 -0
  99. package/dist/holmes/rtm/rtm-check.d.ts +13 -0
  100. package/dist/holmes/rtm/rtm-graph.d.ts +88 -0
  101. package/dist/holmes/rtm/taint.d.ts +35 -0
  102. package/dist/holmes/rtm/test-scope.d.ts +85 -0
  103. package/dist/holmes/server/dashboard.d.ts +85 -0
  104. package/dist/holmes/server/dashboard.js +2188 -0
  105. package/dist/holmes/spec/approval-blockers.d.ts +62 -0
  106. package/dist/holmes/spec/breaking-change.d.ts +42 -0
  107. package/dist/holmes/spec/legacy-format.d.ts +93 -0
  108. package/dist/holmes/spec/spec-digest.d.ts +29 -0
  109. package/dist/holmes/spec/spec-parser.d.ts +12 -0
  110. package/dist/holmes/spec/spec-store.conformance.d.ts +10 -0
  111. package/dist/holmes/spec/spec-store.d.ts +130 -0
  112. package/dist/holmes/spec/spec-types.d.ts +150 -0
  113. package/dist/holmes/spec/validator.d.ts +65 -0
  114. package/package.json +2 -1
@@ -0,0 +1,13 @@
1
+ import { Spec } from '../spec/spec-parser';
2
+ import { ScannedFile } from '../cpg/cpg-scanner';
3
+ export interface RtmIssue {
4
+ kind: 'orphan' | 'cycle' | 'dangling' | 'duplicate-id' | 'dangling-implements' | 'wrong-kind-implements';
5
+ id: string;
6
+ detail: string;
7
+ }
8
+ export declare function computeBlastRadius(specs: Spec[], targetId: string): {
9
+ impactedSpecCount: number;
10
+ hitsFoundational: boolean;
11
+ };
12
+ export declare function rtmCheck(specs: Spec[]): RtmIssue[];
13
+ export declare function checkImplements(scanned: ScannedFile[], specs: Spec[]): RtmIssue[];
@@ -0,0 +1,88 @@
1
+ /**
2
+ * The RTM graph. **NOT PERSISTED — read this before assuming otherwise.**
3
+ *
4
+ * Every one of the seven handlers that touches a graph (`rtm_impact`, `rtm_reindex`,
5
+ * `context_bundle`, `review_scope`, `review_prepare`, `risk_check`, `test_run`) constructs
6
+ * `new RtmGraph()` with no path, so the store is `:memory:`, built from scratch on each call and
7
+ * discarded when the call returns. Nothing writes `.ax/rtm.sqlite`.
8
+ *
9
+ * The surrounding machinery reads as though a persistent graph exists — `applyIncremental`,
10
+ * `rtm_reindex`, a `.gitignore` entry for `.ax/rtm.sqlite` — and it does not. I misread exactly this
11
+ * and reasoned from a persistent graph that was never there, so it is stated here rather than left
12
+ * to be inferred from seven constructor calls.
13
+ *
14
+ * This is a DELIBERATE position, not an omission (ADR-011): the graph is a derived index whose four
15
+ * inputs all come from git-tracked files, so rebuilding is always correct, a past commit's `.md` +
16
+ * source reconstructs that commit's graph for free, and staleness cannot occur. Persisting is
17
+ * deferred until graph build exceeds ~1 s per call, at which point ADR-011 lists the safety
18
+ * machinery that has to land with it.
19
+ *
20
+ * CONSEQUENCE FOR `rtm_reindex`: it calls `buildRtm` (a full build at HEAD) and only then
21
+ * `applyIncremental`, which removes and re-adds the changed files' subgraphs from that same scan.
22
+ * The result is identical to the full build, so the incremental pass is currently redundant work
23
+ * rather than a saving. It becomes meaningful the moment a persisted graph exists.
24
+ */
25
+ export declare class RtmGraph {
26
+ private readonly db;
27
+ constructor(dbPath?: string);
28
+ private nodeStmt?;
29
+ private edgeStmt?;
30
+ addNode(id: string, kind: string, sourcePath?: string): void;
31
+ addEdge(src: string, dst: string, rel: string, sourcePath?: string): void;
32
+ /**
33
+ * @implements A-SPEC-139
34
+ * Run `fn` inside ONE SQLite transaction, so a build commits once instead of once per insert.
35
+ * Returns fn's value; on a throw it rolls back and re-throws — a failed build leaves no half-graph
36
+ * a caller could mistake for a complete one (stricter than the previous partial-insert behavior).
37
+ * better-sqlite3 nests via savepoints, so calling this inside an outer transaction is safe.
38
+ */
39
+ transaction<T>(fn: () => T): T;
40
+ reachable(fromId: string): string[];
41
+ incoming(toId: string): string[];
42
+ /**
43
+ * Callers of a symbol — `calls` edges only, walked backwards. Impact propagation needs exactly
44
+ * this and not `incoming`, which would also drag in `implements` and `depends_on` and turn a
45
+ * "who calls me" question into "what is attached to me in any way at all".
46
+ */
47
+ callersOf(id: string): string[];
48
+ /** How many distinct symbols call this one. The hub signal for bounded propagation (REQ-127). */
49
+ callerCount(id: string): number;
50
+ /**
51
+ * Specs this code node anchors, plus their transitive `depends_on` ancestors.
52
+ *
53
+ * Deliberately NOT `reachable`, which follows every relation. Once call edges exist, a generic
54
+ * forward walk from a CODE node crosses `calls` too and collects the specs of everything the
55
+ * symbol CALLS — silently answering "what does this depend on" while claiming to answer "what
56
+ * breaks if I change this". Adversarial review caught exactly that: changing a caller reported the
57
+ * callee's spec. Impact walks callers BACKWARD; only anchors are followed forward.
58
+ */
59
+ specsOf(codeId: string): string[];
60
+ /**
61
+ * Neighbours with the relation that connects them, so a traversal can price a `calls` hop
62
+ * differently from a spec-chain hop. Same ordering guarantee as `neighbors`.
63
+ *
64
+ * A node reachable by several relations appears once per relation; callers take the cheapest.
65
+ */
66
+ neighborsWithRel(id: string): Array<{
67
+ id: string;
68
+ rel: string;
69
+ }>;
70
+ /**
71
+ * This node's `depends_on` PARENTS — outgoing only, so it climbs the spec chain without descending
72
+ * into siblings. A shared parent (one REQ under which many slices hang) is a bidirectional hub;
73
+ * following it in both directions walks from any slice into every other one.
74
+ */
75
+ parentsOf(id: string): string[];
76
+ /** Nodes exactly one edge away in EITHER direction, sorted ascending and deduped. */
77
+ neighbors(id: string): string[];
78
+ removeBySource(sourcePath: string): void;
79
+ codeNodeIds(qn: string): string[];
80
+ callReachable(fromId: string): string[];
81
+ /** @implements A-SPEC-138 — every CODE node id, for the taint pass to match source/sink names against. */
82
+ allCodeNodeIds(): string[];
83
+ /** @implements A-SPEC-138 — direct calls-only callees of a node (one hop), for BFS path assembly. */
84
+ callees(fromId: string): string[];
85
+ nodeCount(): number;
86
+ edgeCount(): number;
87
+ close(): void;
88
+ }
@@ -0,0 +1,35 @@
1
+ import { RtmGraph } from './rtm-graph';
2
+ /**
3
+ * Call-graph taint REACHABILITY (REQ-138). This is a SCREENING signal, not a data-flow proof: it
4
+ * reports call paths from a source-named function to a sink-named function, so a security review has
5
+ * candidate paths to start from. It does NOT track tainted data (no def-use, no parameter/return
6
+ * propagation) and does NOT model sanitizers — so it over-reports (a call path that never carries
7
+ * tainted data) and can under-report (flow through a non-call channel). Every consumer must carry the
8
+ * honesty envelope (see `TAINT_LIMITS`) and phrase findings as "reaches", never "vulnerable".
9
+ */
10
+ export interface TaintConfig {
11
+ sources: string[];
12
+ sinks: string[];
13
+ maxPaths?: number;
14
+ }
15
+ export interface TaintPair {
16
+ source: string;
17
+ sink: string;
18
+ path: string[];
19
+ }
20
+ /** The limits every taint report must disclose — this is reachability, not data-flow. */
21
+ export declare const TAINT_LIMITS: readonly ["name-based matching", "no def-use", "no sanitizers", "call-edge-only"];
22
+ /**
23
+ * A small, conservative default source/sink set. Patterns are case-insensitive substrings on a node's
24
+ * qualified name. Deliberately narrow (precision over recall) and overridable by config.
25
+ */
26
+ export declare const DEFAULT_TAINT_CONFIG: TaintConfig;
27
+ /**
28
+ * Source→sink call-reachability pairs over the graph. Deterministic: sources and sinks are iterated
29
+ * in the graph's sorted node order, pairs are deduped by (source, sink) and sorted, and capped at
30
+ * `maxPaths` with `truncated` reporting the remainder. Pure except the graph read.
31
+ */
32
+ export declare function taintReachability(graph: RtmGraph, cfg: TaintConfig): {
33
+ pairs: TaintPair[];
34
+ truncated: number;
35
+ };
@@ -0,0 +1,85 @@
1
+ import { Spec } from '../spec/spec-parser';
2
+ /**
3
+ * Intelligent regression test-scope (target-architecture §5, differentiator ③) — SAFE by default.
4
+ *
5
+ * Decides HOW MUCH to re-test for a change. Adversarial review (C1/C2/C3/H1) proved the first cut was
6
+ * unsound in production, so this version is rebuilt around one rule: NEVER report a narrower scope than
7
+ * can be justified. When the impact analysis is uncertain or the test↔spec mapping is incomplete, it
8
+ * escalates to `full` — a false "safe" (skipping a test that would have caught a regression) is the
9
+ * only unacceptable outcome; over-running tests is merely slower.
10
+ *
11
+ * unit — impacted specs map to anchored tests, low downstream blast, no coverage gaps
12
+ * partial — moderate downstream blast
13
+ * full — foundational REQ reached, wide blast, a coverage gap, OR impacted specs with NO
14
+ * resolvable anchored tests (can't narrow safely) OR no analysis at all
15
+ *
16
+ * Key fixes vs. the first cut:
17
+ * - C1: impacted spec ids are stripped of the graph's `SPEC:` node-id prefix before use.
18
+ * - C2: impacted TEST files come from a SEPARATE test-file @implements scan (scanTestAnchors), because
19
+ * the CPG scanner deliberately excludes test files from the production symbol graph.
20
+ * - C3/H1: the tier is driven by downstream BLAST RADIUS + coverage gaps + test resolvability, not by
21
+ * the ancestor-chain length (which is ~constant depth, not breadth) — and defaults to `full`.
22
+ */
23
+ export type RegressionTier = 'unit' | 'partial' | 'full';
24
+ export interface TestScopeThresholds {
25
+ partialBlast?: number;
26
+ fullBlast?: number;
27
+ }
28
+ export interface TestScope {
29
+ tier: RegressionTier;
30
+ impactedSpecs: string[];
31
+ impactedTestFiles: string[];
32
+ blastRadius: number;
33
+ hitsFoundational: boolean;
34
+ coverageGaps: string[];
35
+ reason: string;
36
+ /** Changed source files that resolved into NO lane (A-SPEC-130) — nonempty forces `full`. */
37
+ unresolvedFiles: string[];
38
+ }
39
+ /**
40
+ * @implements A-SPEC-130
41
+ * Lane-3 self-selection and the unresolved remainder, threaded into the tier decision. Optional and
42
+ * additive: every existing five-argument caller is untouched, and an empty extras changes nothing.
43
+ */
44
+ export interface TestScopeExtras {
45
+ /** Changed files that ARE test files: they join the selected set of any non-full tier. */
46
+ changedTestFiles?: string[];
47
+ /** Changed scannable sources no lane resolved: tier becomes `full`, reason names them. */
48
+ unresolvedFiles?: string[];
49
+ }
50
+ /**
51
+ * @implements A-SPEC-130
52
+ * Three-lane resolution for changed files. Impact propagation is symbol-keyed, so three classes of
53
+ * changed file used to vanish before the tier decision (measured 2026-08-06: five changed sources,
54
+ * zero changed symbols, tier "nothing to re-test", noop passed:true):
55
+ *
56
+ * lane 1 symbols changed -> the existing symbol path owns it; not accounted here
57
+ * lane 2 scanned, 0 symbols, -> its `implementsSpecs` join the impacted set directly — the
58
+ * readable @implements anchor was always on disk; only the symbol keying dropped it
59
+ * lane 3 a test file -> selects ITSELF (the symbol scan excludes tests by design)
60
+ * else scannable source -> UNRESOLVED: the graph cannot see it, the tier must widen
61
+ *
62
+ * Docs, specs, playbooks and anything under `.ax/` never qualify as unresolved — a documentation
63
+ * change must not trigger a full regression. Pure set arithmetic over signals already in memory.
64
+ */
65
+ export interface ChangedFileAccount {
66
+ anchorImpactedSpecs: string[];
67
+ changedTestFiles: string[];
68
+ unresolvedFiles: string[];
69
+ }
70
+ export declare function accountChangedFiles(changedFiles: string[], scanEntry: (rel: string) => {
71
+ implementsSpecs: string[];
72
+ symbolCount: number;
73
+ } | undefined): ChangedFileAccount;
74
+ /** Frameworks this counter understands, for diagnostics and tests. */
75
+ export declare const SUPPORTED_TEST_FRAMEWORKS: string[];
76
+ export declare function countTestCases(source: string, filePath?: string): number;
77
+ /** A-SPEC ids anchored by a file, counting only standalone comment-line markers outside literals. */
78
+ export declare function extractAnchors(source: string): string[];
79
+ /**
80
+ * Scan the repo for TEST files and the A-SPEC ids they @implement. Separate from the CPG scan (which
81
+ * excludes tests), so the test↔spec edges actually exist for scoping. Returns repo-relative POSIX
82
+ * paths → the impacted-spec ids they anchor. Pure-ish (fs read only); resilient to unreadable files.
83
+ */
84
+ export declare function scanTestAnchors(root: string): Record<string, string[]>;
85
+ export declare function computeTestScope(impactedSpecsRaw: string[], testAnchors: Record<string, string[]>, specs: Spec[], coverageGaps?: string[], cfg?: TestScopeThresholds, extras?: TestScopeExtras): TestScope;
@@ -0,0 +1,85 @@
1
+ import * as http from 'node:http';
2
+ export interface DashboardOptions {
3
+ root: string;
4
+ port?: number;
5
+ }
6
+ export interface DashboardServerHandle {
7
+ server: http.Server;
8
+ url: string;
9
+ port: number;
10
+ stop: () => Promise<void>;
11
+ }
12
+ export interface GraphNode {
13
+ id: string;
14
+ type: 'spec' | 'code';
15
+ kind: string;
16
+ label: string;
17
+ covered?: boolean;
18
+ }
19
+ export interface GraphEdge {
20
+ from: string;
21
+ to: string;
22
+ rel: 'implements' | 'depends_on' | 'calls' | 'contains' | 'verifies';
23
+ }
24
+ /**
25
+ * Start a lightweight standalone Node.js HTTP server for interactive dashboard & RTM visualization.
26
+ *
27
+ * @implements A-SPEC-215
28
+ * @implements A-SPEC-219
29
+ */
30
+ export declare function startDashboardServer(options: DashboardOptions): Promise<DashboardServerHandle>;
31
+ /**
32
+ * One end-to-end 6-stage trace row: REQ -> H-SPEC -> A-SPEC -> T-SPEC -> File -> AST Symbol.
33
+ *
34
+ * Every stage is nullable ON PURPOSE. A stage that does not exist in the repository is reported as
35
+ * `null` and named in `missingStages`; it is never back-filled with a synthesized spec id or with a
36
+ * placeholder file/symbol, because a traceability matrix that invents its own evidence cannot be
37
+ * audited against the repository it claims to describe.
38
+ *
39
+ * @implements A-SPEC-219
40
+ */
41
+ export interface PipelineRow {
42
+ reqId: string;
43
+ reqTitle: string;
44
+ hspecId: string | null;
45
+ aspecId: string | null;
46
+ tspecId: string | null;
47
+ fileId: string | null;
48
+ symbolId: string | null;
49
+ symbolLine: number | null;
50
+ /** How many of the 6 stages are backed by a real artifact (1..6; REQ itself always counts). */
51
+ stagesComplete: number;
52
+ /** Human-readable names of the stages with no artifact, in pipeline order. */
53
+ missingStages: string[];
54
+ /** COVERED only when all 6 stages resolve to a real artifact. */
55
+ status: 'COVERED' | 'UNCOVERED';
56
+ findingsCount: number;
57
+ criticalCount: number;
58
+ /**
59
+ * false when no findings ledger exists. `findingsCount: 0` then means "not scanned", never
60
+ * "scanned and clean", and the audit lens must render the two differently.
61
+ */
62
+ findingsScanned: boolean;
63
+ mutantCount: number;
64
+ /**
65
+ * `null` — never a number. A mutation SCORE requires executing the test suite once per mutant;
66
+ * this endpoint only generates mutants statically, so it has no basis for a score and says so
67
+ * rather than reporting a constant that reads as a measurement.
68
+ */
69
+ mutationScore: null;
70
+ mutationScoreMeasured: false;
71
+ }
72
+ export declare function isCanonicalStatus(status: unknown): boolean;
73
+ /** `A-SPEC-219.1` -> `A-SPEC`, `REQ-021` -> `REQ`. */
74
+ export declare function specKindOf(id: string): string;
75
+ /**
76
+ * Build the 6-stage pipeline matrix from the repository's real specs, scanned files and findings.
77
+ *
78
+ * Pure and exported so the truthfulness invariants can be asserted directly, without an HTTP round
79
+ * trip: no row may name an artifact that the inputs do not contain, and no symbol may be dropped.
80
+ *
81
+ * @implements A-SPEC-219
82
+ */
83
+ export declare function buildPipelineRows(specs: any[], files: any[], allFindings: any[], options?: {
84
+ findingsScanned?: boolean;
85
+ }): PipelineRow[];