@ssheleg/agent-stack 0.8.0 → 0.10.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 +132 -0
- package/README.md +18 -4
- package/package.json +1 -1
- package/plugins/agent-stack/.claude-plugin/plugin.json +1 -1
- package/plugins/agent-stack/skills/agent-evals/SKILL.md +44 -3
- package/plugins/agent-stack/skills/agent-harness/SKILL.md +37 -9
- package/plugins/agent-stack/skills/agent-harness/references/layers.md +4 -0
- package/plugins/agent-stack/skills/agent-harness/references/pi-sdk.md +318 -0
- package/plugins/agent-stack/skills/agent-harness/references/pi.md +241 -0
- package/plugins/agent-stack/skills/agent-harness/scripts/audit_agent.py +100 -32
- package/plugins/agent-stack/skills/agent-orchestrator/SKILL.md +100 -101
- package/plugins/agent-stack/skills/agent-orchestrator/references/graph-engineering.md +327 -0
- package/plugins/agent-stack/skills/agent-orchestrator/references/llm-proxy-billing.md +1 -1
- package/plugins/agent-stack/skills/agent-orchestrator/references/patterns.md +38 -14
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,137 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.10.0] — 2026-08-15
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **`agent-orchestrator/references/graph-engineering.md` — deciding the shape of the work
|
|
8
|
+
before doing it.** The pack could wire a loop, prove it behaved, connect it and tell it
|
|
9
|
+
what to do, and had nothing to say about the question that comes before all four: *does
|
|
10
|
+
this actually have to happen in a line?* Node and edge, the fake-edge test, the diamond,
|
|
11
|
+
the two ways a diamond fails silently, the checker node, static versus dynamic, and the
|
|
12
|
+
cost table that says when a graph is not worth building.
|
|
13
|
+
|
|
14
|
+
Sourced from *Graph Engineering with Claude*
|
|
15
|
+
(`https://x.com/Mahaximus_/status/2082442856417956173`, published 2026-07-29), and the
|
|
16
|
+
link is kept so the original can be re-read rather than remembered through the summary.
|
|
17
|
+
Four sections are **this pack's** and are marked as such in the file: what the host
|
|
18
|
+
actually runs, the barrier distinction, what a checker costs, and auditability as a hard
|
|
19
|
+
rule rather than a preference.
|
|
20
|
+
|
|
21
|
+
- **What Claude Code actually executes, with version evidence.** The source's one
|
|
22
|
+
operational claim aged out six weeks after publication: the `workflow` keyword it names
|
|
23
|
+
was renamed to `ultracode` in **v2.1.160**, and the YAML it shows is a way of describing
|
|
24
|
+
a graph in a prompt rather than a syntax the host parses — the execution contract is a
|
|
25
|
+
script whose primitives are `agent()`, `parallel()` (a barrier) and `pipeline()` (none).
|
|
26
|
+
Every claim in that section carries the `v2.1.x` changelog entry that establishes it,
|
|
27
|
+
which is why the correction reads as a dated fact rather than as an error by the author.
|
|
28
|
+
|
|
29
|
+
- **`agent-harness` — *Static or dynamic, the second question*.** The workflow-versus-agent
|
|
30
|
+
table decided one thing and left the other open. Six rows, and one of them is hard: a run
|
|
31
|
+
that has to be auditable is static, because a graph that picks its own next nodes produces
|
|
32
|
+
a shape nobody drew, and then *"here is the design"* and *"here is what happened"* stop
|
|
33
|
+
being the same document.
|
|
34
|
+
|
|
35
|
+
- **`agent-evals` §5a — the checker node as an evaluator that runs inside the graph.** Its
|
|
36
|
+
five catches split three code checks and two judge calls, so §5's *cheap checks first*
|
|
37
|
+
applies to a position in the graph rather than to a suite. And the part that makes it eval
|
|
38
|
+
work: **a checker that has never rejected anything is a finding, not a reassurance** — its
|
|
39
|
+
verdicts are scores with a source, and its rejection rate belongs on the same dashboard as
|
|
40
|
+
its pass rate.
|
|
41
|
+
|
|
42
|
+
- **A sixth scanner detector, `unguarded-fanout`.** `asyncio.gather` with no
|
|
43
|
+
`return_exceptions=True`, or `Promise.all` with no `allSettled` and no per-branch
|
|
44
|
+
`.catch`: the first sibling to fail cancels the batch, the others' completed work is
|
|
45
|
+
discarded, and the node consuming the results cannot tell a failed branch from an empty
|
|
46
|
+
one. Conservative like the rest — the capturing form anywhere in the file silences it.
|
|
47
|
+
|
|
48
|
+
### Changed
|
|
49
|
+
|
|
50
|
+
- **The self-test proves silence as well as noise.** `PLANTS` and `CLEAN` replaced the
|
|
51
|
+
single dict, because one detector now reads two languages and needed a plant in each, and
|
|
52
|
+
because a detector that fires on the defect *and* on its fix has no discriminating power.
|
|
53
|
+
A fan-out that **does** capture its branches is now a fixture the pass must stay silent
|
|
54
|
+
on. `self-test: 6/6` → **`9/9`** (seven plants, two clean fixtures), counted by running it.
|
|
55
|
+
|
|
56
|
+
- **`agent-orchestrator` §5 no longer contradicts its own data model.** `PlanStage` declared
|
|
57
|
+
`depends_on` and the executor beside it walked `plan.stages` in list order — a plan that
|
|
58
|
+
went to the trouble of saying it need not be serialised, serialised. It now executes in
|
|
59
|
+
dependency layers (Kahn), gates a layer of more than one on the checker before anything
|
|
60
|
+
consumes it, and `ExecutionPlan` grows the `layers()` that makes the declaration mean
|
|
61
|
+
something. A cycle fails the plan rather than deadlocking the run.
|
|
62
|
+
|
|
63
|
+
### Removed
|
|
64
|
+
|
|
65
|
+
- **The hardcoded context-window table.** `references/patterns.md` carried nine vendor model
|
|
66
|
+
ids with their windows and a `DEFAULT_CONTEXT_WINDOW` of 16 000. Every number was correct
|
|
67
|
+
when written and none survived: ids were renamed, long-context variants shipped under the
|
|
68
|
+
same family name, and a system reading that table would size its budget for a window an
|
|
69
|
+
order of magnitude smaller than the one it was given. Replaced by the resolution order —
|
|
70
|
+
configuration, then the provider, then a conservative floor **with a loud log line** — and
|
|
71
|
+
the check is mechanical: no vendor model id remains anywhere in the shipped skill text.
|
|
72
|
+
Two illustrative ones in `SKILL.md` and `llm-proxy-billing.md` went with it, because a
|
|
73
|
+
class fixed in one place and left in two others is not fixed.
|
|
74
|
+
|
|
75
|
+
- **Two duplicated homes.** §8's learning tables and §10's prompt-assembly snippet restated
|
|
76
|
+
what `references/patterns.md` and `agent-harness/references/system-prompt.md` already own.
|
|
77
|
+
Both now state the decision and point at the home. `SKILL.md` is **502 lines / 5670
|
|
78
|
+
tokens** against a 4750 working budget — the number is counted, it is over, and the next
|
|
79
|
+
addition to this body should split rather than absorb.
|
|
80
|
+
|
|
81
|
+
## [0.9.0] — 2026-08-15
|
|
82
|
+
|
|
83
|
+
### Added
|
|
84
|
+
|
|
85
|
+
- **`agent-harness/references/pi.md` and `pi-sdk.md` — the harness doctrine as a worked
|
|
86
|
+
implementation.** Every other reference in that skill states a rule; **Pi** is small enough
|
|
87
|
+
to read and complete enough to have made each of those decisions in public. So each section
|
|
88
|
+
says what Pi does and then **which rule it is an instance of** — the second half is the
|
|
89
|
+
point, and where Pi disagrees with this pack, that is said rather than smoothed over.
|
|
90
|
+
|
|
91
|
+
Read from `pi.dev/docs/latest` on 2026-08-15: sixteen doc pages plus the package source.
|
|
92
|
+
All sixteen verified reachable (`200`); the only non-resolving URLs in either file are the
|
|
93
|
+
two deliberate placeholders inside custom-provider examples.
|
|
94
|
+
|
|
95
|
+
- **`pi.md`** — the four ways to run it; **sessions as a JSONL tree** (8-hex `id`, `parentId`,
|
|
96
|
+
version 3, `BranchSummaryEntry`) matched to *time travel and forking* in
|
|
97
|
+
`agent-orchestrator/references/runtime.md`; **compaction with the real numbers**
|
|
98
|
+
(`contextTokens > contextWindow - reserveTokens`, defaults 16,384 and 20,000, tool results
|
|
99
|
+
truncated to 2,000 chars while summarizing) matched to the compaction ladder, with what the
|
|
100
|
+
ladder adds that Pi leaves to you; settings precedence that **merges rather than replaces**;
|
|
101
|
+
skills, prompt templates and packages; and the trust model.
|
|
102
|
+
|
|
103
|
+
Its sharpest section is **the deliberate absence of a sandbox**, quoted: *"prompt injection
|
|
104
|
+
from repository files … is expected local-agent risk and cannot be reliably prevented by
|
|
105
|
+
pi."* That is `layers.md`'s delegation thesis stated by the project itself — and for an
|
|
106
|
+
audit it changes the finding, because "no permission model" here is a delegation, not a
|
|
107
|
+
defect. Three containerization patterns are compared by **where credentials end up**, which
|
|
108
|
+
is the question that actually decides between them.
|
|
109
|
+
|
|
110
|
+
- **`pi-sdk.md`** — `createAgentSession()`, `ModelRuntime`, `SessionManager`, `defineTool()`,
|
|
111
|
+
`DefaultResourceLoader`; the RPC protocol with its command groups, its full event lifecycle
|
|
112
|
+
and the **`\n`-only JSONL framing warning**; JSON mode's delta-only records and why;
|
|
113
|
+
the `ExtensionAPI` surface; and **the eight seams** — `tool_call` (can block),
|
|
114
|
+
`tool_result` (a middleware chain), `context`, `before_agent_start`, the three provider
|
|
115
|
+
hooks, and the compaction pair — each matched to the doctrine it lets you implement.
|
|
116
|
+
`tool_call` blocking is called out as the single most important one for an audit: it is
|
|
117
|
+
where a per-tool, per-caller policy can actually live.
|
|
118
|
+
|
|
119
|
+
- Noted with its evidence and its limit: **Pi discovers skills from `~/.agents/skills/`**,
|
|
120
|
+
which on this machine is the ssheleg hub — 72 entries, every family skill carrying the
|
|
121
|
+
`name` and `description` front matter Pi requires. Stated as a fact about the path and the
|
|
122
|
+
front matter, **not** as an observed load: Pi is not installed here. The reference also
|
|
123
|
+
names Pi's documented divergence from the Agent Skills standard (a skill name may differ
|
|
124
|
+
from its directory) and warns that `make-skill`'s validator enforces the strict rule.
|
|
125
|
+
|
|
126
|
+
### Changed
|
|
127
|
+
|
|
128
|
+
- `references/layers.md` points at the two new files as the worked example of the kernel
|
|
129
|
+
layer it describes abstractly.
|
|
130
|
+
- `agent-harness`'s description gains the embedding triggers (`agent SDK`, `embed an agent`,
|
|
131
|
+
`Pi harness`, `встроить агента`) — 807/1024, inside the family's 970 working budget. The
|
|
132
|
+
repository's own front-matter gate caught a first draft at 1066 and refused the write.
|
|
133
|
+
|
|
134
|
+
|
|
3
135
|
## [0.8.0] — 2026-08-14
|
|
4
136
|
|
|
5
137
|
### Added
|
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ Part of the [ssheleg skill family](https://github.com/ssheleg/sshlg-skills).
|
|
|
11
11
|
|
|
12
12
|
Four skills — `agent-orchestrator` for wiring the loop, `agent-evals` for proving it
|
|
13
13
|
behaves, `agent-interop` for everything it talks to outside its own process,
|
|
14
|
-
`agent-harness` for what it is **told** — and
|
|
14
|
+
`agent-harness` for what it is **told** — and nineteen references they load on demand,
|
|
15
15
|
plus one scanner.
|
|
16
16
|
|
|
17
17
|
**The orchestrator** (`SKILL.md`) — what the agent reads first:
|
|
@@ -31,6 +31,10 @@ plus one scanner.
|
|
|
31
31
|
decay, plus conflict resolution when a new learning contradicts an old one
|
|
32
32
|
- context budget allocation by priority
|
|
33
33
|
- self-learning feedback loops
|
|
34
|
+
- **the shape of the work, decided before the work**: an edge that carries no data is
|
|
35
|
+
no edge, a plan that declares `depends_on` is executed in dependency layers rather
|
|
36
|
+
than in list order, and a parallel layer gets a checker before the node that
|
|
37
|
+
consumes it
|
|
34
38
|
|
|
35
39
|
**The evals skill** (`agent-evals/SKILL.md`) — how you know any of it works. An
|
|
36
40
|
agent's behaviour is not in its source, so the artifact under test is the
|
|
@@ -61,19 +65,29 @@ ACP, AGNTCY, AP2, Agent Skills — so an agent stops guessing.
|
|
|
61
65
|
model, and the one where most agent bugs actually live: *the biggest performance
|
|
62
66
|
improvements often come from clearly explaining tool usage in the system prompt*, and *even
|
|
63
67
|
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.
|
|
68
|
+
retry or a sub-agent, it asks four questions about the text. Seven references —
|
|
65
69
|
`system-prompt.md` (right altitude, enumerated vocabulary, and the three things reasoning
|
|
66
70
|
models changed — starting with **do not add chain-of-thought**), `tools.md` (the
|
|
67
71
|
agent–computer interface, with a worked before/after and poka-yoke), `techniques.md`
|
|
68
72
|
(fifteen techniques, a verdict each **for production** rather than a benchmark),
|
|
69
73
|
`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)
|
|
74
|
+
environment's job), `audit.md` (seven tracks, evidence tiers, a plan instead of a score) —
|
|
75
|
+
plus **`pi.md` and `pi-sdk.md`, the doctrine as a worked implementation**: Pi read end to
|
|
76
|
+
end, each mechanism matched to the rule it instantiates, its divergences named, and the
|
|
77
|
+
eight extension seams where a permission gate or a context rewrite can actually live.
|
|
71
78
|
|
|
72
79
|
It runs in both directions: **building a harness and auditing somebody else's are one
|
|
73
80
|
checklist read forwards and backwards.** `scripts/audit_agent.py` is the mechanical half —
|
|
74
|
-
|
|
81
|
+
six conservative detectors, and it always prints what it *cannot* see plus a denominator,
|
|
75
82
|
so its silence is never read as a pass.
|
|
76
83
|
|
|
84
|
+
**`references/graph-engineering.md`** — deciding the shape of the work before
|
|
85
|
+
doing it: node and edge, the fake-edge test, the diamond and the two ways it
|
|
86
|
+
fails silently, the checker node and what it costs, static versus dynamic with
|
|
87
|
+
auditability as the hard rule, when a graph is not worth building, and what a
|
|
88
|
+
host actually executes when it fans out — with the version evidence, because the
|
|
89
|
+
keyword the source named was renamed six weeks after it was published.
|
|
90
|
+
|
|
77
91
|
**`references/context-engineering.md`** — what the loop gives up when the window
|
|
78
92
|
runs out: the five-rung compaction ladder and why to re-measure between rungs,
|
|
79
93
|
the tool-pair boundary invariant, typed carryover blocks copied across the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ssheleg/agent-stack",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.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.
|
|
5
|
+
"version": "0.10.0",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "ssheleg",
|
|
8
8
|
"url": "https://x.com/sshlg93"
|
|
@@ -7,9 +7,10 @@ description: >-
|
|
|
7
7
|
evals. Covers the three observability primitives (run, trace, thread) crossed with three
|
|
8
8
|
eval granularities (single-step, full-turn, multi-turn), the offline/online/ad-hoc
|
|
9
9
|
timing axis, pass-fail rubrics over scalar scores, cheap code checks before model
|
|
10
|
-
judges,
|
|
11
|
-
|
|
12
|
-
"
|
|
10
|
+
judges, the checker node as an evaluator running inside the graph, simulated users with
|
|
11
|
+
adversarial personas, annotation queues, and what to instrument so any of it is
|
|
12
|
+
possible. Triggers - "agent eval", "eval suite", "LLM judge", "regression fixture",
|
|
13
|
+
"trajectory eval", "checker node", "is the agent getting better", "эвалы агента",
|
|
13
14
|
"оценка агента", "LLM-судья", "регрессионный набор", "как проверить агента". Not for
|
|
14
15
|
unit tests of ordinary code, or for benchmarking a model.
|
|
15
16
|
license: MIT
|
|
@@ -159,6 +160,44 @@ domain expert and accept that this tier stays human.
|
|
|
159
160
|
|
|
160
161
|
---
|
|
161
162
|
|
|
163
|
+
## 5a. The checker node — an evaluator that runs inside the graph
|
|
164
|
+
|
|
165
|
+
Everything above evaluates a run *afterwards*. One evaluator runs **during** it, and it is
|
|
166
|
+
the one most systems are missing: a **checker node** sitting between a parallel layer and
|
|
167
|
+
the node that consumes it. Its only job is *usable / not usable*, and the convergence
|
|
168
|
+
depends on **it** rather than on the branches — otherwise the gate has a bypass.
|
|
169
|
+
|
|
170
|
+
It matters here because it is the same machinery as §5, positioned differently:
|
|
171
|
+
|
|
172
|
+
| It catches | Decided by |
|
|
173
|
+
|---|---|
|
|
174
|
+
| an empty or null output | a code check |
|
|
175
|
+
| a confidence signal below the downstream bar | a code check |
|
|
176
|
+
| a shape that will break the consumer's parsing | a code check |
|
|
177
|
+
| two outputs that cannot both be true | a judge |
|
|
178
|
+
| an output answering a different question than the one asked | a judge |
|
|
179
|
+
|
|
180
|
+
Three of five are free. Run them first — §5's *cheap checks first*, applied to a position
|
|
181
|
+
in the graph rather than to a suite.
|
|
182
|
+
|
|
183
|
+
**A checker is a node, so it can be wrong, and its failure mode is silent approval.** A
|
|
184
|
+
model checker that has never been shown a bad input passes everything, and a graph with a
|
|
185
|
+
checker that always says yes is **worse** than one with none: the missing checkpoint has
|
|
186
|
+
been replaced by a false one that everything downstream now trusts. Three consequences,
|
|
187
|
+
and they are eval work rather than orchestration work:
|
|
188
|
+
|
|
189
|
+
- **Watch it refuse a planted bad output** before trusting it, exactly as §5 requires of
|
|
190
|
+
any judge before it scores unattended.
|
|
191
|
+
- **Record every verdict as a score bound to the run**, with `source: code_check` or
|
|
192
|
+
`llm_judge` (§7). A checker whose verdicts are not stored cannot be asked afterwards how
|
|
193
|
+
often it fired, which means it cannot be calibrated.
|
|
194
|
+
- **A checker that has never rejected anything is a finding, not a reassurance.** Put the
|
|
195
|
+
rejection rate on the same dashboard as the pass rate; a rate of zero is either a
|
|
196
|
+
perfect upstream or a broken gate, and only the stored verdicts can tell you which.
|
|
197
|
+
|
|
198
|
+
Where the checker sits in the shape, and why the convergence needs one at all:
|
|
199
|
+
`agent-orchestrator/references/graph-engineering.md`.
|
|
200
|
+
|
|
162
201
|
## 6. The corpus grows from production
|
|
163
202
|
|
|
164
203
|
Never author the suite up front. Every production failure and every thumbs-down becomes a
|
|
@@ -215,6 +254,8 @@ None of the above runs without these, and they are the part people skip:
|
|
|
215
254
|
- [ ] Pass/fail rubrics with enumerated failure conditions, written with behaviour owners
|
|
216
255
|
- [ ] Code checks before model judges
|
|
217
256
|
- [ ] Judge calibrated against human labels before it is trusted
|
|
257
|
+
- [ ] Every checker node watched refusing a planted output, its verdicts stored as scores,
|
|
258
|
+
and its rejection rate on the dashboard — a checker at zero rejections is a finding
|
|
218
259
|
- [ ] Domain-expert review for output a general judge cannot grade
|
|
219
260
|
- [ ] Every production failure minimised into a permanent fixture
|
|
220
261
|
- [ ] Annotation queue with filters, and the two reviewer roles kept separate
|
|
@@ -2,15 +2,16 @@
|
|
|
2
2
|
name: agent-harness
|
|
3
3
|
description: >-
|
|
4
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
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
description", "
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
the loop's plumbing, its evals, or
|
|
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", "static or dynamic", "audit this agent",
|
|
12
|
+
"embed an agent", "agent SDK", "Pi harness", "системный промпт", "агент не вызывает тул",
|
|
13
|
+
"аудит агента", "встроить агента". Not for the loop's plumbing, its evals, or its
|
|
14
|
+
protocols — those are siblings.
|
|
14
15
|
---
|
|
15
16
|
|
|
16
17
|
# Agent harness — what the agent is told, and how to audit what someone else told theirs
|
|
@@ -81,6 +82,30 @@ that only where a fixed path genuinely cannot be written.
|
|
|
81
82
|
from a known set. Orchestration invents the set per request. If you can enumerate the
|
|
82
83
|
branches, you wanted routing and it is cheaper.
|
|
83
84
|
|
|
85
|
+
### Static or dynamic — the second question, and it is not the same one
|
|
86
|
+
|
|
87
|
+
Having chosen a workflow, one thing is still open: **is its shape known before it runs?**
|
|
88
|
+
A **static** graph has every node and edge decided up front. A **dynamic** one grows — a
|
|
89
|
+
node finishes, reads what it found, and decides what comes next.
|
|
90
|
+
|
|
91
|
+
| Reach for | When |
|
|
92
|
+
|---|---|
|
|
93
|
+
| **static** | the task repeats and the structure is the same every time |
|
|
94
|
+
| **static** | predictability and speed matter more than flexibility |
|
|
95
|
+
| **static** | **always first** — go dynamic only after the static version hits a wall you can name |
|
|
96
|
+
| dynamic | the scope of the work depends on what is discovered along the way |
|
|
97
|
+
| dynamic | a node must choose its successors from its own output |
|
|
98
|
+
| **never dynamic** | **the run has to be auditable** — see below |
|
|
99
|
+
|
|
100
|
+
**The audit rule is hard, not a preference.** A dynamic graph's executed shape is not the
|
|
101
|
+
shape anybody drew, so *"here is the design"* and *"here is what happened"* stop being the
|
|
102
|
+
same document and every claim about the run becomes unfalsifiable from outside. Most
|
|
103
|
+
workflows that feel like they need a dynamic graph need a better static one.
|
|
104
|
+
|
|
105
|
+
The rest of the model — the fake-edge test, the diamond, the checker node before a
|
|
106
|
+
convergence, and what a host actually executes when it fans out — is
|
|
107
|
+
`agent-orchestrator/references/graph-engineering.md`.
|
|
108
|
+
|
|
84
109
|
---
|
|
85
110
|
|
|
86
111
|
## References
|
|
@@ -95,6 +120,8 @@ and `test/validate.py` fails the build on a reference that does not say when it
|
|
|
95
120
|
| [`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
121
|
| [`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
122
|
| [`references/audit.md`](references/audit.md) | reviewing **an agent system you did not build** — seven tracks, evidence tiers, and a prioritized plan |
|
|
123
|
+
| [`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 |
|
|
124
|
+
| [`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 |
|
|
98
125
|
|
|
99
126
|
**`scripts/audit_agent.py`** — the mechanical half of the audit. It finds what is visible
|
|
100
127
|
without understanding intent (an unbounded loop, a tool with no description, a swallowed
|
|
@@ -149,6 +176,7 @@ prompt.
|
|
|
149
176
|
## Checklist — a harness worth shipping
|
|
150
177
|
|
|
151
178
|
- [ ] Workflow-versus-agent decided deliberately, and the simpler option was actually tried
|
|
179
|
+
- [ ] Static-versus-dynamic decided too, and a run that must be auditable is static
|
|
152
180
|
- [ ] System prompt at the **right altitude** — heuristics, not hardcoded branches, not vague hope
|
|
153
181
|
- [ ] Every status, category and enum the agent must produce is **enumerated in the prompt**
|
|
154
182
|
- [ ] Today's date, and any other volatile context, injected rather than assumed
|
|
@@ -62,6 +62,10 @@ surrounds it. Read as a weakness, it looks like a missing feature. Read as archi
|
|
|
62
62
|
is a clear statement: *a harness that also claims to be a sandbox is claiming a guarantee it
|
|
63
63
|
cannot keep*, because it runs in the same process as the code it would be confining.
|
|
64
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
|
+
|
|
65
69
|
Two consequences worth stating plainly:
|
|
66
70
|
|
|
67
71
|
- **A harness advertising "safe tool execution" without an OS-level or container boundary is
|