orchestrator-workflow 0.35.0 → 0.37.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.
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Structural schema for the reviewer output contract (the final ```yaml
3
+ * block in `assets/agents/reviewer.md`, mirrored byte-for-byte in
4
+ * `assets/skill/references/contracts.md`). This module is the single
5
+ * hand-maintained copy of that shape in code; `test/docs-consistency.test.ts`
6
+ * parses the contract block itself and asserts it matches the constants
7
+ * below exactly, so a contract edit without a matching edit here fails the
8
+ * suite instead of drifting silently.
9
+ *
10
+ * This validator checks structure only. It never judges semantic adequacy,
11
+ * never waives a finding, and its passing is never orchestrator acceptance.
12
+ */
13
+ /** Top-level field names, in the contract's own order. */
14
+ export declare const TOP_LEVEL_FIELDS: readonly ["status", "role", "task_id", "summary", "findings", "acceptance_recommendation", "missing_tests", "residual_risks", "reproduction", "method_applied", "withdrawn"];
15
+ /** Field names of one `findings[]` entry, in the contract's own order. */
16
+ export declare const FINDING_FIELDS: readonly ["severity", "category", "description", "suggested_fix", "recurrence", "introduced_by_delta"];
17
+ /** Field names of the `reproduction` object, in the contract's own order. */
18
+ export declare const REPRODUCTION_FIELDS: readonly ["method", "sample_size", "result", "matches_implementer_claim"];
19
+ /** Field names of one `withdrawn[]` entry, in the contract's own order. */
20
+ export declare const WITHDRAWN_FIELDS: readonly ["description", "reason"];
21
+ /**
22
+ * Enum spellings keyed by their bare field name. Every enum-bearing field
23
+ * in the contract has a name unique across the whole block, so a flat map
24
+ * (rather than one keyed by full path) is enough and matches how the
25
+ * contract text itself reads (`key: a | b | c`).
26
+ */
27
+ export declare const ENUM_VALUES: Readonly<Record<string, readonly string[]>>;
28
+ export interface Diagnostic {
29
+ /** Dotted/bracketed location of the offending field, e.g. `findings[0].severity`. */
30
+ path: string;
31
+ /** What the schema requires at that path. */
32
+ expected: string;
33
+ /** What was actually found (or "missing"). */
34
+ got: string;
35
+ }
36
+ export interface ValidationResult {
37
+ valid: boolean;
38
+ diagnostics: Diagnostic[];
39
+ /** Non-fatal observations, e.g. prose found after the fenced block. */
40
+ warnings: string[];
41
+ }
42
+ /**
43
+ * This validator reports structural validity only. It does not judge
44
+ * semantic adequacy, cannot waive findings, and passing it does not
45
+ * constitute orchestrator acceptance.
46
+ */
47
+ export declare const STRUCTURAL_ONLY_NOTE = "Structural check only: this does not judge semantic adequacy, cannot waive findings, and does not constitute orchestrator acceptance.";
48
+ /** Every field name any of the four contract constants declares. */
49
+ export type SchemaFieldName = (typeof TOP_LEVEL_FIELDS)[number] | (typeof FINDING_FIELDS)[number] | (typeof REPRODUCTION_FIELDS)[number] | (typeof WITHDRAWN_FIELDS)[number];
50
+ /**
51
+ * The structural kind of one contract field: which input classes its
52
+ * checker accepts and which it rejects. Declared once, next to the
53
+ * dispatch tables above, and read by both this module (for the `expected`
54
+ * text a diagnostic carries) and `test/review-report.test.ts`'s case
55
+ * generator, which derives its whole case list from these kinds rather
56
+ * than from a hand-enumerated list of checks.
57
+ *
58
+ * - `enum`: present, a string, and one of `ENUM_VALUES[field]`.
59
+ * - `string`: present and a string; the empty string is accepted.
60
+ * - `non-empty-string`: present, a string, and not blank.
61
+ * - `scalar`: present and either a string or a number.
62
+ * - `array`: present and an array; an empty array is accepted, and every
63
+ * element must be a string (each non-string element is its own
64
+ * diagnostic at `<field>[<index>]`; see {@link checkArrayField}).
65
+ * - `mapping-list`: `array`, and every element a mapping.
66
+ * - `mapping`: present and a mapping.
67
+ *
68
+ * A new kind is declared here, in {@link KIND_EXPECTED}, and in the
69
+ * generator's own `Record<FieldKind, ...>` value tables; each of those is
70
+ * keyed by this type, so a kind with no expectation text or no input
71
+ * classes is a compile error rather than an untested kind.
72
+ */
73
+ export type FieldKind = "enum" | "string" | "non-empty-string" | "scalar" | "array" | "mapping-list" | "mapping";
74
+ /**
75
+ * The declared kind of every field of every contract constant, keyed by
76
+ * bare field name the way {@link ENUM_VALUES} is: a name is unique across
77
+ * the whole contract block except for `description`, which `findings[]`
78
+ * and `withdrawn[]` share with the same kind. The `satisfies
79
+ * Record<SchemaFieldName, FieldKind>` clause means a name added to any of
80
+ * the four constants without a kind here is a TypeScript compile error,
81
+ * the same way it is already an error to add one without a checker in the
82
+ * dispatch tables above. Were a future contract to reuse one name at two
83
+ * levels with two different kinds, this flat map could hold only one of
84
+ * them: the generator asserts each field's real diagnostics against its
85
+ * declared kind, so that shows up as a failing generated case rather than
86
+ * as an unchecked field.
87
+ */
88
+ export declare const FIELD_KINDS: {
89
+ status: "enum";
90
+ role: "enum";
91
+ task_id: "non-empty-string";
92
+ summary: "array";
93
+ findings: "mapping-list";
94
+ acceptance_recommendation: "enum";
95
+ missing_tests: "array";
96
+ residual_risks: "array";
97
+ reproduction: "mapping";
98
+ method_applied: "enum";
99
+ withdrawn: "mapping-list";
100
+ severity: "enum";
101
+ category: "enum";
102
+ description: "string";
103
+ suggested_fix: "string";
104
+ recurrence: "enum";
105
+ introduced_by_delta: "enum";
106
+ method: "scalar";
107
+ sample_size: "scalar";
108
+ result: "scalar";
109
+ matches_implementer_claim: "enum";
110
+ reason: "string";
111
+ };
112
+ /**
113
+ * The `expected` text this validator's diagnostics about `field` carry.
114
+ * The checkers above hold that text literally, at their own push sites;
115
+ * this is the schema's declaration of the same text, which the generated
116
+ * test cases assert the checkers actually produce, so a checker whose
117
+ * behaviour stops matching its declared kind fails a case instead of
118
+ * drifting quietly.
119
+ */
120
+ export declare function expectedTextFor(field: SchemaFieldName): string;
121
+ /** The `expected` text a diagnostic about one element of a `mapping-list` carries. */
122
+ export declare const MAPPING_LIST_ELEMENT_EXPECTED: string;
123
+ /** The `expected` text a diagnostic about one non-string element of a plain `array`-kind field (`summary`, `missing_tests`, `residual_risks`) carries. */
124
+ export declare const ARRAY_ELEMENT_EXPECTED: string;
125
+ interface ExtractedYaml {
126
+ yamlText: string;
127
+ warnings: string[];
128
+ }
129
+ /**
130
+ * A reviewer return is commonly wrapped in a single fenced code block.
131
+ * Strips one leading/trailing fence when present, whatever language tag
132
+ * it carries (```yaml, ```yml, a bare ``` , or any other tag -- a
133
+ * language-less fence previously fell through to the "literal YAML"
134
+ * branch below and produced a confusing YAML parse error instead of a
135
+ * clean structural diagnostic; fix-round, review finding L2); anything
136
+ * unfenced is treated as literal YAML. The fence is located anywhere in
137
+ * the input, not only at its very start: a return prefixed with prose
138
+ * ("Here is my report:\n```yaml ...") previously fell through to the
139
+ * "literal YAML" branch, since the fence pattern was anchored to the
140
+ * start of the string, and produced a raw parse error instead of a
141
+ * structural diagnostic (fix-round, review finding L1). Prose found
142
+ * before the opening fence or after the closing fence is tolerated, but
143
+ * each is named as its own warning rather than silently dropped.
144
+ *
145
+ * The opening fence's whole backtick run is captured, and the closing
146
+ * fence must be a run at least as long, starting at column 0, with
147
+ * nothing but whitespace after it (CommonMark's own rule): the pattern
148
+ * backreferences the captured run and anchors it with `^` under the `m`
149
+ * flag. So a triple-backtick sequence inside a value (a reviewer quoting
150
+ * a fenced snippet in a `description` block scalar, which YAML
151
+ * necessarily indents) can no longer close the block early and hand the
152
+ * parser a truncated document, which surfaced as diagnostics about
153
+ * fields the return actually carried (fix-round, review finding L3);
154
+ * and a return a reviewer wrapped in four backticks precisely because
155
+ * it contains a fence of its own is closed by its own four-backtick run
156
+ * rather than by that inner one. Matching a fixed three backticks
157
+ * instead of the run left a longer opener's remaining backticks in the
158
+ * info string, which read as the tag `` `yaml `` and matched no
159
+ * yaml/yml fence at all. The OPENING fence keeps its own position
160
+ * discipline unchanged: it is located anywhere in the input rather than
161
+ * anchored to a line start.
162
+ *
163
+ * Lookarounds on both sides of the run keep it whole, so the opening
164
+ * run is never re-entered at a shorter length. Without them, an input
165
+ * whose long backtick run has no valid closer is retried at every
166
+ * shorter run length from every offset inside the run, each retry
167
+ * rescanning the lazy body: work quadratic in the run's length, which a
168
+ * single pasted return of a few hundred backticks already turns into
169
+ * seconds (CHANGELOG [Unreleased] names the measurement). Keeping the
170
+ * run whole also makes the "closing run at least as long as the opening
171
+ * one" rule above literal: an opener longer than any closing run in the
172
+ * input is no fence at all, where splitting the run instead matched it
173
+ * and pushed the leftover backticks into the info string. One cost
174
+ * stays: every backtick run is still tried as an opener candidate, and a
175
+ * candidate with no qualifying closer scans to the end of the input, so
176
+ * an input of many runs with no valid closer costs work quadratic in the
177
+ * number of runs (well under a second at several thousand runs; a
178
+ * well-formed return is unaffected). Anchoring the opener to a line
179
+ * start would remove it, at the price of the position-free opener the
180
+ * paragraph above keeps.
181
+ *
182
+ * When the input carries more than one fenced block (a reviewer pasting
183
+ * a worked example ahead of the real return, say), the FIRST fence whose
184
+ * info string's first whitespace-delimited word is `yaml` or `yml`
185
+ * (case-insensitive) is preferred over every earlier fence, tagged or
186
+ * not; only when none of the fences carries that word does today's
187
+ * original first-fence behaviour apply. The whole info string is
188
+ * captured, not only a leading run of letters, so a tag followed by
189
+ * attributes (` ```yaml title=x `) is still recognised as `yaml` --
190
+ * previously the capture stopped at the first non-letter and required a
191
+ * newline right after it, so an attribute-bearing info string matched no
192
+ * fence at all, tagged or not; this also widens the untagged first-fence
193
+ * fallback, so an attribute-bearing fence with no yaml/yml word is at
194
+ * least recognised as a fence. This preference rule is not free of
195
+ * surprises of its own: a reviewer whose own return is left unfenced and
196
+ * who then quotes a ```yaml example afterward has that later example
197
+ * validated instead of their real return, which the emitted warning
198
+ * names. Preferring a later, differently-positioned fence over
199
+ * `fences[0]` is itself named as a warning, distinct from the existing
200
+ * before/after prose warnings; the before-warning is suppressed when the
201
+ * text preceding the chosen fence consists only of the skipped fence(s)
202
+ * and whitespace, since calling a legitimate (if unpreferred) fenced
203
+ * block "prose" alongside the skip warning that already names it is
204
+ * redundant; real prose ahead of a skipped fence still warns as before.
205
+ */
206
+ export declare function extractYamlSource(raw: string): ExtractedYaml;
207
+ /**
208
+ * Validates a reviewer return against the reviewer output contract's
209
+ * structure. Reports structural validity ONLY: it never judges semantic
210
+ * adequacy, never waives a finding, and passing it is never orchestrator
211
+ * acceptance.
212
+ */
213
+ export declare function validateReviewReport(raw: string): ValidationResult;
214
+ export {};