@xenos1996/usa 2.3.3 → 2.4.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 (39) hide show
  1. package/README.md +2 -2
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +21 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/engine/audit.d.ts.map +1 -1
  6. package/dist/engine/audit.js +22 -0
  7. package/dist/engine/audit.js.map +1 -1
  8. package/dist/engine/evaluate.d.ts.map +1 -1
  9. package/dist/engine/evaluate.js +1 -0
  10. package/dist/engine/evaluate.js.map +1 -1
  11. package/dist/foundation/interview.d.ts +63 -0
  12. package/dist/foundation/interview.d.ts.map +1 -0
  13. package/dist/foundation/interview.js +459 -0
  14. package/dist/foundation/interview.js.map +1 -0
  15. package/dist/foundation/loader.d.ts +22 -0
  16. package/dist/foundation/loader.d.ts.map +1 -0
  17. package/dist/foundation/loader.js +240 -0
  18. package/dist/foundation/loader.js.map +1 -0
  19. package/dist/foundation/types.d.ts +73 -0
  20. package/dist/foundation/types.d.ts.map +1 -0
  21. package/dist/foundation/types.js +55 -0
  22. package/dist/foundation/types.js.map +1 -0
  23. package/dist/report/foundation.d.ts +44 -0
  24. package/dist/report/foundation.d.ts.map +1 -0
  25. package/dist/report/foundation.js +147 -0
  26. package/dist/report/foundation.js.map +1 -0
  27. package/dist/report/json.d.ts +1 -0
  28. package/dist/report/json.d.ts.map +1 -1
  29. package/dist/report/json.js +2 -0
  30. package/dist/report/json.js.map +1 -1
  31. package/dist/report/markdown.d.ts.map +1 -1
  32. package/dist/report/markdown.js +10 -0
  33. package/dist/report/markdown.js.map +1 -1
  34. package/dist/types.d.ts +6 -0
  35. package/dist/types.d.ts.map +1 -1
  36. package/dist/types.js.map +1 -1
  37. package/package.json +1 -1
  38. package/rules/core/foundation.yaml +307 -0
  39. package/rules/index.yaml +1 -0
@@ -0,0 +1,240 @@
1
+ /**
2
+ * Deterministic loader for the foundation intent file.
3
+ *
4
+ * Contract (fail-closed):
5
+ * - Missing `<root>/.usa/foundation.yaml` → `[]` (no intent, no facts).
6
+ * - Malformed YAML, unparseable dates, or unknown shapes → push nothing and
7
+ * THROW a loud Error naming the file. The caller (coordinator) converts the
8
+ * throw into an audit warning; we never silently audit against half an
9
+ * intent, so `loadFoundationFacts` either returns clean facts or throws.
10
+ * - Intent entries that do not sanitize to `lowercase [a-z0-9-]+` are skipped
11
+ * silently (no throw): a sloppy label must not fail the whole audit, it
12
+ * simply asserts nothing.
13
+ */
14
+ import fs from 'node:fs';
15
+ import path from 'node:path';
16
+ import { parse as parseYaml } from 'yaml';
17
+ import { FOUNDATION_BASENAME, FOUNDATION_DIR, FOUNDATION_VERSION, STAGE_OPTIONS, defaultFoundation, } from './types.js';
18
+ import { asMap, isMap } from '../util/yaml.js';
19
+ export function foundationFile(root) {
20
+ return path.join(root, FOUNDATION_DIR, FOUNDATION_BASENAME);
21
+ }
22
+ const INTENT_RE = /^[a-z0-9-]+$/;
23
+ /**
24
+ * Sanitizes one raw intents[] entry to an `intent:<value>` flag, or
25
+ * `undefined` when the entry is not usable. Never throws.
26
+ */
27
+ export function sanitizeIntent(value) {
28
+ if (typeof value !== 'string')
29
+ return undefined;
30
+ const slug = value.trim().toLowerCase();
31
+ if (!slug || !INTENT_RE.test(slug))
32
+ return undefined;
33
+ return `intent:${slug}`;
34
+ }
35
+ function fail(file, reason) {
36
+ throw new Error(`${file}: ${reason}`);
37
+ }
38
+ function hasDate(value) {
39
+ if (value instanceof Date)
40
+ return true;
41
+ if (Array.isArray(value))
42
+ return value.some(hasDate);
43
+ if (isMap(value))
44
+ return Object.values(value).some(hasDate);
45
+ return false;
46
+ }
47
+ function reqMap(file, where, value) {
48
+ if (!isMap(value))
49
+ fail(file, `expected "${where}" to be a YAML mapping`);
50
+ return value;
51
+ }
52
+ function reqStrList(file, where, value) {
53
+ if (!Array.isArray(value))
54
+ fail(file, `expected "${where}" to be a YAML list`);
55
+ return value.map((entry) => String(entry));
56
+ }
57
+ function reqBool(file, where, value) {
58
+ if (typeof value !== 'boolean')
59
+ fail(file, `expected "${where}" to be true/false`);
60
+ return value;
61
+ }
62
+ /**
63
+ * Strictly parses foundation YAML text into a FoundationConfig. Unknown
64
+ * shapes throw; absent pillar sections backfill from defaults so the result
65
+ * always satisfies the schema. Exported for `foundation show` and tests.
66
+ *
67
+ * One section per helper — adding a pillar section means adding a function,
68
+ * not growing this one (see docs; the complexity budget is enforced by lint).
69
+ */
70
+ export function parseFoundationYamlText(text, file) {
71
+ const doc = readYamlDoc(text, file);
72
+ const project = parseProjectSection(doc, file);
73
+ const stage = parseStageValue(doc, file);
74
+ return {
75
+ version: FOUNDATION_VERSION,
76
+ project,
77
+ ...(stage === undefined ? {} : { stage }),
78
+ pillars: parsePillarsSection(doc, project.name, file),
79
+ };
80
+ }
81
+ /** Parse + top-level shape checks, in the order a human debugs them. */
82
+ function readYamlDoc(text, file) {
83
+ let raw;
84
+ try {
85
+ raw = parseYaml(text);
86
+ }
87
+ catch (err) {
88
+ fail(file, `malformed YAML (${err.message})`);
89
+ }
90
+ if (!isMap(raw))
91
+ fail(file, 'expected a YAML mapping at the top level');
92
+ if (hasDate(raw))
93
+ fail(file, 'unparseable date value (quote date-like strings)');
94
+ const doc = raw;
95
+ if (doc.version !== FOUNDATION_VERSION) {
96
+ fail(file, `unsupported version ${JSON.stringify(doc.version)} (expected 1)`);
97
+ }
98
+ return doc;
99
+ }
100
+ /** Defaults carrier: the project name seeds backfill for absent sections. */
101
+ function baseFor(name) {
102
+ return defaultFoundation(typeof name === 'string' && name ? name : 'project');
103
+ }
104
+ function parseProjectSection(doc, file) {
105
+ if (!isMap(doc.project))
106
+ fail(file, 'missing or invalid "project" mapping');
107
+ const project = doc.project;
108
+ if (project.name !== undefined && typeof project.name !== 'string') {
109
+ fail(file, 'expected "project.name" to be a string');
110
+ }
111
+ if (project.vision !== undefined && typeof project.vision !== 'string') {
112
+ fail(file, 'expected "project.vision" to be a string');
113
+ }
114
+ if (project.intents !== undefined && !Array.isArray(project.intents)) {
115
+ fail(file, 'expected "project.intents" to be a YAML list');
116
+ }
117
+ const base = baseFor(project.name);
118
+ return {
119
+ name: typeof project.name === 'string' ? project.name : base.project.name,
120
+ vision: typeof project.vision === 'string' ? project.vision : '',
121
+ intents: parseIntentsList(project, file),
122
+ };
123
+ }
124
+ /**
125
+ * A missing list means no intents. Non-string entries are not intents at
126
+ * all: they skip silently (no throw) at the fact boundary via
127
+ * sanitizeIntent. A stray non-string in intents[] asserts nothing.
128
+ */
129
+ function parseIntentsList(project, file) {
130
+ if (project.intents === undefined)
131
+ return [];
132
+ if (!Array.isArray(project.intents)) {
133
+ fail(file, 'expected "project.intents" to be a YAML list');
134
+ }
135
+ return project.intents.filter((entry) => typeof entry === 'string');
136
+ }
137
+ function parseStageValue(doc, file) {
138
+ if (doc.stage === undefined)
139
+ return undefined;
140
+ if (typeof doc.stage !== 'string')
141
+ fail(file, 'expected "stage" to be a string');
142
+ const stage = doc.stage;
143
+ if (!STAGE_OPTIONS.includes(stage)) {
144
+ fail(file, `unknown stage ${JSON.stringify(stage)} (expected one of ${STAGE_OPTIONS.join('|')})`);
145
+ }
146
+ return stage;
147
+ }
148
+ /**
149
+ * A present field is parsed, an absent one backfills — one generic shape for
150
+ * every leaf, so a new leaf is one call, not one branch.
151
+ */
152
+ function fieldOr(raw, key, fallback, file, where, parse) {
153
+ const value = raw[key];
154
+ return value === undefined ? fallback : parse(file, where, value);
155
+ }
156
+ /** A present section must be a mapping; an absent one backfills wholesale. */
157
+ function sectionOr(pillars, key, fallback, file, where) {
158
+ const value = pillars[key];
159
+ return value === undefined ? fallback : reqMap(file, where, value);
160
+ }
161
+ function parsePillarsSection(doc, name, file) {
162
+ if (doc.pillars !== undefined && !isMap(doc.pillars)) {
163
+ fail(file, 'expected "pillars" to be a YAML mapping');
164
+ }
165
+ const base = baseFor(name);
166
+ const pillars = asMap(doc.pillars);
167
+ return {
168
+ docs: {
169
+ required: fieldOr(sectionOr(pillars, 'docs', { ...base.pillars.docs }, file, 'pillars.docs'), 'required', [...base.pillars.docs.required], file, 'pillars.docs.required', reqStrList),
170
+ },
171
+ governance: parseGovernancePillar(pillars, base, file),
172
+ ai: parseAiPillar(pillars, base, file),
173
+ testing: parseTestingPillar(pillars, base, file),
174
+ environment: {
175
+ files: fieldOr(sectionOr(pillars, 'environment', { ...base.pillars.environment }, file, 'pillars.environment'), 'files', [...base.pillars.environment.files], file, 'pillars.environment.files', reqStrList),
176
+ },
177
+ pipelines: parsePipelinesPillar(pillars, base, file),
178
+ standards: fieldOr(pillars, 'standards', [], file, 'pillars.standards', reqStrList),
179
+ specs: fieldOr(pillars, 'specs', [], file, 'pillars.specs', reqStrList),
180
+ };
181
+ }
182
+ /** One boolean leaf per call — a new governance promise is one line. */
183
+ function parseGovernancePillar(pillars, base, file) {
184
+ const raw = sectionOr(pillars, 'governance', { ...base.pillars.governance }, file, 'pillars.governance');
185
+ const fallback = base.pillars.governance;
186
+ return {
187
+ codeOfConduct: fieldOr(raw, 'codeOfConduct', fallback.codeOfConduct, file, 'pillars.governance.codeOfConduct', reqBool),
188
+ contributing: fieldOr(raw, 'contributing', fallback.contributing, file, 'pillars.governance.contributing', reqBool),
189
+ securityPolicy: fieldOr(raw, 'securityPolicy', fallback.securityPolicy, file, 'pillars.governance.securityPolicy', reqBool),
190
+ license: fieldOr(raw, 'license', fallback.license, file, 'pillars.governance.license', reqBool),
191
+ };
192
+ }
193
+ function parseAiPillar(pillars, base, file) {
194
+ const raw = sectionOr(pillars, 'ai', { ...base.pillars.ai }, file, 'pillars.ai');
195
+ return {
196
+ readable: fieldOr(raw, 'readable', base.pillars.ai.readable, file, 'pillars.ai.readable', reqBool),
197
+ writable: fieldOr(raw, 'writable', base.pillars.ai.writable, file, 'pillars.ai.writable', reqBool),
198
+ };
199
+ }
200
+ function parseTestingPillar(pillars, base, file) {
201
+ const raw = sectionOr(pillars, 'testing', { ...base.pillars.testing }, file, 'pillars.testing');
202
+ const dirs = fieldOr(raw, 'dirs', [...base.pillars.testing.dirs], file, 'pillars.testing.dirs', reqStrList);
203
+ const minCoverage = parseCoverageBar(raw, base, file);
204
+ return { dirs, ...(minCoverage === undefined ? {} : { minCoverage }) };
205
+ }
206
+ /** `null` is how the renderer writes a cleared threshold; both mean "no bar". */
207
+ function parseCoverageBar(raw, base, file) {
208
+ const value = raw['minCoverage'];
209
+ if (value === undefined || value === null)
210
+ return base.pillars.testing.minCoverage;
211
+ if (typeof value !== 'number' || !Number.isFinite(value) || value < 0 || value > 100) {
212
+ fail(file, 'expected "pillars.testing.minCoverage" to be a number from 0 to 100');
213
+ }
214
+ return value;
215
+ }
216
+ function parsePipelinesPillar(pillars, base, file) {
217
+ const raw = sectionOr(pillars, 'pipelines', { ...base.pillars.pipelines }, file, 'pillars.pipelines');
218
+ return {
219
+ ci: fieldOr(raw, 'ci', [...base.pillars.pipelines.ci], file, 'pillars.pipelines.ci', reqStrList),
220
+ local: fieldOr(raw, 'local', [...base.pillars.pipelines.local], file, 'pillars.pipelines.local', reqStrList),
221
+ };
222
+ }
223
+ /**
224
+ * Reads `<root>/.usa/foundation.yaml` and returns one `intent:<value>` flag
225
+ * per usable intents[] entry. Missing file → `[]`. Anything broken → throws.
226
+ */
227
+ export function loadFoundationFacts(root) {
228
+ const file = foundationFile(root);
229
+ if (!fs.existsSync(file))
230
+ return [];
231
+ const config = parseFoundationYamlText(fs.readFileSync(file, 'utf8'), file);
232
+ const facts = [];
233
+ for (const entry of config.project.intents) {
234
+ const flag = sanitizeIntent(entry);
235
+ if (flag !== undefined)
236
+ facts.push(flag);
237
+ }
238
+ return facts;
239
+ }
240
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/foundation/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Foundation intent schema — the interview half of Foundation Readiness.
3
+ *
4
+ * This module is deterministic only: plain types, option vocabularies, and a
5
+ * defaults factory. No I/O, no LLM, no scoring. The coordinator (not this
6
+ * package) wires `loadFoundationFacts` output into audit facts; a broken
7
+ * intent file must therefore fail loudly at the parse boundary rather than
8
+ * silently auditing against half an intent.
9
+ */
10
+ /** The only foundation schema version this worker reads and writes. */
11
+ export declare const FOUNDATION_VERSION: 1;
12
+ /** Project-relative path of the intent file, e.g. `<root>/.usa/foundation.yaml`. */
13
+ export declare const FOUNDATION_DIR = ".usa";
14
+ export declare const FOUNDATION_BASENAME = "foundation.yaml";
15
+ /** Intents the interview multi-select offers. Fact flags are `intent:<value>`. */
16
+ export declare const INTENT_OPTIONS: readonly ["api", "cli", "library", "service", "frontend", "docs-site", "data-pipeline", "mobile"];
17
+ export type FoundationIntentOption = (typeof INTENT_OPTIONS)[number];
18
+ /** Stage targets the interview offers. Mirrors the audit maturity scale. */
19
+ export declare const STAGE_OPTIONS: readonly ["prototype", "mvp", "beta", "production", "legacy"];
20
+ export type FoundationStageOption = (typeof STAGE_OPTIONS)[number];
21
+ export interface FoundationProject {
22
+ name: string;
23
+ vision: string;
24
+ intents: string[];
25
+ }
26
+ export interface FoundationDocsPillar {
27
+ required: string[];
28
+ }
29
+ export interface FoundationGovernancePillar {
30
+ codeOfConduct: boolean;
31
+ contributing: boolean;
32
+ securityPolicy: boolean;
33
+ license: boolean;
34
+ }
35
+ export interface FoundationAiPillar {
36
+ readable: boolean;
37
+ writable: boolean;
38
+ }
39
+ export interface FoundationTestingPillar {
40
+ dirs: string[];
41
+ minCoverage?: number;
42
+ }
43
+ export interface FoundationEnvironmentPillar {
44
+ files: string[];
45
+ }
46
+ export interface FoundationPipelinesPillar {
47
+ ci: string[];
48
+ local: string[];
49
+ }
50
+ export interface FoundationPillars {
51
+ docs: FoundationDocsPillar;
52
+ governance: FoundationGovernancePillar;
53
+ ai: FoundationAiPillar;
54
+ testing: FoundationTestingPillar;
55
+ environment: FoundationEnvironmentPillar;
56
+ pipelines: FoundationPipelinesPillar;
57
+ standards: string[];
58
+ specs: string[];
59
+ }
60
+ export interface FoundationConfig {
61
+ version: typeof FOUNDATION_VERSION;
62
+ project: FoundationProject;
63
+ /** Stage the project is aiming at; one of STAGE_OPTIONS. */
64
+ stage?: string;
65
+ pillars: FoundationPillars;
66
+ }
67
+ /**
68
+ * The defaults file `--non-interactive` writes (and the interview starts
69
+ * from): stack-sensible, CI-safe, deliberately boring. Every value survives a
70
+ * `render → parse` round-trip.
71
+ */
72
+ export declare function defaultFoundation(projectName: string): FoundationConfig;
73
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/foundation/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,uEAAuE;AACvE,eAAO,MAAM,kBAAkB,EAAG,CAAU,CAAC;AAE7C,oFAAoF;AACpF,eAAO,MAAM,cAAc,SAAS,CAAC;AACrC,eAAO,MAAM,mBAAmB,oBAAoB,CAAC;AAErD,kFAAkF;AAClF,eAAO,MAAM,cAAc,mGASjB,CAAC;AAEX,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAErE,4EAA4E;AAC5E,eAAO,MAAM,aAAa,+DAAgE,CAAC;AAE3F,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,0BAA0B;IACzC,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,2BAA2B;IAC1C,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,yBAAyB;IACxC,EAAE,EAAE,MAAM,EAAE,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,oBAAoB,CAAC;IAC3B,UAAU,EAAE,0BAA0B,CAAC;IACvC,EAAE,EAAE,kBAAkB,CAAC;IACvB,OAAO,EAAE,uBAAuB,CAAC;IACjC,WAAW,EAAE,2BAA2B,CAAC;IACzC,SAAS,EAAE,yBAAyB,CAAC;IACrC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,kBAAkB,CAAC;IACnC,OAAO,EAAE,iBAAiB,CAAC;IAC3B,4DAA4D;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,iBAAiB,CAAC;CAC5B;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,gBAAgB,CAqBvE"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Foundation intent schema — the interview half of Foundation Readiness.
3
+ *
4
+ * This module is deterministic only: plain types, option vocabularies, and a
5
+ * defaults factory. No I/O, no LLM, no scoring. The coordinator (not this
6
+ * package) wires `loadFoundationFacts` output into audit facts; a broken
7
+ * intent file must therefore fail loudly at the parse boundary rather than
8
+ * silently auditing against half an intent.
9
+ */
10
+ /** The only foundation schema version this worker reads and writes. */
11
+ export const FOUNDATION_VERSION = 1;
12
+ /** Project-relative path of the intent file, e.g. `<root>/.usa/foundation.yaml`. */
13
+ export const FOUNDATION_DIR = '.usa';
14
+ export const FOUNDATION_BASENAME = 'foundation.yaml';
15
+ /** Intents the interview multi-select offers. Fact flags are `intent:<value>`. */
16
+ export const INTENT_OPTIONS = [
17
+ 'api',
18
+ 'cli',
19
+ 'library',
20
+ 'service',
21
+ 'frontend',
22
+ 'docs-site',
23
+ 'data-pipeline',
24
+ 'mobile',
25
+ ];
26
+ /** Stage targets the interview offers. Mirrors the audit maturity scale. */
27
+ export const STAGE_OPTIONS = ['prototype', 'mvp', 'beta', 'production', 'legacy'];
28
+ /**
29
+ * The defaults file `--non-interactive` writes (and the interview starts
30
+ * from): stack-sensible, CI-safe, deliberately boring. Every value survives a
31
+ * `render → parse` round-trip.
32
+ */
33
+ export function defaultFoundation(projectName) {
34
+ return {
35
+ version: FOUNDATION_VERSION,
36
+ project: { name: projectName, vision: '', intents: ['library'] },
37
+ stage: 'prototype',
38
+ pillars: {
39
+ docs: { required: ['README.md'] },
40
+ governance: {
41
+ codeOfConduct: true,
42
+ contributing: true,
43
+ securityPolicy: true,
44
+ license: true,
45
+ },
46
+ ai: { readable: true, writable: false },
47
+ testing: { dirs: ['tests'], minCoverage: 80 },
48
+ environment: { files: ['.env.example'] },
49
+ pipelines: { ci: ['.github/workflows/ci.yml'], local: ['test', 'build'] },
50
+ standards: [],
51
+ specs: [],
52
+ },
53
+ };
54
+ }
55
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/foundation/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,uEAAuE;AACvE,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAU,CAAC;AAE7C,oFAAoF;AACpF,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC;AACrC,MAAM,CAAC,MAAM,mBAAmB,GAAG,iBAAiB,CAAC;AAErD,kFAAkF;AAClF,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,KAAK;IACL,KAAK;IACL,SAAS;IACT,SAAS;IACT,UAAU;IACV,WAAW;IACX,eAAe;IACf,QAAQ;CACA,CAAC;AAIX,4EAA4E;AAC5E,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,CAAU,CAAC;AA2D3F;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,WAAmB;IACnD,OAAO;QACL,OAAO,EAAE,kBAAkB;QAC3B,OAAO,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,SAAS,CAAC,EAAE;QAChE,KAAK,EAAE,WAAW;QAClB,OAAO,EAAE;YACP,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC,WAAW,CAAC,EAAE;YACjC,UAAU,EAAE;gBACV,aAAa,EAAE,IAAI;gBACnB,YAAY,EAAE,IAAI;gBAClB,cAAc,EAAE,IAAI;gBACpB,OAAO,EAAE,IAAI;aACd;YACD,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE;YACvC,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE;YAC7C,WAAW,EAAE,EAAE,KAAK,EAAE,CAAC,cAAc,CAAC,EAAE;YACxC,SAAS,EAAE,EAAE,EAAE,EAAE,CAAC,0BAA0B,CAAC,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;YACzE,SAAS,EAAE,EAAE;YACb,KAAK,EAAE,EAAE;SACV;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,44 @@
1
+ import type { Finding } from '../types.js';
2
+ /**
3
+ * Foundation readiness section (FND-* rule pack).
4
+ *
5
+ * Frozen contract with the interview/loader and rule-pack workers: a
6
+ * foundation finding is a report finding whose `ruleId` starts with `FND-`
7
+ * and which carries `tags: ['pillar:<id>']`, where `<id>` is exactly one of
8
+ * the seven pillar ids below. Findings are read defensively — `tags` is not
9
+ * yet on the `Finding` interface in this worktree, so pillar membership is
10
+ * resolved through a structural cast and anything without a recognised
11
+ * pillar tag falls into a trailing "Other" group rather than being dropped.
12
+ *
13
+ * Pure and deterministic: fixed pillar order, items sorted by rule id, no
14
+ * dates, no randomness. Returns `[]` when there is nothing foundation to
15
+ * report so the caller can skip the section silently.
16
+ */
17
+ export declare const FOUNDATION_PREFIX = "FND-";
18
+ export interface FoundationPillar {
19
+ id: string;
20
+ title: string;
21
+ icon: string;
22
+ }
23
+ /** The seven foundation pillars, in stable presentation order. */
24
+ export declare const FOUNDATION_PILLARS: readonly FoundationPillar[];
25
+ export type FoundationGrade = 'READY' | 'PARTIAL' | 'MISSING';
26
+ /** True for findings produced by the foundation (FND-*) rule pack. */
27
+ export declare function isFoundationFinding(f: Finding): boolean;
28
+ /**
29
+ * The pillar a foundation finding belongs to, from its `pillar:<id>` tag.
30
+ * Returns `null` when the finding carries no recognised pillar tag — the
31
+ * caller groups those under "Other" so nothing is silently dropped.
32
+ */
33
+ export declare function pillarOf(f: Finding): string | null;
34
+ /** READY when everything applicable passes, MISSING when nothing does. */
35
+ export declare function gradePillar(passed: number, applicable: number): FoundationGrade;
36
+ /**
37
+ * Renders the "Foundation Readiness" markdown section as lines, one
38
+ * subsection per pillar that has applicable FND findings. Per-pillar
39
+ * readiness is shown as passed/applicable counts plus a READY / PARTIAL /
40
+ * MISSING grade; open FND items are listed under their pillar. Empty input
41
+ * (or input with no FND findings) yields `[]`.
42
+ */
43
+ export declare function renderFoundationSection(findings: Finding[]): string[];
44
+ //# sourceMappingURL=foundation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"foundation.d.ts","sourceRoot":"","sources":["../../src/report/foundation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C;;;;;;;;;;;;;;GAcG;AAEH,eAAO,MAAM,iBAAiB,SAAS,CAAC;AAGxC,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,kEAAkE;AAClE,eAAO,MAAM,kBAAkB,EAAE,SAAS,gBAAgB,EAQzD,CAAC;AAIF,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;AAI9D,sEAAsE;AACtE,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAEvD;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAUlD;AAED,0EAA0E;AAC1E,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,eAAe,CAI/E;AAoBD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE,CA2ErE"}
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Foundation readiness section (FND-* rule pack).
3
+ *
4
+ * Frozen contract with the interview/loader and rule-pack workers: a
5
+ * foundation finding is a report finding whose `ruleId` starts with `FND-`
6
+ * and which carries `tags: ['pillar:<id>']`, where `<id>` is exactly one of
7
+ * the seven pillar ids below. Findings are read defensively — `tags` is not
8
+ * yet on the `Finding` interface in this worktree, so pillar membership is
9
+ * resolved through a structural cast and anything without a recognised
10
+ * pillar tag falls into a trailing "Other" group rather than being dropped.
11
+ *
12
+ * Pure and deterministic: fixed pillar order, items sorted by rule id, no
13
+ * dates, no randomness. Returns `[]` when there is nothing foundation to
14
+ * report so the caller can skip the section silently.
15
+ */
16
+ export const FOUNDATION_PREFIX = 'FND-';
17
+ const PILLAR_TAG_PREFIX = 'pillar:';
18
+ /** The seven foundation pillars, in stable presentation order. */
19
+ export const FOUNDATION_PILLARS = [
20
+ { id: 'docs', title: 'Docs', icon: '📚' },
21
+ { id: 'governance', title: 'Governance', icon: '🏛️' },
22
+ { id: 'ai-readiness', title: 'AI readiness', icon: '🤖' },
23
+ { id: 'testing', title: 'Testing', icon: '🧪' },
24
+ { id: 'environment', title: 'Environment', icon: '🌍' },
25
+ { id: 'pipelines', title: 'Pipelines', icon: '🔁' },
26
+ { id: 'standards', title: 'Standards', icon: '📏' },
27
+ ];
28
+ const PILLAR_IDS = new Set(FOUNDATION_PILLARS.map((p) => p.id));
29
+ /** True for findings produced by the foundation (FND-*) rule pack. */
30
+ export function isFoundationFinding(f) {
31
+ return f.ruleId.startsWith(FOUNDATION_PREFIX);
32
+ }
33
+ /**
34
+ * The pillar a foundation finding belongs to, from its `pillar:<id>` tag.
35
+ * Returns `null` when the finding carries no recognised pillar tag — the
36
+ * caller groups those under "Other" so nothing is silently dropped.
37
+ */
38
+ export function pillarOf(f) {
39
+ const tags = f.tags;
40
+ if (!tags)
41
+ return null;
42
+ for (const t of tags) {
43
+ if (t.startsWith(PILLAR_TAG_PREFIX)) {
44
+ const id = t.slice(PILLAR_TAG_PREFIX.length);
45
+ if (PILLAR_IDS.has(id))
46
+ return id;
47
+ }
48
+ }
49
+ return null;
50
+ }
51
+ /** READY when everything applicable passes, MISSING when nothing does. */
52
+ export function gradePillar(passed, applicable) {
53
+ if (passed >= applicable)
54
+ return 'READY';
55
+ if (passed <= 0)
56
+ return 'MISSING';
57
+ return 'PARTIAL';
58
+ }
59
+ /** A finding counts toward readiness unless it is waived or inapplicable. */
60
+ function isApplicable(f) {
61
+ return !f.suppressedReason && f.status !== 'NOT_APPLICABLE';
62
+ }
63
+ const OPEN_TAG = {
64
+ FAIL: '🔴',
65
+ WRONG: '⚠️',
66
+ MISSING: '🚫',
67
+ UNKNOWN: '❓',
68
+ DEPRECATED: '💀',
69
+ EXPERIMENTAL: '🧪',
70
+ };
71
+ function byRuleId(a, b) {
72
+ return a.ruleId.localeCompare(b.ruleId, undefined, { numeric: true });
73
+ }
74
+ /**
75
+ * Renders the "Foundation Readiness" markdown section as lines, one
76
+ * subsection per pillar that has applicable FND findings. Per-pillar
77
+ * readiness is shown as passed/applicable counts plus a READY / PARTIAL /
78
+ * MISSING grade; open FND items are listed under their pillar. Empty input
79
+ * (or input with no FND findings) yields `[]`.
80
+ */
81
+ export function renderFoundationSection(findings) {
82
+ const fnd = findings.filter(isFoundationFinding).filter(isApplicable);
83
+ if (fnd.length === 0)
84
+ return [];
85
+ const byPillar = new Map();
86
+ for (const f of fnd) {
87
+ const key = pillarOf(f) ?? 'other';
88
+ const list = byPillar.get(key) ?? [];
89
+ list.push(f);
90
+ byPillar.set(key, list);
91
+ }
92
+ const ordered = [
93
+ ...FOUNDATION_PILLARS.filter((p) => byPillar.has(p.id)).map((p) => ({
94
+ title: p.title,
95
+ icon: p.icon,
96
+ items: (byPillar.get(p.id) ?? []).sort(byRuleId),
97
+ })),
98
+ ...(byPillar.has('other')
99
+ ? [{ title: 'Other', icon: '🧱', items: (byPillar.get('other') ?? []).sort(byRuleId) }]
100
+ : []),
101
+ ];
102
+ const grades = ordered.map(({ items }) => {
103
+ const passed = items.filter((f) => f.status === 'PASS').length;
104
+ return gradePillar(passed, items.length);
105
+ });
106
+ const ready = grades.filter((g) => g === 'READY').length;
107
+ const out = [];
108
+ out.push('## 🏛️ Foundation Readiness');
109
+ out.push('');
110
+ out.push('How ready the project foundations are — vision, intents, and per-pillar ' +
111
+ 'evidence from `.usa/foundation.yaml`. Grades: **READY** (every applicable ' +
112
+ 'check passing), **PARTIAL** (some open), **MISSING** (none passing).');
113
+ out.push('');
114
+ out.push(`**Readiness: ${ready} of ${ordered.length} pillar${ordered.length === 1 ? '' : 's'} ready** · ` +
115
+ ordered.map((g, i) => `${g.title} ${grades[i]}`).join(' · '));
116
+ out.push('');
117
+ ordered.forEach(({ title, icon, items }, i) => {
118
+ const passed = items.filter((f) => f.status === 'PASS').length;
119
+ const open = items.filter((f) => f.status !== 'PASS');
120
+ out.push(`### ${icon} ${title} — **${grades[i]}** · ${passed} passed / ${items.length} applicable`);
121
+ out.push('');
122
+ if (open.length === 0) {
123
+ out.push('No open findings in this pillar. ✅');
124
+ out.push('');
125
+ return;
126
+ }
127
+ for (const f of open) {
128
+ const tag = OPEN_TAG[f.status] ?? '❓';
129
+ out.push(`- ${tag} **${f.title}** \`${f.ruleId}\` — ${f.message}`);
130
+ if (f.remediation)
131
+ out.push(` - 🛠️ ${f.remediation}`);
132
+ }
133
+ if (passed > 0) {
134
+ out.push('');
135
+ out.push(`<details><summary>${passed} check(s) passing in ${title}</summary>`);
136
+ out.push('');
137
+ for (const f of items.filter((f) => f.status === 'PASS')) {
138
+ out.push(`- ✅ ${f.title} \`${f.ruleId}\``);
139
+ }
140
+ out.push('');
141
+ out.push('</details>');
142
+ }
143
+ out.push('');
144
+ });
145
+ return out;
146
+ }
147
+ //# sourceMappingURL=foundation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"foundation.js","sourceRoot":"","sources":["../../src/report/foundation.ts"],"names":[],"mappings":"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"}
@@ -30,6 +30,7 @@ export interface JsonFinding {
30
30
  references?: string[];
31
31
  automatability?: Finding['automatability'];
32
32
  review?: Finding['review'];
33
+ tags?: string[];
33
34
  }
34
35
  export interface JsonReport {
35
36
  schema: typeof JSON_SCHEMA;
@@ -1 +1 @@
1
- {"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/report/json.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAElE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,WAAW,uBAAuB,CAAC;AAEhD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IAC9B,YAAY,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IACtC,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC3C,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;CAC5B;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,OAAO,WAAW,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC9B,SAAS,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IACpC,OAAO,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IAChC,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAC5B,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AA0BD,0DAA0D;AAC1D,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,UAAU,CAW5D;AAED,wEAAwE;AACxE,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAEtD"}
1
+ {"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/report/json.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAElE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,WAAW,uBAAuB,CAAC;AAEhD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IAC9B,YAAY,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IACtC,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC3C,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,OAAO,WAAW,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC9B,SAAS,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IACpC,OAAO,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IAChC,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAC5B,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AA2BD,0DAA0D;AAC1D,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,UAAU,CAW5D;AAED,wEAAwE;AACxE,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAEtD"}
@@ -34,6 +34,8 @@ function projectFinding(f) {
34
34
  out.evidenceHint = f.evidenceHint;
35
35
  if (f.references && f.references.length > 0)
36
36
  out.references = f.references;
37
+ if (f.tags && f.tags.length > 0)
38
+ out.tags = f.tags;
37
39
  if (f.automatability)
38
40
  out.automatability = f.automatability;
39
41
  if (f.review)
@@ -1 +1 @@
1
- {"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/report/json.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,oBAAoB,CAAC;AAkChD,SAAS,cAAc,CAAC,CAAU;IAChC,MAAM,GAAG,GAAgB;QACvB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,YAAY,EAAE,CAAC,CAAC,YAAY;QAC5B,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,YAAY,EAAE,CAAC,CAAC,YAAY;QAC5B,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,SAAS,EAAE,CAAC,CAAC,SAAS;KACvB,CAAC;IACF,IAAI,CAAC,CAAC,gBAAgB;QAAE,GAAG,CAAC,gBAAgB,GAAG,CAAC,CAAC,gBAAgB,CAAC;IAClE,IAAI,CAAC,CAAC,WAAW;QAAE,GAAG,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC;IACnD,IAAI,CAAC,CAAC,GAAG;QAAE,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC;IAC3B,IAAI,CAAC,CAAC,YAAY;QAAE,GAAG,CAAC,YAAY,GAAG,CAAC,CAAC,YAAY,CAAC;IACtD,IAAI,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC;QAAE,GAAG,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC;IAC3E,IAAI,CAAC,CAAC,cAAc;QAAE,GAAG,CAAC,cAAc,GAAG,CAAC,CAAC,cAAc,CAAC;IAC5D,IAAI,CAAC,CAAC,MAAM;QAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,OAAO,GAAG,CAAC;AACb,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,YAAY,CAAC,MAAmB;IAC9C,OAAO;QACL,MAAM,EAAE,WAAW;QACnB,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,cAAc,CAAC;KAC9C,CAAC;AACJ,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,UAAU,CAAC,MAAmB;IAC5C,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;AAC9D,CAAC"}
1
+ {"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/report/json.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,oBAAoB,CAAC;AAmChD,SAAS,cAAc,CAAC,CAAU;IAChC,MAAM,GAAG,GAAgB;QACvB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,YAAY,EAAE,CAAC,CAAC,YAAY;QAC5B,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,YAAY,EAAE,CAAC,CAAC,YAAY;QAC5B,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,SAAS,EAAE,CAAC,CAAC,SAAS;KACvB,CAAC;IACF,IAAI,CAAC,CAAC,gBAAgB;QAAE,GAAG,CAAC,gBAAgB,GAAG,CAAC,CAAC,gBAAgB,CAAC;IAClE,IAAI,CAAC,CAAC,WAAW;QAAE,GAAG,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC;IACnD,IAAI,CAAC,CAAC,GAAG;QAAE,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC;IAC3B,IAAI,CAAC,CAAC,YAAY;QAAE,GAAG,CAAC,YAAY,GAAG,CAAC,CAAC,YAAY,CAAC;IACtD,IAAI,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC;QAAE,GAAG,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC;IAC3E,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;IACnD,IAAI,CAAC,CAAC,cAAc;QAAE,GAAG,CAAC,cAAc,GAAG,CAAC,CAAC,cAAc,CAAC;IAC5D,IAAI,CAAC,CAAC,MAAM;QAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,OAAO,GAAG,CAAC;AACb,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,YAAY,CAAC,MAAmB;IAC9C,OAAO;QACL,MAAM,EAAE,WAAW;QACnB,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,cAAc,CAAC;KAC9C,CAAC;AACJ,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,UAAU,CAAC,MAAmB;IAC5C,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;AAC9D,CAAC"}