3 Commits

Author SHA1 Message Date
LZH-YS1998 5aa57e69ee 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>
2026-07-08 21:06:39 +08:00
LZH-YS1998 4b29b89371 refactor: unify tool approval into a single engine and cut prompt storms
Collapse the dual permission stack into one policy. The runtime-side
ToolPermissionResolver (own safe lists, own grant memory, bypassed the
ApprovalEngine whenever it said ALLOW) is deleted; runtime_v2 now consults
ApprovalEngine.predict(), a synchronous fast path reading the same config
and the same persisted allowlist as the async authorize pipeline, so a
grant given anywhere is honored everywhere. permissions.py keeps only a
policy-free adapter; the duplicated permissions_v2 config fields and the
runtime grant persistence loop are removed (stale YAML keys are ignored).

New shell_safety module becomes the single source of truth for shell
classification: flag-audited read-only commands (awk/od/jq/sed -n/diff/
git subcommand table/... auto-allow; find -delete, sort -o, curl -o/-d,
rg --pre still prompt even when the bare name is config-listed),
keyword-aware compound splitting (loop/branch headers no longer poison
grants), expansion-safe $() handling, and fail-closed treatment of
anything unparseable or substitution-bearing.

Grant semantics are rebuilt around derived word-boundary prefixes:
"python3 -c" instead of token bags, interpreter -c/-m kept in the prefix,
bash/eval/sudo never grantable as prefixes, read-only segments exempt
from the every-candidate-must-match rule so a granted command chained
with ls/echo verification passes, and approve-once now records the exact
candidates as a session grant so identical re-runs stop re-prompting.
The authorize heuristic also audits the original command text instead of
the quote-dropping preview (echo "<EOF>" no longer reads as redirection).

Validated live on zz_perm_probe1 (native minimal org): awk/od/ls/cat/
sha256sum ran with zero cards, python3 -c parked once and three different
python3 -c commands then passed via the persisted prefix grant, and an
agent-issued rm -f compound correctly re-prompted showing only the
segments needing approval. Full suite failures are byte-identical to the
pre-change HEAD baseline (27 pre-existing).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 18:43:27 +08:00
LZH-YS1998 d78931979d Initial commit 2026-07-01 17:56:31 +08:00