Approving (or sending feedback on) the delivery review card runs employee
self-evolution as company work items, but the finalizer required the
turn's FINAL chat text to be bare JSON. The hardened native runtime
appends a verification status line to every final text and the manager
dispatch guard displaces the final message with a justification, so every
reflection died with invalid_self_evolution_json even when the model
produced valid patches on all three attempts, and the FAILED items
polluted the delivered run's terminal verdict.
- Add a submit_self_evolution_patches tool as the authoritative result
channel (exposed only on self-evolution work items, approval-exempt).
The text parser becomes a fallback that scans fenced blocks and
balanced JSON objects, and retry feedback now carries the concrete
parse failure plus the tool instruction.
- Settle abandoned reflections as CANCELLED (self_evolution_abandoned)
and exclude kind=self_evolution from run-lifecycle settlement so an
opt-in reflection can never dirty a delivered run.
- Claim the review card with a consuming CAS before spawning (duplicate
approve/feedback replies answer idempotently instead of re-entering),
bound the reflection run with a 40-minute deadline that cancels
leftover self-evolution items, and hand the claim back to pending when
the consumed run crashes mid-flight.
Verified live on real runs: the unfixed code failed the approve path in
90s with zero patches recorded; with the fix both the approve and the
feedback paths recorded patches end-to-end (CEO->COO and CEO->CMO
cascades, zero retries, human feedback reflected in patch content).
tests/: 1924 passed.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>
Project 3333 forensics: env_engineer sent a blocking question to the CTO,
got a full reply 96s later, and still deadlocked the whole run — the
park half (`_park_for_blocking_comms`) had no wired consumer, so
WAITING_FOR_PEER work items could never be released.
Unpark path (root fix):
- The dispatcher loop now calls `_try_unpark_blocking_comms` each tick
for parked, non-in-flight tasks; blocking replies land as durable
inbox files, so the check is read-only until all replies are present.
- `_try_unpark_blocking_comms` accepts orphaned waits (peer_wait
stripped by the legacy resolver while the work item stayed parked)
and falls back to the park predicate itself: an empty unresolved
blocking outbox releases the task, anything pending keeps it parked.
- `resolve_task_peer_wait` no longer touches comms_blocking waits (it
flipped task.status without the work-item phase and stripped the
peer_wait evidence); `_resume_peer_checkpoint` re-enters the company
runtime for comms/orphaned waits and lets the dispatcher converge.
File tools (defaults changed at their declaration sites, honoring the
"empty tools = everything, explicit list = exactly that" contract):
- corporate builtin groups gain file_write/file_edit for coordination,
QA, and data-acquisition roles.
- all shipped org YAML role tool lists gain the missing
file_write/file_edit entries.
- coordination turn modes no longer strip file_write/file_edit at
runtime — in-context content (briefs, matrices) must be persistable
instead of getting trapped in blocking DM hand-offs.
Also includes the pending office_ui ws_handler change from the working
tree.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>