Code map

Fisk AI turns a fisk command-line application into an LLM agent by introspecting its command tree and exposing the allowed commands as tools. This section is a reading guide to how that is implemented, for contributors, reviewers, and anyone auditing the harness before trusting it with a production tool.

Snapshot

Generated 2026-08-25 against tag v0.0.5. Commits after this one may make parts of this map stale.

The mental model

There is one core and several faces. A fisk application is introspected once into a set of tools; a YAML file narrows that set and decides what needs approval; and then the same selection is driven by a model in an agent loop, served to an MCP client, or served to other agents and to people. Three durable stores sit underneath, and none of them is part of the conversation the model sees until the harness decides to put it there.

fisk CLI appintrospected onceagent.yamlselects and gatestool set and loopone flat namespacegated, bounded, journaledrunterminal, human gatemcphttp clientsa2aother agentsservejobs and slackmemorymodel-written notesknowledgeoperator documentssessionsappend-only journalthe same selection drives every face; only some of them can reach a person
One core, four faces, three stores. A terminal run reaches its own agent over the same protocol it uses to reach somebody else's.

What the design optimizes for

Nothing is silently weakened. A configured confirm tag that matches no tool is warned about, because leaving it unreported would give a false sense of safety. A tool-name collision aborts the run rather than shadowing, because shadowing a gated command would strip its gate. A tag-based exclude on a remote host is rejected outright, because discovery carries no tags and the filter could never be honored.

Failures land at startup. An unknown backend, a typo in an options block, a bucket with a time-to-live, an unreachable peer, a stale knowledge manifest: all of them stop the process before the model is contacted, and the error names the key to change.

Untrusted text stays data. Model-written memories and retrieved documents are fenced, labeled as data rather than instruction, sanitized at write time, and sanitized again at render time.

How to read this section

Start with Architecture for the layering and the patterns that repeat, then Configuration, since every entry point begins by parsing a file. From there The agent loop and Tools and introspection are the core, and the rest can be read in any order.

Every page names the files and symbols it describes, states the invariants the safety story depends on, and says where something is declared but not yet wired.

Explore

  • Architecture: How the packages layer and which patterns repeat across them
  • Configuration: Parse agent.yaml once, default it, and validate it for the command that asked
  • The agent loop: Call the model, run the tools it asks for, journal each step, under a budget
  • Tools and introspection: Turn a fisk command tree, peer agents and MCP servers into one flat tool set
  • Model providers: Speak one neutral conversation model and translate it at a single boundary
  • Memory: Store model-written notes under validated keys and scoped overwrites
  • Knowledge: Index operator documents into one SQLite file and answer with citations
  • Durable state: Journal every step, fold it back into a resumable run, and keep the task record apart
  • Serving: Host an agent behind channels and speak one validated protocol to peers
  • Telemetry: Report a run as OpenTelemetry spans and metrics without letting content leak
  • The terminal: Render one conversation the same way live, replayed and piped
  • Reference: The command surface, the source map and the vocabulary