fix: release comms-blocking parks when replies arrive and give every role file authoring tools

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>
This commit is contained in:
LZH-YS1998
2026-07-08 21:06:39 +08:00
parent 4b29b89371
commit 5aa57e69ee
12 changed files with 110 additions and 10 deletions
+11 -1
View File
@@ -8476,6 +8476,16 @@ class WSHandler:
for item in list(pause_request.get("required_fields", []) or [])
if str(item).strip()
]
resume_hint = str(pause_request.get("resume_hint", "") or "").strip()
if not resume_hint and "blocked by autonomy policy" in f"{prompt} {summary}".lower():
# This park came from a tool-approval timeout. The approval card
# posted earlier stays pending and clickable indefinitely, so point
# the user at it instead of leaving typed input as the only path.
resume_hint = (
"Tip: the tool-approval card above is still active — choose an option "
"there (e.g. Approve) to grant the permission and resume this task "
"automatically. Reply here only to give different instructions."
)
return {
"checkpoint_type": "task_user_input",
@@ -8489,7 +8499,7 @@ class WSHandler:
"input_questions": input_questions,
"required_fields": required_fields,
"context_note": str(pause_request.get("context_note", "") or "").strip(),
"resume_hint": str(pause_request.get("resume_hint", "") or "").strip(),
"resume_hint": resume_hint,
"requesting_role_id": str(
payload.get("requesting_role_id") or pause_request.get("requesting_role_id") or ""
).strip(),