@xenos1996/usa 2.0.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.
Files changed (163) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +335 -0
  3. package/USA.md +597 -0
  4. package/dist/bootstrap/catalog.d.ts +46 -0
  5. package/dist/bootstrap/catalog.d.ts.map +1 -0
  6. package/dist/bootstrap/catalog.js +312 -0
  7. package/dist/bootstrap/catalog.js.map +1 -0
  8. package/dist/bootstrap/index.d.ts +36 -0
  9. package/dist/bootstrap/index.d.ts.map +1 -0
  10. package/dist/bootstrap/index.js +177 -0
  11. package/dist/bootstrap/index.js.map +1 -0
  12. package/dist/cli.d.ts +5 -0
  13. package/dist/cli.d.ts.map +1 -0
  14. package/dist/cli.js +706 -0
  15. package/dist/cli.js.map +1 -0
  16. package/dist/config.d.ts +7 -0
  17. package/dist/config.d.ts.map +1 -0
  18. package/dist/config.js +88 -0
  19. package/dist/config.js.map +1 -0
  20. package/dist/detect/index.d.ts +58 -0
  21. package/dist/detect/index.d.ts.map +1 -0
  22. package/dist/detect/index.js +329 -0
  23. package/dist/detect/index.js.map +1 -0
  24. package/dist/engine/audit.d.ts +32 -0
  25. package/dist/engine/audit.d.ts.map +1 -0
  26. package/dist/engine/audit.js +366 -0
  27. package/dist/engine/audit.js.map +1 -0
  28. package/dist/engine/diff.d.ts +24 -0
  29. package/dist/engine/diff.d.ts.map +1 -0
  30. package/dist/engine/diff.js +136 -0
  31. package/dist/engine/diff.js.map +1 -0
  32. package/dist/engine/evaluate.d.ts +19 -0
  33. package/dist/engine/evaluate.d.ts.map +1 -0
  34. package/dist/engine/evaluate.js +377 -0
  35. package/dist/engine/evaluate.js.map +1 -0
  36. package/dist/engine/gate.d.ts +19 -0
  37. package/dist/engine/gate.d.ts.map +1 -0
  38. package/dist/engine/gate.js +47 -0
  39. package/dist/engine/gate.js.map +1 -0
  40. package/dist/engine/loader.d.ts +37 -0
  41. package/dist/engine/loader.d.ts.map +1 -0
  42. package/dist/engine/loader.js +388 -0
  43. package/dist/engine/loader.js.map +1 -0
  44. package/dist/engine/maturity.d.ts +20 -0
  45. package/dist/engine/maturity.d.ts.map +1 -0
  46. package/dist/engine/maturity.js +157 -0
  47. package/dist/engine/maturity.js.map +1 -0
  48. package/dist/engine/score.d.ts +19 -0
  49. package/dist/engine/score.d.ts.map +1 -0
  50. package/dist/engine/score.js +141 -0
  51. package/dist/engine/score.js.map +1 -0
  52. package/dist/engine/sections.d.ts +14 -0
  53. package/dist/engine/sections.d.ts.map +1 -0
  54. package/dist/engine/sections.js +50 -0
  55. package/dist/engine/sections.js.map +1 -0
  56. package/dist/evolution/benchmark.d.ts +12 -0
  57. package/dist/evolution/benchmark.d.ts.map +1 -0
  58. package/dist/evolution/benchmark.js +107 -0
  59. package/dist/evolution/benchmark.js.map +1 -0
  60. package/dist/evolution/capability.d.ts +22 -0
  61. package/dist/evolution/capability.d.ts.map +1 -0
  62. package/dist/evolution/capability.js +69 -0
  63. package/dist/evolution/capability.js.map +1 -0
  64. package/dist/evolution/coverage.d.ts +15 -0
  65. package/dist/evolution/coverage.d.ts.map +1 -0
  66. package/dist/evolution/coverage.js +65 -0
  67. package/dist/evolution/coverage.js.map +1 -0
  68. package/dist/evolution/gap.d.ts +10 -0
  69. package/dist/evolution/gap.d.ts.map +1 -0
  70. package/dist/evolution/gap.js +52 -0
  71. package/dist/evolution/gap.js.map +1 -0
  72. package/dist/evolution/propose.d.ts +50 -0
  73. package/dist/evolution/propose.d.ts.map +1 -0
  74. package/dist/evolution/propose.js +188 -0
  75. package/dist/evolution/propose.js.map +1 -0
  76. package/dist/evolution/queue.d.ts +64 -0
  77. package/dist/evolution/queue.d.ts.map +1 -0
  78. package/dist/evolution/queue.js +192 -0
  79. package/dist/evolution/queue.js.map +1 -0
  80. package/dist/evolution/release.d.ts +11 -0
  81. package/dist/evolution/release.d.ts.map +1 -0
  82. package/dist/evolution/release.js +55 -0
  83. package/dist/evolution/release.js.map +1 -0
  84. package/dist/evolution/run.d.ts +88 -0
  85. package/dist/evolution/run.d.ts.map +1 -0
  86. package/dist/evolution/run.js +258 -0
  87. package/dist/evolution/run.js.map +1 -0
  88. package/dist/evolution/schedule.d.ts +59 -0
  89. package/dist/evolution/schedule.d.ts.map +1 -0
  90. package/dist/evolution/schedule.js +77 -0
  91. package/dist/evolution/schedule.js.map +1 -0
  92. package/dist/evolution/types.d.ts +174 -0
  93. package/dist/evolution/types.d.ts.map +1 -0
  94. package/dist/evolution/types.js +8 -0
  95. package/dist/evolution/types.js.map +1 -0
  96. package/dist/index.d.ts +36 -0
  97. package/dist/index.d.ts.map +1 -0
  98. package/dist/index.js +30 -0
  99. package/dist/index.js.map +1 -0
  100. package/dist/learn/index.d.ts +27 -0
  101. package/dist/learn/index.d.ts.map +1 -0
  102. package/dist/learn/index.js +196 -0
  103. package/dist/learn/index.js.map +1 -0
  104. package/dist/report/markdown.d.ts +16 -0
  105. package/dist/report/markdown.d.ts.map +1 -0
  106. package/dist/report/markdown.js +488 -0
  107. package/dist/report/markdown.js.map +1 -0
  108. package/dist/snapshot/index.d.ts +55 -0
  109. package/dist/snapshot/index.d.ts.map +1 -0
  110. package/dist/snapshot/index.js +76 -0
  111. package/dist/snapshot/index.js.map +1 -0
  112. package/dist/store/index.d.ts +31 -0
  113. package/dist/store/index.d.ts.map +1 -0
  114. package/dist/store/index.js +69 -0
  115. package/dist/store/index.js.map +1 -0
  116. package/dist/types.d.ts +287 -0
  117. package/dist/types.d.ts.map +1 -0
  118. package/dist/types.js +16 -0
  119. package/dist/types.js.map +1 -0
  120. package/dist/util/glob.d.ts +11 -0
  121. package/dist/util/glob.d.ts.map +1 -0
  122. package/dist/util/glob.js +86 -0
  123. package/dist/util/glob.js.map +1 -0
  124. package/dist/util/project.d.ts +90 -0
  125. package/dist/util/project.d.ts.map +1 -0
  126. package/dist/util/project.js +636 -0
  127. package/dist/util/project.js.map +1 -0
  128. package/dist/util/yaml.d.ts +28 -0
  129. package/dist/util/yaml.d.ts.map +1 -0
  130. package/dist/util/yaml.js +48 -0
  131. package/dist/util/yaml.js.map +1 -0
  132. package/package.json +94 -0
  133. package/rules/core/architecture.yaml +190 -0
  134. package/rules/core/cicd.yaml +212 -0
  135. package/rules/core/code-quality.yaml +261 -0
  136. package/rules/core/dependencies.yaml +132 -0
  137. package/rules/core/documentation.yaml +119 -0
  138. package/rules/core/future-readiness.yaml +91 -0
  139. package/rules/core/release.yaml +131 -0
  140. package/rules/core/repo.yaml +313 -0
  141. package/rules/core/security.yaml +496 -0
  142. package/rules/core/supply-chain.yaml +357 -0
  143. package/rules/core/testing.yaml +266 -0
  144. package/rules/detectors.yaml +2028 -0
  145. package/rules/index.yaml +42 -0
  146. package/rules/profiles/maturity.yaml +135 -0
  147. package/rules/stacks/ai-era.yaml +193 -0
  148. package/rules/stacks/api-backend.yaml +121 -0
  149. package/rules/stacks/cli.yaml +105 -0
  150. package/rules/stacks/compliance.yaml +157 -0
  151. package/rules/stacks/containers.yaml +124 -0
  152. package/rules/stacks/data.yaml +165 -0
  153. package/rules/stacks/go.yaml +134 -0
  154. package/rules/stacks/iac.yaml +128 -0
  155. package/rules/stacks/jvm.yaml +150 -0
  156. package/rules/stacks/ml-ai.yaml +140 -0
  157. package/rules/stacks/mobile.yaml +121 -0
  158. package/rules/stacks/node-typescript.yaml +166 -0
  159. package/rules/stacks/python.yaml +175 -0
  160. package/rules/stacks/rust.yaml +129 -0
  161. package/rules/stacks/solidity.yaml +139 -0
  162. package/rules/stacks/swift.yaml +100 -0
  163. package/rules/stacks/web-frontend.yaml +159 -0
@@ -0,0 +1,88 @@
1
+ import { type Snapshot } from '../snapshot/index.js';
2
+ import { Store } from '../store/index.js';
3
+ import type { AuditReport, Facts } from '../types.js';
4
+ import { type QueueSummary } from './queue.js';
5
+ import { type ScheduleResult } from './schedule.js';
6
+ import type { AuditRun, BenchmarkCase, Capability, CapabilityGap, CandidateCapability, CoverageModel, ReAuditDelta, ReleaseDecision, ReleaseGate } from './types.js';
7
+ export interface EvolutionCycleInput {
8
+ target: string;
9
+ rulesDir?: string;
10
+ engineVersion?: string;
11
+ repository?: string;
12
+ candidateCapability?: Capability;
13
+ benchmarkCases?: BenchmarkCase[];
14
+ releaseGate?: ReleaseGate;
15
+ store?: Store;
16
+ /**
17
+ * When no explicit candidate is supplied, propose one (or more) from the
18
+ * BEFORE gaps, deterministically, and run the first proposable candidate
19
+ * through benchmark + release. Nothing is registered — the proposal is a
20
+ * candidate only. Records the full proposal list on the output.
21
+ */
22
+ proposeFromGaps?: boolean;
23
+ /** Called for each gap that could not be turned into a candidate. */
24
+ onUnproposable?: (gap: CapabilityGap, reason: string) => void;
25
+ /**
26
+ * Path to a previously generated USA report. When no explicit candidate is
27
+ * supplied, its open findings are turned into a `learn-proposals` candidate of
28
+ * manual checks (`usa learn` → proposal). Lower precedence than
29
+ * `candidateCapability`; higher than `proposeFromGaps`.
30
+ */
31
+ learnReportPath?: string;
32
+ /** Minimum severity considered when learning from `learnReportPath`. */
33
+ learnMinSeverity?: 'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW' | 'FUTURE';
34
+ /**
35
+ * When true, and only when there is no explicit `candidateCapability` and no
36
+ * `learnReportPath`, evaluate EVERY proposable candidate (one per open gap)
37
+ * via `scheduleCandidates` instead of just the first. Ignored otherwise.
38
+ */
39
+ allGaps?: boolean;
40
+ /**
41
+ * Persist gaps into the persistent queue and close the targeted gap(s) when a
42
+ * candidate is accepted. Defaults to true when a `store` is present. Requires
43
+ * a store; ignored otherwise.
44
+ */
45
+ persistGaps?: boolean;
46
+ }
47
+ export interface AuditWithCoverage {
48
+ report: AuditReport;
49
+ facts: Facts;
50
+ coverage: CoverageModel;
51
+ gaps: CapabilityGap[];
52
+ capabilitySetId: string;
53
+ auditRunId: string;
54
+ runRecord: AuditRun;
55
+ }
56
+ export interface EvolutionCycleOutput {
57
+ snapshot: Snapshot;
58
+ before: AuditWithCoverage;
59
+ /** Candidate actually benchmarked/released (explicit or auto-proposed). */
60
+ candidate?: {
61
+ capabilityId: string;
62
+ gapIds: string[];
63
+ release?: ReleaseDecision;
64
+ };
65
+ /** All candidates proposed from gaps (empty when none were requested). */
66
+ proposed: CandidateCapability[];
67
+ /** Suggestion count when the candidate was learned from a report. */
68
+ learnedSuggestions?: number;
69
+ /** Persistent-queue view after the run (when a store was used). */
70
+ queue?: QueueSummary;
71
+ /** Batch scheduler outcome (only in `allGaps` mode). */
72
+ schedule?: ScheduleResult;
73
+ after?: AuditWithCoverage & {
74
+ delta: ReAuditDelta;
75
+ };
76
+ }
77
+ /**
78
+ * The full, deterministic evolution cycle:
79
+ *
80
+ * SNAPSHOT → AUDIT → COVERAGE → GAPS → (CANDIDATE → BENCHMARK → RELEASE)
81
+ * → RE-AUDIT → DELTA
82
+ *
83
+ * No LLM is required: every stage is a deterministic function of the snapshot +
84
+ * capability set + engine version. Records written to the Store are
85
+ * content-addressed and reproducible.
86
+ */
87
+ export declare function runEvolutionCycle(input: EvolutionCycleInput): EvolutionCycleOutput;
88
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/evolution/run.ts"],"names":[],"mappings":"AAGA,OAAO,EAA8C,KAAK,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACjG,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAQtD,OAAO,EAAY,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,KAAK,EACV,QAAQ,EACR,aAAa,EACb,UAAU,EACV,aAAa,EACb,mBAAmB,EACnB,aAAa,EACb,YAAY,EACZ,eAAe,EACf,WAAW,EACZ,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,UAAU,CAAC;IACjC,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;IACjC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,KAAK,CAAC,EAAE,KAAK,CAAC;IACd;;;;;OAKG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,qEAAqE;IACrE,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9D;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,QAAQ,CAAC;IACrE;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,aAAa,CAAC;IACxB,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,QAAQ,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,2EAA2E;IAC3E,SAAS,CAAC,EAAE;QACV,YAAY,EAAE,MAAM,CAAC;QACrB,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,OAAO,CAAC,EAAE,eAAe,CAAC;KAC3B,CAAC;IACF,0EAA0E;IAC1E,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,qEAAqE;IACrE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mEAAmE;IACnE,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,KAAK,CAAC,EAAE,iBAAiB,GAAG;QAAE,KAAK,EAAE,YAAY,CAAA;KAAE,CAAC;CACrD;AAID;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,mBAAmB,GAAG,oBAAoB,CA2ClF"}
@@ -0,0 +1,258 @@
1
+ import { runAudit } from '../engine/audit.js';
2
+ import { detect, loadDetectorFile } from '../detect/index.js';
3
+ import { Project } from '../util/project.js';
4
+ import { canonicalJson, hashText, snapshotOfProject } from '../snapshot/index.js';
5
+ import { computeCoverage } from './coverage.js';
6
+ import { deriveGaps } from './gap.js';
7
+ import { basePackIds, resolveCapabilitySetId } from './capability.js';
8
+ import { runBenchmark } from './benchmark.js';
9
+ import { DEFAULT_RELEASE_GATE, evaluateRelease } from './release.js';
10
+ import { proposeCandidates, proposeFromSuggestions } from './propose.js';
11
+ import { learnFromReport } from '../learn/index.js';
12
+ import { GapQueue } from './queue.js';
13
+ import { scheduleCandidates } from './schedule.js';
14
+ const OPEN = new Set(['FAIL', 'WRONG', 'MISSING', 'DEPRECATED', 'EXPERIMENTAL']);
15
+ /**
16
+ * The full, deterministic evolution cycle:
17
+ *
18
+ * SNAPSHOT → AUDIT → COVERAGE → GAPS → (CANDIDATE → BENCHMARK → RELEASE)
19
+ * → RE-AUDIT → DELTA
20
+ *
21
+ * No LLM is required: every stage is a deterministic function of the snapshot +
22
+ * capability set + engine version. Records written to the Store are
23
+ * content-addressed and reproducible.
24
+ */
25
+ export function runEvolutionCycle(input) {
26
+ const engineVersion = input.engineVersion ?? 'dev';
27
+ const snapshot = makeSnapshot(input.target);
28
+ const before = audit(input, snapshot, engineVersion, [], input.repository);
29
+ const out = { snapshot, before, proposed: [] };
30
+ const queue = useQueue(input);
31
+ if (queue) {
32
+ queue.recordGaps(before.gaps);
33
+ out.queue = queue.summarize();
34
+ }
35
+ const candidate = resolveCandidate(input, before, out);
36
+ if (isAllGapsMode(input)) {
37
+ runAllGaps(input, snapshot, before, out, queue, engineVersion);
38
+ return out;
39
+ }
40
+ if (!candidate)
41
+ return out;
42
+ const gate = input.releaseGate ?? DEFAULT_RELEASE_GATE;
43
+ const bench = runBenchmark(candidate, input.benchmarkCases ?? [], input.rulesDir, engineVersion);
44
+ const release = evaluateRelease(bench, gate);
45
+ // Gaps this candidate provably targets, by required capability. This drives
46
+ // the queue — it must be exact, never a "the candidate is about everything"
47
+ // fallback, or an unrelated release would close unrelated gaps.
48
+ const targeted = before.gaps
49
+ .filter((g) => g.requiredCapability === candidate.id)
50
+ .map((g) => g.id);
51
+ out.candidate = {
52
+ capabilityId: candidate.id,
53
+ gapIds: targeted,
54
+ release,
55
+ };
56
+ input.store?.put({ kind: 'benchmark', capabilityId: candidate.id, ...bench });
57
+ input.store?.put({ kind: 'release', capabilityId: candidate.id, ...release });
58
+ if (release.decision === 'ACCEPT') {
59
+ const after = audit(input, snapshot, engineVersion, [candidate], input.repository);
60
+ out.after = { ...after, delta: compareReAudit(before, after) };
61
+ releaseIntoQueue(queue, out, candidate, targeted);
62
+ }
63
+ return out;
64
+ }
65
+ /**
66
+ * Whether this run should sweep every proposable candidate. Only an explicit
67
+ * `allGaps` with no explicit candidate and no report to learn from qualifies;
68
+ * everything else keeps the single-candidate behavior.
69
+ */
70
+ function isAllGapsMode(input) {
71
+ return !!input.allGaps && !input.candidateCapability && !input.learnReportPath;
72
+ }
73
+ /**
74
+ * The batch, queue-driven half of the loop: evaluate EVERY proposable
75
+ * candidate (one per open gap) through the scheduler. The first RELEASED
76
+ * candidate defines the output `candidate` and drives a single re-audit; if
77
+ * nothing releases, `candidate` reflects the first attempt and `after` stays
78
+ * undefined. Never runs the single-candidate path, so nothing is benchmarked
79
+ * twice.
80
+ */
81
+ function runAllGaps(input, snapshot, before, out, queue, engineVersion) {
82
+ const proposed = proposeCandidates(before.coverage, before.gaps, {
83
+ createdBy: 'evolution:propose',
84
+ onUnproposable: input.onUnproposable,
85
+ });
86
+ out.proposed = proposed;
87
+ const result = scheduleCandidates({
88
+ candidates: proposed,
89
+ gaps: before.gaps,
90
+ benchmarkCases: input.benchmarkCases,
91
+ rulesDir: input.rulesDir,
92
+ engineVersion,
93
+ releaseGate: input.releaseGate,
94
+ queue,
95
+ persist: input.store ? (kind, body) => input.store.put({ kind, ...body }) : undefined,
96
+ });
97
+ out.schedule = result;
98
+ if (queue)
99
+ out.queue = queue.summarize();
100
+ const firstReleased = result.candidates.find((c) => c.outcome === 'RELEASED');
101
+ const primary = firstReleased ?? result.candidates[0];
102
+ if (!primary)
103
+ return;
104
+ out.candidate = {
105
+ capabilityId: primary.capabilityId,
106
+ gapIds: primary.gapIds,
107
+ release: primary.release,
108
+ };
109
+ if (!firstReleased)
110
+ return;
111
+ const capability = proposed.find((c) => c.capability.id === firstReleased.capabilityId)?.capability;
112
+ if (!capability)
113
+ return;
114
+ const after = audit(input, snapshot, engineVersion, [capability], input.repository);
115
+ out.after = { ...after, delta: compareReAudit(before, after) };
116
+ }
117
+ /** A released capability closes exactly the queue gaps it targeted. */
118
+ function releaseIntoQueue(queue, out, candidate, targeted) {
119
+ if (!queue || targeted.length === 0)
120
+ return;
121
+ queue.closeGaps(targeted, `released ${candidate.id}@${candidate.version ?? '?'}`);
122
+ out.queue = queue.summarize();
123
+ }
124
+ /** The persistent gap queue, when a store backs this run. */
125
+ function useQueue(input) {
126
+ const enabled = input.persistGaps ?? input.store !== undefined;
127
+ if (!enabled || !input.store)
128
+ return undefined;
129
+ return new GapQueue(input.store);
130
+ }
131
+ /**
132
+ * Choose the capability to benchmark: the explicit one, or the first candidate
133
+ * auto-proposed from the BEFORE gaps. When proposing, all proposals are
134
+ * recorded on the output (even though only the first is evaluated this run).
135
+ */
136
+ function resolveCandidate(input, before, out) {
137
+ if (input.candidateCapability)
138
+ return input.candidateCapability;
139
+ if (input.learnReportPath)
140
+ return learnCandidate(input, out);
141
+ if (!input.proposeFromGaps)
142
+ return undefined;
143
+ const proposed = proposeCandidates(before.coverage, before.gaps, {
144
+ createdBy: 'evolution:propose',
145
+ onUnproposable: input.onUnproposable,
146
+ });
147
+ out.proposed = proposed;
148
+ return proposed[0]?.capability;
149
+ }
150
+ /** Turn a report's open findings into a `learn-proposals` candidate. */
151
+ function learnCandidate(input, out) {
152
+ let suggestions;
153
+ try {
154
+ suggestions = learnFromReport({
155
+ reportPath: input.learnReportPath,
156
+ minSeverity: input.learnMinSeverity,
157
+ });
158
+ }
159
+ catch (err) {
160
+ // A malformed/foreign report must not abort the audit: warn and continue
161
+ // with the BEFORE half (consistent with ADR-0009: fail closed, not crash).
162
+ input.onUnproposable?.({ id: 'learn-proposals' }, `could not learn from ${input.learnReportPath}: ${err.message}`);
163
+ return undefined;
164
+ }
165
+ out.learnedSuggestions = suggestions.length;
166
+ const candidate = proposeFromSuggestions(suggestions, { createdBy: 'evolution:learn' });
167
+ if (!candidate) {
168
+ input.onUnproposable?.({ id: 'learn-proposals' }, `no actionable suggestions in ${input.learnReportPath}`);
169
+ return undefined;
170
+ }
171
+ out.proposed = [candidate];
172
+ return candidate.capability;
173
+ }
174
+ /* -------------------------------------------------------------------- core -- */
175
+ function makeSnapshot(target) {
176
+ const project = new Project(target);
177
+ const git = project.gitInfo();
178
+ return snapshotOfProject(project, git.isRepo ? { commit: git.commit, ref: git.ref, repoUrl: git.repoUrl } : null);
179
+ }
180
+ function audit(input, snapshot, engineVersion, extraCapabilities, repository) {
181
+ const started = new Date().toISOString();
182
+ const outcome = runAudit({
183
+ target: snapshot.root,
184
+ rulesDir: input.rulesDir,
185
+ usaVersion: engineVersion,
186
+ extraPacks: extraCapabilities.map((c) => c.pack).filter((p) => !!p),
187
+ });
188
+ const report = outcome.report;
189
+ // Capability set identity is resolved from the *same* rules dir the audit
190
+ // used, so the reproducibility boundary is exactly what ran.
191
+ const capabilitySetId = resolveCapabilitySetId(basePackIds(report.options.rulesDir), extraCapabilities, engineVersion);
192
+ const project = new Project(snapshot.root);
193
+ const git = project.gitInfo();
194
+ const detection = detect(project, loadDetectorFile(report.options.rulesDir), git, []);
195
+ const facts = detection.facts;
196
+ const extraLangs = extraCapabilities.flatMap((c) => c.languages ?? []);
197
+ const coverage = computeCoverage(report, facts, extraLangs);
198
+ const resultId = input.store ? input.store.put(report) : undefined;
199
+ const body = {
200
+ repository: repository ?? git.repoUrl ?? snapshot.root,
201
+ snapshotId: snapshot.id,
202
+ capabilitySetId,
203
+ engineVersion,
204
+ status: 'completed',
205
+ startedAt: started,
206
+ endedAt: new Date().toISOString(),
207
+ resultId,
208
+ provenance: {},
209
+ };
210
+ // The run's identity is its content address (stored without an `id` field so
211
+ // the address is exactly the hash of the stored bytes, hence retrievable).
212
+ const auditRunId = input.store ? input.store.put(body) : hashText(canonicalJson(body));
213
+ const runRecord = { id: auditRunId, ...body };
214
+ const gaps = deriveGaps(coverage, auditRunId, snapshot.id);
215
+ return { report, facts, coverage, gaps, capabilitySetId, auditRunId, runRecord };
216
+ }
217
+ /* ------------------------------------------------------------------ delta -- */
218
+ function openStatuses(report) {
219
+ const map = new Map();
220
+ for (const f of report.findings)
221
+ map.set(f.ruleId, f.status);
222
+ return map;
223
+ }
224
+ function compareReAudit(before, after) {
225
+ const gapReduced = before.gaps.some((g) => g.kind === 'unsupported-technology' && after.coverage.coveredLanguages.includes(g.target));
226
+ const b = openStatuses(before.report);
227
+ const a = openStatuses(after.report);
228
+ const findingsAdded = [];
229
+ const findingsRemoved = [];
230
+ for (const id of new Set([...b.keys(), ...a.keys()])) {
231
+ const was = b.get(id) ?? 'NOT_APPLICABLE';
232
+ const is = a.get(id) ?? 'NOT_APPLICABLE';
233
+ const wasOpen = OPEN.has(was);
234
+ const isOpen = OPEN.has(is);
235
+ if (!wasOpen && isOpen)
236
+ findingsAdded.push(id);
237
+ else if (wasOpen && !isOpen)
238
+ findingsRemoved.push(id);
239
+ }
240
+ return {
241
+ before: {
242
+ automationCoverage: before.coverage.automationCoverage,
243
+ languageCoverage: before.coverage.languageCoverage,
244
+ unsupported: before.coverage.unsupportedLanguages,
245
+ },
246
+ after: {
247
+ automationCoverage: after.coverage.automationCoverage,
248
+ languageCoverage: after.coverage.languageCoverage,
249
+ unsupported: after.coverage.unsupportedLanguages,
250
+ },
251
+ coverageDelta: after.coverage.languageCoverage - before.coverage.languageCoverage,
252
+ findingsAdded,
253
+ findingsRemoved,
254
+ gapReduced,
255
+ intendedFindingDetectable: findingsAdded.length > 0,
256
+ };
257
+ }
258
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/evolution/run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ import type { GapQueue } from './queue.js';
2
+ import type { BenchmarkCase, BenchmarkResult, CandidateCapability, CapabilityGap, ReleaseDecision, ReleaseGate } from './types.js';
3
+ /**
4
+ * The queue-driven scheduler: the unattended half of the loop.
5
+ *
6
+ * A single cycle evaluates one candidate. The scheduler walks a *batch* of
7
+ * candidates (one per open gap, produced by the proposal stage) and runs each
8
+ * through BENCHMARK → RELEASE, closing the queue gap for every accepted
9
+ * capability. It is still fully deterministic and offline: the same candidates,
10
+ * cases, and gate produce the same outcome list, and nothing is ever registered.
11
+ *
12
+ * The scheduler never proposes and never audits — it is a pure coordination of
13
+ * the stages that already exist, so it cannot invent work the proposal and gate
14
+ * steps would not have produced anyway.
15
+ */
16
+ export interface ScheduledCandidate {
17
+ capabilityId: string;
18
+ /** Gaps this candidate targeted (by required capability). */
19
+ gapIds: string[];
20
+ release: ReleaseDecision;
21
+ outcome: 'RELEASED' | 'REJECTED';
22
+ /** Queue gaps actually closed by this release (empty when rejected). */
23
+ closedGapIds: string[];
24
+ benchmark: BenchmarkResult;
25
+ /**
26
+ * Set when the scheduler overrode an ACCEPT to a REJECT because the candidate
27
+ * offers no automated detection to prove (e.g. only `manual` checks).
28
+ */
29
+ blockedReason?: string;
30
+ }
31
+ export interface ScheduleResult {
32
+ attempted: number;
33
+ released: number;
34
+ rejected: number;
35
+ candidates: ScheduledCandidate[];
36
+ }
37
+ export interface ScheduleInput {
38
+ /** Candidates to evaluate, in the order they should be attempted. */
39
+ candidates: CandidateCapability[];
40
+ /** The BEFORE gaps, used to map each candidate to the gaps it targets. */
41
+ gaps: CapabilityGap[];
42
+ benchmarkCases?: BenchmarkCase[];
43
+ rulesDir?: string;
44
+ engineVersion?: string;
45
+ releaseGate?: ReleaseGate;
46
+ /** When present, accepted candidates close their targeted gaps. */
47
+ queue?: GapQueue;
48
+ /** Persist benchmark + release records (needs a store). */
49
+ persist?: (kind: 'benchmark' | 'release', body: Record<string, unknown>) => void;
50
+ }
51
+ /**
52
+ * Evaluate every candidate in order and return one outcome per candidate.
53
+ *
54
+ * The order is significant and preserved: the caller (which sorted gaps by
55
+ * priority then id) decides what "first" means. Each candidate is independent,
56
+ * so a rejection never blocks a later release.
57
+ */
58
+ export declare function scheduleCandidates(input: ScheduleInput): ScheduleResult;
59
+ //# sourceMappingURL=schedule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule.d.ts","sourceRoot":"","sources":["../../src/evolution/schedule.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,WAAW,EACZ,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,eAAe,CAAC;IACzB,OAAO,EAAE,UAAU,GAAG,UAAU,CAAC;IACjC,wEAAwE;IACxE,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,EAAE,eAAe,CAAC;IAC3B;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,kBAAkB,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,aAAa;IAC5B,qEAAqE;IACrE,UAAU,EAAE,mBAAmB,EAAE,CAAC;IAClC,0EAA0E;IAC1E,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,mEAAmE;IACnE,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;CAClF;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,aAAa,GAAG,cAAc,CAIvE"}
@@ -0,0 +1,77 @@
1
+ import { runBenchmark } from './benchmark.js';
2
+ import { evaluateRelease, DEFAULT_RELEASE_GATE } from './release.js';
3
+ /**
4
+ * Evaluate every candidate in order and return one outcome per candidate.
5
+ *
6
+ * The order is significant and preserved: the caller (which sorted gaps by
7
+ * priority then id) decides what "first" means. Each candidate is independent,
8
+ * so a rejection never blocks a later release.
9
+ */
10
+ export function scheduleCandidates(input) {
11
+ const gate = input.releaseGate ?? DEFAULT_RELEASE_GATE;
12
+ const candidates = input.candidates.map((candidate) => evaluateCandidate(candidate, input, gate));
13
+ return summarize(candidates);
14
+ }
15
+ /** Benchmark → gate → (release ⇒ close) for one candidate. */
16
+ function evaluateCandidate(candidate, input, gate) {
17
+ const benchmark = runBenchmark(candidate.capability, input.benchmarkCases ?? [], input.rulesDir, input.engineVersion ?? 'dev');
18
+ const release = evaluateRelease(benchmark, gate);
19
+ const gapIds = targetedGapIds(input.gaps, candidate.capability.id);
20
+ input.persist?.('benchmark', { capabilityId: candidate.capability.id, ...benchmark });
21
+ input.persist?.('release', { capabilityId: candidate.capability.id, ...release });
22
+ // A gate ACCEPT only proves the candidate matches its fixtures. A candidate
23
+ // whose pack is entirely `manual` checks proves nothing automated: every
24
+ // `manual` check is UNKNOWN, so it trivially has zero FP/FN and would pass
25
+ // on a vacuous benchmark. Releasing it would close a real gap with a
26
+ // capability that detects nothing — so the scheduler refuses.
27
+ const blockedReason = release.decision === 'ACCEPT' ? unbenchmarkable(candidate) : undefined;
28
+ const released = release.decision === 'ACCEPT' && blockedReason === undefined;
29
+ const entry = {
30
+ capabilityId: candidate.capability.id,
31
+ gapIds,
32
+ release,
33
+ outcome: released ? 'RELEASED' : 'REJECTED',
34
+ closedGapIds: released ? closeTargets(input, candidate, gapIds) : [],
35
+ benchmark,
36
+ };
37
+ if (blockedReason)
38
+ entry.blockedReason = blockedReason;
39
+ return entry;
40
+ }
41
+ /** Close the queue gaps a released candidate targets (empty when no queue). */
42
+ function closeTargets(input, candidate, gapIds) {
43
+ if (!input.queue)
44
+ return [];
45
+ return input.queue.closeGaps(gapIds, `released ${candidate.capability.id}@${candidate.capability.version ?? '?'}`);
46
+ }
47
+ /**
48
+ * Why a candidate must not be released despite a passing gate, or undefined if
49
+ * it is genuinely releasable. Today: a pack with no automated (non-`manual`)
50
+ * rule cannot be proven to detect anything.
51
+ */
52
+ function unbenchmarkable(candidate) {
53
+ const rules = candidate.capability.pack?.rules ?? [];
54
+ if (rules.length === 0)
55
+ return 'capability contributes no rules';
56
+ const automated = rules.filter((r) => r.check.kind !== 'manual');
57
+ if (automated.length === 0) {
58
+ return `only manual checks (${rules.length}) — no automated detection to prove`;
59
+ }
60
+ return undefined;
61
+ }
62
+ /** Gaps a candidate provably targets, by required capability. Never a fallback. */
63
+ function targetedGapIds(gaps, capabilityId) {
64
+ return gaps.filter((g) => g.requiredCapability === capabilityId).map((g) => g.id);
65
+ }
66
+ function summarize(candidates) {
67
+ let released = 0;
68
+ let rejected = 0;
69
+ for (const c of candidates) {
70
+ if (c.outcome === 'RELEASED')
71
+ released += 1;
72
+ else
73
+ rejected += 1;
74
+ }
75
+ return { attempted: candidates.length, released, rejected, candidates };
76
+ }
77
+ //# sourceMappingURL=schedule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule.js","sourceRoot":"","sources":["../../src/evolution/schedule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AA+DrE;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAoB;IACrD,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,IAAI,oBAAoB,CAAC;IACvD,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;IAClG,OAAO,SAAS,CAAC,UAAU,CAAC,CAAC;AAC/B,CAAC;AAED,8DAA8D;AAC9D,SAAS,iBAAiB,CACxB,SAA8B,EAC9B,KAAoB,EACpB,IAAiB;IAEjB,MAAM,SAAS,GAAG,YAAY,CAC5B,SAAS,CAAC,UAAU,EACpB,KAAK,CAAC,cAAc,IAAI,EAAE,EAC1B,KAAK,CAAC,QAAQ,EACd,KAAK,CAAC,aAAa,IAAI,KAAK,CAC7B,CAAC;IACF,MAAM,OAAO,GAAG,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IACnE,KAAK,CAAC,OAAO,EAAE,CAAC,WAAW,EAAE,EAAE,YAAY,EAAE,SAAS,CAAC,UAAU,CAAC,EAAE,EAAE,GAAG,SAAS,EAAE,CAAC,CAAC;IACtF,KAAK,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,EAAE,YAAY,EAAE,SAAS,CAAC,UAAU,CAAC,EAAE,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;IAElF,4EAA4E;IAC5E,yEAAyE;IACzE,2EAA2E;IAC3E,qEAAqE;IACrE,8DAA8D;IAC9D,MAAM,aAAa,GAAG,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7F,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,KAAK,QAAQ,IAAI,aAAa,KAAK,SAAS,CAAC;IAE9E,MAAM,KAAK,GAAuB;QAChC,YAAY,EAAE,SAAS,CAAC,UAAU,CAAC,EAAE;QACrC,MAAM;QACN,OAAO;QACP,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU;QAC3C,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;QACpE,SAAS;KACV,CAAC;IACF,IAAI,aAAa;QAAE,KAAK,CAAC,aAAa,GAAG,aAAa,CAAC;IACvD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,+EAA+E;AAC/E,SAAS,YAAY,CACnB,KAAoB,EACpB,SAA8B,EAC9B,MAAgB;IAEhB,IAAI,CAAC,KAAK,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IAC5B,OAAO,KAAK,CAAC,KAAK,CAAC,SAAS,CAC1B,MAAM,EACN,YAAY,SAAS,CAAC,UAAU,CAAC,EAAE,IAAI,SAAS,CAAC,UAAU,CAAC,OAAO,IAAI,GAAG,EAAE,CAC7E,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,eAAe,CAAC,SAA8B;IACrD,MAAM,KAAK,GAAG,SAAS,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;IACrD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,iCAAiC,CAAC;IACjE,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IACjE,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,uBAAuB,KAAK,CAAC,MAAM,qCAAqC,CAAC;IAClF,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,mFAAmF;AACnF,SAAS,cAAc,CAAC,IAAqB,EAAE,YAAoB;IACjE,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,kBAAkB,KAAK,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AACpF,CAAC;AAED,SAAS,SAAS,CAAC,UAAgC;IACjD,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,OAAO,KAAK,UAAU;YAAE,QAAQ,IAAI,CAAC,CAAC;;YACvC,QAAQ,IAAI,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;AAC1E,CAAC"}