imprint-mcp 0.6.5 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +278 -16
  3. package/package.json +2 -2
  4. package/prompts/audit-agent.md +28 -7
  5. package/prompts/auth-compile-agent.md +65 -7
  6. package/prompts/build-planning.md +3 -3
  7. package/prompts/compile-agent.md +922 -183
  8. package/prompts/live-verifier-agent.md +25 -8
  9. package/prompts/master-teach-api-researcher.md +813 -0
  10. package/prompts/master-teach-baseline-mvp-review.md +217 -0
  11. package/prompts/master-teach-completion-review.md +188 -0
  12. package/prompts/master-teach-decision.md +885 -0
  13. package/prompts/master-teach-focused-planner.md +764 -0
  14. package/prompts/master-teach-parameter-advisor.md +58 -0
  15. package/prompts/master-teach-recording-evidence.md +19 -0
  16. package/prompts/master-teach-refine-plan.md +7 -0
  17. package/prompts/master-teach-tool-advisor.md +130 -0
  18. package/prompts/playbook-compilation.md +45 -54
  19. package/prompts/prereq-builder.md +28 -6
  20. package/prompts/prereq-planner.md +2 -2
  21. package/prompts/request-triage.md +51 -9
  22. package/prompts/tool-candidate-detection.md +75 -38
  23. package/prompts/tool-planning.md +3 -3
  24. package/src/cli.ts +197 -151
  25. package/src/imprint/agent.ts +47 -33
  26. package/src/imprint/api-research-agent.ts +933 -0
  27. package/src/imprint/audit.ts +72 -7
  28. package/src/imprint/auth-compile-agent.ts +136 -62
  29. package/src/imprint/auth-compile-tools.ts +99 -18
  30. package/src/imprint/auth-verifier.ts +10 -20
  31. package/src/imprint/backend-ladder.ts +517 -365
  32. package/src/imprint/body-structure.ts +656 -0
  33. package/src/imprint/build-plan.ts +54 -323
  34. package/src/imprint/cdp-browser-fetch.ts +734 -29
  35. package/src/imprint/cdp-jar-cache.ts +7 -12
  36. package/src/imprint/claude-cli-compile.ts +283 -321
  37. package/src/imprint/codex-cli-compile.ts +482 -350
  38. package/src/imprint/codex-sdk-turn.ts +102 -0
  39. package/src/imprint/compile-agent-types.ts +49 -10
  40. package/src/imprint/compile-agent.ts +222 -266
  41. package/src/imprint/compile-done-sentinel.ts +211 -0
  42. package/src/imprint/compile-provider-control.ts +401 -0
  43. package/src/imprint/compile-provider-recovery.ts +142 -0
  44. package/src/imprint/compile-strategy.ts +5 -0
  45. package/src/imprint/compile-tools.ts +1901 -3020
  46. package/src/imprint/compile-verification.ts +20 -3
  47. package/src/imprint/compile.ts +391 -84
  48. package/src/imprint/compiler-log.ts +12 -0
  49. package/src/imprint/compiler-process.ts +440 -0
  50. package/src/imprint/concurrency.ts +43 -58
  51. package/src/imprint/credential-extract.ts +1 -88
  52. package/src/imprint/effects.ts +9 -0
  53. package/src/imprint/emit.ts +18 -2
  54. package/src/imprint/evidence-inspection.ts +55 -0
  55. package/src/imprint/freeform-redact.ts +34 -234
  56. package/src/imprint/import-module-fresh.ts +30 -0
  57. package/src/imprint/live-finesse-runner.ts +299 -0
  58. package/src/imprint/live-verifier.ts +726 -364
  59. package/src/imprint/llm.ts +466 -422
  60. package/src/imprint/log.ts +1 -9
  61. package/src/imprint/login.ts +30 -12
  62. package/src/imprint/master-teach-agent-contracts.ts +875 -0
  63. package/src/imprint/master-teach-agents.ts +2850 -0
  64. package/src/imprint/master-teach-checks.ts +341 -0
  65. package/src/imprint/master-teach-controller.ts +7159 -0
  66. package/src/imprint/master-teach-plan.ts +1410 -0
  67. package/src/imprint/master-teach-prompt-projections.ts +347 -0
  68. package/src/imprint/master-teach-store.ts +961 -0
  69. package/src/imprint/mcp-cdp-sessions.ts +60 -0
  70. package/src/imprint/mcp-compile-server.ts +564 -662
  71. package/src/imprint/mcp-live-verifier-server.ts +267 -178
  72. package/src/imprint/mcp-server.ts +46 -57
  73. package/src/imprint/native-agent-pass.ts +260 -0
  74. package/src/imprint/native-agent-usage.ts +141 -0
  75. package/src/imprint/native-teach-agents.ts +495 -0
  76. package/src/imprint/param-grounding.ts +488 -347
  77. package/src/imprint/playbook-runner.ts +254 -63
  78. package/src/imprint/prereq-builder.ts +55 -543
  79. package/src/imprint/private-file.ts +18 -0
  80. package/src/imprint/probe-backends.ts +135 -33
  81. package/src/imprint/provider-retry.ts +501 -0
  82. package/src/imprint/provider-terminal.ts +214 -0
  83. package/src/imprint/recording-request.ts +297 -3
  84. package/src/imprint/recording-verification.ts +444 -0
  85. package/src/imprint/redact.ts +33 -749
  86. package/src/imprint/refine-worker.ts +326 -0
  87. package/src/imprint/refine.ts +241 -0
  88. package/src/imprint/replay-capture.ts +85 -37
  89. package/src/imprint/replay-evidence.ts +1007 -0
  90. package/src/imprint/request-capture.ts +14 -0
  91. package/src/imprint/research-response-evidence.ts +45 -0
  92. package/src/imprint/runtime.ts +616 -128
  93. package/src/imprint/sensitive-keys.ts +0 -6
  94. package/src/imprint/session-merge.ts +103 -7
  95. package/src/imprint/stealth-fetch.ts +25 -8
  96. package/src/imprint/stealth-token-cache.ts +16 -16
  97. package/src/imprint/teach-plan.ts +0 -242
  98. package/src/imprint/teach-research-memory.ts +229 -0
  99. package/src/imprint/teach-state.ts +47 -626
  100. package/src/imprint/teach.ts +12 -3477
  101. package/src/imprint/tool-candidates.ts +75 -210
  102. package/src/imprint/tool-loader.ts +3 -0
  103. package/src/imprint/tool-plan.ts +3 -134
  104. package/src/imprint/tracing.ts +24 -7
  105. package/src/imprint/triage-selection.ts +44 -0
  106. package/src/imprint/types.ts +107 -7
  107. package/src/imprint/endpoint-key.ts +0 -23
package/CHANGELOG.md CHANGED
@@ -2,6 +2,28 @@
2
2
 
3
3
  All notable changes to Imprint. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) (Added / Changed / Deprecated / Removed / Fixed / Security).
4
4
 
5
+ ## [0.7.0] — 2026-10-14
6
+
7
+ ### Added
8
+ - Master-led teaching with editable operation plans, focused agent passes, and dependency-aware tool compilation.
9
+ - Independent verification receipts and retained evidence for generated tool and producer-to-consumer checks.
10
+
11
+ ### Changed
12
+ - Partial teaches keep ready tools but exit nonzero when planned work remains unresolved.
13
+ - `imprint teach` emits the MCP server; `imprint install` connects it to an AI platform.
14
+ - CI runs the network-isolated verifier suite on macOS and static checks on Linux.
15
+
16
+ ### Fixed
17
+ - Cancelled teaching work no longer starts a late tool invocation.
18
+ - Completed native assignments release their prompt and response data from the active queue.
19
+ - `.redacted.json` is atomically replaced with private file permissions.
20
+ - A whole-playbook deadline governs a hanging step even when its step timeout is nearby.
21
+
22
+ ### Validation
23
+ - The Flights58 run completed with 14/14 tools and passed 30/30 independently graded cases, including fresh booking chains. Flights59–62 ended partial, so repeatability and Hotels destination/date validation remain outstanding. See [the validation timeline](timeline.md).
24
+
25
+ ---
26
+
5
27
  ## [0.2.0] — 2026-05-14
6
28
 
7
29
  v0.2 overhauls the teach-to-tool pipeline, adds full observability tracing, and introduces state-aware API replay. 12 new features, 7 bug fixes across 24 commits.
package/README.md CHANGED
@@ -27,7 +27,7 @@ bun install -g imprint-mcp
27
27
  imprint teach southwest --url https://www.southwest.com
28
28
  ```
29
29
 
30
- A browser opens. You drive the workflow and narrate what you're doing. Imprint records every request and interaction, then compiles a deterministic **MCP tool** your agent can call forever.
30
+ A browser opens. You drive the workflows and narrate what you're doing. Imprint records every request and interaction, then compiles the complete discovered set of deterministic **MCP tools** your agent can call later.
31
31
 
32
32
  Want to try a finished MCP before recording anything?
33
33
 
@@ -81,7 +81,7 @@ regenerate/record it with `bun scripts/demo-teach.ts`.)*
81
81
  </td>
82
82
  <td align="center" width="33%">
83
83
  <h3>2. Compile</h3>
84
- <p>Generates two replay artifacts:<br><br><code>workflow.json</code> — API-level replay<br><code>playbook.yaml</code> — DOM-level fallback<br><br>Credentials are redacted automatically.</p>
84
+ <p>Builds an API workflow when the recording supports one. A DOM playbook is the final fallback, used only when the agent finds the faster replay paths incompatible.<br><br>Known login credentials are replaced with credential placeholders; other recorded data remains available to the agents.</p>
85
85
  </td>
86
86
  <td align="center" width="34%">
87
87
  <h3>3. Use</h3>
@@ -91,12 +91,258 @@ regenerate/record it with `bun scripts/demo-teach.ts`.)*
91
91
  </table>
92
92
 
93
93
  > [!TIP]
94
- > All three steps happen in a single `imprint teach` command. Credentials and PII are redacted automatically before anything reaches the LLM.
95
-
96
- When one recording yields multiple tools, all candidates are selected by default.
97
- Imprint automatically includes upstream lookup/producer tools required by any
98
- selected downstream tool. Use `--primary-tool` to compile only the primary tool
99
- and its prerequisites; `--all-tools` makes the default full-set selection explicit.
94
+ > Recording and compilation happen in one foreground `imprint teach` command. Install the completed tools in your MCP client with `imprint install`. Only known user-supplied login credentials are replaced before teaching; cookies, API tokens, responses, and personal data remain visible to the agents.
95
+
96
+ Recordings and logs, including files named `.redacted.json`, are not safe to share publicly. Automatic PII and token redaction is disabled; review any file before sharing it.
97
+ Imprint writes `.redacted.json` with private file permissions. A teach that leaves
98
+ planned tools unresolved reports a partial result and exits nonzero, even if some
99
+ ready tools were published.
100
+
101
+ For every teach, a master agent accounts for the complete discovered operation
102
+ set. Focused advisors review tool boundaries and parameters, focused planners
103
+ map one tool at a time, and focused compilers build one tool at a time. The
104
+ master chooses the build waves: independent tools can run together, while a
105
+ producer runs before its consumers. Failed checks return factual evidence to
106
+ the master, which can revise the affected tool and its dependants without
107
+ rebuilding unrelated tools. Recorded response availability is supplied before
108
+ MVP selection. The boundary advisor and master receive the same human scope.
109
+ Agents choose separate tools for distinct recorded purposes before narrowing each
110
+ tool's inputs; unsupported purposes remain explicit coverage limits. Invalid focused-planner reports return exact diagnostics to the
111
+ master for repair while preserving successful sibling proposals; they never
112
+ become accepted execution plans. The retained master receives changed research
113
+ handoffs without repeatedly resending unchanged history; host validation still
114
+ uses the full evidence. Codex teaches use one native agent family, with up to ten
115
+ concurrent children. Agents can delegate further and continue the same conversations
116
+ through repairs. Each research pass stays in one native assignment: test and
117
+ inspection results return directly to that researcher, with the same host validation.
118
+ Master, planner and reviewer repairs and shared-memory queries use that same channel,
119
+ without routing every intermediate response through the parent.
120
+ Inspected alternative requests carry their nearest recorded action, and agents
121
+ explain how any substituted request compares with the selected purpose. Shared
122
+ research delivers a short index; detailed methods and failed approaches are
123
+ stored as immutable assets that agents read only when relevant.
124
+ Independent research calls keep separate browser state and reserve paced start times
125
+ without holding a shared site lock through slow responses.
126
+ Master-directed follow-ups resume the same child. Codex owns child lifecycle and concurrency; Imprint retains
127
+ provider retries, deadlines, execution tools and strict evidence checks. Other
128
+ providers retain their existing execution paths with four focused workers.
129
+ Independent research repairs share the master’s parallel waves; dependent repairs,
130
+ compilation and execution follow the accepted producer ordering. Compiler conversations
131
+ survive revision-directory changes, and finished tools enter verification immediately
132
+ while independent siblings continue compiling. Consumers still wait for verified producers.
133
+ Capture timeouts group repeated endpoint facts so telemetry does not crowd out
134
+ distinct responses, while keeping matching and readiness rules unchanged.
135
+ Research request diagnostics also show bounded decoded body differences, helping
136
+ agents distinguish changed inputs from accidental nesting or encoding changes.
137
+ Agents judge those differences; they are not an automatic pass/fail rule.
138
+
139
+ Before that tool's planning, one retained researcher conversation first proves the
140
+ smallest useful API call. If part of the selected MVP contract or a required
141
+ downstream value is still unproven, the researcher returns that working partial
142
+ result instead of pretending it is complete or discarding it. Optional breadth
143
+ waits for the later best-effort pass. Once all first passes finish, the master
144
+ can send the exact missing question back to that same conversation with only
145
+ the relevant sibling results and recorded requests.
146
+ An independent proven tool can prepare its plan and compile a draft while
147
+ other research continues, when no queued research needs that attention. The master still
148
+ reviews the complete plan before normal verification and publication; only an
149
+ exactly matching draft is reused. With native delegation, completed research reaches
150
+ the master while unrelated drafts finish. Those drafts settle before final planning
151
+ can reuse or replace them. Declared consumers retain producer-first ordering.
152
+ Researchers can call proven sibling requests with fresh inputs before testing a
153
+ consumer; recorded continuation values are not a substitute for fresh output.
154
+ Compilers can inspect full retained responses from that tool's earlier research
155
+ through a local index, then choose relevant repeat and contrast cases for offline
156
+ checks. Each observation keeps its own inputs, outcome and response chain. Researchers can
157
+ query an entire retained response with a bounded, offline data projection; failed
158
+ queries return for repair, and projected output is labelled separately from raw text.
159
+ Teaching now selects a fixed set of recording-backed examples and matches live calls to those examples, changing only expired dates or state. A separate evidence reader establishes expected facts from raw recorded/live responses before seeing parser output, then judges the parser against those facts. Citations can quote the original response bytes or their displayed JSON representation. Each selected live case is reviewed against its matched recorded response chain; unrelated fixtures are left for their own case reviews. Every selected live case and declared dependency chain must pass before publication. Missing coverage is unverified, and raw failures stay with the draft for repair. Fixture bodies are checked before compilation, and research history and inspected recording evidence survive same-run contract revisions. Grounded input mappings are kept separate from the limits of the recorded test cases; missing contrasts alone should not freeze a tool to recorded constants. Research can batch selected calls sequentially and retain isolated browsers during agent thinking. Bootstrap snapshots are cached separately by the requested URL, and capture failures show which matcher conditions failed; cold-start setup remains unchanged. Readiness failures state when no actions have started, and schema repair errors name the exact required fields. These checks need fresh repeated validation before a reliability claim.
160
+
161
+ Repair or extend an installed data tool with `imprint refine <site> --tool <name> --issue "<change>" --from-session <recording.json>`. Refinement works in an isolated staging home, preserves existing parameter contracts, and requires recording/live verification plus a strict audit before replacement. Failed refinements preserve installed tools and local evidence. Use `imprint audit <site> --strict` to reject known broken calls even when the aggregate score exceeds 95%. See [targeted refinement](docs/refinement.md).
162
+
163
+ MVP reviewers see the checked request and parser code alongside live results.
164
+ Publication retains the backend from that exact reviewed passing call in
165
+ `backends.json`, so a fresh MCP process starts on the tested path. This records
166
+ one execution choice, not a cold/warm benchmark or proof of repeatability.
167
+ They also receive actual research comparisons and inspected response excerpts,
168
+ not just the researcher's explanation of what those tests proved.
169
+ Agents are instructed to distinguish competing meanings of ambiguous fields
170
+ with focused evidence, rather than treating a coincidentally matching number
171
+ as proof. Uncertain mappings go back to the master for research or a narrower MVP.
172
+ Invalid research handoffs also return to the master with their actual test
173
+ history, rather than ending the whole teach or counting as an API failure.
174
+ Browser snapshots are reused by tool and rung without cookie-name requirements.
175
+ An explicit bootstrap URL runs before resolving request URLs that need its
176
+ captured state. MCP closes an idle or timed-out tool's CDP sessions without
177
+ closing another tool's browser, and a cancelled call does not start another rung.
178
+ Fetch-bootstrap tries the API request before deciding whether to escalate; a
179
+ missing cookie marker is not reported as an HTTP failure.
180
+ Rewording auth or token notes reuses that proof; the master explicitly requests
181
+ new research when the actual strategy changes.
182
+ The final reviewer receives the same human scope and checks requested tool
183
+ connections rather than requiring explicitly excluded operations.
184
+ If an agent mistypes run metadata, repair feedback supplies the exact current values.
185
+ Recorded page references support generated API-navigation URLs; the final URL
186
+ need not appear literally in the recording, but must be grounded and live-tested.
187
+ Tool handoffs use agent-selected concrete result paths, not array wildcards.
188
+ Binding failures explain the path problem and distinguish it from an API call failure.
189
+ Result reviewers see the actual invocation inputs; an unrelated planned test's
190
+ expected answer is never substituted for the research baseline or a chain call.
191
+ A successful chain result can be reviewed even if a standalone test failed;
192
+ that failed test remains visible and still prevents completion until repaired.
193
+ Compiler guidance separates a returned value's location from its meaning and
194
+ omits uncertain optional metadata instead of filling it from unrelated matching
195
+ shapes. Extra responses used to corroborate research stay in the evidence;
196
+ required execution requests must contribute necessary state or core output.
197
+ Agents ground rendered-result completion checks in core content and inspect
198
+ observed layout variations before treating an incidental element as required.
199
+ Agents can scope a background response capture to a specific navigation click.
200
+ Requests started before that action cannot satisfy the capture, including ones
201
+ that finish later. Without an action boundary, capture starts with navigation.
202
+ Navigation clicks wait for the selected target to become clickable within the
203
+ existing navigation deadline, then dispatch once. Failed clicks report bounded
204
+ match, geometry, computed-style and center-hit facts so agents can repair their
205
+ chosen interaction from actual page evidence.
206
+ Before accepting a navigation capture as reusable, researchers repeat a valid
207
+ input and compare a small core-input variation with the same candidate. They
208
+ reuse existing decisive observations and distinguish session reuse from setup.
209
+ When a background capture fails despite current page results, agents inspect
210
+ their delivery source, including structured document data. Changing the baseline
211
+ input does not repair the failed valid case. Reviewers trace ambiguous metadata
212
+ to its context; matching keywords or units alone cannot justify a named field.
213
+ Compilers test the complete current research response before live validation,
214
+ including result frames beyond initial metadata, alongside recording examples.
215
+ For a request chain, they receive its actual ordered response bodies as a local
216
+ offline fixture. They test associations using current response identities and
217
+ unmatched records, rather than copying one example's values into parser logic.
218
+ For framed protocols, a small parser test checks that an earlier empty or metadata
219
+ frame does not hide later records; agents derive the expected result from evidence.
220
+ Failed browser calls can include bounded page evidence from browser inspection,
221
+ including through fallback and MCP audit errors. Agents use it to investigate missing
222
+ captures without treating a timeout as automatic infrastructure failure or rendered
223
+ text as API success. Network-capture timeouts also include a bounded list of
224
+ observed response endpoints, methods, resource types, statuses and navigation
225
+ scope facts, with omitted counts. These facts help agents compare a failed
226
+ matcher with actual traffic; they do not change response selection.
227
+ Parser checks distinguish unsupported missing fields from evidenced protocol defaults.
228
+ Auditors receive exact report tool names.
229
+ Planning and final review also check how callers obtain required inputs,
230
+ without relying on identifiers hidden in the recording.
231
+ Research uses a small contrasting core-input check before claiming parameter
232
+ mappings are proven; optional parameter breadth remains deferred.
233
+ Agents check the advertised meaning, not just whether results change; a range
234
+ contrast distinguishes its bounds from a fixed result region that merely moves.
235
+ Handoffs identify the response evidence that establishes the core records' scope
236
+ for the compiler to preserve. Demonstrated ignored inputs return for contract
237
+ revision; they are not deferred as optional minimization. Audits distinguish a
238
+ bound pair's combined behavior from proof of each input's individual effect.
239
+ For rendered results after navigation or actions, agents verify that the current
240
+ collection finished rendering; document load, a page shell, or an updated control
241
+ alone cannot establish readiness. When timing is uncertain, agents compare
242
+ initial setup with changed-input calls in the same tool's warm session.
243
+ Selection handling respects structured field boundaries and complete identities.
244
+ Checking an input does not prove that it selects the corresponding result.
245
+ That contrast must distinguish claimed mappings from defaults; changing one
246
+ input does not prove the others, and unproven mappings return for follow-up.
247
+ The master reviews that evidence even when research labels itself proven;
248
+ missing proof within one tool can return to its retained researcher.
249
+ Live verification uses the planner's selected test inputs, not a replacement
250
+ with the research baseline; the proven backend remains reusable.
251
+ The planner chooses that first live case to challenge weak core evidence;
252
+ additional unexecuted cases are not claimed as coverage.
253
+ Research handoff repair reports independent missing fields together, so one
254
+ repair turn can correct the candidate, test reference, and remaining proof gaps.
255
+ If a repair exposes further schema errors, the same conversation can correct
256
+ them within the shared deadline. Identical rejected outputs stop the repair loop;
257
+ invalid decisions never execute.
258
+ Blocked terminal counts include unresolved discoveries even when no tool was planned.
259
+ Researchers can inspect or search bounded portions of retained live results,
260
+ including HTML attributes and embedded state, without repeating the API call.
261
+ Compilers receive the selected research call's full saved response and inputs
262
+ for offline parser tests, not just a written summary. This evidence stays out of
263
+ published runtime artifacts.
264
+ After live failures, the master can return an unchanged tool to its retained
265
+ researcher with the actual failure evidence, then replan only the affected tool.
266
+ MVP reviewers receive the checked build's parser to distinguish observed values
267
+ from input echoes; audits require an attributable effect, not merely changed ordering.
268
+ Server-returned query text is also an echo, not proof of applied settings.
269
+ Final review also sees prior semantic rejections and their actual inputs, so a
270
+ later passing baseline does not silently erase an unresolved core failure.
271
+ MVP reviewers check returned values against their claimed meaning: optional
272
+ breadth can wait, but mislabeled data is a repair, not polish.
273
+ If the Codex child reports missing stdin despite a non-empty prompt, Imprint
274
+ retries that exact delivery once on the same conversation and deadline.
275
+
276
+ Researchers can return a concrete input or dependency gap for a master decision
277
+ without exhausting transport permutations. The master coordinates affected
278
+ producer outputs and consumer inputs together; fresh live proof is still required.
279
+ Agents can plan repeated calls to the same tool and bind each call to an exact
280
+ prior result. The runtime checks a finite invocation order and invalidates dependent
281
+ proof when that source result changes; a continuation does not require a separate
282
+ public tool. Existing single-call plans retain their behavior.
283
+ Chain checks and audits compare actual producer record structures with the
284
+ consumer's public contract. One selected record can contain several members;
285
+ unless explicitly excluded, an available fresh multi-member record is checked
286
+ and compared with the complete consumer result.
287
+ A passing singleton check does not establish that every selected member survives.
288
+ Validation, request construction, and parsing keep group properties separate
289
+ from member properties; a valid group need not repeat its overall fields on every
290
+ member. Parsers preserve the distinction between alternatives and required
291
+ components, including when action links exist only on components. Verification
292
+ compares eligible source records with the output and checks each attribute against
293
+ its own evidence; a plausible subset or matching sibling value is insufficient.
294
+ Missing optional details must not erase required members, and constructed
295
+ selections must preserve the complete selected record through the consumer result.
296
+ Reviewers also report
297
+ explicit parser or request guards that reject inputs allowed by the public contract;
298
+ a fixture's shape must not silently become a restriction on callers.
299
+
300
+ Generated modules reload from their resolved filesystem paths, so repeated
301
+ research tests also work when the teach directory is reached through a symlink.
302
+ Generated wrappers forward caller cancellation and request/response observation
303
+ callbacks. Cancellation reaches active fetch requests and response reads; a
304
+ cancelled call is reported separately from a request timeout. Raw prepared-request
305
+ observations stay inside host diagnostics. Parsers distinguish a valid empty
306
+ result from a missing or unsupported result envelope.
307
+
308
+ Semantic agents receive the current shared deadline and remaining time on each
309
+ turn, including output repairs, so they can budget for compilation and live
310
+ checks. Repair feedback identifies missing fields by path and expected type,
311
+ including whether a list or scalar is expected. Invalid output remains rejected.
312
+ Baseline and dependency API calls are cancelled when that budget expires,
313
+ with a short bounded cleanup period; late results cannot become successful checks.
314
+ Exhausting the run deadline is reported as a failed run; provider
315
+ unavailability is reserved for an actual provider interruption.
316
+
317
+ Every teach is fresh and stays in the foreground until it reaches a terminal
318
+ result. There are no resume, phase-window, primary-tool, or partial-selection
319
+ modes. A run succeeds only when every planned tool is verified; otherwise the
320
+ terminal reports the failure honestly and exits non-zero.
321
+
322
+ For an API operation that only the page can construct, a workflow navigation
323
+ may explicitly select one matching live background response and return its body
324
+ to the parser. The teaching agent derives that matcher from recording evidence;
325
+ the runtime does not guess which request matters or turn the capability into a
326
+ site rule. The recorded response used for offline checks is separate from the
327
+ response order in a fresh live call. Playbooks remain the final fallback.
328
+
329
+ During research and compilation, request transforms can compute navigation
330
+ targets and click actions from current inputs or earlier responses. The declared
331
+ API response matcher stays fixed so live and offline checks select the same data.
332
+ Dependent selections preserve the machine values required by the next tool.
333
+ Producer compilers receive the current tested consumer construction for declared
334
+ links, so they can check the required representation instead of guessing from names.
335
+ Adding contextual recording references preserves request proof when the tested
336
+ request and public inputs remain covered; executable request changes still need
337
+ matching proof. Parser tests compare contrasting fixture records and check that
338
+ reported summaries agree with their underlying data. They retain records with
339
+ absent optional fields and distinguish requested context from observed attributes.
340
+ Provider capacity failures retry the same conversation within the existing
341
+ deadline; deterministic request and access errors remain terminal.
342
+ Compile-time browser cleanup waits for concurrent calls to finish; one completed
343
+ request cannot idle-close another request's active browser.
344
+ MCP failures include the completed backend attempts and timings, so a final
345
+ fallback error does not hide an earlier navigation timeout.
100
346
 
101
347
  The recorder also has a bounded fallback for Next.js React Server Component
102
348
  responses that Chromium evicts before `Network.getResponseBody` can read them.
@@ -166,6 +412,9 @@ bunx playwright install chromium
166
412
  | 4 | Cursor | `cursor` on PATH |
167
413
 
168
414
  Override with `--provider <name>` and `--model <name>`.
415
+ Codex teaching defaults to `gpt-6-sol`. Keep the Codex CLI current when using
416
+ that model for audits or standalone compilation; older installations may reject
417
+ it even when the Codex app offers it.
169
418
 
170
419
  </details>
171
420
 
@@ -196,21 +445,28 @@ The full order is `fetch → fetch-bootstrap → cdp-replay → stealth-fetch
196
445
 
197
446
  For bot-protected sites, `imprint probe-backends <site> --tool <toolName>` writes a `backends.json` preference cache so cron and MCP start from the known-good backend instead of rediscovering blocked rungs. Use `imprint probe-backends <site> --all` to refresh every tool in a multi-tool site; `imprint mcp status` reports stale or invalid backend caches before they quietly fall back to the default ladder. CDP replay records both cold and warm timings when it succeeds: a timeout-safe cold start may rank by its fast warm runtime, but a cold start above the preferred threshold stays behind cold-safe backends in durable cache order.
198
447
 
199
- During `imprint teach`, the independent final verifier uses the same probe before it runs the compiler-written integration suite. Probe time is separate from the suite timeout, and verification pins the selected backend. Compiler revisions reuse that proven preference without probing; only a transport/network/browser failure can prompt a reprobe. Semantic failures return directly to the compiler. Live verifier progress and retained suite receipts are written beside the generated tool as `.live-verifier-log.jsonl` and `.live-verification-evidence.json`.
448
+ During `imprint teach`, each tool goes through contract, replay, live, and
449
+ producer-consumer checks as applicable. The checks leave factual receipts. A
450
+ failure goes back to the master for a focused repair, and an independent final
451
+ reviewer sees both the current plan and the check history before the run can
452
+ complete.
200
453
 
201
- Every recording compiles to *both* `workflow.json` and `playbook.yaml`, so the ladder always has a DOM fallback.
454
+ The agent prefers an API `workflow.json`. It adds `playbook.yaml` only as the
455
+ last fallback when the higher replay rungs are not compatible with the
456
+ recorded operation.
202
457
 
203
458
  ---
204
459
 
205
460
  ## Platform Support
206
461
 
207
- At the end of `imprint teach`, pick your AI platform and Imprint wires it up:
462
+ After `imprint teach` completes, register the generated site with
463
+ `imprint install <site> --platform <platform>`:
208
464
 
209
465
  | Platform | Integration |
210
466
  |:--|:--|
211
- | **Claude Code** | Automatic — runs `claude mcp add` |
212
- | **Codex CLI** | Automatic — runs `codex mcp add` |
213
- | **Claude Desktop** | Paste-ready JSON config |
467
+ | **Claude Code** | Runs `claude mcp add` |
468
+ | **Codex CLI** | Runs `codex mcp add` |
469
+ | **Claude Desktop** | Writes or prints the MCP config |
214
470
  | **OpenClaw** | MCP config + SKILL.md export |
215
471
  | **Hermes** | MCP config + SKILL.md + cron mapping |
216
472
 
@@ -269,16 +525,20 @@ imprint <command> --help # per-command options
269
525
 
270
526
  | Category | Commands |
271
527
  |:--|:--|
272
- | **Pipeline** | `teach` · `record` · `redact` · `generate` · `compile-playbook` · `emit` |
528
+ | **Teaching** | `teach` (the single fresh foreground flow) |
529
+ | **Artifact utilities** | `record` · `redact` · `generate` · `compile-playbook` · `emit` |
273
530
  | **Runtime** | `cron` · `mcp-server` · `playbook` · `probe-backends` · `audit` |
274
531
  | **Credentials** | `credential set` · `credential list` · `credential export` · `credential import` · `credential migrate` |
275
532
  | **Utilities** | `mcp` · `login` · `assemble` · `check` · `doctor` · `install` · `uninstall` |
276
533
 
534
+ The artifact utilities are useful on individual files, but they are not
535
+ resumable phases of `imprint teach`.
536
+
277
537
  ---
278
538
 
279
539
  ## Sharing Skills
280
540
 
281
- Teach on your laptop, ship to a remote agent. Generated MCP folders contain the portable tool artifacts: `workflow.json`, `playbook.yaml`, `index.ts`, optional shared modules, and cron/backend metadata. Copy `~/.imprint/<site>` into the receiver's `~/.imprint/<site>` or commit it to a private repo, install Imprint there, then register it:
541
+ Teach on your laptop, ship to a remote agent. Generated MCP folders contain the portable tool artifacts: `workflow.json` or the fallback `playbook.yaml`, `index.ts`, optional parser/request-transform modules, and cron/backend metadata. Copy `~/.imprint/<site>` into the receiver's `~/.imprint/<site>` or commit it to a private repo, install Imprint there, then register it:
282
542
 
283
543
  ```bash
284
544
  bun install -g imprint-mcp
@@ -342,3 +602,5 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for full guidelines.
342
602
  **[MIT License](LICENSE)**
343
603
 
344
604
  </div>
605
+
606
+ Teach research retains each received response before later requests, extraction, or parsing can fail. Agents can inspect bounded excerpts of failed calls without repeating them; those responses remain failed evidence.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "imprint-mcp",
3
- "version": "0.6.5",
3
+ "version": "0.7.0",
4
4
  "description": "Teach an AI agent how to use any website. Once. Records a real browser session + narration; generates a deterministic MCP tool plus a DOM-replay playbook fallback.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -56,6 +56,7 @@
56
56
  "@modelcontextprotocol/sdk": "^1.0.0",
57
57
  "@napi-rs/keyring": "^1.3.0",
58
58
  "@noble/hashes": "^2.2.0",
59
+ "@openai/codex-sdk": "^0.159.2",
59
60
  "@opentelemetry/api": "^1.9.1",
60
61
  "chrome-remote-interface": "^0.33.0",
61
62
  "env-paths": "^3.0.0",
@@ -64,7 +65,6 @@
64
65
  "playwright": "^1.49.0",
65
66
  "playwright-extra": "^4.3.6",
66
67
  "puppeteer-extra-plugin-stealth": "^2.11.2",
67
- "redactum": "^1.1.0",
68
68
  "semver": "^7.8.4",
69
69
  "tldts": "^7.4.8",
70
70
  "yaml": "^2.8.4",
@@ -1,6 +1,8 @@
1
+ When the initial task supplies recording-backed fixed cases, use that list instead of creating additional challenges or sweeping unrelated parameter combinations. Preserve the recorded operation and coupled inputs, updating only expired dates/state and using fresh producer outputs. Report each supplied caseId on its corresponding invocation. Missing coverage is unverified. This fixed-case policy takes precedence over general differential-sweep instructions below.
2
+
1
3
  # Imprint Audit Agent
2
4
 
3
- You are an automated QA auditor. A set of eligible MCP tools is connected to you. Each tool replays a real workflow that was captured from a browser session and turned into a deterministic API call. Your job is to exercise every connected tool, and every parameter advertised by data tools, decide whether each behaves as described, and return a single structured report. Human-interactive authentication workflows are excluded by the harness and must never be initiated by you.
5
+ You are an automated QA auditor. A set of eligible MCP tools is connected to you. Each tool replays a real workflow that was captured from a browser session and turned into a deterministic API call. Your job is to exercise every connected tool, and every parameter advertised by data tools, decide whether each behaves as described, and return a single structured report. Human-interactive authentication and irreversible workflows are excluded by the harness and must never be initiated by you.
4
6
 
5
7
  You do not write code, read source files, or fix anything. You only call the connected tools, observe their output, and judge it.
6
8
 
@@ -19,18 +21,19 @@ Your priority is **functional coverage, not edge cases.** A tool that returns da
19
21
  **Verify the result is actually FOR what you asked.** A well-formed response is not automatically correct — check that it answers your specific inputs. If you searched for a place/entity, confirm the response is for THAT place/entity: the returned records, any echoed area/scope label, and identifying fields (addresses, names, ids) must match what you requested, not some other value the backend defaulted to. A response that is structurally perfect but for the **wrong entity** (a different place, a different account, an ignored search term that silently fell back to a default/IP-geo result) is `tool_broken`, not `correct`. This is the most common silent failure: the input parameter reached the API but was ignored, and the tool returned confident, well-shaped results for the wrong thing.
20
22
 
21
23
  3. **Differentially test EACH advertised data-tool parameter.** This is the core of the audit. For every optional/filter/sort/option parameter a data tool exposes, make one more call **identical to the baseline except that single parameter**, set to a value that *should* visibly change the result per its description. Do not apply this procedure to authentication tools. Compare the new result to the baseline and classify the parameter with exactly one `verdict`:
22
- - `works` — the result changed the way the description promises (a filter added/removed/reshaped results; a sort reordered them; a mode/basis changed the relevant field). Name the observed change in the reason.
24
+ - `works` — the result changed the way the description promises, with evidence attributable to that parameter (a filter changed matching records; a sort obeyed its requested ordering; a mode/basis changed the relevant field). Name that evidence, not merely that two responses differed.
23
25
  - `no_op` — there is positive evidence that the parameter is inert: use a meaningfully discriminating value and show that the response still reflects the baseline value or otherwise ignores the requested change. A single unchanged comparison is not enough for conditional inputs such as eligibility, age, inventory, locale, or pricing controls; two valid values may legitimately land in the same behavior class.
24
26
  - `broken` — there is positive evidence that the parameter produces a wrong result: it errors because of a valid value, contradicts the requested value, or corrupts the response. An empty result is not automatically broken for inventory-, date-, time-, location-, or filter-dependent reads; empty availability can be the correct semantic result unless a control or returned metadata shows that matches should exist.
25
- - `untestable` — reserve this for genuine impossibility, NOT inconvenience. Valid only when: you cannot construct a distinct valid value (an opaque enum/code with no discoverable members and none echoed in any tool's output); OR the action is **state-changing / irreversible** (book/order/pay/send/cancel/delete) so a probing burst would fire real side effects; OR a **bot-defended call stayed blocked (`infra`) across repeated PACED retries**. State which in the reason. **Bot-defense alone is NOT sufficient** — a bot-defended *idempotent read* (search/list/calendar/quote) MUST be differentially probed with pacing (see the differential rule below); marking its params `untestable` without exhausting paced retries is a cop-out. Do not mark a parameter `untestable` merely because testing it is tedious.
26
- To isolate the parameter, change only that one field between the two calls. When two parameters interact (e.g. a min/max pair), test the pair together and say so in the reason.
27
+ - `untestable` — reserve this for genuine impossibility, NOT inconvenience. Valid only when: you cannot construct a distinct valid value (an opaque enum/code with no discoverable members and none echoed in any tool's output); OR valid bound inputs cannot be varied independently and the result cannot attribute an effect to the individual member; OR the action is **state-changing / irreversible** (book/order/pay/send/cancel/delete) so a probing burst would fire real side effects; OR a **bot-defended call stayed blocked (`infra`) across repeated PACED retries**. State which in the reason. **Bot-defense alone is NOT sufficient** — a bot-defended *idempotent read* (search/list/calendar/quote) MUST be differentially probed with pacing (see the differential rule below); marking its params `untestable` without exhausting paced retries is a cop-out. Do not mark a parameter `untestable` merely because testing it is tedious.
28
+ To isolate the parameter, change only that one field between the two calls. When validity requires two parameters to change together (e.g. a bound producer-returned pair), keep the pair coherent and say so in the reason. That comparison proves the pair's combined behavior, not each member's individual effect or necessity. Grade an individual member `works` only when the evidence supports its own advertised claim; otherwise record the successful invocations and mark that member `untestable` with the attribution limit. Do not mix incompatible values merely to force an isolated test.
29
+ Echoed inputs, including fields labeled `applied` or `effective`, prove only that the tool repeated the request, not that the website honored it. Inventory, prices and ordering can change between identical requests. If that variability is the only apparent signal, repeat the baseline as a control when useful and look for an attributable effect or independently observed state. A changed list by itself is not proof of an unrelated parameter. If the available tool output cannot distinguish the claim, preserve that lack of proof as `untestable` with the actual attempts; do not manufacture either a pass or a defect.
27
30
  For conditional parameters, choose a boundary value likely to cross a behavior class and inspect echoed request metadata as well as result data. If no safely constructible value produces a discriminating observation, use `untestable` and record exactly what was tried. Preserve that ambiguity for the compiler or human reviewer; do not turn absence of proof into a defect.
28
31
  Promo/coupon/voucher/discount-code parameters need a **known valid code** to produce a visible discount. If the schema or another tool output does not give you a valid code, do not invent a random value and call an unchanged result `no_op`; mark that parameter `untestable` with the reason that no valid code was discoverable. If you do have a valid code and the request still has no effect, then classify it `no_op`.
29
32
 
30
33
  4. **Judge the baseline invocation** against what the description and schema promise, with exactly one `verdict`:
31
34
  - `correct` — sensible, well-formed, on-topic data matching the description (or a legitimately empty result for inputs that should yield none). Read the payload — do not judge solely on "it returned without throwing."
32
35
  - `tool_broken` — the tool ran but the result is wrong: malformed or empty when data was expected, fields missing or mis-mapped, an internal error, the wrong kind of data, or a shape that contradicts the schema/description.
33
- - `infra` — environmental, not a tool bug: rate limiting, bot-defense challenge, HTTP 403/429, network error, timeout, or an upstream 5xx.
36
+ - `infra` — evidence supports an environmental failure, such as rate limiting, bot-defense challenge, HTTP 403/429, connectivity loss, or an upstream 5xx. A timeout while waiting for a selected response or page element does not by itself establish an environmental cause; a workflow can wait for something its actions never produce.
34
37
  - `bad_params` — your own mistake: a value the schema/description should have told you was invalid. Use this so the tool isn't penalized for your error.
35
38
  Set `ok` to `true` only for `correct`; otherwise `false`. Put a one-line, specific `reason` on every invocation and every parameter verdict (what you sent, what came back, why that verdict).
36
39
 
@@ -39,15 +42,33 @@ Your priority is **functional coverage, not edge cases.** A tool that returns da
39
42
  ## Rules
40
43
 
41
44
  - **Call tools strictly sequentially.** Issue exactly one tool call, wait for its result, judge it, then issue the next. Never issue tool calls in parallel or batch several into one turn. Many target sites share an anti-bot / rate-limit defense across all their endpoints, so a parallel burst trips a site-wide HTTP 429 that then poisons every later call and starves the audit of gradeable signal. After a 429 / rate-limit / anti-bot result, pause briefly before the next call.
42
- - **Never recover authentication during an audit.** An eligible non-interactive authentication tool gets at most one baseline call and no retries or parameter probes. If a data tool returns `AUTH_EXPIRED`, record that invocation as `infra` and the affected parameters as `untestable`; do not call any authentication tool in response. Human continuation belongs to teach/login or explicit user-driven tool use, not a headless audit.
43
- - **Differentially test EVERY parameter — including on bot-defended endpoints.** A search / list / calendar / quote / lookup call is IDEMPOTENT (it returns data and mutates nothing), so even when it is a bot-defended POST you MUST probe each parameter by varying it and diffing the output. Do not bail after one call. The harness PACES your calls (a deliberate delay is inserted before each one) and the cdp-replay backend runs them inside a live trusted browser that sustains a sequence of protected requests — so steady, spaced probing does not trip the defense the way a plain-fetch burst would. **Bot-defense is NOT, by itself, a reason to mark a parameter `untestable`.** ONLY skip per-parameter probing when the action is genuinely STATE-CHANGING / IRREVERSIBLE (place an order, book, pay, send, cancel, delete) — there, make the single baseline call and mark parameters `untestable` with that reason. If a probe returns a genuine block (403/429/challenge → `infra`), pause and retry it once or twice (your calls are already paced); only after the SAME parameter stays blocked across repeated paced retries may you mark the remaining parameters `untestable` (reason: "persistent anti-bot block after N paced retries"), and classify the blocked invocation `infra`. Never pre-emptively give up on a bot-defended *read*.
45
+ - **Recover only unattended authentication during an audit, at most once total.** Establish each eligible non-interactive authentication tool once as its baseline and never differentially probe it. Across the entire audit, you may perform at most one recovery authentication call: if a data tool returns `AUTH_EXPIRED` before that allowance is used, rerun one already-proven non-interactive authentication tool and retry the interrupted data call once. After that single recovery call, classify any later `AUTH_EXPIRED` result as `infra` without authenticating again. Never initiate or retry authentication that can pause for human input; human continuation belongs to teach/login or explicit user-driven tool use.
46
+ - **Differentially test EVERY parameter — including on bot-defended endpoints.** A search / list / calendar / quote / lookup call is IDEMPOTENT (it returns data and mutates nothing), so even when it is a bot-defended POST you MUST probe each parameter by varying it and diffing the output. Do not bail after one call. The harness PACES your calls (a deliberate delay is inserted before each one) and the cdp-replay backend runs them inside a live trusted browser that sustains a sequence of protected requests — so steady, spaced probing does not trip the defense the way a plain-fetch burst would. **Bot-defense is NOT, by itself, a reason to mark a parameter `untestable`.** Irreversible workflows are never connected to an audit; if one appears because of a harness defect, do not invoke it and report the exclusion failure in `notes`. For a connected state-changing but reversible workflow, make the single baseline call and mark parameters `untestable` with that reason. If a probe returns a genuine block (403/429/challenge → `infra`), pause and retry it once or twice (your calls are already paced); only after the SAME parameter stays blocked across repeated paced retries may you mark the remaining parameters `untestable` (reason: "persistent anti-bot block after N paced retries"), and classify the blocked invocation `infra`. Never pre-emptively give up on a bot-defended *read*.
44
47
  - Derive parameters **only** from each tool's schema and description. Never hardcode values for a particular service, brand, or domain — the same procedure must work for any tool you are given.
45
48
  - Audit **every eligible connected** tool, and within each data tool, test **every** advertised parameter (subject to the read-type rule above). Do not skip a tool because another failed. Authentication tools are limited to one baseline as described above.
46
49
  - Prefer `infra` over `tool_broken`/`broken` when the evidence points to anti-bot, rate-limiting, or network/upstream failure — a blocked request is not a code bug.
50
+ - Inspect supplied failure details and rendered-page evidence before attributing a timeout. A loaded results page alongside a missing expected capture is evidence to investigate the workflow's trigger or response selection, not proof that the requested API tool succeeded. Compare a supported contrasting input when useful. Cite concrete contradictions for `tool_broken`; if the cause remains unresolved, use `infra` with that uncertainty stated rather than inventing bot defense. Keep unsuccessful core tools and their dependent coverage gaps explicit even when the graded score passes.
47
51
  - Prefer `bad_params` over `tool_broken` when re-reading the schema shows your own inputs were invalid.
52
+ - Check source coverage when the result or available evidence makes it testable. A bounded collection may legitimately be sparse, but a plausible non-empty subset alone does not prove completeness. Investigate missing eligible records and distinguish observed absence from extraction loss. For related returned attributes that can differ, use an available contrasting record to verify each attribute rather than treating baseline equality as proof. If source coverage cannot be established, report that limit without inventing a failure.
48
53
  - Require affirmative evidence before assigning `no_op` or `broken`. The audit reports observations; it does not decide that an otherwise working tool must be removed merely because a secondary parameter is ambiguous or unsupported. Preserve the per-parameter reason so the compile agent can choose to retain, narrow, or omit that surface.
49
54
  - **Chain producer-sourced values.** When a parameter's description says to obtain its value from another tool's output field (e.g. "Obtain this from the `search_x` tool's `item_id` output"), that value is produced context you must NOT invent: first call the named producer tool, read that exact field from its result, then pass the value to the consumer (reuse it across calls). Judge the consumer on that real value. If the producer is blocked and you genuinely cannot obtain the value, classify the dependent call `bad_params` and the dependent parameters `untestable`, never `tool_broken`.
50
55
 
56
+ Compare the consumer's public contract with the actual producer record shapes.
57
+ One selected record can contain several members even when the description uses
58
+ a singular noun. Unless the public contract explicitly excludes that structure,
59
+ use an available fresh multi-member producer record for a representative chain
60
+ call. Compare all selected members and their order with the consumer result;
61
+ a plausible result for only the first member is not a correct grouped result.
62
+ The consumer may legitimately return components that together cover the selected
63
+ record; each component need not cover every member. Check that their relationship
64
+ and value scopes are explicit instead of assuming component records are complete
65
+ alternatives. Cite a concrete missing or contradictory relationship, not merely
66
+ a component containing fewer members than the overall selection.
67
+ A runtime rejection does not retroactively make a contract-compatible producer
68
+ value bad input. Changing labels between two singleton records does not cover
69
+ this distinction. If no suitable record is available, report the coverage gap
70
+ without inventing a selection or declaring an unobserved failure.
71
+
51
72
  ## Output
52
73
 
53
74
  End your final message with **exactly one** fenced `json` block and nothing after it. It must parse as this object:
@@ -12,8 +12,9 @@ The runtime only executes the program you write.
12
12
  1. Call `read_session_summary`.
13
13
  2. Inspect relevant requests and responses with `search_requests`,
14
14
  `read_request`, and `read_response_body`.
15
- 3. Write `workflow.json` and any recording-grounded
16
- `request-transform.ts` needed by the requests.
15
+ 3. Write `workflow.json`, an offline `request.test.ts`, and any
16
+ recording-grounded `request-transform.ts` needed by the requests. Call
17
+ `run_tests` and fix request construction before live verification.
17
18
  4. Call `run_verification` with one declared action and its parameters, then
18
19
  stop. The orchestrator runs it in a verification browser and resumes you with
19
20
  the observed status, body preview, continuation, and next action.
@@ -110,8 +111,11 @@ semantics.
110
111
  and the caller-facing message. Carry every prior capture referenced as
111
112
  `${state.X}` by the next action unless that action produces it before use.
112
113
  - A `success` outcome is the artifact's authentication completion criterion.
113
- - `persist` names captured non-cookie values that data tools consume later as
114
- `${credential.NAME}`. Cookies persist automatically.
114
+ - `persist` names durable credential interfaces that data tools consume later as
115
+ `${credential.NAME}`. Cookies persist automatically. These interface names do
116
+ not constrain your internal capture names. When they differ, set
117
+ `persistBindings` to `{ "credential_interface": "compiled_capture" }`; the
118
+ runtime stores the compiled capture under the downstream interface name.
115
119
  - Set `crossOriginCookieReinjection` only when the recording proves a
116
120
  cross-origin response cookie must be projected into the browser jar.
117
121
 
@@ -120,10 +124,33 @@ semantics.
120
124
  Use the standard workflow request schema: `method`, `url`, `headers`,
121
125
  `recordingRequestSeq`, optional string `body`, optional `captures`, optional
122
126
  `mode: "navigate"` with bounded navigation criteria, and optional `effect`.
127
+ Navigation can explicitly select a completed page-generated response with
128
+ `networkResponse: { urlIncludes, recordingResponseRequestSeq, method?, resourceType?, occurrence? }`; use
129
+ that only when the recording proves the browser must create the request and
130
+ the selected body supplies this action's needed data.
123
131
  Set `recordingRequestSeq` to the exact `seq` from `read_request` that grounds
124
- the request. It is required on requests whose captures appear in
125
- `authConfig.persist`, so `imprint login` extracts each value only from its
126
- producing recorded response.
132
+ the outgoing request. It is required on requests whose captures appear in
133
+ `authConfig.persist`. For an ordinary request, that request's response is the
134
+ capture evidence. For `navigation.networkResponse`, the capture evidence is
135
+ instead the response cited by `recordingResponseRequestSeq`.
136
+
137
+ For a response field that contains another JSON document as a string, use a
138
+ JSON capture with `path` for the outer field and `decodeJsonPath` for the value
139
+ inside the decoded document. Do not capture structured nested JSON credentials
140
+ with a regular expression; response escaping can change or truncate the value.
141
+
142
+ For every durable interface in `authConfig.persist`, exercise its capture in
143
+ `request.test.ts`. Load the redacted recording through
144
+ `process.env.IMPRINT_SESSION_PATH`, locate the declared `recordingRequestSeq`,
145
+ or locate `navigation.networkResponse.recordingResponseRequestSeq` when the
146
+ capture reads a selected page-generated response. Independently decode the
147
+ intended response field, and assert that evaluating the compiled capture
148
+ produces that exact value. A nonempty assertion or
149
+ comparison of the locator to itself is insufficient: the test must catch a
150
+ broad regex or wrong nested path that resolves to a different field. Keep
151
+ captured values in memory; never inline or print them. The host checks that the
152
+ test file exists and runs it; independent reviewers judge whether its evidence
153
+ is convincing.
127
154
 
128
155
  `mode: "navigate"` performs a real top-level browser navigation for GET and
129
156
  `application/x-www-form-urlencoded` POST requests. Use it when the recording
@@ -133,10 +160,41 @@ preserved. Its response exposes the browser's final URL in the synthetic
133
160
  `source: "response_header"` when a redirect URL carries state needed by a later
134
161
  request.
135
162
 
163
+ When `navigation.networkResponse` is present, the selected response body is
164
+ returned instead of the rendered document. This is a precise agent-authored
165
+ match, not automatic XHR selection and not a DOM playbook. Prefer a normal API
166
+ request when it can express the same operation.
167
+ The outer `recordingRequestSeq` must cite the document navigation, while
168
+ `recordingResponseRequestSeq` must cite the background request whose response
169
+ is returned. Do not use either sequence for both roles.
170
+
136
171
  Use runtime templates exactly as supported:
137
172
  `${credential.X}`, `${param.X}`, `${state.X}`,
138
173
  `${response[N].path}`, and `${generated.uuid|nonce|epoch_s|epoch_ms|iso8601}`.
139
174
 
175
+ Every request body containing one of those runtime templates MUST declare
176
+ `bodyPlaceholderEncoding`. Choose it from the recorded wire format, not merely
177
+ the Content-Type:
178
+
179
+ - `"json-string"` when placeholders sit inside JSON string literals.
180
+ - `"form-urlencoded"` when each placeholder is a form field value.
181
+ - `"raw"` for multipart, opaque, or transform-owned payload bytes.
182
+
183
+ If the body mixes encoding layers, build it in `request-transform.ts` and keep
184
+ the workflow declaration `"raw"`; do not ask the runtime to infer a site-specific
185
+ codec.
186
+
187
+ Write `request.test.ts` to render the actual workflow offline with adversarial
188
+ synthetic credentials, decode the body according to its wire format, and assert
189
+ exact round-trip equality. Choose the cases and test structure from the recorded
190
+ request. Never place real credentials in the test or contact the site.
191
+
192
+ Independently classify every auth request's outward effect. If the session
193
+ summary marks a request `irreversible: true`, preserve `effect: "irreversible"`
194
+ and its exact `recordingRequestSeq`; do not request live verification for that
195
+ workflow. The host blocks live auth when triage provenance is missing or when
196
+ any generated request remains irreversible.
197
+
140
198
  Ground every request, capture, predicate, retry bound, navigation criterion, and
141
199
  transform in the recording. Preserve functional headers and request encoding.
142
200
  Do not store recorded secrets or one-time values as literals. When browser code