fix(context,tools): context hygiene + tool ergonomics from freestyle QA

Found while live-QAing freestyle_planning on a 12B local model:

- list_dir tool: recursive, .gitignore-aware listing so weak models stop
  flooding context with `ls -R` over node_modules/build/dist. Wired into
  the fileRead toggle + advertised to the planner (architect_freestyle).
- ContextClassifier: assistantToolCall turns are STRUCTURED, so the token
  pruner never shreds the model's own tool-call history — that was causing
  amnesia loops (re-issuing calls it had already made).
- Retire instruction-doc LLMLingua pruning (DOC_SOURCE_TYPES emptied): it
  fused load-bearing procedural text into unparseable soup. The static
  block stays small by dropping CLAUDE.md at the loader instead.
- AgentInstructionsLoader: load only AGENTS.md, not CLAUDE.md — the latter
  targets the outer assistant and polluted the agent's stage context.
- DefaultSessionReducer: WorkflowFailed flips session status to FAILED (was
  stuck ACTIVE forever, so clients/approval loops never saw a terminal).
- ShellTool: run shell command lines (cd/&&/pipes) via `sh -c`; unrunnable
  program is recoverable instead of an uncaught IOException killing the
  stage; malformed argv (non-string/collapsed-array) rejected with guidance.
- llmlingua sidecar: cap force_tokens to max_force_token (big docs blew the
  assert and 500'd, so doc pruning silently failed open).

Tests added/updated across all of the above.
This commit is contained in:
2026-07-02 00:44:04 +04:00
parent cb4e41a59f
commit 968cbfa973
15 changed files with 482 additions and 55 deletions
@@ -1,8 +1,9 @@
# Architect — Freestyle Execution Plan
You are the architect stage in a freestyle workflow. Your only output is a single JSON
`execution_plan` artifact. Do not write prose design documents; emit the plan and nothing
else.
You are the architect stage in a freestyle workflow. Your only output is the
`execution_plan` artifact, produced by calling the **`emit_artifact`** tool with the plan's
fields filled in. Do not write prose design documents and do not write the plan as a plain
message; call `emit_artifact` and nothing else.
## Inputs available to you
@@ -27,7 +28,7 @@ Emit a JSON object that validates against the `execution_plan` schema:
"produces": "<unique artifact_id this stage emits, your choice of name>",
"kind": "<one of the available artifact kinds listed in your context>",
"needs": ["<artifact_id consumed from an earlier stage>"],
"tools": ["file_read", "file_write", "file_edit", "ShellTool"]
"tools": ["file_read", "file_write", "file_edit", "shell"]
}
],
"edges": [
@@ -58,10 +59,12 @@ Emit a JSON object that validates against the `execution_plan` schema:
- Declare `needs`: every upstream artifact id the stage's prompt references. Every id in
`needs` must be `produces`d by a strictly earlier stage.
- Include `tools` per stage as it needs them, using only names from this set:
`file_read`, `file_write`, `file_edit`, `ShellTool`, `task_context`, `task_update`,
`file_read`, `file_write`, `file_edit`, `list_dir`, `shell`, `task_context`, `task_update`,
`task_search`. Stages that write or edit files take the file set
(`["file_read", "file_write", "file_edit", "ShellTool"]`). Do not invent names beyond
this set.
(`["file_read", "file_write", "file_edit", "list_dir", "shell"]`). `list_dir` gives a
recursive, `.gitignore`-aware tree (skips `node_modules`/`build`/`dist`) — give it to any
stage that explores or scaffolds a project, so it never needs `shell` `ls -R`/`find`. Do not
invent names beyond this set.
- **Task tracking — only if the `analysis` references a task** (an id like `auth-142` that
the analyst found, opened with `task_create`, or named as the ready task of a
`task_decompose` graph; if none is referenced there is no task to track). Thread **only that