@substrate-ai/sdlc 0.20.3 → 0.20.5

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 (63) hide show
  1. package/dist/run-model/index.d.ts +2 -2
  2. package/dist/run-model/index.d.ts.map +1 -1
  3. package/dist/run-model/index.js +2 -1
  4. package/dist/run-model/index.js.map +1 -1
  5. package/dist/run-model/per-story-state.d.ts +16 -2
  6. package/dist/run-model/per-story-state.d.ts.map +1 -1
  7. package/dist/run-model/schemas.d.ts +16 -2
  8. package/dist/run-model/schemas.d.ts.map +1 -1
  9. package/dist/run-model/verification-result.d.ts +53 -3
  10. package/dist/run-model/verification-result.d.ts.map +1 -1
  11. package/dist/run-model/verification-result.js +28 -0
  12. package/dist/run-model/verification-result.js.map +1 -1
  13. package/dist/verification/checks/acceptance-criteria-evidence-check.d.ts.map +1 -1
  14. package/dist/verification/checks/acceptance-criteria-evidence-check.js +65 -8
  15. package/dist/verification/checks/acceptance-criteria-evidence-check.js.map +1 -1
  16. package/dist/verification/checks/build-check.d.ts.map +1 -1
  17. package/dist/verification/checks/build-check.js +64 -8
  18. package/dist/verification/checks/build-check.js.map +1 -1
  19. package/dist/verification/checks/index.d.ts +4 -1
  20. package/dist/verification/checks/index.d.ts.map +1 -1
  21. package/dist/verification/checks/index.js +3 -1
  22. package/dist/verification/checks/index.js.map +1 -1
  23. package/dist/verification/checks/phantom-review-check.d.ts.map +1 -1
  24. package/dist/verification/checks/phantom-review-check.js +21 -2
  25. package/dist/verification/checks/phantom-review-check.js.map +1 -1
  26. package/dist/verification/checks/runtime-probe-check.d.ts +43 -0
  27. package/dist/verification/checks/runtime-probe-check.d.ts.map +1 -0
  28. package/dist/verification/checks/runtime-probe-check.js +152 -0
  29. package/dist/verification/checks/runtime-probe-check.js.map +1 -0
  30. package/dist/verification/checks/trivial-output-check.d.ts.map +1 -1
  31. package/dist/verification/checks/trivial-output-check.js +21 -3
  32. package/dist/verification/checks/trivial-output-check.js.map +1 -1
  33. package/dist/verification/findings.d.ts +61 -0
  34. package/dist/verification/findings.d.ts.map +1 -0
  35. package/dist/verification/findings.js +39 -0
  36. package/dist/verification/findings.js.map +1 -0
  37. package/dist/verification/index.d.ts +6 -1
  38. package/dist/verification/index.d.ts.map +1 -1
  39. package/dist/verification/index.js +4 -0
  40. package/dist/verification/index.js.map +1 -1
  41. package/dist/verification/probes/executor.d.ts +39 -0
  42. package/dist/verification/probes/executor.d.ts.map +1 -0
  43. package/dist/verification/probes/executor.js +109 -0
  44. package/dist/verification/probes/executor.js.map +1 -0
  45. package/dist/verification/probes/index.d.ts +14 -0
  46. package/dist/verification/probes/index.d.ts.map +1 -0
  47. package/dist/verification/probes/index.js +12 -0
  48. package/dist/verification/probes/index.js.map +1 -0
  49. package/dist/verification/probes/parser.d.ts +26 -0
  50. package/dist/verification/probes/parser.d.ts.map +1 -0
  51. package/dist/verification/probes/parser.js +134 -0
  52. package/dist/verification/probes/parser.js.map +1 -0
  53. package/dist/verification/probes/types.d.ts +122 -0
  54. package/dist/verification/probes/types.d.ts.map +1 -0
  55. package/dist/verification/probes/types.js +68 -0
  56. package/dist/verification/probes/types.js.map +1 -0
  57. package/dist/verification/types.d.ts +10 -1
  58. package/dist/verification/types.d.ts.map +1 -1
  59. package/dist/verification/verification-pipeline.d.ts +3 -1
  60. package/dist/verification/verification-pipeline.d.ts.map +1 -1
  61. package/dist/verification/verification-pipeline.js +20 -2
  62. package/dist/verification/verification-pipeline.js.map +1 -1
  63. package/package.json +6 -3
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Host-sandbox probe executor — Epic 55 / Phase 2.
3
+ *
4
+ * Runs one runtime probe directly on the operator machine via a detached
5
+ * shell process, with stream-separated capture and a hard timeout that
6
+ * terminates the entire process group. Same safety posture as BuildCheck —
7
+ * specifically the detached-process-group + SIGKILL-on-timeout pattern —
8
+ * so probe execution cannot orphan long-running descendants.
9
+ *
10
+ * Twin-sandbox execution is **deferred to Phase 3** (Digital Twin
11
+ * integration). RuntimeProbeCheck handles the `sandbox: twin` case itself
12
+ * without routing through this module.
13
+ */
14
+ import { spawn } from 'node:child_process';
15
+ import { DEFAULT_PROBE_TIMEOUT_MS, PROBE_TAIL_BYTES, } from './types.js';
16
+ // ---------------------------------------------------------------------------
17
+ // Helpers
18
+ // ---------------------------------------------------------------------------
19
+ /** Return the last N bytes of a UTF-8 string (sliced by length for simplicity). */
20
+ function tail(text, bytes = PROBE_TAIL_BYTES) {
21
+ return text.length <= bytes ? text : text.slice(text.length - bytes);
22
+ }
23
+ /**
24
+ * Execute one probe on the host and return a structured ProbeResult.
25
+ *
26
+ * Behavior notes:
27
+ * - The shell used is `/bin/sh -c '<probe.command>'` inside a detached
28
+ * process group (so the entire tree is killed on timeout).
29
+ * - stdout and stderr are captured independently; each is returned
30
+ * tailed to PROBE_TAIL_BYTES (≤ 4 KiB) so published tarballs of the
31
+ * run manifest stay small.
32
+ * - Timeout defaults to `probe.timeout_ms ?? DEFAULT_PROBE_TIMEOUT_MS`
33
+ * (60 s). When the timeout fires, the process group is SIGKILL'd and
34
+ * the returned result has `outcome: 'timeout'`, `exitCode` undefined.
35
+ * - Never throws. Spawn errors (e.g. exec format error) are returned as
36
+ * `outcome: 'fail'` with exitCode -1 and the error message captured on
37
+ * stderrTail, so the caller can emit a deterministic finding.
38
+ */
39
+ export function executeProbeOnHost(probe, options = {}) {
40
+ const timeoutMs = probe.timeout_ms ?? DEFAULT_PROBE_TIMEOUT_MS;
41
+ const cwd = options.cwd ?? process.cwd();
42
+ const env = options.env ?? process.env;
43
+ const start = Date.now();
44
+ return new Promise((resolve) => {
45
+ let stdout = '';
46
+ let stderr = '';
47
+ let settled = false;
48
+ const child = spawn(probe.command, [], {
49
+ cwd,
50
+ env,
51
+ detached: true,
52
+ shell: true,
53
+ stdio: ['ignore', 'pipe', 'pipe'],
54
+ });
55
+ const finalize = (result) => {
56
+ if (settled)
57
+ return;
58
+ settled = true;
59
+ resolve(result);
60
+ };
61
+ child.on('error', (err) => {
62
+ // spawn error (ENOENT, EACCES, EMFILE, etc.) — never reach 'close'.
63
+ finalize({
64
+ outcome: 'fail',
65
+ command: probe.command,
66
+ exitCode: -1,
67
+ stdoutTail: tail(stdout),
68
+ stderrTail: tail(stderr + (stderr.length > 0 && !stderr.endsWith('\n') ? '\n' : '') + `spawn error: ${err.message}\n`),
69
+ durationMs: Date.now() - start,
70
+ });
71
+ });
72
+ child.stdout?.on('data', (chunk) => {
73
+ stdout += chunk.toString();
74
+ });
75
+ child.stderr?.on('data', (chunk) => {
76
+ stderr += chunk.toString();
77
+ });
78
+ const timeoutHandle = setTimeout(() => {
79
+ try {
80
+ if (child.pid !== undefined) {
81
+ process.kill(-child.pid, 'SIGKILL');
82
+ }
83
+ }
84
+ catch {
85
+ // Process already exited between timeout fire and kill call.
86
+ }
87
+ finalize({
88
+ outcome: 'timeout',
89
+ command: probe.command,
90
+ stdoutTail: tail(stdout),
91
+ stderrTail: tail(stderr),
92
+ durationMs: Date.now() - start,
93
+ });
94
+ }, timeoutMs);
95
+ child.on('close', (code) => {
96
+ clearTimeout(timeoutHandle);
97
+ const duration = Date.now() - start;
98
+ finalize({
99
+ outcome: code === 0 ? 'pass' : 'fail',
100
+ command: probe.command,
101
+ ...(code !== null ? { exitCode: code } : {}),
102
+ stdoutTail: tail(stdout),
103
+ stderrTail: tail(stderr),
104
+ durationMs: duration,
105
+ });
106
+ });
107
+ });
108
+ }
109
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../src/verification/probes/executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Runtime probe public surface — Epic 55 / Phase 2.
3
+ *
4
+ * Re-exports the parser, executor, and supporting types. The actual
5
+ * VerificationCheck implementation lives in ../checks/runtime-probe-check.ts
6
+ * to keep the existing `checks/` directory as the canonical location for
7
+ * all VerificationCheck subclasses.
8
+ */
9
+ export { DEFAULT_PROBE_TIMEOUT_MS, PROBE_TAIL_BYTES, RuntimeProbeListSchema, RuntimeProbeSandboxSchema, RuntimeProbeSchema, } from './types.js';
10
+ export type { ProbeResult, RuntimeProbe, RuntimeProbeParseResult, RuntimeProbeSandbox, } from './types.js';
11
+ export { parseRuntimeProbes } from './parser.js';
12
+ export { executeProbeOnHost } from './executor.js';
13
+ export type { HostExecuteOptions } from './executor.js';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/verification/probes/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,wBAAwB,EACxB,gBAAgB,EAChB,sBAAsB,EACtB,yBAAyB,EACzB,kBAAkB,GACnB,MAAM,YAAY,CAAA;AACnB,YAAY,EACV,WAAW,EACX,YAAY,EACZ,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAEhD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAClD,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Runtime probe public surface — Epic 55 / Phase 2.
3
+ *
4
+ * Re-exports the parser, executor, and supporting types. The actual
5
+ * VerificationCheck implementation lives in ../checks/runtime-probe-check.ts
6
+ * to keep the existing `checks/` directory as the canonical location for
7
+ * all VerificationCheck subclasses.
8
+ */
9
+ export { DEFAULT_PROBE_TIMEOUT_MS, PROBE_TAIL_BYTES, RuntimeProbeListSchema, RuntimeProbeSandboxSchema, RuntimeProbeSchema, } from './types.js';
10
+ export { parseRuntimeProbes } from './parser.js';
11
+ export { executeProbeOnHost } from './executor.js';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/verification/probes/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,wBAAwB,EACxB,gBAAgB,EAChB,sBAAsB,EACtB,yBAAyB,EACzB,kBAAkB,GACnB,MAAM,YAAY,CAAA;AAQnB,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAEhD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Runtime probe parser — Epic 55 / Phase 2.
3
+ *
4
+ * Locates the `## Runtime Probes` section in a story's markdown content and
5
+ * extracts any probe declarations contained in a `yaml` code fence inside
6
+ * it. Never throws: every failure mode is returned as a RuntimeProbeParseResult
7
+ * variant so the VerificationCheck can emit a structured finding rather than
8
+ * crash the verification pipeline.
9
+ */
10
+ import { type RuntimeProbeParseResult } from './types.js';
11
+ /**
12
+ * Parse the `## Runtime Probes` section of a story's markdown content.
13
+ *
14
+ * Outcomes:
15
+ * - section missing → { kind: 'absent' }
16
+ * - section present, no yaml fence → { kind: 'invalid' }
17
+ * - section present, yaml fence malformed → { kind: 'invalid' }
18
+ * - section present, yaml root is not a list → { kind: 'invalid' }
19
+ * - section present, entry fails RuntimeProbeSchema → { kind: 'invalid' }
20
+ * - section present, yaml valid, all entries valid → { kind: 'parsed' }
21
+ *
22
+ * Duplicate names within a single story are surfaced as `invalid` so that
23
+ * finding messages can unambiguously reference a probe by name.
24
+ */
25
+ export declare function parseRuntimeProbes(storyContent: string): RuntimeProbeParseResult;
26
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../src/verification/probes/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAGL,KAAK,uBAAuB,EAC7B,MAAM,YAAY,CAAA;AAmEnB;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,uBAAuB,CAsDhF"}
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Runtime probe parser — Epic 55 / Phase 2.
3
+ *
4
+ * Locates the `## Runtime Probes` section in a story's markdown content and
5
+ * extracts any probe declarations contained in a `yaml` code fence inside
6
+ * it. Never throws: every failure mode is returned as a RuntimeProbeParseResult
7
+ * variant so the VerificationCheck can emit a structured finding rather than
8
+ * crash the verification pipeline.
9
+ */
10
+ import { load as yamlLoad, YAMLException } from 'js-yaml';
11
+ import { RuntimeProbeListSchema, } from './types.js';
12
+ // ---------------------------------------------------------------------------
13
+ // Section extraction
14
+ // ---------------------------------------------------------------------------
15
+ const SECTION_HEADING = /^##\s+Runtime\s+Probes\s*$/i;
16
+ /**
17
+ * Return the raw text of the story's `## Runtime Probes` section (excluding
18
+ * the heading line itself), or `undefined` if the section is not present.
19
+ *
20
+ * The section ends at the next `##` heading or end-of-file. Sub-headings
21
+ * (`###`, `####`) remain part of the section body.
22
+ */
23
+ function extractRuntimeProbesSection(storyContent) {
24
+ const lines = storyContent.split(/\r?\n/);
25
+ const start = lines.findIndex((line) => SECTION_HEADING.test(line.trim()));
26
+ if (start === -1)
27
+ return undefined;
28
+ let end = lines.length;
29
+ for (let i = start + 1; i < lines.length; i += 1) {
30
+ if (/^##\s+\S/.test(lines[i] ?? '')) {
31
+ end = i;
32
+ break;
33
+ }
34
+ }
35
+ return lines.slice(start + 1, end).join('\n');
36
+ }
37
+ /**
38
+ * Extract the body of the first ```yaml (or ```yml) fenced block in the
39
+ * given section text. Returns `undefined` if no yaml fence is present.
40
+ *
41
+ * The opening fence is recognized case-insensitively and may carry an
42
+ * arbitrary trailing info string (e.g. ```yaml title=...). The closing
43
+ * fence is any line whose first non-whitespace run is exactly three
44
+ * backticks.
45
+ */
46
+ function extractYamlFence(section) {
47
+ const lines = section.split(/\r?\n/);
48
+ let inside = false;
49
+ let collected;
50
+ for (const line of lines) {
51
+ if (!inside) {
52
+ if (/^\s*```\s*(yaml|yml)\b/i.test(line)) {
53
+ inside = true;
54
+ collected = [];
55
+ }
56
+ continue;
57
+ }
58
+ // inside a yaml fence
59
+ if (/^\s*```\s*$/.test(line)) {
60
+ return (collected ?? []).join('\n');
61
+ }
62
+ collected?.push(line);
63
+ }
64
+ // Unterminated fence → treat as missing; the caller surfaces this as an
65
+ // `invalid` parse result with a clear message.
66
+ return undefined;
67
+ }
68
+ // ---------------------------------------------------------------------------
69
+ // parseRuntimeProbes — public entry point
70
+ // ---------------------------------------------------------------------------
71
+ /**
72
+ * Parse the `## Runtime Probes` section of a story's markdown content.
73
+ *
74
+ * Outcomes:
75
+ * - section missing → { kind: 'absent' }
76
+ * - section present, no yaml fence → { kind: 'invalid' }
77
+ * - section present, yaml fence malformed → { kind: 'invalid' }
78
+ * - section present, yaml root is not a list → { kind: 'invalid' }
79
+ * - section present, entry fails RuntimeProbeSchema → { kind: 'invalid' }
80
+ * - section present, yaml valid, all entries valid → { kind: 'parsed' }
81
+ *
82
+ * Duplicate names within a single story are surfaced as `invalid` so that
83
+ * finding messages can unambiguously reference a probe by name.
84
+ */
85
+ export function parseRuntimeProbes(storyContent) {
86
+ const section = extractRuntimeProbesSection(storyContent);
87
+ if (section === undefined) {
88
+ return { kind: 'absent' };
89
+ }
90
+ const yamlBody = extractYamlFence(section);
91
+ if (yamlBody === undefined) {
92
+ return {
93
+ kind: 'invalid',
94
+ error: '## Runtime Probes section is present but contains no terminated ```yaml fenced block',
95
+ };
96
+ }
97
+ let parsed;
98
+ try {
99
+ parsed = yamlLoad(yamlBody) ?? [];
100
+ }
101
+ catch (err) {
102
+ const detail = err instanceof YAMLException ? err.message : String(err);
103
+ return { kind: 'invalid', error: `YAML parse error: ${detail}` };
104
+ }
105
+ if (!Array.isArray(parsed)) {
106
+ return {
107
+ kind: 'invalid',
108
+ error: `probe block root must be a YAML list; got ${typeof parsed}`,
109
+ };
110
+ }
111
+ const validation = RuntimeProbeListSchema.safeParse(parsed);
112
+ if (!validation.success) {
113
+ const first = validation.error.issues[0];
114
+ const path = first?.path.join('.') ?? '';
115
+ const message = first?.message ?? 'schema validation failed';
116
+ return {
117
+ kind: 'invalid',
118
+ error: `probe list is malformed at ${path || '<root>'}: ${message}`,
119
+ };
120
+ }
121
+ const probes = validation.data;
122
+ const seen = new Set();
123
+ for (const probe of probes) {
124
+ if (seen.has(probe.name)) {
125
+ return {
126
+ kind: 'invalid',
127
+ error: `duplicate probe name: ${probe.name}`,
128
+ };
129
+ }
130
+ seen.add(probe.name);
131
+ }
132
+ return { kind: 'parsed', probes };
133
+ }
134
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../../src/verification/probes/parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Runtime probe types — Epic 55 / Phase 2.
3
+ *
4
+ * A "runtime probe" is an author-declared executable command that the
5
+ * verification pipeline runs against a real or ephemeral target environment
6
+ * to answer the question "does the artifact this story produced actually
7
+ * work?". Runtime probes exist specifically to catch the class of bugs that
8
+ * static shape-gates (phantom-review, trivial-output, ac-evidence, build)
9
+ * cannot — runtime misconfiguration, wrong image paths, systemd semantics,
10
+ * credential issues, and so on.
11
+ *
12
+ * This file defines the data shape; parsing lives in ./parser.ts, execution
13
+ * lives in ./executor.ts, and the VerificationCheck implementation lives in
14
+ * ../checks/runtime-probe-check.ts.
15
+ */
16
+ import { z } from 'zod';
17
+ /**
18
+ * Execution sandbox for a runtime probe.
19
+ *
20
+ * - `host`: probe runs directly on the operator's machine. Explicit opt-in.
21
+ * Cheapest; most dangerous. Authors choosing `host` acknowledge the probe
22
+ * may touch host state (ports, systemd units, filesystem) and take
23
+ * responsibility for cleanup.
24
+ * - `twin`: probe runs inside an ephemeral sandbox brokered by the Digital
25
+ * Twin subsystem (Epic 47). Twin integration is **deferred to Phase 3** —
26
+ * probes with `sandbox: twin` currently emit a `probe-deferred` warn
27
+ * finding rather than executing. Authors can declare twin-scoped probes
28
+ * today and they will execute transparently once Phase 3 lands.
29
+ */
30
+ export declare const RuntimeProbeSandboxSchema: z.ZodEnum<{
31
+ host: "host";
32
+ twin: "twin";
33
+ }>;
34
+ export type RuntimeProbeSandbox = z.infer<typeof RuntimeProbeSandboxSchema>;
35
+ /**
36
+ * Default per-probe timeout in milliseconds. Matches the existing
37
+ * BuildCheck ceiling (60 s) — deliberate, so probe timeouts are bounded
38
+ * by the same policy the pipeline already uses for long-running checks.
39
+ */
40
+ export declare const DEFAULT_PROBE_TIMEOUT_MS = 60000;
41
+ /** Hard upper bound on per-probe stdout/stderr retention (≤ 4 KiB — the
42
+ * same convention as VerificationFinding.{stdoutTail,stderrTail}). */
43
+ export declare const PROBE_TAIL_BYTES: number;
44
+ /**
45
+ * Zod schema for one runtime probe declared in a story's
46
+ * `## Runtime Probes` section.
47
+ *
48
+ * Required fields (`name`, `sandbox`, `command`) force authors to make
49
+ * intent explicit — no silent defaults that could mask a miswritten probe.
50
+ * Optional fields cover operational knobs with sensible fallbacks.
51
+ */
52
+ export declare const RuntimeProbeSchema: z.ZodObject<{
53
+ name: z.ZodString;
54
+ sandbox: z.ZodEnum<{
55
+ host: "host";
56
+ twin: "twin";
57
+ }>;
58
+ command: z.ZodString;
59
+ timeout_ms: z.ZodOptional<z.ZodNumber>;
60
+ description: z.ZodOptional<z.ZodString>;
61
+ }, z.core.$strip>;
62
+ export type RuntimeProbe = z.infer<typeof RuntimeProbeSchema>;
63
+ /** Zod schema for the full list (wrapping the per-probe schema). */
64
+ export declare const RuntimeProbeListSchema: z.ZodArray<z.ZodObject<{
65
+ name: z.ZodString;
66
+ sandbox: z.ZodEnum<{
67
+ host: "host";
68
+ twin: "twin";
69
+ }>;
70
+ command: z.ZodString;
71
+ timeout_ms: z.ZodOptional<z.ZodNumber>;
72
+ description: z.ZodOptional<z.ZodString>;
73
+ }, z.core.$strip>>;
74
+ /**
75
+ * Result of parsing the `## Runtime Probes` section from story markdown.
76
+ *
77
+ * Parsing never throws — instead it returns one of three variants so the
78
+ * VerificationCheck can distinguish and emit appropriate findings:
79
+ *
80
+ * - `absent`: section missing entirely. Treat as "no probes declared" →
81
+ * check emits pass with skip note. Backward compat for every
82
+ * story authored before Phase 2.
83
+ * - `parsed`: section present, YAML valid, all entries match
84
+ * RuntimeProbeSchema. `probes` is the parsed array (may be
85
+ * empty if the YAML list was intentionally `[]`).
86
+ * - `invalid`: section present but YAML is malformed, the root value is
87
+ * not a list, or at least one entry fails schema validation.
88
+ * The check surfaces `invalid` as a fail finding with the
89
+ * original parse error so authors see the exact problem.
90
+ */
91
+ export type RuntimeProbeParseResult = {
92
+ kind: 'absent';
93
+ } | {
94
+ kind: 'parsed';
95
+ probes: RuntimeProbe[];
96
+ } | {
97
+ kind: 'invalid';
98
+ error: string;
99
+ };
100
+ /**
101
+ * Outcome of one probe execution.
102
+ *
103
+ * Mirrors the optional `{command, exitCode, stdoutTail, stderrTail,
104
+ * durationMs}` surface on VerificationFinding so the RuntimeProbeCheck can
105
+ * lift ProbeResult fields into a finding with minimal translation.
106
+ *
107
+ * `outcome` disambiguates the three terminal states the check cares about:
108
+ *
109
+ * - `pass`: command exited 0 within its timeout.
110
+ * - `fail`: command exited non-zero within its timeout.
111
+ * - `timeout`: probe exceeded its timeout and was killed. `exitCode` is
112
+ * undefined (the process never reported one).
113
+ */
114
+ export interface ProbeResult {
115
+ outcome: 'pass' | 'fail' | 'timeout';
116
+ command: string;
117
+ exitCode?: number;
118
+ stdoutTail: string;
119
+ stderrTail: string;
120
+ durationMs: number;
121
+ }
122
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/verification/probes/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAMvB;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,yBAAyB;;;EAA2B,CAAA;AACjE,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAA;AAM3E;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,QAAS,CAAA;AAE9C;uEACuE;AACvE,eAAO,MAAM,gBAAgB,QAAW,CAAA;AAExC;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;iBAW7B,CAAA;AAEF,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAA;AAE7D,oEAAoE;AACpE,eAAO,MAAM,sBAAsB;;;;;;;;;kBAA8B,CAAA;AAMjE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,uBAAuB,GAC/B;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,YAAY,EAAE,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAMtC;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IACpC,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;CACnB"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Runtime probe types — Epic 55 / Phase 2.
3
+ *
4
+ * A "runtime probe" is an author-declared executable command that the
5
+ * verification pipeline runs against a real or ephemeral target environment
6
+ * to answer the question "does the artifact this story produced actually
7
+ * work?". Runtime probes exist specifically to catch the class of bugs that
8
+ * static shape-gates (phantom-review, trivial-output, ac-evidence, build)
9
+ * cannot — runtime misconfiguration, wrong image paths, systemd semantics,
10
+ * credential issues, and so on.
11
+ *
12
+ * This file defines the data shape; parsing lives in ./parser.ts, execution
13
+ * lives in ./executor.ts, and the VerificationCheck implementation lives in
14
+ * ../checks/runtime-probe-check.ts.
15
+ */
16
+ import { z } from 'zod';
17
+ // ---------------------------------------------------------------------------
18
+ // Sandbox — where the probe runs
19
+ // ---------------------------------------------------------------------------
20
+ /**
21
+ * Execution sandbox for a runtime probe.
22
+ *
23
+ * - `host`: probe runs directly on the operator's machine. Explicit opt-in.
24
+ * Cheapest; most dangerous. Authors choosing `host` acknowledge the probe
25
+ * may touch host state (ports, systemd units, filesystem) and take
26
+ * responsibility for cleanup.
27
+ * - `twin`: probe runs inside an ephemeral sandbox brokered by the Digital
28
+ * Twin subsystem (Epic 47). Twin integration is **deferred to Phase 3** —
29
+ * probes with `sandbox: twin` currently emit a `probe-deferred` warn
30
+ * finding rather than executing. Authors can declare twin-scoped probes
31
+ * today and they will execute transparently once Phase 3 lands.
32
+ */
33
+ export const RuntimeProbeSandboxSchema = z.enum(['host', 'twin']);
34
+ // ---------------------------------------------------------------------------
35
+ // RuntimeProbe — one author-declared probe
36
+ // ---------------------------------------------------------------------------
37
+ /**
38
+ * Default per-probe timeout in milliseconds. Matches the existing
39
+ * BuildCheck ceiling (60 s) — deliberate, so probe timeouts are bounded
40
+ * by the same policy the pipeline already uses for long-running checks.
41
+ */
42
+ export const DEFAULT_PROBE_TIMEOUT_MS = 60_000;
43
+ /** Hard upper bound on per-probe stdout/stderr retention (≤ 4 KiB — the
44
+ * same convention as VerificationFinding.{stdoutTail,stderrTail}). */
45
+ export const PROBE_TAIL_BYTES = 4 * 1024;
46
+ /**
47
+ * Zod schema for one runtime probe declared in a story's
48
+ * `## Runtime Probes` section.
49
+ *
50
+ * Required fields (`name`, `sandbox`, `command`) force authors to make
51
+ * intent explicit — no silent defaults that could mask a miswritten probe.
52
+ * Optional fields cover operational knobs with sensible fallbacks.
53
+ */
54
+ export const RuntimeProbeSchema = z.object({
55
+ /** Stable, unique-within-story identifier used in finding messages and logs. */
56
+ name: z.string().min(1, 'probe name is required'),
57
+ /** Where the probe runs. See RuntimeProbeSandboxSchema. */
58
+ sandbox: RuntimeProbeSandboxSchema,
59
+ /** Shell command line(s). Passed to a detached `sh -c` wrapper on host execution. */
60
+ command: z.string().min(1, 'probe command is required'),
61
+ /** Optional per-probe timeout in ms. Defaults to DEFAULT_PROBE_TIMEOUT_MS. */
62
+ timeout_ms: z.number().int().positive().optional(),
63
+ /** Optional human-readable description. Surfaced in finding messages. */
64
+ description: z.string().optional(),
65
+ });
66
+ /** Zod schema for the full list (wrapping the per-probe schema). */
67
+ export const RuntimeProbeListSchema = z.array(RuntimeProbeSchema);
68
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/verification/probes/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,8EAA8E;AAC9E,iCAAiC;AACjC,8EAA8E;AAE9E;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;AAGjE,8EAA8E;AAC9E,2CAA2C;AAC3C,8EAA8E;AAE9E;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,MAAM,CAAA;AAE9C;uEACuE;AACvE,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,GAAG,IAAI,CAAA;AAExC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,gFAAgF;IAChF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,wBAAwB,CAAC;IACjD,2DAA2D;IAC3D,OAAO,EAAE,yBAAyB;IAClC,qFAAqF;IACrF,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,2BAA2B,CAAC;IACvD,8EAA8E;IAC9E,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAClD,yEAAyE;IACzE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACnC,CAAC,CAAA;AAIF,oEAAoE;AACpE,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAA"}
@@ -8,6 +8,8 @@
8
8
  * Package placement: packages/sdlc/src/verification/ — SDLC-specific fields
9
9
  * (storyKey, commitSha, priorStoryFiles) make these types inappropriate for @substrate-ai/core.
10
10
  */
11
+ import type { VerificationFinding } from './findings.js';
12
+ export type { VerificationFinding, VerificationFindingSeverity } from './findings.js';
11
13
  /**
12
14
  * Slim projection of code-review dispatch signals needed by PhantomReviewCheck.
13
15
  *
@@ -102,12 +104,19 @@ export interface VerificationContext {
102
104
  /**
103
105
  * Result returned by a single VerificationCheck.run() invocation.
104
106
  *
105
- * AC2: status is 'pass' | 'warn' | 'fail'.
107
+ * `details` is a human-readable rendering, preserved for any consumer that
108
+ * already reads it. `findings` (story 55-1) is the structured per-issue
109
+ * surface — downstream consumers (retry prompts, run manifest, post-run
110
+ * analysis) should prefer it. Checks that emit findings should derive
111
+ * `details` via `renderFindings(findings)` so the two stay in sync.
106
112
  */
107
113
  export interface VerificationResult {
108
114
  status: 'pass' | 'warn' | 'fail';
109
115
  details: string;
110
116
  duration_ms: number;
117
+ /** Structured per-issue payload. Optional for backward compatibility with
118
+ * checks and consumers that pre-date story 55-1. */
119
+ findings?: VerificationFinding[];
111
120
  }
112
121
  /**
113
122
  * Per-check result included in a VerificationSummary.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/verification/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,6GAA6G;IAC7G,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,mFAAmF;IACnF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAMD;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,uEAAuE;IACvE,MAAM,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAA;IACtC,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,oEAAoE;IACpE,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IACzB,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;CACjC;AAMD;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAA;IAChB,sDAAsD;IACtD,UAAU,EAAE,MAAM,CAAA;IAClB,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAA;IACjB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAA;IACf,sEAAsE;IACtE,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IAC1B;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,aAAa,CAAA;IAC5B;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,eAAe,CAAA;IAChC;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAMD;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;IAChC,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAwB,SAAQ,kBAAkB;IACjE,SAAS,EAAE,MAAM,CAAA;CAClB;AAMD;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,uBAAuB,EAAE,CAAA;IACjC,gDAAgD;IAChD,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;IAChC,WAAW,EAAE,MAAM,CAAA;CACpB;AAMD;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAA;IACZ,mFAAmF;IACnF,IAAI,EAAE,GAAG,GAAG,GAAG,CAAA;IACf;;;OAGG;IACH,GAAG,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAA;CAC/D"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/verification/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AAGxD,YAAY,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,eAAe,CAAA;AAMrF;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,6GAA6G;IAC7G,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,mFAAmF;IACnF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAMD;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,uEAAuE;IACvE,MAAM,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAA;IACtC,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,oEAAoE;IACpE,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IACzB,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;CACjC;AAMD;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAA;IAChB,sDAAsD;IACtD,UAAU,EAAE,MAAM,CAAA;IAClB,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAA;IACjB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAA;IACf,sEAAsE;IACtE,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IAC1B;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,aAAa,CAAA;IAC5B;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,eAAe,CAAA;IAChC;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAMD;;;;;;;;GAQG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;IAChC,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB;wDACoD;IACpD,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAA;CACjC;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAwB,SAAQ,kBAAkB;IACjE,SAAS,EAAE,MAAM,CAAA;CAClB;AAMD;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,uBAAuB,EAAE,CAAA;IACjC,gDAAgD;IAChD,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;IAChC,WAAW,EAAE,MAAM,CAAA;CACpB;AAMD;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAA;IACZ,mFAAmF;IACnF,IAAI,EAAE,GAAG,GAAG,GAAG,CAAA;IACf;;;OAGG;IACH,GAAG,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAA;CAC/D"}
@@ -52,11 +52,13 @@ export declare class VerificationPipeline {
52
52
  /**
53
53
  * Create a VerificationPipeline pre-loaded with the canonical check set.
54
54
  *
55
- * Canonical Tier A check order (architecture section 3.5):
55
+ * Canonical Tier A check order:
56
56
  * 1. PhantomReviewCheck — story 51-2 (runs first: unreviewed stories skipped)
57
57
  * 2. TrivialOutputCheck — story 51-3
58
58
  * 3. AcceptanceCriteriaEvidenceCheck
59
59
  * 4. BuildCheck — story 51-4
60
+ * 5. RuntimeProbeCheck — Epic 55 Phase 2: runtime behavior gate; runs last
61
+ * in Tier A because probes may depend on built artifacts
60
62
  *
61
63
  * @param bus Typed event bus for verification events.
62
64
  * @param config Optional config (used to forward threshold to TrivialOutputCheck).
@@ -1 +1 @@
1
- {"version":3,"file":"verification-pipeline.d.ts","sourceRoot":"","sources":["../../src/verification/verification-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EAEnB,mBAAmB,EACpB,MAAM,YAAY,CAAA;AAGnB,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAA;AA2BhF;;;;;;GAMG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA2B;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAElD;;;OAGG;gBACS,GAAG,EAAE,aAAa,CAAC,UAAU,CAAC,EAAE,MAAM,GAAE,iBAAiB,EAAO;IAO5E;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI;IAIxC;;;;;;;;;;OAUG;IACG,GAAG,CAAC,OAAO,EAAE,mBAAmB,EAAE,IAAI,GAAE,GAAG,GAAG,GAAS,GAAG,OAAO,CAAC,mBAAmB,CAAC;CAuD7F;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,iCAAiC,CAC/C,GAAG,EAAE,aAAa,CAAC,UAAU,CAAC,EAC9B,MAAM,CAAC,EAAE,wBAAwB,GAChC,oBAAoB,CAQtB"}
1
+ {"version":3,"file":"verification-pipeline.d.ts","sourceRoot":"","sources":["../../src/verification/verification-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EAEnB,mBAAmB,EACpB,MAAM,YAAY,CAAA;AAGnB,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAA;AA4BhF;;;;;;GAMG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA2B;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAElD;;;OAGG;gBACS,GAAG,EAAE,aAAa,CAAC,UAAU,CAAC,EAAE,MAAM,GAAE,iBAAiB,EAAO;IAO5E;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI;IAIxC;;;;;;;;;;OAUG;IACG,GAAG,CAAC,OAAO,EAAE,mBAAmB,EAAE,IAAI,GAAE,GAAG,GAAG,GAAS,GAAG,OAAO,CAAC,mBAAmB,CAAC;CAqE7F;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iCAAiC,CAC/C,GAAG,EAAE,aAAa,CAAC,UAAU,CAAC,EAC9B,MAAM,CAAC,EAAE,wBAAwB,GAChC,oBAAoB,CAStB"}