- /agent [filter] lists the run's agents (glyphs, elapsed, task) via the
native selector and switchSession()es to the agent's own session file
- run is restored in the agent session by deriving the run id from the
session file path (<stateDir>/runs/<runId>/sessions/...)
- main session file recorded in the run manifest so /back works even after
a reload while viewing an agent chat
- widget re-attach timer guard on session switch
The main session and subagents share the same model backend; when that
backend serializes requests (cloud rate limits or a local server), subagent
streams queue the main chat. Adds two config knobs:
- agent_concurrency (default 3): a semaphore in AgentTree.start caps how many
subagent sessions stream simultaneously (slot is released on completion,
timeout, or setup error so failures cannot deadlock the queue).
- subagent_model (optional): routes spawned agents to a different model or
backend, e.g. ollama/gemma4:e4b, so subagents never contend with the main
session at all. Wired through the spawn tool, the main-session tools, and
the per-agent runtime tools.
Documents both in .hypothesis-machine.example.yaml and adds a concurrency-cap
test (43 tests passing, tsc clean).
- research_control pause/resume now validate the loop state before touching
the tree, so pausing a stopped loop can no longer leave the tree 'paused'
while the loop is not (spawn would fail until a restart).
- read_artifact confinement resolves symlinks (realpath) before checking the
project boundary, preventing symlink-based file leaks.
- Adds confinement tests (42 tests passing, tsc clean).
- web.ts: outbound downloads resolve DNS once, validate the address, and
connect to the validated IP directly, closing the DNS-rebinding TOCTOU
window; malformed SearXNG result URLs are skipped instead of failing the
whole search; web cache is bounded (evicts oldest past 500 entries).
- experiment.ts: reviewer must not be a descendant of the experiment author
(tool-level lineage check on top of the author-id check); stdout/stderr
buffers capped at 512 KB.
- Confirmed Pi's extension tool registry is per-extension-instance, so
reload re-registration is safe; no change needed there.
- Adds a lineage-independence test (39 tests passing, tsc clean).
- AgentTree.restart() revives a stopped run in the same session: resets the
root, archives old branches, and restores spawnability (stop no longer
cancels the root).
- ResearchLoop.start() restarts from stopped/completed and resets iteration
counters; setGoal is allowed in terminal states; supervisor 'start' revives
the tree when the root is not spawnable.
- Cancelled/failed/archived children no longer count toward the per-agent
child limit and archived agents are ignored by the duplicate-task guard.
- cancel() no longer overwrites an already recorded agent result.
- Add agent_timeout_seconds (default 1800) so hung agent sessions fail
instead of blocking wait() forever.
- FTS search now prefix-matches tokens (tolerates inflections) and safely
handles punctuation/FTS5 metacharacters instead of returning false
negatives or throwing.
- Add tests for restart semantics, child limits, result preservation,
agent timeouts, and FTS morphology/special characters (38/38 passing).