@ssheleg/agent-stack 0.7.2 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,125 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.9.0] — 2026-08-15
4
+
5
+ ### Added
6
+
7
+ - **`agent-harness/references/pi.md` and `pi-sdk.md` — the harness doctrine as a worked
8
+ implementation.** Every other reference in that skill states a rule; **Pi** is small enough
9
+ to read and complete enough to have made each of those decisions in public. So each section
10
+ says what Pi does and then **which rule it is an instance of** — the second half is the
11
+ point, and where Pi disagrees with this pack, that is said rather than smoothed over.
12
+
13
+ Read from `pi.dev/docs/latest` on 2026-08-15: sixteen doc pages plus the package source.
14
+ All sixteen verified reachable (`200`); the only non-resolving URLs in either file are the
15
+ two deliberate placeholders inside custom-provider examples.
16
+
17
+ - **`pi.md`** — the four ways to run it; **sessions as a JSONL tree** (8-hex `id`, `parentId`,
18
+ version 3, `BranchSummaryEntry`) matched to *time travel and forking* in
19
+ `agent-orchestrator/references/runtime.md`; **compaction with the real numbers**
20
+ (`contextTokens > contextWindow - reserveTokens`, defaults 16,384 and 20,000, tool results
21
+ truncated to 2,000 chars while summarizing) matched to the compaction ladder, with what the
22
+ ladder adds that Pi leaves to you; settings precedence that **merges rather than replaces**;
23
+ skills, prompt templates and packages; and the trust model.
24
+
25
+ Its sharpest section is **the deliberate absence of a sandbox**, quoted: *"prompt injection
26
+ from repository files … is expected local-agent risk and cannot be reliably prevented by
27
+ pi."* That is `layers.md`'s delegation thesis stated by the project itself — and for an
28
+ audit it changes the finding, because "no permission model" here is a delegation, not a
29
+ defect. Three containerization patterns are compared by **where credentials end up**, which
30
+ is the question that actually decides between them.
31
+
32
+ - **`pi-sdk.md`** — `createAgentSession()`, `ModelRuntime`, `SessionManager`, `defineTool()`,
33
+ `DefaultResourceLoader`; the RPC protocol with its command groups, its full event lifecycle
34
+ and the **`\n`-only JSONL framing warning**; JSON mode's delta-only records and why;
35
+ the `ExtensionAPI` surface; and **the eight seams** — `tool_call` (can block),
36
+ `tool_result` (a middleware chain), `context`, `before_agent_start`, the three provider
37
+ hooks, and the compaction pair — each matched to the doctrine it lets you implement.
38
+ `tool_call` blocking is called out as the single most important one for an audit: it is
39
+ where a per-tool, per-caller policy can actually live.
40
+
41
+ - Noted with its evidence and its limit: **Pi discovers skills from `~/.agents/skills/`**,
42
+ which on this machine is the ssheleg hub — 72 entries, every family skill carrying the
43
+ `name` and `description` front matter Pi requires. Stated as a fact about the path and the
44
+ front matter, **not** as an observed load: Pi is not installed here. The reference also
45
+ names Pi's documented divergence from the Agent Skills standard (a skill name may differ
46
+ from its directory) and warns that `make-skill`'s validator enforces the strict rule.
47
+
48
+ ### Changed
49
+
50
+ - `references/layers.md` points at the two new files as the worked example of the kernel
51
+ layer it describes abstractly.
52
+ - `agent-harness`'s description gains the embedding triggers (`agent SDK`, `embed an agent`,
53
+ `Pi harness`, `встроить агента`) — 807/1024, inside the family's 970 working budget. The
54
+ repository's own front-matter gate caught a first draft at 1066 and refused the write.
55
+
56
+
57
+ ## [0.8.0] — 2026-08-14
58
+
59
+ ### Added
60
+
61
+ - **`agent-harness`, a fourth skill — the layer between the loop and the model.** The pack
62
+ could wire an agent (`agent-orchestrator`), prove it behaved (`agent-evals`) and connect
63
+ it to other processes (`agent-interop`), and said nothing about **what the agent is
64
+ told**. Five references and a scanner. It runs in both directions: building a harness and
65
+ auditing somebody else's are the same checklist read forwards and backwards, which is why
66
+ the audit lives here rather than in a sixth skill.
67
+
68
+ It is a fourth skill rather than a section because `agent-orchestrator`'s body is
69
+ **489 lines / ~4761 tokens** — already past the 4750 working limit — and could not absorb
70
+ a paragraph, let alone a layer.
71
+
72
+ - **`references/system-prompt.md`** — the right altitude (hardcoded branches on one side,
73
+ vague hope on the other), what actually belongs in a system prompt in order of behaviour
74
+ bought, **enumerating the vocabulary** so an agent stops inventing `pending` and `to-do` in
75
+ the same run, injecting what the model cannot know, and flexible-while-learning versus
76
+ strict-in-production. Plus the three things reasoning models changed: **do not add
77
+ chain-of-thought** (it can degrade instruction-following), give goals rather than
78
+ procedures, and treat reasoning effort as a per-stage dial.
79
+
80
+ - **`references/tools.md`** — the agent–computer interface. Fewer tools than instinct
81
+ suggests, namespacing, and the description as the product: a worked before/after where the
82
+ strong version names *when*, *what it costs*, *how to narrow*, and **the neighbouring tool
83
+ it is confused with** — the highest-value sentence in a tool definition and the one almost
84
+ nobody writes. Then meaning over identifiers, token efficiency as a correctness issue,
85
+ errors that teach, and **poka-yoke** — changing the interface so the wrong call cannot be
86
+ made.
87
+
88
+ - **`references/techniques.md`** — fifteen techniques with a **verdict each for a production
89
+ loop**, not a benchmark score. ReAct is the agent loop and its under-quoted failure is that
90
+ non-informative results derail it; reflection is strong exactly where a cheap objective
91
+ signal exists and is a second opinion from the same source where it does not; Tree of
92
+ Thoughts is almost never worth its combinatorics. Ends with an ordered five-question
93
+ chooser.
94
+
95
+ - **`references/layers.md`** — the question that resolves most framework arguments (*which
96
+ layer am I working at*), what a harness owns, and the design position that **permission
97
+ boundaries usually belong to the environment**: a harness that also claims to be a sandbox
98
+ is claiming a guarantee it cannot keep from inside the same process.
99
+
100
+ - **`references/audit.md`** — seven tracks, three evidence tiers (**measured / documented /
101
+ judgement**, never inflated), computed priority, and a report shape that ends in a plan
102
+ rather than a score. The finding that ends most audits early is stated first: no evals
103
+ makes everything downstream unfalsifiable, including the audit.
104
+
105
+ - **`scripts/audit_agent.py`** — the mechanical half. Five conservative detectors
106
+ (unbounded loop, empty tool description, swallowed error, missing timeout, duplicated
107
+ model literal), each requiring the file to show **two** independent signs of an agent, each
108
+ finding carrying `file:line`. It always prints **what it cannot see** and a **denominator**,
109
+ because `read: 1` alone looks like a broken pass while `1 of 4261` is itself a finding.
110
+ Virtualenvs are skipped by their `pyvenv.cfg` marker rather than by name — a real
111
+ repository met during testing kept 4249 of its 4261 files in `myenv/`, and was excluded
112
+ only because `site-packages` happened to be listed too.
113
+
114
+ ### Changed
115
+
116
+ - **`PROTOCOL_PINNED` now covers `agent-harness`.** Its references document guidance that
117
+ moves, so each carries `**Spec pinned:** … · read <date>` and the build fails without it.
118
+ - **CI runs the scanner's own self-test**, and asserts that a real-tree run discloses both
119
+ its blind-spot list and its denominator — a scanner that could stop disclosing would be a
120
+ scanner nobody could calibrate.
121
+
122
+
3
123
  ## v0.7.2 — the plants say whether they landed, and two of them were not
4
124
 
5
125
  Eight negative self-tests asserted inline, in Python, that their edit had happened —
package/README.md CHANGED
@@ -9,9 +9,10 @@ Part of the [ssheleg skill family](https://github.com/ssheleg/sshlg-skills).
9
9
 
10
10
  ## What is in here
11
11
 
12
- Three skills — `agent-orchestrator` for building one, `agent-evals` for proving it
13
- behaves, `agent-interop` for everything it talks to outside its own process — and
14
- eleven references they load on demand.
12
+ Four skills — `agent-orchestrator` for wiring the loop, `agent-evals` for proving it
13
+ behaves, `agent-interop` for everything it talks to outside its own process,
14
+ `agent-harness` for what it is **told** — and eighteen references they load on demand,
15
+ plus one scanner.
15
16
 
16
17
  **The orchestrator** (`SKILL.md`) — what the agent reads first:
17
18
 
@@ -56,6 +57,26 @@ undoes both), `mcp-ship.md` (mounting, and the 404 that is really a double path)
56
57
  an API gateway does not). Plus a link map, and a verdict on each neighbouring standard —
57
58
  ACP, AGNTCY, AP2, Agent Skills — so an agent stops guessing.
58
59
 
60
+ **The harness skill** (`agent-harness/SKILL.md`) — the layer between the loop and the
61
+ model, and the one where most agent bugs actually live: *the biggest performance
62
+ improvements often come from clearly explaining tool usage in the system prompt*, and *even
63
+ small refinements to tool descriptions can yield dramatic improvements*. Before adding a
64
+ retry or a sub-agent, it asks four questions about the text. Seven references —
65
+ `system-prompt.md` (right altitude, enumerated vocabulary, and the three things reasoning
66
+ models changed — starting with **do not add chain-of-thought**), `tools.md` (the
67
+ agent–computer interface, with a worked before/after and poka-yoke), `techniques.md`
68
+ (fifteen techniques, a verdict each **for production** rather than a benchmark),
69
+ `layers.md` (which layer you are building at, and why permission boundaries are usually the
70
+ environment's job), `audit.md` (seven tracks, evidence tiers, a plan instead of a score) —
71
+ plus **`pi.md` and `pi-sdk.md`, the doctrine as a worked implementation**: Pi read end to
72
+ end, each mechanism matched to the rule it instantiates, its divergences named, and the
73
+ eight extension seams where a permission gate or a context rewrite can actually live.
74
+
75
+ It runs in both directions: **building a harness and auditing somebody else's are one
76
+ checklist read forwards and backwards.** `scripts/audit_agent.py` is the mechanical half —
77
+ five conservative detectors, and it always prints what it *cannot* see plus a denominator,
78
+ so its silence is never read as a pass.
79
+
59
80
  **`references/context-engineering.md`** — what the loop gives up when the window
60
81
  runs out: the five-rung compaction ladder and why to re-measure between rungs,
61
82
  the tool-pair boundary invariant, typed carryover blocks copied across the
@@ -139,6 +160,10 @@ audit row has to carry to prove a control was on.
139
160
  trajectory rather than a final answer, turning a production failure into a
140
161
  permanent fixture, calibrating a judge, gating a release on offline evals.
141
162
 
163
+ `agent-harness`: writing or fixing a system prompt, shaping tools so the model picks the
164
+ right one, choosing between ReAct, reflection, planning and voting — or auditing an agent
165
+ system somebody else built. Not the loop's plumbing, its evals, or its protocols.
166
+
142
167
  `agent-interop`: building or consuming an MCP server, exposing or calling another
143
168
  agent over A2A, publishing to the MCP Registry, or putting a gateway in front of
144
169
  agent traffic. Not for designing one server's tool set — that is a design problem,
@@ -147,7 +172,7 @@ construction, which is `make-skill`. That boundary runs both ways: `make-skill`
147
172
  what changes *because you are writing a skill*, and the protocol itself is described
148
173
  here and nowhere else in the family.
149
174
 
150
- None of the three triggers for a single LLM call in a script or for prompt wording —
175
+ None of the four triggers for a single LLM call in a script or for prompt wording —
151
176
  that is not an orchestrator, and pulling this much doctrine for it is how a skill
152
177
  teaches you to route around it.
153
178
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ssheleg/agent-stack",
3
- "version": "0.7.2",
3
+ "version": "0.9.0",
4
4
  "description": "Production patterns for AI agent orchestrators \u2014 tool-calling loops, multi-stage pipelines with checkpoints, LLM provider routing with fallback, four-layer memory with confidence decay \u2014 plus the wallet side of reselling LLM access. This package is the installer CLI.",
5
5
  "bin": {
6
6
  "agent-stack": "bin/agent-stack.js"
@@ -2,7 +2,7 @@
2
2
  "name": "agent-stack",
3
3
  "displayName": "Agent Stack",
4
4
  "description": "Two skills: agent-orchestrator \u2014 tool-calling loops, multi-stage pipelines with checkpoints, provider routing with fallback, four-layer memory, context engineering, plus the wallet side of reselling LLM access; and agent-evals \u2014 run/trace/thread evals, judges, and fixtures grown from production.",
5
- "version": "0.7.2",
5
+ "version": "0.9.0",
6
6
  "author": {
7
7
  "name": "ssheleg",
8
8
  "url": "https://x.com/sshlg93"
@@ -0,0 +1,163 @@
1
+ ---
2
+ name: agent-harness
3
+ description: >-
4
+ Use when the question is what the agent is TOLD rather than how its loop is wired — writing
5
+ or fixing a system prompt, shaping tools so the model picks the right one, deciding whether
6
+ a job wants a workflow or an agent, or choosing between ReAct, reflection and voting. Also
7
+ auditing an agent system somebody else built: tracks, evidence tiers and a prioritized plan
8
+ instead of a score, plus a scanner. Carries Pi as a worked kernel implementation — SDK, RPC
9
+ and extension seams — for embedding or extending a harness. Triggers - "system prompt",
10
+ "tool description", "agent picks the wrong tool", "agent loops forever", "prompt
11
+ engineering", "ReAct", "workflow or agent", "audit this agent", "embed an agent", "agent
12
+ SDK", "Pi harness", "системный промпт", "агент не вызывает тул", "аудит агента", "встроить
13
+ агента". Not for the loop's plumbing, its evals, or its protocols — those are siblings.
14
+ ---
15
+
16
+ # Agent harness — what the agent is told, and how to audit what someone else told theirs
17
+
18
+ `agent-orchestrator` wires the loop. `agent-evals` proves it behaves. `agent-interop` gets
19
+ it talking to other processes. **This skill is the layer between them and the model: the
20
+ prompt, the tools, and the shape of the work.**
21
+
22
+ It runs in both directions. Building one and auditing one are the same checklist read
23
+ forwards and backwards, which is why they live together here.
24
+
25
+ ---
26
+
27
+ ## Rule zero — most agent bugs are prompt bugs wearing a stack trace
28
+
29
+ The instinct when an agent misbehaves is to change the code. The measured reality, in every
30
+ source this skill was built from, is that the largest behavioural changes come from the
31
+ text: **"the biggest performance improvements often come from clearly explaining tool usage
32
+ in the system prompt"**, and **"even small refinements to tool descriptions can yield
33
+ dramatic improvements."**
34
+
35
+ Before adding a retry, a router, or a sub-agent, check in this order:
36
+
37
+ 1. **Does the tool description say when to use it, not just what it does?**
38
+ 2. **Does the system prompt name the vocabulary?** An agent told to track status will invent
39
+ `pending` and `to-do` and `done` and `completed` in the same run unless the allowed values
40
+ are enumerated.
41
+ 3. **Does the agent know today's date?** A model with a training cutoff will answer from
42
+ memory rather than search unless the current date is injected.
43
+ 4. **Is the instruction flexible where it should be strict?** *"Use the tools in the order
44
+ that makes most sense to you"* is right while you are learning the task and wrong in
45
+ production, where *"you MUST execute a web search for each task"* is what stops a step
46
+ from being skipped.
47
+
48
+ Only then reach for architecture. Reaching for it first is how a prompt defect becomes a
49
+ permanent structural cost.
50
+
51
+ ---
52
+
53
+ ## Workflow or agent — decide this before anything else
54
+
55
+ An **agent** dynamically directs its own process. A **workflow** follows predefined code
56
+ paths. The choice is not about sophistication; it is about whether the number of steps is
57
+ knowable in advance.
58
+
59
+ | Build a workflow when | Build an agent when |
60
+ |---|---|
61
+ | requirements are clear and stable | the task is open-ended or exploratory |
62
+ | predictability and explicit control matter | flexibility outweighs predictability |
63
+ | debugging and cost control are priorities | adaptive reasoning across variables is needed |
64
+ | you can name every step now | step count is unpredictable and cannot be hardcoded |
65
+
66
+ **Start at the simplest thing that works, and stop there.** An agent adds latency, cost and
67
+ a class of failure a workflow does not have — it needs *trust in its own decisions*. Pay for
68
+ that only where a fixed path genuinely cannot be written.
69
+
70
+ ### The five workflow patterns, before you reach for autonomy
71
+
72
+ | Pattern | Shape | Reach for it when |
73
+ |---|---|---|
74
+ | **Prompt chaining** | sequential calls, each on the last output, with programmatic checks between | the task decomposes into fixed steps — outline then draft, draft then translate |
75
+ | **Routing** | classify the input, send it to a specialist | categories are distinct and each wants its own prompt |
76
+ | **Parallelization** | *sectioning* (independent subtasks at once) or *voting* (same task N times) | subtasks are independent, or confidence needs more than one sample |
77
+ | **Orchestrator–workers** | a central model decomposes and delegates, then synthesizes | the subtasks **cannot be predefined** — this is the honest boundary with routing |
78
+ | **Evaluator–optimizer** | one model produces, another critiques, loop | clear evaluation criteria exist and iteration measurably helps |
79
+
80
+ **Orchestrator–workers versus routing is the distinction people get wrong.** Routing picks
81
+ from a known set. Orchestration invents the set per request. If you can enumerate the
82
+ branches, you wanted routing and it is cheaper.
83
+
84
+ ---
85
+
86
+ ## References
87
+
88
+ Each opens with its own **Load this when** line and a revision stamp — this material moves,
89
+ and `test/validate.py` fails the build on a reference that does not say when it was read.
90
+
91
+ | File | Read it when |
92
+ |---|---|
93
+ | [`references/system-prompt.md`](references/system-prompt.md) | you are **writing or fixing the prompt** — altitude, structure, vocabulary, dynamic context, and what changes for reasoning models |
94
+ | [`references/tools.md`](references/tools.md) | the model **picks the wrong tool, or none** — the agent–computer interface: how many, named how, described how, returning what |
95
+ | [`references/techniques.md`](references/techniques.md) | you are choosing between **ReAct, reflection, voting, planning** and the rest — every entry carries a verdict for production, not a benchmark score |
96
+ | [`references/layers.md`](references/layers.md) | deciding **what your harness owns** — kernel, workbench and product layers, and why permission boundaries are usually somebody else's job |
97
+ | [`references/audit.md`](references/audit.md) | reviewing **an agent system you did not build** — seven tracks, evidence tiers, and a prioritized plan |
98
+ | [`references/pi.md`](references/pi.md) | you want the doctrine above as a **worked implementation** — Pi's sessions, compaction, config, skills, trust and containerization, each matched to the rule it implements, and the places it deliberately disagrees |
99
+ | [`references/pi-sdk.md`](references/pi-sdk.md) | you are **embedding or extending** a harness — the SDK, the RPC protocol, JSON mode, and the eight extension seams where a permission gate, a context rewrite or a cost hook can actually live |
100
+
101
+ **`scripts/audit_agent.py`** — the mechanical half of the audit. It finds what is visible
102
+ without understanding intent (an unbounded loop, a tool with no description, a swallowed
103
+ tool error, a hardcoded model, a missing timeout) and **prints the list of things it cannot
104
+ see**, so its silence is never read as a pass.
105
+
106
+ ---
107
+
108
+ ## Auditing an agent system — the short version
109
+
110
+ The long version is `references/audit.md`. The shape:
111
+
112
+ 1. **Run the scanner first.** It is cheap, and its blind-spot list tells you what the rest of
113
+ the audit must cover by hand.
114
+ 2. **Walk the seven tracks** — prompt, tools, control flow, context, failure, permission,
115
+ evidence — and record a finding only with an observation attached.
116
+ 3. **Tier every recommendation** by what backs it: measured here, documented upstream, or
117
+ judgement.
118
+ 4. **Output a prioritized plan, not a score.** A number tells nobody what to change on
119
+ Monday. This is the same rule `agent-evals` applies to eval rubrics and
120
+ `seo-aeo-audit` to sites.
121
+
122
+ **The finding that ends most audits early:** the system has no evals. Everything downstream
123
+ is then unfalsifiable — including this audit. Say so first, and make it the first item.
124
+
125
+ ---
126
+
127
+ ## Boundaries
128
+
129
+ **Against `agent-orchestrator`.** That skill owns the loop's *plumbing*: iteration guards,
130
+ trimming, sub-agent dispatch, provider routing, memory layers, checkpoints. This one owns
131
+ what the model is *told*. They meet in one place:
132
+ `agent-orchestrator/references/context-engineering.md` covers **compaction** — what to drop
133
+ when the window fills — while this skill's `system-prompt.md` covers what to put there in
134
+ the first place. Filling and emptying, two files.
135
+
136
+ **Against `agent-evals`.** That skill measures whether an agent behaves, from execution
137
+ records. This one reviews how it was *built*, from its source and prompts. An audit that
138
+ finds no evals hands over to it; an eval suite that keeps failing on the same axis hands
139
+ back here.
140
+
141
+ **Against `agent-interop`.** MCP, A2A, the registry, gateways — the wire between processes.
142
+ Tool *descriptions* are here; tool *protocol* is there.
143
+
144
+ **Not covered:** model choice and pricing (see the `claude-api` skill for Anthropic's), the
145
+ wallet under resale (`agent-orchestrator/references/llm-proxy-billing.md`), and RAG
146
+ retrieval quality, which is a search problem this skill only touches where it enters the
147
+ prompt.
148
+
149
+ ---
150
+
151
+ ## Checklist — a harness worth shipping
152
+
153
+ - [ ] Workflow-versus-agent decided deliberately, and the simpler option was actually tried
154
+ - [ ] System prompt at the **right altitude** — heuristics, not hardcoded branches, not vague hope
155
+ - [ ] Every status, category and enum the agent must produce is **enumerated in the prompt**
156
+ - [ ] Today's date, and any other volatile context, injected rather than assumed
157
+ - [ ] Tools: a few high-impact ones, namespaced, each described as if to a new colleague
158
+ - [ ] Tool responses carry **meaning, not identifiers**, and are paginated or truncated by default
159
+ - [ ] Tool errors **teach the next attempt** instead of restating a stack trace
160
+ - [ ] One technique chosen per problem, with a reason — not ReAct because it was in a paper
161
+ - [ ] Sub-agents return **distilled summaries**, not transcripts
162
+ - [ ] The agent can be observed: which tool, which arguments, which observation, how many tokens
163
+ - [ ] An eval exists before the prompt is tuned, or the tuning is folklore
@@ -0,0 +1,141 @@
1
+ # Auditing an agent system
2
+
3
+ **Load this when:** reviewing an agent system you did not build — a due-diligence pass, an
4
+ inherited codebase, or a "why is this unreliable" investigation.
5
+
6
+ **Spec pinned:** the tracks below are this pack's synthesis of Anthropic agent guidance, `promptingguide.ai` and the sibling skills · read 2026-08-14
7
+
8
+ ## Contents
9
+
10
+ - What this audit produces
11
+ - Run the scanner first
12
+ - Seven tracks
13
+ - Evidence tiers
14
+ - Priority, computed
15
+ - The report
16
+ - Traps
17
+
18
+ ## What this audit produces
19
+
20
+ **A prioritized change plan, with an observation behind every finding.** Not a score.
21
+
22
+ A number compresses away the only useful information — *what to change on Monday* — and
23
+ invites arguing about the number. This is the same rule `agent-evals` applies to eval
24
+ rubrics and `seo-aeo-audit` applies to sites, and it is the family's position rather than a
25
+ preference: **pass/fail with a named failure condition beats a scalar that names no fix.**
26
+
27
+ ## Run the scanner first
28
+
29
+ ```bash
30
+ python3 scripts/audit_agent.py <path> # human-readable
31
+ python3 scripts/audit_agent.py <path> --json # machine-readable
32
+ ```
33
+
34
+ It finds only what is mechanically visible, and **it prints the list of what it cannot see.**
35
+ Read that list: it is the agenda for the manual half. A scanner that goes quiet is reporting
36
+ its own blindness, and an audit that stops there has audited the scanner.
37
+
38
+ ## Seven tracks
39
+
40
+ Walk them in order. Later tracks assume earlier ones.
41
+
42
+ ### 1 — Prompt
43
+
44
+ - Is there a system prompt under version control, or is it a string literal edited in place?
45
+ - **Altitude**: hardcoded branches (brittle) or vague hope (useless)? See `system-prompt.md`.
46
+ - Are the values the agent must emit **enumerated**, or invented per run?
47
+ - Is volatile context — the date above all — **injected**?
48
+ - Is tool *policy* in the prompt, or only tool *schema*?
49
+ - Has it been pruned, or only appended to since the first incident?
50
+
51
+ ### 2 — Tools
52
+
53
+ - How many? Can the team say, without hesitating, which applies to a borderline case?
54
+ - Are descriptions written **for a model choosing under uncertainty**, or for a human reading docs?
55
+ - Do responses return **meaning or identifiers**?
56
+ - Is there a default limit on response size, or only an optional one?
57
+ - Do errors **name the next action**?
58
+ - Are destructive tools guarded by shape (`confirm: true`, absolute paths, enums) rather than by instruction?
59
+
60
+ ### 3 — Control flow
61
+
62
+ - **Workflow or agent — and was that decided, or defaulted?** An agent where a chain would do is the most expensive finding on this list.
63
+ - Is there a **bounded iteration guard**, and what happens at the bound — a partial answer, or nothing?
64
+ - Are retries and fallbacks **multiplied**? Three providers × three retries is nine calls for one prompt.
65
+ - Is there loop detection, or does a repeated near-identical tool call run until the budget does?
66
+ - Do sub-agents return **distilled summaries** or transcripts?
67
+
68
+ ### 4 — Context
69
+
70
+ - Does anything measure window usage **before** a request fails?
71
+ - Is there a compaction strategy, and does it preserve **decisions and open questions** rather than the discussion?
72
+ - Can a large tool result be **offloaded** and referenced, or does it land in the window whole?
73
+ - Is memory a design, or the conversation history by default?
74
+
75
+ ### 5 — Failure
76
+
77
+ - What happens when a tool errors — is it distinguished from a tool returning nothing?
78
+ - Under MCP, is `isError: true` handled, or does a 200 read as success?
79
+ - Is there a timeout on every external call?
80
+ - Is degradation **honest** — does the user learn the answer is partial?
81
+ - Is there a path where the agent silently does nothing and reports success?
82
+
83
+ ### 6 — Permission
84
+
85
+ - **Which layer owns the boundary?** If the harness delegates it (`layers.md`), audit the surroundings instead of filing a finding.
86
+ - Is tool access differentiated per caller, or is one credential shared by every path?
87
+ - Is tool output treated as **untrusted input**?
88
+ - Can an audit row prove a control was applied — does it carry the **policy version**?
89
+ - Is there a deterministic limit anywhere consequential, or only probabilistic content checks?
90
+
91
+ ### 7 — Evidence
92
+
93
+ - **Are there evals?** If not, this is finding number one and everything else is unfalsifiable.
94
+ - Do they judge the **trajectory**, or only the final answer?
95
+ - Has any production failure become a permanent fixture?
96
+ - Is a judge calibrated against human labels, or trusted because it is a judge?
97
+ - Can a past run be replayed — is the execution record durable?
98
+
99
+ ## Evidence tiers
100
+
101
+ Every finding carries one, and the tier is part of the finding:
102
+
103
+ | Tier | Means | Example |
104
+ |---|---|---|
105
+ | **Measured** | observed here, in this system, with the observation attached | "`agent.py:212` — the `while` has no bound; a repeated call ran 47 times in the log at `logs/2026-08-02`" |
106
+ | **Documented** | the upstream source says so, and this system contradicts it | "descriptions restate the name; Anthropic's tool guidance calls this the highest-leverage fix" |
107
+ | **Judgement** | experience, no measurement available here | "two tools look interchangeable to us" |
108
+
109
+ **Never present judgement as measured.** A finding whose tier is honest survives the meeting
110
+ where it is challenged; one that is inflated loses the whole report.
111
+
112
+ ## Priority, computed
113
+
114
+ `P = blast × confidence / effort`
115
+
116
+ - **blast** 3 = a user of the system is harmed · 2 = the operator · 1 = a future maintainer
117
+ - **confidence** 3 = measured · 2 = documented · 1 = judgement
118
+ - **effort** 1 = under an hour · 2 = a session · 3 = its own project
119
+
120
+ Computed, not felt — so a dramatic finding nobody can act on ranks below a boring one that
121
+ is fixed before lunch, and the ranking can be argued with on its inputs.
122
+
123
+ ## The report
124
+
125
+ 1. **One paragraph** — what the system is, which layer, and the single most important thing.
126
+ 2. **The scanner output**, including its blind-spot list, verbatim.
127
+ 3. **Findings by track**, each with observation, tier and priority.
128
+ 4. **The plan** — ordered by P, with the first three items sized so they can start immediately.
129
+ 5. **What was not looked at**, and why. An audit that does not say where it stopped is read
130
+ as complete.
131
+
132
+ ## Traps
133
+
134
+ - **Auditing the code and not the prompt.** The prompt is the largest behavioural surface and
135
+ is often not in the repository at all — ask where it lives before concluding it is fine.
136
+ - **Filing "no permission model" against a harness that delegates by design.** Check the
137
+ layer first (`layers.md`).
138
+ - **Grading instead of planning.** A score ends the conversation the audit was meant to start.
139
+ - **Confusing "no evals" with "not measured yet."** It is the root finding; put it first,
140
+ because every other conclusion inherits it.
141
+ - **Reading a silent scanner as a clean system.** It is silent about what it can see.
@@ -0,0 +1,104 @@
1
+ # Layers — what your harness owns, and what it must not
2
+
3
+ **Load this when:** deciding what to build versus adopt, or comparing agent frameworks and
4
+ finding the comparison keeps sliding.
5
+
6
+ **Spec pinned:** the three-layer reading of Pi / Goose / OpenCode (gist `AIMOWAY/bd8007c8`); Anthropic agent guidance · read 2026-08-14
7
+
8
+ ## Contents
9
+
10
+ - The question that resolves most framework arguments
11
+ - Three layers
12
+ - What a harness owns
13
+ - What a harness should delegate
14
+ - Choosing your layer
15
+ - Traps
16
+
17
+ ## The question that resolves most framework arguments
18
+
19
+ "Which of these agent frameworks is better" is usually unanswerable because the candidates
20
+ sit at different heights. The question that resolves it:
21
+
22
+ > **Which layer of the agent stack am I trying to work at?**
23
+
24
+ Compare within a layer. Across layers, the comparison is a category error, and the argument
25
+ will not converge no matter how long it runs.
26
+
27
+ ## Three layers
28
+
29
+ | Layer | What it is | Shape | Best when |
30
+ |---|---|---|---|
31
+ | **Kernel / harness** | the agent loop itself — runtime, LLM API abstraction, tool dispatch, a terminal UI | a toolkit you build *on* | you are building an agent product, or studying how agents actually work |
32
+ | **Workbench / orchestration** | a local environment: desktop app, CLI and API, extensions, workflows across many kinds of work | a product you *extend* | you want capability now, across coding, research and automation, without owning the loop |
33
+ | **Product agent** | a domain agent — most visibly coding: explore, plan, edit, test, with built-in modes | a product you *use* | the domain is the one it was built for |
34
+
35
+ The distinction is not quality. A kernel is *supposed* to be smaller than a workbench; that
36
+ is what makes it legible.
37
+
38
+ ## What a harness owns
39
+
40
+ If you are building at the kernel layer, these are yours and nobody else's:
41
+
42
+ 1. **The loop** — iterate, dispatch tools, decide when to stop. With a bounded iteration
43
+ guard, because an unbounded loop is the defect that costs money while looking like work.
44
+ 2. **The model boundary** — one abstraction over providers, so the loop does not know which
45
+ vendor answered. See `agent-orchestrator` §6.
46
+ 3. **Tool dispatch and the ACI** — registration, schemas, parallel versus sequential
47
+ execution, error surfacing. See `tools.md`.
48
+ 4. **Context accounting** — knowing how full the window is *before* the request fails, and
49
+ what to do about it. See `agent-orchestrator/references/context-engineering.md`.
50
+ 5. **Observability** — which tool, which arguments, which observation, how many tokens. If
51
+ this is missing, every other item becomes unfalsifiable.
52
+ 6. **The interrupt/resume contract** — one mechanism, not two. See
53
+ `agent-orchestrator/references/runtime.md`.
54
+
55
+ ## What a harness should delegate
56
+
57
+ The interesting stance, and it is a design position rather than an omission:
58
+
59
+ **Permission boundaries usually belong to the environment, not the harness.** Pi states this
60
+ explicitly — it provides the kernel and delegates sandboxing and permissions to whatever
61
+ surrounds it. Read as a weakness, it looks like a missing feature. Read as architecture, it
62
+ is a clear statement: *a harness that also claims to be a sandbox is claiming a guarantee it
63
+ cannot keep*, because it runs in the same process as the code it would be confining.
64
+
65
+ **Worked out in full in `pi.md` and `pi-sdk.md`** — the kernel layer read end to end, with
66
+ each mechanism matched to the rule it implements and its divergences named. Use it as the
67
+ concrete example when this file's abstractions need a body.
68
+
69
+ Two consequences worth stating plainly:
70
+
71
+ - **A harness advertising "safe tool execution" without an OS-level or container boundary is
72
+ advertising a preference, not a control.** MCP says the same about roots: servers *SHOULD*
73
+ respect them, and real enforcement is OS permissions and sandboxing.
74
+ - **Deciding the layer decides the audit.** If the harness delegates permission, the audit
75
+ looks at what surrounds it, and "the harness has no permission model" stops being a
76
+ finding and becomes a question about the deployment.
77
+
78
+ Also usually delegated: identity and secrets (a credential store, never the loop), durable
79
+ state (a database or a file system, not the conversation), and policy (see
80
+ `agent-orchestrator/references/governance.md` — permission, not protocol).
81
+
82
+ ## Choosing your layer
83
+
84
+ - **Building a product with agentic features** → adopt a workbench or embed a kernel; do not
85
+ write a third loop. Loops are commodity; your tools and prompt are not.
86
+ - **Building an agent platform others build on** → the kernel layer is yours, and the ACI is
87
+ your product surface.
88
+ - **Automating your own work** → a product agent, and stop. The most common expensive mistake
89
+ is building a kernel to solve a workbench problem.
90
+
91
+ **The test that catches the mistake early:** if you cannot name a behaviour you need that the
92
+ layer above does not provide, you are building the layer for its own sake.
93
+
94
+ ## Traps
95
+
96
+ - **Comparing across layers**, then choosing on a benchmark that only makes sense within one.
97
+ - **Writing a loop because the loop is the interesting part.** It is a week; the tools and
98
+ the prompt are the year.
99
+ - **Claiming a security boundary the layer cannot enforce.** Say what is enforced and by
100
+ what; a sandbox protects the host, not the sandbox.
101
+ - **Adopting a workbench and then fighting its opinions.** Its opinions are the product; if
102
+ you disagree with enough of them, you wanted the kernel.
103
+ - **Assuming the layer is stable.** These projects move; check what the current version
104
+ actually owns before designing around a division of labour you read about once.