Report chain: when consecutive report cards exceed the failure limit the
parent now fails through transition_work_item (settlement, dependents,
manager visibility) instead of parking forever in AWAITING_MANAGER_REVIEW
behind a metadata hold no reconcile path could clear. The hold stamp
survives only as the quarantine fallback when the FAILED write does not
land, mirroring the attempt ledger's terminalize pattern.
Cursor prompt spill: one stable file per task (retries overwrite instead
of accumulating) and a self-ignoring .gitignore so workspace git never
picks up .opc/external_prompts.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
On Windows, an npm-installed `claude` resolves to a .cmd shim, so
_resolve_launch_command wraps it in `cmd.exe /d /s /c ...`. cmd.exe treats a
newline inside an argument as end-of-command, silently truncating a multiline
prompt at the first line break -- the agent received only the "## Task Brief"
heading and replied that no task was included.
Detect this case in _interactive_prompt_transport and deliver the prompt over
the existing stdin channel instead. The guard requires all three of: nt
platform, a newline in the prompt, and a command that resolves to .cmd/.bat.
It reuses _resolve_windows_command_shim so the check matches the same
resolution logic that decides whether cmd.exe wrapping happens.
Also records prompt_transport_reason in the stdin metadata to distinguish this
trigger from the pre-existing oversized-prompt path.
Verified against the real claude CLI: transport flips to stdin and the CLI
confirms all prompt lines arrive intact.
Cursor-agent puts prompts on argv, so oversized company/report handoffs hit
OS ARG_MAX, crash the card as FAILED, and reconcile kept minting new Report
attempts forever. Spill large Cursor prompts to a workspace file and hold the
report chain after consecutive failures.
Suite went from 27 failures plus one permanent hang (never finished) to
1846 passed / 0 failed in ~85s, including under FORCE_COLOR.
- office_shutdown_lifecycle: construct WSHandler via the real __init__
(helper) instead of hand-copied __new__ stubs that drift from the
constructor (#11 added _runtime_status_sync_task and the stubs hung);
the formerly-hanging wait now has a 5s wait_for.
- import-time patch hygiene: company_recruiter / company_reorg /
engine_session_defaults replaced module-level permanent
tempfile.TemporaryDirectory monkeypatching with paired
setUpModule/tearDownModule, fixing order-dependent sqlite failures in
transcript_pagination during full runs.
- stale tests updated to current product semantics: resume stubs use
status="done" (failed is deliberately non-resumable), fix4 asserts the
native review contract through build_company_work_item_contract,
delivery fixture carries user_visible/feedback_scope=final, ownership
doc names progress_log, session compression calls
maybe_compact_session(force=True) explicitly, hard delete removes the
work item row, parallel-isolation asserts delegate rebind and stubs
_get_project_delegate, role update goes through OrgService on an
editable custom org (plus read-only rejection case), collab_rpc patches
the single os.name decision point instead of poisoning pathlib, codex
no-pty builds inside the patch, identity-guard false positives reworded.
- cli_board actions rewritten against the real OfficeServiceFactory seam
with a tempdir OPC_HOME (old direct-engine stubs were never consulted
and the tests wrote into the real OPC home).
- cli_app assertions strip ANSI via _plain_output so a color-forcing
shell (FORCE_COLOR) cannot break plain-text expectations.
- deleted never-runnable test_org_concurrency (pytest.mark.asyncio
without the plugin, stdlib-only assertions) and three dead skipped
filesystem-handoff tests.
- pyproject: dev extra (pytest, pytest-timeout) and a 300s per-test
timeout backstop so a wedged test fails instead of stalling the suite.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>