Wiki / Project

Architecture#

L0 portcode-evidence   Evidence, Ledger (JSONL, E-0001 ids, unknown→resolved), Pin (sha256/format), sniff()
L1 portcode-port       survey, parity (token-wise numeric tolerance + PNG), scaffold, shot (ANSI→SVG), site (md→html, safe)
L1 portcode-llm        Client (SSE), ModelProfile, repair_json, parse_text_tool_calls, strip_think
L2 portcode-agent      config → permission → tool(+Ctx) → tools/* → skills → mcp → agents(prompts) → run(loop) → session
L3 portcode-cli        clap commands, terminal UI (Ui + Gate impls), doctor, eval
   portcode-testkit    scripted /v1 server (tests, demos)

Layering: a crate depends only on lower layers. unsafe_code = "forbid" workspace-wide. Input-facing crates deny unwrap/expect/indexing.

Agent loop (run.rs)#

send(text) → for each step: fit context (prune old tool output → summarise) → chat with the agent's visible tools → push assistant message → for each tool call: loop guard, exec → push tool message → persist. exec validates the object/required params, runs the tool in its own task (a panic becomes an error string), clips output to the profile limit.

Tool contract (tool.rs)#

name, description, schema, example, run(ctx, args). Ctx carries the project root, permission rules + gate, per-session state (files read with mtimes, todos), the ledger, cancel flag, read-only flag. Paths resolve lexically then via the longest existing ancestor's real path (symlink escapes ask external_directory); .git is write-protected; .env/keys ask secret_file.

Permissions#

Rules::check(tool, target, default): most specific pattern wins; ties → deny > ask > allow. bash: hard-deny list first, then explicit patterns, then a read-only allowlist (never when the command contains ; & | > < \ $(). Read-only agents deny edit` and every prompt.

Subprocesses#

run_command: sh -c, stdin null, own process group, wall-clock deadline, 1 MB capture per stream (drained so the child never blocks), group SIGKILL on timeout/cancel, provider key env vars scrubbed.

Evidence flow#

pin/screenshot/evidence_add → ledger → docs/PORT.md cites ids → site_build groups evidence by subject with attached screenshots and open unknowns. Screenshots are produced from captured output with its sha256 recorded; they are not drawn.

Edit this page on GitHub