Skip to content

feat(flow): authoring session wraps Recorder; compile wrapper returns needs_human_admit - #449

Merged
abrichr merged 3 commits into
mainfrom
feat/authoring-session-2026-08-31
Sep 1, 2026
Merged

feat(flow): authoring session wraps Recorder; compile wrapper returns needs_human_admit#449
abrichr merged 3 commits into
mainfrom
feat/authoring-session-2026-08-31

Conversation

@abrichr

@abrichr abrichr commented Aug 31, 2026

Copy link
Copy Markdown
Member

Implementation continues. Do not merge unless the founder says so. This PR is F1 of the authoring mailbox stack: ChatGPT.com can drive once on the person's computer, Flow records, a person admits. The un-park gate is a synthetic CI job, not a real bank or tax job.

Synthetic un-park gate

tests/test_authoring.py is the gate. It drives MockMed through Playwright: no PHI, CI only, never shown as the user's path on start or pack pages. A green run of that file is enough to keep implementing mailbox/MCP/local drive. Production should serve mailbox and /mcp (web 464). Rollback is AUTHORING_MCP=0. User jobs are the ones they name.

Summary

F1 of the hosted authoring MCP stack. New openadapt_flow/authoring.py wraps the existing Recorder for a scripted first demonstration. Desktop and --authoring stdio call this session (open_session / AuthoringSession). It does not fork the recording format, does not change compile_recording, and does not copy emit/mcp_tool.py.

Behavior

  • Agent click / type_text / press go through Recorderevents.jsonl + frames (same path as record_desktop_demo).
  • pause_for_input captures the pause-target node (backend_pixels + before_png) at pause start and returns {paused, param, secret} with no value.
  • Continue calls Recorder.record_observed on that pause-target. It does not call backend.type_text / Recorder.type_text and does not read current OS focus (overlay Continue can steal it).
  • Secret pause: secret=True, no text on disk, redact_region of pause-target bounds (frames blacked out). Empty readable field stays paused. Masked AX-empty + operator Continue still records.
  • Non-secret MockMed note (CI fixture): text_value_at / Playwright input_value on the pause-target pixels; text goes into record_observed only. Empty/unreadable non-secret field stays paused.
  • AuthoringSession.compile() calls compile_recording (signature unchanged, returns Workflow) and wraps the result as { status: "needs_human_admit", workflow_id, recording_retained: true }. Never paints VERIFIED. Optional bundle_dir / name (A1 calls compile() with no args).
  • Compile refuses if a secret-field pause has no TYPE/param event, if the session was halted, or if a pause is still in progress.
  • Citrix / RDP / Windows native (win, win_agent) refuse agent-drive with COACH_ONLY. Do not spawn win_agent / parallels_vm.launch_agent.
  • Capture observers already drop OS-injected events. This PR does not invent record_injected.

Taxes/RBC/Amex are an example job only and are not hardcoded. MockMed is not a product path.

Gaps closed (2026-09-01 review vs design)

  • Halt is abort: _halted is now enforced; compile after halt is refused.
  • Compile while paused is refused (does not drop a secret TYPE).
  • compile() no longer requires bundle_dir/name.
  • open_session() factory for Desktop / stdio --authoring.
  • Pause does not claim {recorded: true} or return a value.
  • Continue never calls Recorder.type_text (test spies both backend and recorder).
  • Secret frames are redacted, not only events/meta.
  • Non-secret empty field stays paused (no empty TYPE/param).
  • Playwright input_value fallback when text_value_at is absent.
  • Source contract: no win_agent spawn, no emit/mcp_tool.py.

Tests

tests/test_authoring.py (scripted backend + live MockMed fixture), 29 passed:

  • Continue does not invoke backend.type_text or Recorder.type_text (required).
  • Continue reads the pause-target via text_value_at, not focused_text_value.
  • Playwright input_value path when text_value_at is missing.
  • Secret: no text on disk; pause-target region black in both frames.
  • Non-secret MockMed note may pass text_value_at / input_value into record_observed only; MockMed compile returns needs_human_admit.
  • Compile returns needs_human_admit and actually calls compile_recording (with and without args).
  • Compile refuses a secret pause with no TYPE/param, halt, and in-progress pause.
  • Citrix/RDP/Windows/win_agent raise COACH_ONLY.

Out of scope

  • compiler/compile.py compile_recording signature: unchanged.
  • emit/mcp_tool.py: untouched (replay, not record).
  • Files owned by open PRs 442 (execute/), 443, 445.
  • Do not merge until the founder says so.

Opened by an agent session, not the founder.

… needs_human_admit

Scripted actuate+record goes through the existing Recorder. Continue after
pause_for_input calls record_observed on the pause-target node and never
backend.type_text. Compile wraps compile_recording and returns
needs_human_admit. Citrix/RDP/Windows native refuse agent-drive.

Signed-off-by: Richard Abrich <richard.abrich@mldsai.com>
Halt is abort: compile after halt is refused. Compile() no longer requires
bundle_dir/name and refuses while paused. Continue stays paused on an empty
non-secret field, reads Playwright input_value when text_value_at is absent,
and is tested not to call Recorder.type_text. Secret pause-target frames are
blacked out. open_session is the Desktop/stdio factory. compile_recording
signature and emit/mcp_tool.py are unchanged.

Signed-off-by: Richard Abrich <richard.abrich@mldsai.com>
… gate

MockMed in this file is a Playwright fixture for CI. It is not a user
path and not a reason to wait for a real bank or tax job.

Signed-off-by: Richard Abrich <richard.abrich@mldsai.com>
@abrichr
abrichr merged commit 98d754e into main Sep 1, 2026
16 checks passed
@abrichr
abrichr deleted the feat/authoring-session-2026-08-31 branch September 1, 2026 21:01
@abrichr

abrichr commented Sep 1, 2026

Copy link
Copy Markdown
Member Author

Merged by an agent session, not the founder.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant