skills/sssf/cookbooks/update_config.md
INDigitalStudio 2cc766aabe Add sssf skill, installable via the skills CLI
Port the sssf skill from ~/.agents/skills/sssf into this repo so it can be
distributed and installed with the skills CLI (skills add INDigitalStudio/skills
--skill sssf).

- Copy the skill (SKILL.md, cookbooks, references, scripts, templates, and the
  visualizer app source) into sssf/.
- Gitignore build/runtime artifacts: the visualizer's node_modules/ and dist/,
  Python bytecode, and the machine-specific repos.json.
- Make the skill location-independent: install.py now stamps the skill's real
  path into the stamped justfile's skill_dir (replacing the hardcoded
  ~/.agents/skills/sssf), so 'just obs' finds the visualizer wherever the CLI
  installed the skill.
- Update cookbooks to use <skill>/scripts/... instead of the hardcoded path,
  and document the skills CLI install command.
- Update the repo README with install instructions.
2026-08-09 21:00:28 +00:00

5.6 KiB

Update Config

Add or retune agents in sssf.config.yaml.

Retune model or thinking

Edit the agent's entry in place:

  - name: builder
    model: google/gemini-3.6-flash   # ALWAYS provider/model-id
    thinking: high                   # was medium

Write the model as provider/model-id, never a bare id. The same model is usually carried by several providers, and an ambiguous pattern raises in agents.validate() — grounding every agent that inherits it. See references/config.md.

Thinking levels are Pi's reasoning effort: off | minimal | low | medium | high | xhigh | max. It only bites when the model is registered with reasoning: true in ~/.pi/agent/models.json.

A model change means a fresh session. agent_map.json records the model each coding-agent session was created with. When a joined run (--adw-id) finds the config's model no longer matches the recorded one, that agent starts a new session rather than resuming — the map is updated, never a bad resume. Thinking changes do not invalidate a session; model changes do. Expect the agent to lose its accumulated context window on the first run after the change.

Recolor an agent's lane

  - name: builder
    color: "#22d3ee"      # hex; the starter roster ships violet/cyan/amber/green

Purely cosmetic and safe to change mid-project: the color rides the agent_start event and the agent_sessions row, so the visualizer picks it up on the next run without touching past sessions. Omit the key to let the UI's fallback palette choose.

Retune tools

Pi's seven builtins: read, bash, edit, write, grep, find, ls. The last three are off in bare Pi, so an agent that doesn't name them will shell out through bash to search and list.

Set the roster-wide floor in defaults, then narrow per agent:

defaults:
  tools: [read, bash, edit, write, grep, find, ls]

agents:
  - name: reviewer
    tools:                # explicit list wins over defaults
      - read
      - grep
      - find
      - ls
      - bash
      - write

Resolution: the agent's own list wins → else it inherits defaults.tools → else None, meaning all tools. An empty list is not "all tools"; it is a tool-less agent, and it will stall.

Narrow by role, not by reflex:

  • Any agent that must produce a context_handoff/ artifact needs write — without it, it falls back to a bash heredoc to create the file the gate checks for.
  • Withhold edit/write only where the restriction is the guarantee. The reviewer's contract is "change nothing", so withholding edit makes that structural instead of merely prompted.
  • Recon agents should get the full read surface (read, grep, find, ls) — cheaper and more legible in the trace than the equivalent bash calls.

Extension tools count against the allowlist. --tools filters built-in, extension, and custom tools alike. Once an agent has a tools list — its own, or inherited from defaults — a tool registered by one of its harness_engineering extensions is dropped unless it is named there. Nothing errors: the extension loads, the run passes, the tool is just never offered. Any agent with a tool-registering extension must list that tool by name.

Add harness extensions

    harness_engineering:
      - .pi/extensions/json_guard.ts    # a pi extension FILE PATH

Entries are pi extension file paths, passed through as pi -e <path>, applied to that agent only. Reach for an output-tightening extension when an agent keeps wrapping its envelope in prose and burning correction retries. The starter roster ships with none — this is an escape hatch, not a default.

Adding a tool-registering extension is a two-part edit. The extension path goes in harness_engineering, and the tool name it registers goes in that agent's tools list:

  - name: reviewer
    harness_engineering:
      - .pi/extensions/ast_query.ts     # registers tool: ast_query
    tools:
      - read
      - grep
      - find
      - ls
      - bash
      - ast_query                       # REQUIRED — or the extension loads and its tool is filtered out

Skip the second half and it fails silently: extension loaded, run green, tool never available to the model. Extensions that only shape output or register flags — no new tool — need no tools change.

Add a new agent

Three steps, all required — skipping any one fails agents.validate() at ADW startup, before anything spawns:

  1. Prompts. Create adws/adw_data/prompt_engineering/{name}/system.md (Purpose + Instructions — the agent's static identity, nothing else) and user.md (an h3 per incoming datum: {{prompt}}, {{previous_envelope}}, {{context_handoff_dir}}, then the task, then a ## Report section showing the exact output JSON). Copy an existing pair as the shape.
  2. Config entry. Name, purpose, prompt refs, plus anything that differs from defaults.
  3. An output type. Every agent call parses against a concrete Pydantic model in adw_modules/data_types.py. If none of PlanOutput, BuildOutput, ScoutOutput, ReviewOutput, DocumentOutput fits the new agent's report, add one — see update_modules.md. The user prompt's Report section must show exactly that JSON shape.

Then name the agent in an ADW's REQUIRED_AGENTS and call it.

Rules that do not bend

  • ADW scripts name agents, never models. Swapping a model is a config edit and touches no Python.
  • One agent, one prompt, one purpose. If an entry needs two purposes, it is two agents.
  • Output types never appear in config — they live at the call site, paired with the user prompt.

Full spec: references/config.md.