Skip to content

fix(hooks): config-less Desktop/SDK bootstrap deadlock (#1019)#1021

Merged
michael-wojcik merged 7 commits into
Synaptic-Labs-AI:mainfrom
michael-wojcik:fix-1019-harness-aware-bootstrap
Jun 24, 2026
Merged

fix(hooks): config-less Desktop/SDK bootstrap deadlock (#1019)#1021
michael-wojcik merged 7 commits into
Synaptic-Labs-AI:mainfrom
michael-wojcik:fix-1019-harness-aware-bootstrap

Conversation

@michael-wojcik

Copy link
Copy Markdown
Collaborator

Summary

Resolves the bootstrap deadlock that strands PACT sessions under any config-less team substrate — the Claude Desktop harness, older-CLI full-UUID sessions, and (by construction) the Agent-SDK harness. The platform creates ~/.claude/teams/<full-session-uuid>/ with inboxes/ but no config.json, so the identity-match resolver falls back to a minted session-<id8> name that doesn't match where tasks live — deadlocking the secretary spawn and the bootstrap marker (Edit/Write/Agent blocked all session).

Two surgical, session-id-anchored edits in existing functions — no harness detection, no config self-provision, CLI byte-identical:

  • GATE 1 (pact_context.py::_resolve_aligned_team_name, 3e744931): after the identity-match misses, a new branch-2 anchors on the harness-invariant session_id — if teams/<session_id>/ exists with inboxes/ | file-edits.json (and passes is_safe_path_component as the first conjunct), resolve to it. Heals the dispatch-gate hard-deny and the marker's team resolution. Never-raises preserved.
  • GATE 2 (bootstrap_marker_writer.py::_team_has_secretary, e5177258): the members[] check is tried first (CLI byte-identical), then a config-less fallback accepts teams/<team>/inboxes/secretary.json as the "secretary joined" witness.

Why it's safe

  • CLI byte-identical: branch-2 is unreachable under the interactive CLI (the platform names the dir session-<id8>, so teams/<full-uuid>/ never exists — steady-state and the ~38s cold-start window); the members[] arm is tried first.
  • Independently double-verified: two adversarial verification passes. The first caught that the originally-converged "detect Desktop by config-absence" signal was unsound (config-absence is shared by the CLI ~38s cold-start) and drove the reframe to session-id-anchoring. The second confirmed completeness (no uncovered deadlock path; both deadlock surfaces heal) and the path-safety guard-order.
  • Tests (4b61ebfe): 24-cell suite + a harness axis on the both-modes matrix. Full suite 9490 passed / 0 errors / 0 failures; non-vacuity proven by source-only revert (6 GATE-1 + 2 GATE-2 cells go RED on revert; the non-misfire/security cells correctly stay GREEN). Non-mocked seam tests throughout (the 3 gates are seam-dependent). Load-bearing cell: the CLI cold-start non-misfire proof.

Scope

Deferred validation (post-merge)

The fix targets a substrate this CLI session cannot exercise. Two deferred checks ship as doc cells in the test suite (not runnable CI): a negative probe (SendMessage to a never-spawned synthetic name → confirm its inbox is not pre-created) and a 7-step manual Desktop protocol (confirm end-to-end: secretary spawns, marker writes, tools unblock, harvest non-empty).

Completes the deadlock-fix acceptance criteria of #1019; closure pending the deferred manual Desktop validation. Version bumped to 4.4.39 (PATCH).

@michael-wojcik michael-wojcik merged commit e371ac9 into Synaptic-Labs-AI:main Jun 24, 2026
1 check passed
michael-wojcik added a commit that referenced this pull request Jun 24, 2026
… witness (#1023)

PR #1021's config-less inbox-witness fallback in _team_has_secretary was also consumed by the bootstrap_gate secretary-spawn carve-out (binding 5). The inbox created by TaskUpdate(owner=secretary) BEFORE the Agent spawn made the witness True prematurely, so the carve-out DENIED the canonical secretary spawn — re-deadlocking bootstrap on every fresh CLI session.

Adds a members[]-only JOIN witness (_secretary_in_members) in bootstrap_gate with a broad except for the get_claude_config_dir/Path.home RuntimeError seam; the local marker_writer import is removed and _team_has_secretary keeps its inbox DISPATCH witness for the marker writer. A witness-read error now fires the carve-out (allow) — safe, since it only ever permits the canonical secretary spawn (bindings 1-3 gate all else). Non-vacuous both-modes regression (real task-assignment inbox), symbol-name docstring cleanup, PATCH 4.4.40.

Closes #1023.
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