usesteady 0.1.0-alpha.62 → 0.1.0-alpha.64
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.
- package/CHANGELOG.md +333 -0
- package/README.md +115 -7
- package/dist/src/input/json-to-ir.d.ts +9 -0
- package/dist/src/input/json-to-ir.d.ts.map +1 -1
- package/dist/src/input/json-to-ir.js +103 -0
- package/dist/src/input/json-to-ir.js.map +1 -1
- package/dist/src/input/public-json-schema.d.ts +92 -0
- package/dist/src/input/public-json-schema.d.ts.map +1 -0
- package/dist/src/input/public-json-schema.js +131 -0
- package/dist/src/input/public-json-schema.js.map +1 -0
- package/dist/src/kernel/classifier.d.ts +18 -12
- package/dist/src/kernel/classifier.d.ts.map +1 -1
- package/dist/src/kernel/classifier.js +55 -32
- package/dist/src/kernel/classifier.js.map +1 -1
- package/dist/src/kernel/command-classifier.d.ts +71 -35
- package/dist/src/kernel/command-classifier.d.ts.map +1 -1
- package/dist/src/kernel/command-classifier.js +79 -37
- package/dist/src/kernel/command-classifier.js.map +1 -1
- package/dist/src/kernel/execution-replay.d.ts.map +1 -1
- package/dist/src/kernel/execution-replay.js +90 -44
- package/dist/src/kernel/execution-replay.js.map +1 -1
- package/dist/src/kernel/inline-js-classifier.d.ts +126 -0
- package/dist/src/kernel/inline-js-classifier.d.ts.map +1 -0
- package/dist/src/kernel/inline-js-classifier.js +275 -0
- package/dist/src/kernel/inline-js-classifier.js.map +1 -0
- package/dist/src/kernel/types.d.ts +2 -2
- package/dist/src/kernel/types.d.ts.map +1 -1
- package/dist/src/shell/cli/capabilities.d.ts.map +1 -1
- package/dist/src/shell/cli/capabilities.js +6 -1
- package/dist/src/shell/cli/capabilities.js.map +1 -1
- package/dist/src/shell/cli/main.d.ts +49 -25
- package/dist/src/shell/cli/main.d.ts.map +1 -1
- package/dist/src/shell/cli/main.js +208 -370
- package/dist/src/shell/cli/main.js.map +1 -1
- package/dist/src/shell/cli/use-steady.js +201 -10
- package/dist/src/shell/cli/use-steady.js.map +1 -1
- package/dist/src/shell/cli/workflow-inspect-target-tree.d.ts +121 -0
- package/dist/src/shell/cli/workflow-inspect-target-tree.d.ts.map +1 -0
- package/dist/src/shell/cli/workflow-inspect-target-tree.js +256 -0
- package/dist/src/shell/cli/workflow-inspect-target-tree.js.map +1 -0
- package/dist/src/shell/cli/workflow-inspect-task-to-ir.d.ts +67 -0
- package/dist/src/shell/cli/workflow-inspect-task-to-ir.d.ts.map +1 -0
- package/dist/src/shell/cli/workflow-inspect-task-to-ir.js +192 -0
- package/dist/src/shell/cli/workflow-inspect-task-to-ir.js.map +1 -0
- package/dist/src/shell/cli/workflow-inspect.d.ts +142 -0
- package/dist/src/shell/cli/workflow-inspect.d.ts.map +1 -0
- package/dist/src/shell/cli/workflow-inspect.js +381 -0
- package/dist/src/shell/cli/workflow-inspect.js.map +1 -0
- package/dist/src/shell/cli/workflow-resume-info.d.ts +93 -0
- package/dist/src/shell/cli/workflow-resume-info.d.ts.map +1 -0
- package/dist/src/shell/cli/workflow-resume-info.js +185 -0
- package/dist/src/shell/cli/workflow-resume-info.js.map +1 -0
- package/dist/src/shell/cli/workflow-spec-loader.d.ts +69 -0
- package/dist/src/shell/cli/workflow-spec-loader.d.ts.map +1 -0
- package/dist/src/shell/cli/workflow-spec-loader.js +268 -0
- package/dist/src/shell/cli/workflow-spec-loader.js.map +1 -0
- package/dist/src/workflow/resume-token-builder.d.ts +54 -0
- package/dist/src/workflow/resume-token-builder.d.ts.map +1 -0
- package/dist/src/workflow/resume-token-builder.js +71 -0
- package/dist/src/workflow/resume-token-builder.js.map +1 -0
- package/dist/src/workflow/resume-token-io.d.ts +99 -0
- package/dist/src/workflow/resume-token-io.d.ts.map +1 -0
- package/dist/src/workflow/resume-token-io.js +198 -0
- package/dist/src/workflow/resume-token-io.js.map +1 -0
- package/dist/src/workflow/resume-token-types.d.ts +131 -0
- package/dist/src/workflow/resume-token-types.d.ts.map +1 -0
- package/dist/src/workflow/resume-token-types.js +36 -0
- package/dist/src/workflow/resume-token-types.js.map +1 -0
- package/dist/src/workflow/resume-token-validator.d.ts +48 -0
- package/dist/src/workflow/resume-token-validator.d.ts.map +1 -0
- package/dist/src/workflow/resume-token-validator.js +161 -0
- package/dist/src/workflow/resume-token-validator.js.map +1 -0
- package/dist/src/workflow/resume-verifier-types.d.ts +104 -0
- package/dist/src/workflow/resume-verifier-types.d.ts.map +1 -0
- package/dist/src/workflow/resume-verifier-types.js +19 -0
- package/dist/src/workflow/resume-verifier-types.js.map +1 -0
- package/dist/src/workflow/resume-verifier.d.ts +75 -0
- package/dist/src/workflow/resume-verifier.d.ts.map +1 -0
- package/dist/src/workflow/resume-verifier.js +335 -0
- package/dist/src/workflow/resume-verifier.js.map +1 -0
- package/package.json +11 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,338 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.0-alpha.64 - Governed kernel widening: workflow inspect, resume tokens, bounded node -e replay
|
|
4
|
+
|
|
5
|
+
### Summary
|
|
6
|
+
|
|
7
|
+
This release widens the governed kernel layer along three independent
|
|
8
|
+
axes -- workflow inspect, resume tokens, and bounded `node -e` inline JS
|
|
9
|
+
replay -- without changing any public-wire contract. The published CLI
|
|
10
|
+
shape, JSON adapter schema, capability advertisement, and rejection
|
|
11
|
+
diagnostics are byte-identical to alpha.63 for every input the prior
|
|
12
|
+
release accepted. Operators upgrading from alpha.63 see new surfaces
|
|
13
|
+
appear; nothing previously working changes shape.
|
|
14
|
+
|
|
15
|
+
The kernel work is the headline. K6 closes the bounded-`node -e`
|
|
16
|
+
replayability question that K1-K5 deferred: a tightly constrained
|
|
17
|
+
subset of `node -e "<BODY>"` invocations are now deterministically
|
|
18
|
+
replayable under `usesteady replay --execute`. Everything outside that
|
|
19
|
+
closed structural predicate continues to refuse, with the refusal
|
|
20
|
+
reason refined for diagnosability. K5 echo byte-for-byte preservation
|
|
21
|
+
is restored after a transient byte-layer regression introduced during
|
|
22
|
+
K6 implementation.
|
|
23
|
+
|
|
24
|
+
### What changed (user-visible)
|
|
25
|
+
|
|
26
|
+
**1. Kernel -- K6: bounded `node -e` deterministic replay.**
|
|
27
|
+
|
|
28
|
+
A new closed structural predicate admits `node -e "<BODY>"` invocations
|
|
29
|
+
for replay-under-execution when `<BODY>` is one of five `console.log`
|
|
30
|
+
atom forms (single-quoted string, signed integer literal, boolean
|
|
31
|
+
literal, `null` literal; the double-quoted string form is admissible by
|
|
32
|
+
the inline-JS predicate but unreachable via the v1.0 wire-level quoting
|
|
33
|
+
of the outer command). Two-gate defense in depth: a token denylist
|
|
34
|
+
(`require`, `process`, `fs`, `eval`, `Date`, `Math.random`, ...) and a
|
|
35
|
+
syntax denylist (backticks, `${`, `//`, `/*`, optional chaining,
|
|
36
|
+
dynamic property access) both run before the closed allow-list. The
|
|
37
|
+
K6 prefix probe runs before the K5 denylist so the leading `node -e "`
|
|
38
|
+
shape is not collaterally refused by K5's shell-metacharacter screen.
|
|
39
|
+
Full design contract: `docs/KERNEL_RUN_COMMAND_K6_DESIGN.md` v1.0.
|
|
40
|
+
|
|
41
|
+
**2. Kernel -- new refusal reason `non_deterministic_inline_js`.**
|
|
42
|
+
|
|
43
|
+
`ExecutionReplayVerdict.refused.reason` and `ClassifierResult.reason`
|
|
44
|
+
gain the value `"non_deterministic_inline_js"`. Emitted when a command
|
|
45
|
+
matches the K6 `node -e "<BODY>"` prefix shape but its body fails the
|
|
46
|
+
inline-JS predicate (denied token, denied syntax fragment, or unmatched
|
|
47
|
+
allow-list atom). Out-of-scope `node` invocations that do not match
|
|
48
|
+
the K6 prefix shape (`node -p`, `node script.js`, etc.) continue to
|
|
49
|
+
refuse with the existing K5-era reason `"non_deterministic_command"`.
|
|
50
|
+
All `switch` sites on these discriminated unions are exhaustively
|
|
51
|
+
updated; TypeScript exhaustiveness guarantees no default fallthrough
|
|
52
|
+
hides a missing branch.
|
|
53
|
+
|
|
54
|
+
**3. Kernel -- K6 execution is host-shell-free (`shell: false`).**
|
|
55
|
+
|
|
56
|
+
K6 inline-JS replay invokes `spawnSync('node', ['-e', body], { shell:
|
|
57
|
+
false, cwd: <K4-sandbox>, ... })`. The `shell: false` flag is the K6
|
|
58
|
+
hermeticity invariant: the body string is never reparsed by an
|
|
59
|
+
intermediate host shell, so no platform-specific quoting, glob, or
|
|
60
|
+
metacharacter expansion can mutate observable behavior between
|
|
61
|
+
artifact capture and replay. Execution still binds to the K4 sandbox
|
|
62
|
+
`cwd`; no `KernelResult` widening for stdout, stderr, or exit code.
|
|
63
|
+
|
|
64
|
+
**4. Kernel -- K5 echo byte-for-byte spawn preservation restored.**
|
|
65
|
+
|
|
66
|
+
The K6 implementation transiently widened the K5 `echo` executor to
|
|
67
|
+
spawn the trimmed form of the command instead of the raw command
|
|
68
|
+
bytes from the spec. Observable behavior was identical across every
|
|
69
|
+
supported host shell (all strip surrounding whitespace before
|
|
70
|
+
parsing), but the strict byte-for-byte K5 contract from alpha.59 was
|
|
71
|
+
technically violated. Alpha.64 restores the original byte-preservation
|
|
72
|
+
behavior and pins it with a regression-guard test for whitespace-
|
|
73
|
+
padded `echo` invocations.
|
|
74
|
+
|
|
75
|
+
**5. New CLI surface -- `usesteady workflow inspect <spec>` (P7-min).**
|
|
76
|
+
|
|
77
|
+
A read-only structural-inspection surface for `WorkflowSpec` files.
|
|
78
|
+
Renders the per-task target tree and IR mapping for a spec without
|
|
79
|
+
executing, persisting state, or producing a `KernelArtifact`. Useful
|
|
80
|
+
for validating spec shape before commit, for triaging
|
|
81
|
+
`run <spec.json>` failures, and for review-time spec audits. The
|
|
82
|
+
surface is purely additive: not invoked by any existing flow, never
|
|
83
|
+
mutates filesystem state, and never advertises beyond its own help
|
|
84
|
+
text.
|
|
85
|
+
|
|
86
|
+
**6. New CLI surface -- P2-min resume tokens.**
|
|
87
|
+
|
|
88
|
+
A new resume-token builder, validator, and verifier provide
|
|
89
|
+
survivability for long-running workflows without hidden continuation
|
|
90
|
+
state. Operators can capture a workflow's mid-run state into an
|
|
91
|
+
explicit resume token, inspect it via `usesteady workflow
|
|
92
|
+
resume-info <token>`, and feed it back to resume execution. No
|
|
93
|
+
existing `--prompt` / `run <spec.json>` invocation changes shape; the
|
|
94
|
+
resume surface is opt-in and additive.
|
|
95
|
+
|
|
96
|
+
**7. Public-surface productization: survivability wedge.**
|
|
97
|
+
|
|
98
|
+
`README.md`, the marketing landing surface, and the npm description
|
|
99
|
+
field are aligned to the survivability + governed-replay wedge.
|
|
100
|
+
Em-dash and arrow glyphs replaced with ASCII per encoding governance
|
|
101
|
+
(no public-facing file regresses ASCII-cleanliness). Deterministic
|
|
102
|
+
demo recording assets shipped under `docs/demo/` and
|
|
103
|
+
`marketing/public/demo/`: one hero `multistep-refactor` demo plus a
|
|
104
|
+
four-part survivability sequence (kill-mid-run, diverged-fs,
|
|
105
|
+
non-idempotent, resume-info), each as `.cast`, `.svg`, `.preview.svg`,
|
|
106
|
+
and `.session.txt` so all rendering paths are reproducible. Public
|
|
107
|
+
demo links repointed to anonymous-reachable URLs (P0 marketing fix).
|
|
108
|
+
|
|
109
|
+
**8. No public-wire breaks.**
|
|
110
|
+
|
|
111
|
+
`KernelResult` shape, the `--json` op schema, `usesteady capabilities`
|
|
112
|
+
output (text and JSON), and rejection-message structure are
|
|
113
|
+
byte-identical to alpha.63 for every input the prior release
|
|
114
|
+
accepted. No CLI flag has been retired or renamed. No JSON adapter
|
|
115
|
+
field has been retired or renamed. The K6 widening expands which
|
|
116
|
+
commands `replay --execute` admits without changing the response
|
|
117
|
+
shape for either the admit path (verdict `match` / `mismatch`) or the
|
|
118
|
+
refuse path (verdict `refused` -- the `reason` enum now carries one
|
|
119
|
+
additional value `non_deterministic_inline_js`, but all prior values
|
|
120
|
+
remain emitted unchanged).
|
|
121
|
+
|
|
122
|
+
### Files added / changed (release-relevant)
|
|
123
|
+
|
|
124
|
+
- `src/kernel/inline-js-classifier.ts` -- NEW. Closed structural
|
|
125
|
+
predicate for K6 inline-JS bodies plus the command-shape prefix
|
|
126
|
+
probe and body extraction.
|
|
127
|
+
- `src/kernel/command-classifier.ts` -- K6 routing precedence + new
|
|
128
|
+
`InScopeCommand` discriminated union for the executor.
|
|
129
|
+
- `src/kernel/classifier.ts` -- K6 refusal-reason precedence.
|
|
130
|
+
- `src/kernel/execution-replay.ts` -- K6 `node -e` execution path
|
|
131
|
+
(`shell: false`) + K5 echo byte-preservation restoration.
|
|
132
|
+
- `src/kernel/types.ts` -- additive widening of
|
|
133
|
+
`ExecutionReplayVerdict.refused.reason` and `ClassifierResult.reason`.
|
|
134
|
+
- `src/shell/cli/use-steady.ts` -- help-text refresh for K6 shape;
|
|
135
|
+
workflow inspect + resume-info surfaces.
|
|
136
|
+
- `src/shell/cli/workflow-inspect*.ts`, `workflow-resume-info.ts`,
|
|
137
|
+
`workflow-spec-loader.ts` -- new workflow inspect and resume-info
|
|
138
|
+
surfaces (P7-min, P2-min).
|
|
139
|
+
- `src/workflow/resume-token-*.ts`, `resume-verifier*.ts` -- new
|
|
140
|
+
resume-token builder, validator, verifier.
|
|
141
|
+
- `tests/kernel/inline-js-classifier.test.ts` -- NEW. 90+ unit tests.
|
|
142
|
+
- `tests/kernel/{classifier, command-classifier, execution-replay}.test.ts`
|
|
143
|
+
-- additive K6 sections plus K5 byte-preservation regression guard.
|
|
144
|
+
- `tests/shell/workflow-inspect*.test.ts`,
|
|
145
|
+
`tests/shell/workflow-resume-*.test.ts`,
|
|
146
|
+
`tests/workflow/resume-*.test.ts` -- new workflow inspect and resume
|
|
147
|
+
test suites.
|
|
148
|
+
- `docs/KERNEL_RUN_COMMAND_K6_DESIGN.md` -- v1.0 design contract.
|
|
149
|
+
- `docs/product/k6-kickoff-report-v1.md`,
|
|
150
|
+
`p2-min-resume-token-design-v1.md`,
|
|
151
|
+
`p7-min-workflow-inspect-design-v1.md`,
|
|
152
|
+
`governed-workflow-primitives-investigation-v1.md`,
|
|
153
|
+
`workflow-survivability-pressure-report-v1.md`,
|
|
154
|
+
`public-launch-pack-v1.md`,
|
|
155
|
+
`messaging-compression-v1.md`,
|
|
156
|
+
`launch-thread-v1.md` -- design and product docs.
|
|
157
|
+
- `docs/demo/`, `marketing/public/demo/` -- deterministic demo
|
|
158
|
+
recording assets (hero + four-part survivability).
|
|
159
|
+
- `README.md`, `marketing/src/pages/Landing.tsx`, `package.json`
|
|
160
|
+
description -- survivability-wedge productization, ASCII encoding.
|
|
161
|
+
|
|
162
|
+
### Out of scope for alpha.64
|
|
163
|
+
|
|
164
|
+
- No K7 work.
|
|
165
|
+
- No timeout policy on K6 execution.
|
|
166
|
+
- No multi-segment shell support.
|
|
167
|
+
- No `stdout` / `stderr` / `exitCode` persistence in `KernelResult`.
|
|
168
|
+
- No public-product surface changes beyond the additive workflow
|
|
169
|
+
inspect, resume-info, and demo / marketing routing.
|
|
170
|
+
|
|
171
|
+
## 0.1.0-alpha.63 - JSON adapter publication-truthfulness alignment
|
|
172
|
+
|
|
173
|
+
### Publication-truthfulness consolidation after alpha.62's #45 fix
|
|
174
|
+
|
|
175
|
+
This release consolidates the publication-truthfulness work shipped in
|
|
176
|
+
alpha.62. The alpha.62 fix made the executor and validator tell the truth
|
|
177
|
+
about which `replace` occurrence directives the runtime actually honors;
|
|
178
|
+
alpha.63 makes the JSON adapter's *rejection messages* and the published
|
|
179
|
+
`replace` *example* tell the same truth.
|
|
180
|
+
|
|
181
|
+
This release does **not** close a `usesteady-public` friction issue. No
|
|
182
|
+
`status/accepted` issues transition in this release. It is an internal
|
|
183
|
+
publication-surface alignment, framed accurately so prior friction
|
|
184
|
+
closures are not back-credited.
|
|
185
|
+
|
|
186
|
+
### What changed (user-visible)
|
|
187
|
+
|
|
188
|
+
**1. Missing-field diagnostic on `--json` / `batch` rejection.**
|
|
189
|
+
|
|
190
|
+
Before alpha.63, a malformed JSON op produced a generic stderr line:
|
|
191
|
+
|
|
192
|
+
Error: unknown or invalid operation: {"type":"replace","to":"NEW","file":"x.ts"}
|
|
193
|
+
See `usesteady capabilities` for the full per-op JSON schema
|
|
194
|
+
...
|
|
195
|
+
|
|
196
|
+
The operator had to consult `usesteady capabilities` to discover which
|
|
197
|
+
required field was missing. Alpha.63 names the specific missing
|
|
198
|
+
**public-wire** field inline:
|
|
199
|
+
|
|
200
|
+
Error: unknown or invalid operation: {"type":"replace","to":"NEW","file":"x.ts"}
|
|
201
|
+
op type "replace" requires field "from" but it was not provided.
|
|
202
|
+
See `usesteady capabilities` for the full per-op JSON schema
|
|
203
|
+
...
|
|
204
|
+
|
|
205
|
+
The diagnostic uses the exact key the operator would type. This matters
|
|
206
|
+
because several public-wire field names diverge from IR-canonical names
|
|
207
|
+
(legacy DraftTask naming preserved per design note section 10 #7):
|
|
208
|
+
|
|
209
|
+
- `create_dir` missing `path` -> diagnostic names `"path"`, not `"file"`.
|
|
210
|
+
- `run` missing `to` -> diagnostic names `"to"`, not `"command"`.
|
|
211
|
+
- `append` / `prepend` missing `to` -> diagnostic names `"to"`, not `"text"`.
|
|
212
|
+
|
|
213
|
+
The diagnostic appears only when a specific required public-wire field is
|
|
214
|
+
absent (or present-but-not-a-string). For content-level rejections (empty
|
|
215
|
+
strings after trim, invalid `occurrence` shape) and structural cases
|
|
216
|
+
(non-object input, missing/invalid `type`, unknown op type) the existing
|
|
217
|
+
generic message remains correct and is emitted unchanged.
|
|
218
|
+
|
|
219
|
+
**2. Published `replace` example carries `occurrence:"first"`.**
|
|
220
|
+
|
|
221
|
+
`usesteady capabilities` text + JSON output, the `HELP_TEXT` JSON op
|
|
222
|
+
schema block, and the README capabilities sample now all show:
|
|
223
|
+
|
|
224
|
+
{"type":"replace","file":"src/Button.tsx","from":"old text","to":"new text","occurrence":"first"}
|
|
225
|
+
|
|
226
|
+
Using `"first"` makes the example a *working* invocation. The capabilities
|
|
227
|
+
summary continues to disclose -- byte-identical to alpha.62 -- that
|
|
228
|
+
`"all"` and `{ index: N }` are refused at validate stage. The example
|
|
229
|
+
shift does not erase that disclosure; it complements it by demonstrating
|
|
230
|
+
the directive that *does* round-trip.
|
|
231
|
+
|
|
232
|
+
### What did NOT change
|
|
233
|
+
|
|
234
|
+
**1. Accept/reject boundary unchanged.**
|
|
235
|
+
|
|
236
|
+
`jsonOpToIROperation` is byte-identical to alpha.62. Every JSON op that
|
|
237
|
+
alpha.62 accepted is still accepted byte-for-byte. Every JSON op that
|
|
238
|
+
alpha.62 rejected is still rejected. The new `diagnoseInvalidJsonOp`
|
|
239
|
+
helper is consulted only *after* `jsonOpToIROperation` has already
|
|
240
|
+
returned `null`, to enrich the stderr text. It does not gate anything.
|
|
241
|
+
The byte-for-byte parity is pinned by the legacy
|
|
242
|
+
`json-to-ir.identical-behavior.test.ts` suite.
|
|
243
|
+
|
|
244
|
+
**2. JSON output payload for rejections unchanged.**
|
|
245
|
+
|
|
246
|
+
`{ "success": false, "error": "invalid_op" }` is the rejection payload on
|
|
247
|
+
`--output json`, byte-identical to alpha.62. The diagnostic enrichment
|
|
248
|
+
lives on stderr only. Programmatic consumers that match on
|
|
249
|
+
`obj.error === "invalid_op"` continue to work without change.
|
|
250
|
+
|
|
251
|
+
**3. Unknown extra-field tolerance unchanged.**
|
|
252
|
+
|
|
253
|
+
A JSON op carrying an unrecognized key (for example,
|
|
254
|
+
`{"type":"create","file":"x.ts","garbageField":123}`) is still accepted
|
|
255
|
+
and the extra key is silently dropped, exactly as in alpha.62. Alpha.63
|
|
256
|
+
introduces no unknown-field rejection. Tightening that surface would be
|
|
257
|
+
a public-contract change and is explicitly deferred.
|
|
258
|
+
|
|
259
|
+
**4. `op-registry.ts` untouched and remains non-authoritative.**
|
|
260
|
+
|
|
261
|
+
The IR-canonical OperationRegistry has not changed. The new
|
|
262
|
+
`public-json-schema.ts` companion sits *beside* the registry, records
|
|
263
|
+
public-wire field names (which intentionally diverge from IR-canonical
|
|
264
|
+
names for several ops), and is **descriptive-only**:
|
|
265
|
+
|
|
266
|
+
- Not consumed by the executor.
|
|
267
|
+
- Not consumed by the validator (`feasibility-validator.ts`).
|
|
268
|
+
- Not consumed by the NL parser (`nl-to-ir.ts`).
|
|
269
|
+
- Not consumed by the workflow coordinator.
|
|
270
|
+
- Not consumed by UCP mappers.
|
|
271
|
+
|
|
272
|
+
It is consumed solely by `json-to-ir.ts`'s diagnostic helper. The
|
|
273
|
+
boundary is pinned by contract tests asserting both frozenness and the
|
|
274
|
+
public-wire-vs-IR divergence per op.
|
|
275
|
+
|
|
276
|
+
**5. No occurrence-aware replace execution.**
|
|
277
|
+
|
|
278
|
+
Executor surfaces in `src/execution/` are untouched. Occurrence-aware
|
|
279
|
+
`replace` (the Option B from the #45 investigation) is not in this
|
|
280
|
+
release. `occurrence:"first"` flows through the executor exactly as it
|
|
281
|
+
did in alpha.62; `"all"` and `{ index: N }` continue to be refused at
|
|
282
|
+
validate stage with the alpha.62 truthfulness signaling.
|
|
283
|
+
|
|
284
|
+
### Out of scope (deliberate)
|
|
285
|
+
|
|
286
|
+
- **No friction closure.** No `status/accepted` -> `status/shipped`
|
|
287
|
+
transition. The alpha.62 #45 closure stands; alpha.63 does not
|
|
288
|
+
re-credit it.
|
|
289
|
+
- **No registry authority expansion.** R-alpha-full / registry-driven
|
|
290
|
+
required/optional validation is explicitly deferred per the R-alpha
|
|
291
|
+
investigation recommendation.
|
|
292
|
+
- **No NL surface changes.** `nl-to-ir.ts` is untouched.
|
|
293
|
+
- **No feasibility-validator changes.**
|
|
294
|
+
- **No UCP mapper widening.**
|
|
295
|
+
- **No `create.contents` exposure/removal.**
|
|
296
|
+
- **No timeline / doctor / K6 / marketing-site work.**
|
|
297
|
+
- **No dependency bumps.**
|
|
298
|
+
- **No HELP_TEXT auto-generation.** The one-line `replace`-example
|
|
299
|
+
update in HELP_TEXT was the minimal manual sync to match the
|
|
300
|
+
capabilities catalog.
|
|
301
|
+
|
|
302
|
+
### Verification
|
|
303
|
+
|
|
304
|
+
- `npm run build` clean.
|
|
305
|
+
- `npm run release:gate` 148 files / 5496 passed / 4 skipped / 0 failed.
|
|
306
|
+
- No dependency drift since `v0.1.0-alpha.62`.
|
|
307
|
+
- Cross-surface regression: alpha.60 protected-paths (309 tests),
|
|
308
|
+
alpha.60 #42 OCD warning truthfulness (38 tests), alpha.61 #49
|
|
309
|
+
create_dir truthfulness (169 tests), alpha.62 #45 occurrence
|
|
310
|
+
truthfulness (52 tests) all green on the alpha.63 candidate.
|
|
311
|
+
|
|
312
|
+
### Files changed since `v0.1.0-alpha.62`
|
|
313
|
+
|
|
314
|
+
- `src/input/public-json-schema.ts` (new, descriptive companion)
|
|
315
|
+
- `src/input/json-to-ir.ts` (additive: imports companion, exports
|
|
316
|
+
`diagnoseInvalidJsonOp`; existing functions byte-identical)
|
|
317
|
+
- `src/shell/cli/use-steady.ts` (HELP_TEXT replace example +
|
|
318
|
+
rejection-path stderr enrichment in `processJsonInput`)
|
|
319
|
+
- `src/shell/cli/capabilities.ts` (PUBLIC_JSON_EXAMPLES.replace adds
|
|
320
|
+
`occurrence:"first"`)
|
|
321
|
+
- `README.md` (capabilities sample replace example mirrors catalog)
|
|
322
|
+
- `tests/input/public-json-schema.test.ts` (new contract suite)
|
|
323
|
+
- `tests/input/json-to-ir.test.ts` (new diagnoseInvalidJsonOp suites,
|
|
324
|
+
accept/reject parity re-pinned)
|
|
325
|
+
- `tests/shell/capabilities.test.ts` (new R-alpha-min pins)
|
|
326
|
+
- `tests/shell/json-input.test.ts` (new CLI-surface R-alpha-min suite)
|
|
327
|
+
|
|
328
|
+
### Issue mapping
|
|
329
|
+
|
|
330
|
+
| Item | Disposition |
|
|
331
|
+
|---|---|
|
|
332
|
+
| `usesteady-public` issues closed | none |
|
|
333
|
+
| Status label transitions | none |
|
|
334
|
+
| Indirect linkage | Consolidates alpha.62's [`usesteady-public#45`](https://github.com/shortgigs/usesteady-public/issues/45) (already `status/shipped`) by closing the *internal* publication-truthfulness gap identified in the R-alpha investigation. |
|
|
335
|
+
|
|
3
336
|
## 0.1.0-alpha.62 - replace occurrence-directive truthfulness
|
|
4
337
|
|
|
5
338
|
### Execution truthfulness: replace occurrence directives are no longer silently ignored
|
package/README.md
CHANGED
|
@@ -1,6 +1,88 @@
|
|
|
1
|
-
# UseSteady
|
|
1
|
+
# UseSteady
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Inspect workflows before execution.**
|
|
4
|
+
**Survive interruption without hidden continuation.**
|
|
5
|
+
|
|
6
|
+
<p align="center">
|
|
7
|
+
<a href="docs/demo/hero/">
|
|
8
|
+
<img alt="Hero demo: AI proposes a 4-task refactor, operator inspects, run is killed mid-flight after task 2, operator verifies the resume token, then resumes - no inherited approvals, no hidden state." src="docs/demo/assets/hero/multistep-refactor.svg" width="900" />
|
|
9
|
+
</a>
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
<p align="center">
|
|
13
|
+
<em>One narrative, ~80 seconds, five beats: <strong>inspect</strong> -> approve -> run -> <strong>interrupt</strong> -> verify token -> <strong>resume</strong>. See the <a href="docs/demo/hero/">storyboard</a>.</em>
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
UseSteady is AI-assisted execution that is operationally trustworthy. You describe the workflow, UseSteady inspects it, you approve it, and only then does the work happen. When a long workflow gets interrupted - Ctrl+C, CI timeout, machine reboot - you resume from a visible token without inheriting approval authority and without hidden state.
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# 1. Inspect a workflow before running it. Read-only. Deterministic. No LLM.
|
|
20
|
+
npx usesteady workflow inspect spec.json
|
|
21
|
+
|
|
22
|
+
# 2. Run it. After each task, a resume token is written to
|
|
23
|
+
# <workspace>/.usesteady/resume-tokens/<runId>.json
|
|
24
|
+
npx usesteady run spec.json --yes
|
|
25
|
+
|
|
26
|
+
# 3. Resume after interruption. Per-task verification against current disk state.
|
|
27
|
+
# Approvals are NEVER inherited. Diverged state refuses.
|
|
28
|
+
npx usesteady run spec.json --yes --resume-from <token.json>
|
|
29
|
+
|
|
30
|
+
# 4. Inspect a resume token without running anything.
|
|
31
|
+
npx usesteady workflow resume-info <token.json> --spec spec.json
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
See the [survivability demo suite](docs/demo/survivability/) for four canonical scenarios - each isolates one property in 30-60 seconds. The [hero demo](docs/demo/hero/) composes all four into one continuous flow.
|
|
35
|
+
|
|
36
|
+
### Four survivability demos
|
|
37
|
+
|
|
38
|
+
Each tile prints the operational claim it proves directly into the terminal chrome - a 3-second-readable badge so you know what you are about to watch.
|
|
39
|
+
|
|
40
|
+
<table>
|
|
41
|
+
<tr>
|
|
42
|
+
<td align="center" width="50%">
|
|
43
|
+
<a href="docs/demo/survivability/01-kill-mid-run.md">
|
|
44
|
+
<img alt="Kill mid-run -> resume. Badge: Survives interruption." src="docs/demo/assets/survivability/01-kill-mid-run.preview.svg" width="100%" />
|
|
45
|
+
</a>
|
|
46
|
+
<br />
|
|
47
|
+
<strong>Kill mid-run -> resume</strong><br />
|
|
48
|
+
<em>Survives interruption</em>
|
|
49
|
+
</td>
|
|
50
|
+
<td align="center" width="50%">
|
|
51
|
+
<a href="docs/demo/survivability/02-diverged-fs.md">
|
|
52
|
+
<img alt="Diverged filesystem -> refusal. Badge: Resume refused." src="docs/demo/assets/survivability/02-diverged-fs.preview.svg" width="100%" />
|
|
53
|
+
</a>
|
|
54
|
+
<br />
|
|
55
|
+
<strong>Diverged filesystem -> refusal</strong><br />
|
|
56
|
+
<em>Resume refused</em>
|
|
57
|
+
</td>
|
|
58
|
+
</tr>
|
|
59
|
+
<tr>
|
|
60
|
+
<td align="center" width="50%">
|
|
61
|
+
<a href="docs/demo/survivability/03-non-idempotent.md">
|
|
62
|
+
<img alt="Non-idempotent task -> re-prompt. Badge: Operator approval required." src="docs/demo/assets/survivability/03-non-idempotent.preview.svg" width="100%" />
|
|
63
|
+
</a>
|
|
64
|
+
<br />
|
|
65
|
+
<strong>Non-idempotent task -> re-prompt</strong><br />
|
|
66
|
+
<em>Operator approval required</em>
|
|
67
|
+
</td>
|
|
68
|
+
<td align="center" width="50%">
|
|
69
|
+
<a href="docs/demo/survivability/04-resume-info.md">
|
|
70
|
+
<img alt="workflow resume-info inspection. Badge: Before execution." src="docs/demo/assets/survivability/04-resume-info.preview.svg" width="100%" />
|
|
71
|
+
</a>
|
|
72
|
+
<br />
|
|
73
|
+
<strong><code>workflow resume-info</code> inspection</strong><br />
|
|
74
|
+
<em>Before execution</em>
|
|
75
|
+
</td>
|
|
76
|
+
</tr>
|
|
77
|
+
</table>
|
|
78
|
+
|
|
79
|
+
Click any tile for the walkthrough. Each demo also ships as an animated SVG (in-repo, GitHub-renders) and an [asciinema v2 `.cast`](https://docs.asciinema.org/manual/asciicast/v2/) source - upload to asciinema.org for live playback or convert to MP4/GIF with `agg` / `asciicast2gif`.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## The smaller, interactive surface
|
|
84
|
+
|
|
85
|
+
UseSteady also has an interactive single-step mode for proposing and reviewing individual edits - useful before you graduate to multi-task workflows.
|
|
4
86
|
|
|
5
87
|
```bash
|
|
6
88
|
# Interactive session
|
|
@@ -11,9 +93,6 @@ npx usesteady --prompt "replace 'Submit' with 'Send' in src/Button.tsx"
|
|
|
11
93
|
|
|
12
94
|
# Piped stdin
|
|
13
95
|
echo "rename old.ts to new.ts" | npx usesteady
|
|
14
|
-
|
|
15
|
-
# CI / automation - zero prompts
|
|
16
|
-
npx usesteady run spec.json --yes
|
|
17
96
|
```
|
|
18
97
|
|
|
19
98
|
---
|
|
@@ -137,8 +216,37 @@ Vague input -> Guidance -> You rewrite -> SYSTEM WILL
|
|
|
137
216
|
- No silent execution
|
|
138
217
|
- No vague summaries
|
|
139
218
|
- No hidden changes
|
|
219
|
+
- No hidden continuation across interrupted runs
|
|
220
|
+
- No inherited approvals on resume
|
|
221
|
+
|
|
222
|
+
You see what changes, why it changes, and how risky it is - before anything runs. When a workflow is interrupted, you see the resume token (a plain JSON file in your workspace), and resume requires an explicit `--resume-from` invocation that re-verifies every "already-done" claim against current disk state.
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## What UseSteady is NOT
|
|
227
|
+
|
|
228
|
+
- **Not an autonomous agent.** UseSteady does not run when you are not watching. It does not "figure things out" in the background. It has no daemon, no watcher, no retry loop.
|
|
229
|
+
- **Not a code-generation tool.** UseSteady doesn't write the workflow for you. You describe it (or generate it with whatever tool you like), then UseSteady inspects, approves, runs, and resumes it.
|
|
230
|
+
- **Not a replacement for AI coding assistants.** Use Cursor, Claude, Copilot for the proposal layer. UseSteady is the layer that decides what their proposals are allowed to do to your filesystem.
|
|
231
|
+
- **Not a managed service.** UseSteady runs locally. Your workflows execute on your machine. No telemetry, no cloud workspace, no remote state.
|
|
232
|
+
- **Not a workflow scheduler.** No cron, no triggers, no automatic invocation. The CLI runs when you run it.
|
|
233
|
+
- **Not "smart" about failures.** When a workflow is interrupted and the workspace has diverged from the resume token, UseSteady refuses to resume. It tells you exactly what changed. You decide what to do about it.
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## How UseSteady differs from common alternatives
|
|
238
|
+
|
|
239
|
+
| | Autonomous coding agents | AI copilots / chat assistants | Workflow engines (Airflow, Temporal) | UseSteady |
|
|
240
|
+
|---|---|---|---|---|
|
|
241
|
+
| **Who decides what runs** | The agent | The IDE (after suggestion) | The scheduler | The operator, per step |
|
|
242
|
+
| **What "resume" means** | Restore hidden state, continue | n/a (single-prompt scope) | Resume from internal checkpoint | Re-verify visible token against disk; refuse on divergence |
|
|
243
|
+
| **Approval model** | Inherited or implied | Per-completion in IDE | Configuration-time only | Per-step at runtime, never inherited |
|
|
244
|
+
| **What you can inspect** | Logs, traces, agent reasoning | Diff in the IDE | DAG topology | The exact operations, the exact targets, the exact token bytes |
|
|
245
|
+
| **Where it runs** | Often cloud-managed | IDE host | Cluster | Your local machine |
|
|
246
|
+
| **What gets persisted** | Often hidden internal state | n/a | Engine-managed state stores | A visible JSON file in your workspace |
|
|
247
|
+
| **Failure mode** | Best-effort recovery | n/a (single shot) | DAG retry policy | Refuse on divergence; surface a typed reason |
|
|
140
248
|
|
|
141
|
-
|
|
249
|
+
UseSteady fits a different niche from any of these: long-horizon, multi-step, multi-operator AI-assisted changes whose **operational trust** is more important than autonomous sophistication.
|
|
142
250
|
|
|
143
251
|
---
|
|
144
252
|
|
|
@@ -287,7 +395,7 @@ Sample (truncated):
|
|
|
287
395
|
at validate stage). Tracked at usesteady-public#45.
|
|
288
396
|
Required (IR): file, from, to
|
|
289
397
|
Optional (IR): occurrence
|
|
290
|
-
JSON example: {"type":"replace","file":"src/Button.tsx","from":"old text","to":"new text"}
|
|
398
|
+
JSON example: {"type":"replace","file":"src/Button.tsx","from":"old text","to":"new text","occurrence":"first"}
|
|
291
399
|
|
|
292
400
|
rename
|
|
293
401
|
Rename the file at <from> to <to>.
|
|
@@ -119,4 +119,13 @@ export declare function jsonOpToIROperation(raw: unknown): Operation | null;
|
|
|
119
119
|
* so the same adapter is correct for both — only this metadata differs.
|
|
120
120
|
*/
|
|
121
121
|
export declare function buildIRFromJsonOps(ops: readonly unknown[], rawSource: string, surface: IRSourceSurface & ("json" | "batch")): JsonToIRResult;
|
|
122
|
+
/**
|
|
123
|
+
* If `raw` is a JSON op that `jsonOpToIROperation` would reject because a
|
|
124
|
+
* specific required public-wire field is missing, return a human-readable
|
|
125
|
+
* line naming that field. Otherwise return `null` (caller falls back to
|
|
126
|
+
* the existing generic message).
|
|
127
|
+
*
|
|
128
|
+
* Pure: no I/O, no mutation, no logging.
|
|
129
|
+
*/
|
|
130
|
+
export declare function diagnoseInvalidJsonOp(raw: unknown): string | null;
|
|
122
131
|
//# sourceMappingURL=json-to-ir.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json-to-ir.d.ts","sourceRoot":"","sources":["../../../src/input/json-to-ir.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,eAAe,EAAE,SAAS,EAAqB,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"json-to-ir.d.ts","sourceRoot":"","sources":["../../../src/input/json-to-ir.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,eAAe,EAAE,SAAS,EAAqB,MAAM,SAAS,CAAC;AAgDjF,MAAM,MAAM,cAAc,GACtB;IAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAA;CAAE,GACxC;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAA;CAAE,CAAC;AAwC9E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,CAoGlE;AAID;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,SAAS,OAAO,EAAE,EACvB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,eAAe,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,GAC5C,cAAc,CAchB;AA4CD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CA4CjE"}
|
|
@@ -54,6 +54,7 @@
|
|
|
54
54
|
* `status/pending` and unblock at later milestones per design §9.
|
|
55
55
|
*/
|
|
56
56
|
import { isKnownOperationType } from "./op-registry.js";
|
|
57
|
+
import { PUBLIC_JSON_SCHEMA } from "./public-json-schema.js";
|
|
57
58
|
function parseJsonOccurrence(raw) {
|
|
58
59
|
if (raw === undefined)
|
|
59
60
|
return { kind: "absent" };
|
|
@@ -280,4 +281,106 @@ export function buildIRFromJsonOps(ops, rawSource, surface) {
|
|
|
280
281
|
};
|
|
281
282
|
return { kind: "ok", ir };
|
|
282
283
|
}
|
|
284
|
+
// ─── Diagnostic enrichment (R-alpha-min) ──────────────────────────────────────
|
|
285
|
+
//
|
|
286
|
+
// `jsonOpToIROperation` returns `null` for any op that does not pass the
|
|
287
|
+
// public-schema accept/reject test. That is the load-bearing decision and
|
|
288
|
+
// MUST NOT change shape — every existing test fixture pins it byte-for-byte.
|
|
289
|
+
//
|
|
290
|
+
// What WAS missing before R-alpha-min: the CLI's user-facing message on
|
|
291
|
+
// rejection was generic ("unknown or invalid operation: <verbatim JSON>"),
|
|
292
|
+
// and the public JSON output payload was the equally generic
|
|
293
|
+
// `{ "success": false, "error": "invalid_op" }`. A user who omitted a
|
|
294
|
+
// single required field (typo, copy-paste from a wrong example, etc.) got
|
|
295
|
+
// no signal about which field, and the friction was sometimes reported as
|
|
296
|
+
// "the JSON schema is undiscoverable from the error message".
|
|
297
|
+
//
|
|
298
|
+
// `diagnoseInvalidJsonOp` consults `PUBLIC_JSON_SCHEMA` (the wire-shape
|
|
299
|
+
// companion) and produces a human-readable explanation naming the specific
|
|
300
|
+
// missing required field, using the exact key the operator would have
|
|
301
|
+
// typed. Returns `null` when no specific reason is identifiable (unknown
|
|
302
|
+
// op type, missing `type`, non-object input, etc.) — the caller then falls
|
|
303
|
+
// back to the existing generic message.
|
|
304
|
+
//
|
|
305
|
+
// Scope discipline (load-bearing — R-alpha-min):
|
|
306
|
+
// - Accept/reject boundary unchanged. Every input that returns null from
|
|
307
|
+
// `jsonOpToIROperation` still returns null. Every input that returns
|
|
308
|
+
// an `Operation` still returns the identical `Operation`. This
|
|
309
|
+
// function does not gate anything; it only describes.
|
|
310
|
+
// - No new public `CliErrorCode`. The CLI continues to emit
|
|
311
|
+
// `invalid_op` in the JSON output payload; only the stderr human text
|
|
312
|
+
// is enriched.
|
|
313
|
+
// - No unknown-field rejection. A JSON op with an extra unrecognized
|
|
314
|
+
// key (e.g. `{ type: "create", file: "x", extra: 1 }`) is still
|
|
315
|
+
// accepted by `jsonOpToIROperation` (the extra key is dropped by the
|
|
316
|
+
// per-case branches). This function never flags such cases.
|
|
317
|
+
// - The function MUST NOT mutate its input.
|
|
318
|
+
//
|
|
319
|
+
// Return shape: a single human-readable line, suitable for direct inclusion
|
|
320
|
+
// in the CLI's stderr block. Renders one cause per call (the first missing
|
|
321
|
+
// required field). If multiple required fields are missing, the operator
|
|
322
|
+
// will see the first one and fix it; on the next attempt the second one
|
|
323
|
+
// surfaces. This mirrors how typed-language compilers walk required-arg
|
|
324
|
+
// lists and avoids the "wall of errors" UX.
|
|
325
|
+
/**
|
|
326
|
+
* If `raw` is a JSON op that `jsonOpToIROperation` would reject because a
|
|
327
|
+
* specific required public-wire field is missing, return a human-readable
|
|
328
|
+
* line naming that field. Otherwise return `null` (caller falls back to
|
|
329
|
+
* the existing generic message).
|
|
330
|
+
*
|
|
331
|
+
* Pure: no I/O, no mutation, no logging.
|
|
332
|
+
*/
|
|
333
|
+
export function diagnoseInvalidJsonOp(raw) {
|
|
334
|
+
// Mirror the structural gates in `jsonOpToIROperation` exactly. Each
|
|
335
|
+
// structural gate returning null below corresponds to a case the generic
|
|
336
|
+
// "unknown or invalid operation" message already handles well (no key
|
|
337
|
+
// to name). Only the per-op required-field branch produces a richer
|
|
338
|
+
// diagnostic.
|
|
339
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw))
|
|
340
|
+
return null;
|
|
341
|
+
const op = raw;
|
|
342
|
+
const typeRaw = op["type"];
|
|
343
|
+
if (typeof typeRaw !== "string")
|
|
344
|
+
return null;
|
|
345
|
+
if (!isKnownOperationType(typeRaw))
|
|
346
|
+
return null;
|
|
347
|
+
const schema = PUBLIC_JSON_SCHEMA[typeRaw];
|
|
348
|
+
// Walk required public-wire field names in declared order. The first
|
|
349
|
+
// field that is structurally absent OR present-but-not-a-string (the
|
|
350
|
+
// adapter requires strings for every field except `occurrence`) names
|
|
351
|
+
// the diagnostic.
|
|
352
|
+
//
|
|
353
|
+
// Note: this intentionally does NOT cover field-content errors like
|
|
354
|
+
// "from is empty" or "occurrence shape is invalid" — those have already-
|
|
355
|
+
// documented rejection semantics in jsonOpToIROperation and the existing
|
|
356
|
+
// generic message remains correct for them. R-alpha-min's scope is
|
|
357
|
+
// "missing required field" only.
|
|
358
|
+
for (const fieldName of schema.required) {
|
|
359
|
+
const value = op[fieldName];
|
|
360
|
+
if (value === undefined) {
|
|
361
|
+
return formatMissingFieldMessage(typeRaw, fieldName);
|
|
362
|
+
}
|
|
363
|
+
if (typeof value !== "string") {
|
|
364
|
+
// The per-case branches return null on non-string required fields
|
|
365
|
+
// (via `strField`). Surface this as a typed-field diagnostic so the
|
|
366
|
+
// operator sees what changed.
|
|
367
|
+
return formatNonStringFieldMessage(typeRaw, fieldName, typeof value);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
// Required fields are all present and string-typed, yet the op was
|
|
371
|
+
// rejected. The root cause is content-level (empty string after
|
|
372
|
+
// normalization, invalid occurrence shape, etc.). Fall through to the
|
|
373
|
+
// generic message — the per-case branch already returned a specific
|
|
374
|
+
// null path that the operator's payload makes obvious on inspection.
|
|
375
|
+
return null;
|
|
376
|
+
}
|
|
377
|
+
function formatMissingFieldMessage(opType, fieldName) {
|
|
378
|
+
return (`op type "${opType}" requires field "${fieldName}" but it was not provided. ` +
|
|
379
|
+
`See \`usesteady capabilities\` for the full per-op JSON schema.`);
|
|
380
|
+
}
|
|
381
|
+
function formatNonStringFieldMessage(opType, fieldName, actualType) {
|
|
382
|
+
return (`op type "${opType}" requires field "${fieldName}" to be a string, ` +
|
|
383
|
+
`but received ${actualType}. ` +
|
|
384
|
+
`See \`usesteady capabilities\` for the full per-op JSON schema.`);
|
|
385
|
+
}
|
|
283
386
|
//# sourceMappingURL=json-to-ir.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json-to-ir.js","sourceRoot":"","sources":["../../../src/input/json-to-ir.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"json-to-ir.js","sourceRoot":"","sources":["../../../src/input/json-to-ir.ts"],"names":[],"mappings":"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"}
|