@sleepy_panda_srl/portulan 0.3.0 → 0.4.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/README.md +15 -4
- package/cli/README.md +55 -3
- package/cli/advisory.mjs +167 -53
- package/cli/cache-risk.mjs +69 -0
- package/cli/comments.mjs +8 -5
- package/cli/compile.mjs +492 -146
- package/cli/context.mjs +204 -43
- package/cli/doctor.mjs +211 -33
- package/cli/drills.mjs +32 -7
- package/cli/finish.md +34 -0
- package/cli/finish.mjs +8 -67
- package/cli/form.mjs +34 -18
- package/cli/frontmatter.mjs +39 -0
- package/cli/gate.mjs +14 -12
- package/cli/guidance-files.mjs +335 -0
- package/cli/handoff-policy.mjs +76 -0
- package/cli/html-entities.mjs +2130 -0
- package/cli/import-files.mjs +15 -0
- package/cli/index.mjs +77 -24
- package/cli/init-preview.mjs +553 -0
- package/cli/init.mjs +261 -46
- package/cli/instructions-journal.mjs +1185 -0
- package/cli/instructions.mjs +332 -57
- package/cli/ledger.mjs +123 -37
- package/cli/librarian.mjs +103 -19
- package/cli/persona-routing.mjs +209 -0
- package/cli/plugin-lint.mjs +77 -56
- package/cli/recipe-output.mjs +91 -0
- package/cli/recipe-runner.md +68 -0
- package/cli/recipe-runner.mjs +131 -0
- package/cli/recipe-set.mjs +12 -3
- package/cli/ritual-contexts.mjs +103 -0
- package/cli/sessions.mjs +2 -1
- package/cli/spend-analysis.mjs +111 -0
- package/cli/spend-offer.md +53 -0
- package/cli/spend-offer.mjs +93 -0
- package/cli/stop-diagnostics.mjs +114 -0
- package/cli/stop-gate.mjs +133 -90
- package/cli/stop-policy.mjs +14 -0
- package/cli/symbols.mjs +55 -8
- package/cli/telemetry.mjs +19 -12
- package/cli/upgrade.mjs +62 -44
- package/cli/vendor.mjs +207 -125
- package/core/operating/context.md +368 -60
- package/core/operating/evolution.md +3 -2
- package/core/operating/loop.md +9 -4
- package/core/operating/sessions.md +6 -15
- package/core/personas/README.md +52 -10
- package/core/personas/implementer.md +3 -0
- package/core/personas/librarian.md +3 -0
- package/core/personas/reviewer.md +3 -0
- package/core/templates/handoff.md +6 -2
- package/evals/ab/personas/README.md +111 -0
- package/evals/ab/personas/acquisition.json +330 -0
- package/evals/ab/personas/bindings/implementer.txt +43 -0
- package/evals/ab/personas/bindings/librarian.txt +40 -0
- package/evals/ab/personas/bindings/reviewer.txt +41 -0
- package/evals/ab/personas/corpus.json +69 -0
- package/evals/ab/personas/grader.mjs +171 -0
- package/evals/ab/personas/implementer.json +774 -0
- package/evals/ab/personas/implementer.md +22 -0
- package/evals/ab/personas/librarian.json +758 -0
- package/evals/ab/personas/librarian.md +22 -0
- package/evals/ab/personas/protocol/continuation.mjs.txt +284 -0
- package/evals/ab/personas/protocol/first-outcome.mjs.txt +227 -0
- package/evals/ab/personas/protocol/first-probe.mjs.txt +172 -0
- package/evals/ab/personas/protocol/publisher.mjs.txt +126 -0
- package/evals/ab/personas/protocol/second-probe.mjs.txt +193 -0
- package/evals/ab/personas/repairs/first-control-answer.txt +23 -0
- package/evals/ab/personas/repairs/grader-before-decode-repair.mjs.txt +143 -0
- package/evals/ab/personas/reviewer.json +758 -0
- package/evals/ab/personas/reviewer.md +22 -0
- package/evals/releases/0.4.0.json +154 -0
- package/evals/releases/0.4.0.md +69 -0
- package/package.json +6 -2
- package/packs/rituals/checkpoints/README.md +35 -0
- package/packs/rituals/checkpoints/pack.json +3 -2
- package/packs/tools/local-llm/README.md +46 -6
- package/packs/tools/local-llm/runner/local-llm.mjs +127 -13
- package/packs/tools/local-llm/skills/delegate-local/SKILL.md +26 -2
- package/spec/README.md +37 -4
- package/spec/migrations/0009-instruction-sections-on-read.mjs +60 -11
- package/spec/migrations/0011-persona-bindings-compiled.mjs +23 -0
- package/spec/migrations/README.md +6 -0
- package/spec/pack.schema.json +12 -3
- package/spec/slots.md +262 -117
- package/spec/workspace.schema.json +67 -11
package/core/personas/README.md
CHANGED
|
@@ -29,10 +29,15 @@ token; `effort`, one of `low`, `medium`, `high`, `xhigh` or `max`; `omitClaudeMd
|
|
|
29
29
|
unquoted, whether the role runs without the project's instruction files; and `cacheLifetime`, `5m` or
|
|
30
30
|
`1h`. The effort levels and the name `omitClaudeMd` are adopted from Claude Code's vocabulary, the first
|
|
31
31
|
host to express them. `effort` sets the host subagent's reasoning effort, and is not the thinking cap the
|
|
32
|
-
`tools/local-llm` runner's `--effort` sends with each request it makes. `doctor` fails
|
|
33
|
-
|
|
34
|
-
persona
|
|
35
|
-
|
|
32
|
+
`tools/local-llm` runner's `--effort` sends with each request it makes. `doctor` fails malformed values
|
|
33
|
+
in composed pack personas; `compile` validates every persona source it compiles. Neither supplies a value
|
|
34
|
+
the persona did not write. `compile` writes declared fields from composed pack personas into the
|
|
35
|
+
frontmatter of the role's existing host binding: `agents/<name>.md` in a plugin tree and
|
|
36
|
+
`.claude/agents/<name>.md` in an ordinary project. Compiler and doctor share that selection; a malformed,
|
|
37
|
+
unreadable or escaping plugin marker is not treated as an ordinary project. When
|
|
38
|
+
the declared tree resolves to this compiler's own engine root, including a canonical alias, the same
|
|
39
|
+
pipeline also reads `core/personas/*.md` except this README. A foreign tree's matching files do not
|
|
40
|
+
participate. A core source's declared name must match its filename. The compiler leaves every other line of
|
|
36
41
|
that file as its author wrote it; `--check` byte-compares the result, and a line inside the compiled
|
|
37
42
|
block that `compile` did not write is refused rather than removed. One it cannot catch: a line added inside
|
|
38
43
|
the block in exactly the spelling and order `compile` writes reads as compiled, and is dropped once the
|
|
@@ -41,19 +46,56 @@ field, `compile` owns every top-level key it could write, so a hand-written `exp
|
|
|
41
46
|
even for a key other than `cacheTtl`. A field a host cannot express is
|
|
42
47
|
named, with the persona and the host, in the degradation report `compile` prints. Claude Code takes all
|
|
43
48
|
four on an agent (`cacheLifetime` as `experimental.cacheTtl`), and a vendored `AGENTS.md` takes none.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
`compile` writes only existing bindings; an absent adopter binding remains unbound and is never
|
|
50
|
+
created by compilation. A persona-only workspace can compile its declared fields without a gate
|
|
51
|
+
policy or guidance. Nonregular, escaping and invalid UTF-8 inputs are refused before writes.
|
|
52
|
+
Doctor checks the selected binding's name and declared tool grant, keeping an unread file distinct
|
|
53
|
+
from an absent one. Plugin packaging checks core and actually composed charter owners in both
|
|
54
|
+
directions, including personas declaring no context fields. File equality proves neither plugin
|
|
55
|
+
enablement nor that a running host honored a field. _(Provenance:
|
|
49
56
|
proposal `0036`'s order of work, item 7, and proposal `0039`'s first two rules. The host's keys, values
|
|
50
57
|
and agent locations were read in Claude Code 2.1.317's program text on 2026-11-03.)_
|
|
51
58
|
|
|
52
|
-
|
|
59
|
+
This product binds both composed roles. Supervisor still requires a fresh invocation for a checkpoint.
|
|
60
|
+
Local-worker's host wrapper points to its existing loopback runner; loading that role does not itself
|
|
61
|
+
invoke a local model or prove local execution.
|
|
62
|
+
|
|
63
|
+
The three core sources explicitly declare `model: inherit`, `omitClaudeMd: false` and
|
|
64
|
+
`cacheLifetime: 5m`, leaving effort undeclared. These are product-role policy choices: inherit the
|
|
65
|
+
parent model, retain the instruction floor and request a five-minute cache lifetime. In Claude Code,
|
|
66
|
+
explicit `inherit` outranks the ordinary `CLAUDE_CODE_SUBAGENT_MODEL` default; an invocation's model
|
|
67
|
+
selection and `CLAUDE_CODE_SUBAGENT_MODEL_FORCE=1` can override it. Cache lifetime remains subject to
|
|
68
|
+
the host's precedence rules. Compilation proves the committed bytes, with no claim about quality,
|
|
69
|
+
savings or live loading. _(Host precedence checked against the
|
|
70
|
+
[official subagent documentation](https://code.claude.com/docs/en/sub-agents) on 2026-11-09.)_
|
|
71
|
+
|
|
72
|
+
The acquired [implementer](../../evals/ab/personas/implementer.md),
|
|
73
|
+
[reviewer](../../evals/ab/personas/reviewer.md) and
|
|
74
|
+
[librarian](../../evals/ab/personas/librarian.md) comparisons each have three
|
|
75
|
+
frozen artifact cases, one attempt per arm, through native children on Sonnet 5.5
|
|
76
|
+
in Claude Code 2.1.321. Both arms pass all nine cases. Medium has a lower
|
|
77
|
+
cold-normalized cost index in this observation; observed cache costs differ,
|
|
78
|
+
and the reviewer arm's observed cost rises. These results support the retained
|
|
79
|
+
policy on that corpus and model, with no global medium default earned for other
|
|
80
|
+
inherited models. The [protocol](../../evals/ab/personas/README.md) discloses the
|
|
81
|
+
small sample, both probes, full parent/child usage and one retained-answer
|
|
82
|
+
decoder repair after the first outcome. The shipped offline checker regrades
|
|
83
|
+
the records and checks routing and source bytes.
|
|
84
|
+
|
|
85
|
+
A binding has one persona owner across core and composed pack sources, including an unbound persona or one declaring
|
|
53
86
|
no fields; duplicate destinations are refused before any artifact is written. The binding must be a
|
|
54
87
|
regular file whose real path stays in the real declared tree, including its parent directories.
|
|
55
88
|
`omitClaudeMd` accepts only unquoted `true` or `false`, in both declarations and compiled blocks.
|
|
56
89
|
|
|
90
|
+
`upgrade` refreshes existing eligible bindings through the same compiler planner,
|
|
91
|
+
including normal host-cache pack discovery and its shadow refusals. It preserves
|
|
92
|
+
unrelated binding text and modes, creates no absent binding, and writes no gate
|
|
93
|
+
settings. Core sources still participate only in the installed engine's own
|
|
94
|
+
declared tree; an ordinary adopter receives the baked core agents by updating the
|
|
95
|
+
plugin, without installing a foreign core adapter. The command-level historical
|
|
96
|
+
v0.2.0 demonstration is in
|
|
97
|
+
[`../../cli/persona-upgrade.test.mjs`](../../cli/persona-upgrade.test.mjs).
|
|
98
|
+
|
|
57
99
|
## Status
|
|
58
100
|
|
|
59
101
|
**Milestone 3 — contract, exemplars, and one host binding.** This README fixes the persona contract; the
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
name: implementer
|
|
3
3
|
description: The default working persona. Takes one task through the full loop — research → plan → implement → verify → learn — and hands back a verified change plus what it learned. Delegate a unit of implementation work to it.
|
|
4
4
|
tools: [read, search, edit-code, run-verify, draft-memory, open-pr]
|
|
5
|
+
model: inherit
|
|
6
|
+
omitClaudeMd: false
|
|
7
|
+
cacheLifetime: 5m
|
|
5
8
|
---
|
|
6
9
|
|
|
7
10
|
# Persona — Implementer
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
name: librarian
|
|
3
3
|
description: The persona that tends the curated layer — consolidating memory, regenerating the size-budgeted index, drafting rule-change proposals from incidents and PR reviews, and chasing stale rules toward retirement. It drafts and files; it never accepts. Delegate a memory/evolution housekeeping pass to it.
|
|
4
4
|
tools: [read, search, read-history, draft-memory, draft-proposal, write-index, open-pr]
|
|
5
|
+
model: inherit
|
|
6
|
+
omitClaudeMd: false
|
|
7
|
+
cacheLifetime: 5m
|
|
5
8
|
---
|
|
6
9
|
|
|
7
10
|
# Persona — Librarian
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
name: reviewer
|
|
3
3
|
description: The last-mile check on a change before it merges. Reads a proposed diff against the task's acceptance criteria and the definition of done, re-runs the verify recipe, and returns a verdict — it does not edit the code or merge. Delegate review of a completed change to it.
|
|
4
4
|
tools: [read, search, run-verify, post-review]
|
|
5
|
+
model: inherit
|
|
6
|
+
omitClaudeMd: false
|
|
7
|
+
cacheLifetime: 5m
|
|
5
8
|
---
|
|
6
9
|
|
|
7
10
|
# Persona — Reviewer
|
|
@@ -10,12 +10,16 @@
|
|
|
10
10
|
> decisions and their rationale. When one is owed, and why the commit carries the rest:
|
|
11
11
|
> `../operating/loop.md`.)_
|
|
12
12
|
>
|
|
13
|
+
> Link the records that own measured figures and durable rules. Keep each open decision and its why.
|
|
14
|
+
> A declared token cap binds new handoffs; compress or move and link facts, never split or drop a why.
|
|
15
|
+
> The heading names the outcome; the filename already carries the date. See `../operating/context.md`.
|
|
16
|
+
>
|
|
13
17
|
> **The commit a change lands in:** a subject that says what changed, in the present tense and under 72
|
|
14
18
|
> characters; a blank line; a body of a few lines that says why, and what was rejected when that matters.
|
|
15
19
|
|
|
16
20
|
---
|
|
17
21
|
|
|
18
|
-
#
|
|
22
|
+
# {outcome / open task}
|
|
19
23
|
|
|
20
24
|
**State.** {where things stand: what is done and committed, what is in progress and uncommitted.}
|
|
21
25
|
|
|
@@ -30,7 +34,7 @@
|
|
|
30
34
|
|
|
31
35
|
_A filled one, for a session that stopped mid-change:_
|
|
32
36
|
|
|
33
|
-
#
|
|
37
|
+
# Retry the flaky upload test
|
|
34
38
|
|
|
35
39
|
**State.** The retry wrapper is written and its unit test passes; it is stashed, not committed, because
|
|
36
40
|
the integration suite still fails once in about ten runs.
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Core persona routing comparisons
|
|
2
|
+
|
|
3
|
+
This protocol addresses [#520](https://github.com/sleepy-panda-srl/portulan/issues/520).
|
|
4
|
+
The frozen [corpus](corpus.json) has three artifact tasks per core role and one
|
|
5
|
+
attempt per arm. The [grader](grader.mjs) checks semantic behavior: bounded
|
|
6
|
+
execution and nonmutation for implementer code, executable counterexamples and
|
|
7
|
+
a clean control for reviewer findings, and preservation, escalation and human
|
|
8
|
+
authority for librarian drafts. These observations do not establish general
|
|
9
|
+
quality or a reliability rate.
|
|
10
|
+
|
|
11
|
+
A is the shipped role: inherited model, undeclared effort, instruction floor
|
|
12
|
+
retained and five-minute cache lifetime. B requests medium effort on the same
|
|
13
|
+
concrete inherited model through one native foreground persona child. The parent
|
|
14
|
+
runs at high effort; host request metadata must establish effective child effort.
|
|
15
|
+
The `--agent` main-session override is not this mechanism. Each parent and child
|
|
16
|
+
has a fresh context. Case order alternates A/B then B/A; an invalid invocation or
|
|
17
|
+
failed semantic control stops acquisition without resampling.
|
|
18
|
+
|
|
19
|
+
The observed concrete model is Sonnet 5.5 on Claude Code 2.1.321. A medium win on
|
|
20
|
+
this model and corpus does not establish medium effort for other inherited
|
|
21
|
+
models. The product retains `model: inherit` and undeclared effort; no global
|
|
22
|
+
lower-effort default is earned here.
|
|
23
|
+
|
|
24
|
+
## Acquisition and accounting
|
|
25
|
+
|
|
26
|
+
Private originals retain the journal, CLI output, parent/child transcripts and
|
|
27
|
+
frozen source snapshots. Publication whitelists generic artifact answers,
|
|
28
|
+
numeric request metadata, normalized command arguments, timestamps and digests.
|
|
29
|
+
Answer presentation replaces only known acquisition and plugin-root prefixes
|
|
30
|
+
with `<acquisition>` and `<plugin>`; the record lists the affected answer and
|
|
31
|
+
retains both original and presented answer digests. Artifact contents and scores
|
|
32
|
+
are unchanged. Original answer wording otherwise remains.
|
|
33
|
+
Request identities and context identities are deterministically hashed; original
|
|
34
|
+
local paths, session identities and unrelated conversation content do not ship.
|
|
35
|
+
Public digests permit integrity checks; fidelity to private originals additionally
|
|
36
|
+
requires the independent acquisition review.
|
|
37
|
+
|
|
38
|
+
Acquisition fidelity **PASS**, signed `/root/checkpoint_520_open`, independent
|
|
39
|
+
read-only reviewer, 2026-11-10, for capture
|
|
40
|
+
`ff3688658bc20af6b78e834a5149ea6bd52bc88027b0340ec98cb52430c6d641`.
|
|
41
|
+
The reviewer independently checked all 80 requests (39 parent, 41 child), native
|
|
42
|
+
invocations, frozen sources, original answers, repair history and cost arithmetic.
|
|
43
|
+
The one disclosed citation normalization matches the deterministic transformation
|
|
44
|
+
and changes no JSON artifact or score. The checker and four capture/package tests
|
|
45
|
+
passed. This establishes retained-event fidelity; the sample, decoder repair,
|
|
46
|
+
reconstructed first-probe command and absence of billing evidence remain limits.
|
|
47
|
+
|
|
48
|
+
Two mechanism probes precede the eighteen quality children. The first used the
|
|
49
|
+
host's then-default Fable 5.2 and exceeded the configured one-dollar host-estimate
|
|
50
|
+
ceiling after a child ran. Its failed parent and child requests remain overhead;
|
|
51
|
+
it earns no quality result. Its command was reconstructed after execution from
|
|
52
|
+
the retained source, which was also snapshotted after execution. It is not a
|
|
53
|
+
contemporaneously recorded command. The second probe selected Sonnet 5.5 before
|
|
54
|
+
any quality outcome and demonstrated the native medium-effort mechanism. Quality
|
|
55
|
+
inference is limited to that model.
|
|
56
|
+
|
|
57
|
+
Every observed parent, child and probe request is counted once. The frozen price
|
|
58
|
+
vector is an index in uncached-input-token equivalents, not a price quotation or
|
|
59
|
+
subscription bill: uncached input 1, five-minute writes 1.25, one-hour writes 2,
|
|
60
|
+
unclassified writes 1.25, reads 0.1 and output 5. Registers separate observed
|
|
61
|
+
cost from a cold-normalized index. Normalization reprices all input in the first
|
|
62
|
+
request of each fresh parent and child context at 1.25, retaining subsequent
|
|
63
|
+
requests' observed classes and all output. Probe overhead is reported separately
|
|
64
|
+
from role comparisons. CLI USD values are host lifecycle estimates; they are not
|
|
65
|
+
added to these indexes.
|
|
66
|
+
|
|
67
|
+
## Disclosed decoder repair
|
|
68
|
+
|
|
69
|
+
After the first quality outcome, acquisition stopped because the original
|
|
70
|
+
decoder rejected a correct function inside one JSON fence followed by prose.
|
|
71
|
+
The task requested a JSON artifact without forbidding surrounding prose; the
|
|
72
|
+
original decoder already allowed a whole-answer fence. The retained answer
|
|
73
|
+
passed the unchanged semantic execution checks.
|
|
74
|
+
|
|
75
|
+
The [original grader](repairs/grader-before-decode-repair.mjs.txt) and
|
|
76
|
+
[first answer](repairs/first-control-answer.txt) remain. A bounded decoder repair
|
|
77
|
+
accepts exactly one JSON fence with prose and rejects competing artifacts or
|
|
78
|
+
ambiguous fences. Semantic predicates, cases and pricing code stayed byte for
|
|
79
|
+
byte identical. The original false score is preserved alongside the repaired
|
|
80
|
+
true score. An independent checkpoint approved the exact decoder and continuation
|
|
81
|
+
instrument hashes before the remaining seventeen untouched calls. The first
|
|
82
|
+
child is never rerun. This is a post-outcome instrument repair, not an unchanged
|
|
83
|
+
preregistration.
|
|
84
|
+
|
|
85
|
+
## Offline verification and delivery
|
|
86
|
+
|
|
87
|
+
The offline checker is `node cli/persona-routing.mjs --repo-root .`; it never
|
|
88
|
+
starts a host. It checks the immutable acquisition digest, all three role records,
|
|
89
|
+
semantic scores, generated registers, complete case/arm coverage, source and
|
|
90
|
+
binding bytes, effective effort, unique contexts/requests, frozen task bytes,
|
|
91
|
+
protocol snapshots, repair history and usage accounting. Exit 1 is a finding;
|
|
92
|
+
exit 2 is unavailable data or a failed read. The existing A/B recipe runs it.
|
|
93
|
+
|
|
94
|
+
The records and costs remain observations of source `01ca4887`; later bundle
|
|
95
|
+
changes are not new measurements. Current core charters must remain byte-identical
|
|
96
|
+
to that capture. A current plugin binding may change only its one nonempty,
|
|
97
|
+
single-line description scalar: every other byte, including tools, body and
|
|
98
|
+
context declarations, must match the historical binding. Malformed, duplicate,
|
|
99
|
+
missing or multiline descriptions refuse comparison. This permits the later
|
|
100
|
+
librarian description compression while preserving the acquired routing contract;
|
|
101
|
+
it establishes neither current whole-bundle costs nor equivalent automatic
|
|
102
|
+
delegation after description changes.
|
|
103
|
+
|
|
104
|
+
The npm payload carries the records, frozen protocol evidence, grader and offline
|
|
105
|
+
checker. Live acquisition and private normalization commands remain workshop
|
|
106
|
+
tools. A plugin update delivers the baked `agents/` files. The CLI's persona form
|
|
107
|
+
migration refreshes existing eligible bindings through the compiler planner:
|
|
108
|
+
core sources only in the installed engine's own tree, composed pack sources
|
|
109
|
+
through normal pack resolution. It creates no absent binding, installs no
|
|
110
|
+
foreign core adapter and changes no gate settings. The historical v0.2.0 suite
|
|
111
|
+
demonstrates actual check/write/check, idempotence, refusal and rollback.
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"phase": "complete",
|
|
4
|
+
"sourceCommit": "01ca48872fdceac9d7aa548ac12a5107173f2b31",
|
|
5
|
+
"host": "2.1.321 (Claude Code)",
|
|
6
|
+
"model": "claude-sonnet-5-5",
|
|
7
|
+
"seed": "portulan-m13-personas-20261110",
|
|
8
|
+
"prices": {
|
|
9
|
+
"uncached": 1,
|
|
10
|
+
"written5m": 1.25,
|
|
11
|
+
"written1h": 2,
|
|
12
|
+
"writtenUnknown": 1.25,
|
|
13
|
+
"read": 0.1,
|
|
14
|
+
"output": 5,
|
|
15
|
+
"coldFirstInput": 1.25
|
|
16
|
+
},
|
|
17
|
+
"routing": {
|
|
18
|
+
"model": "inherit",
|
|
19
|
+
"effort": null,
|
|
20
|
+
"omitClaudeMd": false,
|
|
21
|
+
"cacheLifetime": "5m"
|
|
22
|
+
},
|
|
23
|
+
"publication": {
|
|
24
|
+
"answerTransformation": "replace only known plugin-root and acquisition-root prefixes with <plugin> and <acquisition>",
|
|
25
|
+
"normalizedAnswers": [
|
|
26
|
+
"librarian-sealed-a"
|
|
27
|
+
],
|
|
28
|
+
"note": "Original wording otherwise retained; original answers stay private with raw-answer digests. This presentation normalization changes no semantic artifact or score."
|
|
29
|
+
},
|
|
30
|
+
"qualityFrozenAt": "2026-11-10T07:29:01.199Z",
|
|
31
|
+
"continuationFrozenAt": "2026-11-10T07:49:23.195Z",
|
|
32
|
+
"order": [
|
|
33
|
+
"implementer-lower-bound-a",
|
|
34
|
+
"implementer-lower-bound-b",
|
|
35
|
+
"implementer-dedup-b",
|
|
36
|
+
"implementer-dedup-a",
|
|
37
|
+
"implementer-containment-a",
|
|
38
|
+
"implementer-containment-b",
|
|
39
|
+
"reviewer-verdict-b",
|
|
40
|
+
"reviewer-verdict-a",
|
|
41
|
+
"reviewer-clean-a",
|
|
42
|
+
"reviewer-clean-b",
|
|
43
|
+
"reviewer-boundaries-b",
|
|
44
|
+
"reviewer-boundaries-a",
|
|
45
|
+
"librarian-duplicate-a",
|
|
46
|
+
"librarian-duplicate-b",
|
|
47
|
+
"librarian-conflict-b",
|
|
48
|
+
"librarian-conflict-a",
|
|
49
|
+
"librarian-sealed-a",
|
|
50
|
+
"librarian-sealed-b"
|
|
51
|
+
],
|
|
52
|
+
"taskSha256": {
|
|
53
|
+
"implementer-lower-bound": "4862de332848a8546671bbd33b6a2827d3bced336d65b92ed4aa8f02ce763290",
|
|
54
|
+
"implementer-dedup": "558e39b28c0f012f7fc5c0ceeec8898fd6fc77040305c587908b8795113afce8",
|
|
55
|
+
"implementer-containment": "2d991b5fc2fdb3e7d03dbebce8f9406d5ad1e55892d4dce1503a544b24cc525a",
|
|
56
|
+
"reviewer-verdict": "85e4e4f33f81550775e8b155906e2ecfe6c05661ce40da023e3723429a188102",
|
|
57
|
+
"reviewer-clean": "562e341017f1da94f7f8be4c6dd878db8c5ce1498596856c58f003c4256f28c2",
|
|
58
|
+
"reviewer-boundaries": "36d848b6d1d015225680efca9f459fb326b691906de006e429ce62f8f7bb793c",
|
|
59
|
+
"librarian-duplicate": "8332dd4efbcde4643088f07c07439d0abbdf7d703bf1dd4d332531196197512e",
|
|
60
|
+
"librarian-conflict": "4af2b7ce4790e069235825a0b5d64d61ec0a66f0e61294a313701d92d9eb6cca",
|
|
61
|
+
"librarian-sealed": "6408193ff1b6315658d34200116e15f7300e0a5c639fc36ae44391867a69828b"
|
|
62
|
+
},
|
|
63
|
+
"preflights": [
|
|
64
|
+
{
|
|
65
|
+
"key": "mechanism-medium",
|
|
66
|
+
"task": "mechanism",
|
|
67
|
+
"role": "implementer",
|
|
68
|
+
"effort": "medium",
|
|
69
|
+
"requestedModel": null,
|
|
70
|
+
"model": "claude-fable-5-2",
|
|
71
|
+
"parentEffort": "high",
|
|
72
|
+
"fresh": true,
|
|
73
|
+
"context": "context-bd202d2470debba47cf5529f97fd4759da5a81e041d200d112d8ade5c6dc2de0",
|
|
74
|
+
"childContext": "child-3e143bad7e549e19b35c2318b06a8121ad1695e3df8d41c473e09600cb9d2acf",
|
|
75
|
+
"state": "invalid",
|
|
76
|
+
"exit": 1,
|
|
77
|
+
"timedOut": false,
|
|
78
|
+
"started": "2026-11-10T07:15:36.623Z",
|
|
79
|
+
"ended": "2026-11-10T07:15:45.112Z",
|
|
80
|
+
"argv": [
|
|
81
|
+
"-p",
|
|
82
|
+
"This is a frozen evaluation. Invoke the Agent tool exactly once with these input values: {\"subagent_type\":\"portulan:implementer\",\"description\":\"Frozen persona artifact probe\",\"prompt\":\"Read <acquisition>/tasks/mechanism.json and follow its task exactly. This is an artifact proposal, not a completed repository change.\",\"run_in_background\":false,\"effort\":\"medium\"}. Do not supply a child model or change the effort. Wait for that foreground child to finish. Do not answer its task yourself or invoke another child. After completion reply only DONE.",
|
|
83
|
+
"--output-format",
|
|
84
|
+
"json",
|
|
85
|
+
"--effort",
|
|
86
|
+
"high",
|
|
87
|
+
"--plugin-dir",
|
|
88
|
+
"<plugin>",
|
|
89
|
+
"--tools",
|
|
90
|
+
"Agent,Read",
|
|
91
|
+
"--allowedTools",
|
|
92
|
+
"Agent(portulan:implementer),Read",
|
|
93
|
+
"--add-dir",
|
|
94
|
+
"<acquisition>/tasks",
|
|
95
|
+
"--max-budget-usd",
|
|
96
|
+
"1"
|
|
97
|
+
],
|
|
98
|
+
"argvProvenance": "reconstructed-after-execution",
|
|
99
|
+
"instrumentSha256": "a02b6d2185b59e5b43a96a7cb3a5fcee7965c29a45b1533aa02c033369937f44",
|
|
100
|
+
"usage": {
|
|
101
|
+
"parent": [
|
|
102
|
+
{
|
|
103
|
+
"id": "request-832595efc5c05c77691a8e9c83ebd22210d0bf5aecccb43876f0e3860460dad8",
|
|
104
|
+
"model": "claude-fable-5-2",
|
|
105
|
+
"effort": "high",
|
|
106
|
+
"at": 1794294941008,
|
|
107
|
+
"uncached": 2,
|
|
108
|
+
"written5m": 83513,
|
|
109
|
+
"written1h": 0,
|
|
110
|
+
"writtenUnknown": 0,
|
|
111
|
+
"read": 0,
|
|
112
|
+
"output": 245
|
|
113
|
+
}
|
|
114
|
+
],
|
|
115
|
+
"child": [
|
|
116
|
+
{
|
|
117
|
+
"id": "request-4e55082b4084a7622c2d5623a1b91d9bb0ba9e4a6e8445799b10ca7305295b36",
|
|
118
|
+
"model": "claude-fable-5-2",
|
|
119
|
+
"effort": "medium",
|
|
120
|
+
"at": 1794294942508,
|
|
121
|
+
"uncached": 2,
|
|
122
|
+
"written5m": 13333,
|
|
123
|
+
"written1h": 0,
|
|
124
|
+
"writtenUnknown": 0,
|
|
125
|
+
"read": 0,
|
|
126
|
+
"output": 314
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"id": "request-9a157d22debc4d6232568c09309de1c0b38aeb1cfc73384bca3cbce633ad7eec",
|
|
130
|
+
"model": "claude-fable-5-2",
|
|
131
|
+
"effort": "medium",
|
|
132
|
+
"at": 1794294944421,
|
|
133
|
+
"uncached": 2,
|
|
134
|
+
"written5m": 5993,
|
|
135
|
+
"written1h": 0,
|
|
136
|
+
"writtenUnknown": 0,
|
|
137
|
+
"read": 13333,
|
|
138
|
+
"output": 11
|
|
139
|
+
}
|
|
140
|
+
]
|
|
141
|
+
},
|
|
142
|
+
"raw": {
|
|
143
|
+
"parent": "218d6fdf034153ffafe1b6ac5a96854180ea6a4310a4876cd888bcd6ce067d64",
|
|
144
|
+
"child": "324d3c6e00ba0ac72ed03478bffbb6dbf65e8173490467b460f242eaca0fd3ec",
|
|
145
|
+
"result": "40affabe76d7e056ab7867a593410a74ecb2e3eac8e725fcdad5aecf45f2021f"
|
|
146
|
+
},
|
|
147
|
+
"hostEstimateUsd": 1.0539046,
|
|
148
|
+
"reason": "error_max_budget_usd",
|
|
149
|
+
"markerSeen": true,
|
|
150
|
+
"sourceSnapshotTiming": "after-execution",
|
|
151
|
+
"freshContextEvidence": "one parent transcript and one child transcript; no resume option"
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"key": "mechanism-medium",
|
|
155
|
+
"task": "mechanism",
|
|
156
|
+
"role": "implementer",
|
|
157
|
+
"effort": "medium",
|
|
158
|
+
"requestedModel": "claude-sonnet-5-5",
|
|
159
|
+
"model": "claude-sonnet-5-5",
|
|
160
|
+
"parentEffort": "high",
|
|
161
|
+
"fresh": true,
|
|
162
|
+
"context": "context-9521e523e92aab3fb2a046a983432e56511424e7a91df2c4a5a76143e4f87dff",
|
|
163
|
+
"childContext": "child-847477035c4dfacc71140c7d805005629bc874cf015a83acf28bd62a2190be0f",
|
|
164
|
+
"state": "complete",
|
|
165
|
+
"exit": 0,
|
|
166
|
+
"timedOut": false,
|
|
167
|
+
"started": "2026-11-10T07:22:15.599Z",
|
|
168
|
+
"ended": "2026-11-10T07:22:29.819Z",
|
|
169
|
+
"argv": [
|
|
170
|
+
"-p",
|
|
171
|
+
"This is a frozen evaluation. Invoke the Agent tool exactly once with these input values: {\"subagent_type\":\"portulan:implementer\",\"description\":\"Frozen persona artifact probe\",\"prompt\":\"Read <acquisition>/tasks/mechanism.json and follow its task exactly. This is an artifact proposal, not a completed repository change.\",\"run_in_background\":false,\"effort\":\"medium\"}. Do not supply a child model or change the effort. Wait for that foreground child to finish. Do not answer its task yourself or invoke another child. After completion reply only DONE.",
|
|
172
|
+
"--output-format",
|
|
173
|
+
"json",
|
|
174
|
+
"--session-id",
|
|
175
|
+
"<parent-context>",
|
|
176
|
+
"--effort",
|
|
177
|
+
"high",
|
|
178
|
+
"--plugin-dir",
|
|
179
|
+
"<plugin>",
|
|
180
|
+
"--tools",
|
|
181
|
+
"Agent,Read",
|
|
182
|
+
"--allowedTools",
|
|
183
|
+
"Agent(portulan:implementer),Read",
|
|
184
|
+
"--add-dir",
|
|
185
|
+
"<acquisition>/tasks",
|
|
186
|
+
"--max-budget-usd",
|
|
187
|
+
"1",
|
|
188
|
+
"--model",
|
|
189
|
+
"claude-sonnet-5-5"
|
|
190
|
+
],
|
|
191
|
+
"argvProvenance": "recorded-before-execution",
|
|
192
|
+
"instrumentSha256": "fbde0bff490748c02803a6f953505eaa057031285a39957573785cd14aa388d8",
|
|
193
|
+
"usage": {
|
|
194
|
+
"parent": [
|
|
195
|
+
{
|
|
196
|
+
"id": "request-8d5746971407ca792e9da0fb449c6028995eee2f8d7b2ddda1f4e6da61937613",
|
|
197
|
+
"model": "claude-sonnet-5-5",
|
|
198
|
+
"effort": "high",
|
|
199
|
+
"at": 1794295341109,
|
|
200
|
+
"uncached": 2,
|
|
201
|
+
"written5m": 82083,
|
|
202
|
+
"written1h": 0,
|
|
203
|
+
"writtenUnknown": 0,
|
|
204
|
+
"read": 0,
|
|
205
|
+
"output": 245
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
"id": "request-ac34361003d5e3e5e9d2ebe0ac70382e3e7aea7c418ec7c07c73ddc5813c5543",
|
|
209
|
+
"model": "claude-sonnet-5-5",
|
|
210
|
+
"effort": "high",
|
|
211
|
+
"at": 1794295346829,
|
|
212
|
+
"uncached": 2,
|
|
213
|
+
"written5m": 503,
|
|
214
|
+
"written1h": 0,
|
|
215
|
+
"writtenUnknown": 0,
|
|
216
|
+
"read": 82083,
|
|
217
|
+
"output": 5
|
|
218
|
+
}
|
|
219
|
+
],
|
|
220
|
+
"child": [
|
|
221
|
+
{
|
|
222
|
+
"id": "request-9c5e95a551188dc248414fc894df567dadbd76c16bf02cfaa91a1c3cfd946425",
|
|
223
|
+
"model": "claude-sonnet-5-5",
|
|
224
|
+
"effort": "medium",
|
|
225
|
+
"at": 1794295342891,
|
|
226
|
+
"uncached": 2,
|
|
227
|
+
"written5m": 13337,
|
|
228
|
+
"written1h": 0,
|
|
229
|
+
"writtenUnknown": 0,
|
|
230
|
+
"read": 0,
|
|
231
|
+
"output": 314
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
"id": "request-f771db03c2ead365b17b2fcb5ef6f2e0d0d25b594161035e0a092fd115d2fc32",
|
|
235
|
+
"model": "claude-sonnet-5-5",
|
|
236
|
+
"effort": "medium",
|
|
237
|
+
"at": 1794295345372,
|
|
238
|
+
"uncached": 2,
|
|
239
|
+
"written5m": 5989,
|
|
240
|
+
"written1h": 0,
|
|
241
|
+
"writtenUnknown": 0,
|
|
242
|
+
"read": 13337,
|
|
243
|
+
"output": 11
|
|
244
|
+
}
|
|
245
|
+
]
|
|
246
|
+
},
|
|
247
|
+
"raw": {
|
|
248
|
+
"result": "6b6faa6b1ee0157c9b931ab46e15e016df7f34b647bb34c1d7553ed6b2d81441",
|
|
249
|
+
"parent": "31fabf7e7f548051937823e01c49ec1b573d37d903a010eb72eecbdcde91b037",
|
|
250
|
+
"child": "f4af68b961cac7eacfec012332061b67b6ba2f34c2eeb7a9ffc9b43421b211a8"
|
|
251
|
+
},
|
|
252
|
+
"hostEstimateUsd": 0.27008800000000005,
|
|
253
|
+
"invocation": {
|
|
254
|
+
"type": "portulan:implementer",
|
|
255
|
+
"effort": "medium",
|
|
256
|
+
"promptSha256": "7bbcfe957dfaf278f89ae1cb9fb6902479eb1d8f53e131ce49d5f0aa74ff064d",
|
|
257
|
+
"model": null,
|
|
258
|
+
"background": false
|
|
259
|
+
},
|
|
260
|
+
"answer": "MECHANISM_OK",
|
|
261
|
+
"answerRawSha256": "72a7832e87334fc8c2dda2407f419a828f8fb30eda2eed583debfa49b4112c70",
|
|
262
|
+
"answerPresentationSha256": "72a7832e87334fc8c2dda2407f419a828f8fb30eda2eed583debfa49b4112c70",
|
|
263
|
+
"answerNormalized": false,
|
|
264
|
+
"transcriptDuplicates": {
|
|
265
|
+
"parent": 0,
|
|
266
|
+
"child": 2
|
|
267
|
+
},
|
|
268
|
+
"markerSeen": true
|
|
269
|
+
}
|
|
270
|
+
],
|
|
271
|
+
"decodeRepair": {
|
|
272
|
+
"retainedKey": "implementer-lower-bound-a",
|
|
273
|
+
"approvedBy": "/root/checkpoint_520_open",
|
|
274
|
+
"approvalSha256": "9a8c8e99cfaec94ad350cac295d1f79dcca2396645c94578f575c9f69dab1b12",
|
|
275
|
+
"abortedJournalSha256": "6afb381b0e9d3eaefe2514e48d78295b01aec58ae2f878fdbb64c9fc667ad6ab",
|
|
276
|
+
"previousGrader": "9035deb344ea5a3ba5d31485836a5dda4d3dba6e06b20bfa78afb945ae1096b0",
|
|
277
|
+
"grader": "914d7744b73e9a79dd157038ed57c6f3034b2a05ce46fb4b5546a08b2e660978",
|
|
278
|
+
"observedOutcomes": 1,
|
|
279
|
+
"approval": "PASS",
|
|
280
|
+
"reruns": 0,
|
|
281
|
+
"semanticSuffixSha256": "3b8bde9accae1687d26b4621cafbadf7fb11e8ebd5dfd348ba3d15534f451146",
|
|
282
|
+
"explanation": "After one outcome, the original decoder rejected one JSON fence followed by prose. The same retained answer passes the revised decoder; all semantic predicates, cases and price code are byte-identical. The original false score remains. Independent approval covered exact decoder and continuation instrument hashes before the remaining seventeen calls."
|
|
283
|
+
},
|
|
284
|
+
"accounting": {
|
|
285
|
+
"calls": 20,
|
|
286
|
+
"parentContexts": 20,
|
|
287
|
+
"qualityChildren": 18,
|
|
288
|
+
"requests": 80,
|
|
289
|
+
"note": "Both probes, every parent and every child are included. Host USD values are lifecycle estimates, not subscription bills, and are not added to the declared-vector indexes."
|
|
290
|
+
},
|
|
291
|
+
"sources": {
|
|
292
|
+
"evals/ab/personas/corpus.json": "89554b37030657bd7167395e425461cb6f7acf5c223090c074ff054c7dac6b9b",
|
|
293
|
+
"evals/ab/personas/grader.mjs": "914d7744b73e9a79dd157038ed57c6f3034b2a05ce46fb4b5546a08b2e660978",
|
|
294
|
+
"core/personas/implementer.md": "bea6b78808fd6c390ebdfb53124d0b132e8a1454d78cecbabe04a632a0e2d45c",
|
|
295
|
+
"core/personas/reviewer.md": "6c364f370e61bc80a32697dc7d84eeb267ef3a2bbf48da16744356a90ce5078f",
|
|
296
|
+
"core/personas/librarian.md": "a79ef87153c2a5f52d36bd33b95fcdc2b0ed9bf79362a76bbf6a85459c094f46"
|
|
297
|
+
},
|
|
298
|
+
"bindings": {
|
|
299
|
+
"implementer": "3c3874f38defa6ea2bb42e45aa5a3b4267cc6794e1c7b11edc27440f861c0b97",
|
|
300
|
+
"reviewer": "436896a48ce036eeab69091fce7cee7482e8891efa2315da288378d9158f9a69",
|
|
301
|
+
"librarian": "7ad4e74c09482940444be0a1fe4de7eacc98e24aee145fdb6c25a162879053fc"
|
|
302
|
+
},
|
|
303
|
+
"instruments": {
|
|
304
|
+
"firstProbe": {
|
|
305
|
+
"sha256": "a02b6d2185b59e5b43a96a7cb3a5fcee7965c29a45b1533aa02c033369937f44",
|
|
306
|
+
"timing": "snapshotted-after-execution"
|
|
307
|
+
},
|
|
308
|
+
"secondProbe": {
|
|
309
|
+
"sha256": "fbde0bff490748c02803a6f953505eaa057031285a39957573785cd14aa388d8",
|
|
310
|
+
"timing": "frozen-before-execution"
|
|
311
|
+
},
|
|
312
|
+
"firstOutcome": {
|
|
313
|
+
"sha256": "2f0c0843c55ced112b8f5fc6872de6acb84f16319dcdd8edcf763bac4c37aa30",
|
|
314
|
+
"timing": "frozen-before-execution"
|
|
315
|
+
},
|
|
316
|
+
"continuation": {
|
|
317
|
+
"sha256": "34a45b79d5d3a762bbcd46222bdefe479cf031d1d0150665763b8de1c78981ab",
|
|
318
|
+
"timing": "approved-and-frozen-before-seventeen-untouched-cells"
|
|
319
|
+
},
|
|
320
|
+
"publisher": {
|
|
321
|
+
"sha256": "58ceb6aa7b361f627816fc92c1b7cdc755b3c473c5509b25c1a97c3c88a0d96c",
|
|
322
|
+
"timing": "after-acquisition; whitelisted normalization only"
|
|
323
|
+
}
|
|
324
|
+
},
|
|
325
|
+
"files": {
|
|
326
|
+
"implementer.json": "0b63097bec76852cccdd8edf3c7c9f20d83b9caae9536d1badb51a269003cdef",
|
|
327
|
+
"reviewer.json": "b9ea8b9d5b24ab33b67a1274b507b8416a482d349a9d64b4261b76ceac856774",
|
|
328
|
+
"librarian.json": "adf79f475a83dcc321dff1e4867d9af232052ffda6ffc92e5d2c8c75cf65a466"
|
|
329
|
+
}
|
|
330
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: implementer
|
|
3
|
+
description: Carries one task through the full loop — research, plan, implement, verify, learn — and hands back a verified change plus what it learned. Delegate a single unit of implementation work to it. It does not merge and it does not take gated actions.
|
|
4
|
+
tools: Read, Glob, Grep, Edit, Write, Bash
|
|
5
|
+
# compiled by `portulan compile` from core/personas/implementer.md; edit that file, then recompile
|
|
6
|
+
model: "inherit"
|
|
7
|
+
omitClaudeMd: false
|
|
8
|
+
experimental:
|
|
9
|
+
cacheTtl: 5m
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
You are the **implementer** persona of the Portulan engine. Read
|
|
13
|
+
`${CLAUDE_PLUGIN_ROOT}/core/personas/implementer.md` for your charter and
|
|
14
|
+
`${CLAUDE_PLUGIN_ROOT}/core/operating/loop.md` for the loop you carry. This file binds that persona to
|
|
15
|
+
this host; the doctrine lives there, and where the two ever disagree, the persona wins.
|
|
16
|
+
|
|
17
|
+
Take **one task** from intent to a demonstrated change:
|
|
18
|
+
|
|
19
|
+
1. **Research** before planning. Read the repository's workspace — its gate map, definition of done,
|
|
20
|
+
the repo card for this repository, and relevant memory — and never guess what you can check.
|
|
21
|
+
2. **Plan** to a testable shape. If the acceptance criteria cannot be written as observable checks,
|
|
22
|
+
run the `clarify` skill rather than starting anyway.
|
|
23
|
+
3. **Implement** at the altitude of the surrounding code. Writes are isolated: one branch, your own
|
|
24
|
+
files.
|
|
25
|
+
4. **Verify** by climbing the hierarchy — it compiles, then tests pass, then the behaviour is
|
|
26
|
+
exercised. Run the workspace's verify recipe and read the output. Never report done on what you
|
|
27
|
+
could not walk a reviewer through line by line.
|
|
28
|
+
5. **Learn**: write back what the task taught, as a draft. You draft memory and propose rule changes;
|
|
29
|
+
you never accept them. That gate is a human's.
|
|
30
|
+
|
|
31
|
+
**What you do not do.** You do not merge your own work, and you do not take an action the workspace's
|
|
32
|
+
gate map places in the Gated tier — merging, deleting a remote branch, publishing, changing settings,
|
|
33
|
+
spending money, or anything that speaks for the team beyond this repository. You prepare such an action
|
|
34
|
+
and hand it to the human. Which actions those are is the gate map's to say and not this file's, so read
|
|
35
|
+
it rather than this list. Where the line falls — whether pushing a working branch is Auto, say, or the
|
|
36
|
+
gate sits at the merge — is a property of the workspace you are standing in, not of this binding: these
|
|
37
|
+
files ship with the plugin into repositories whose gate maps this one has never seen.
|
|
38
|
+
|
|
39
|
+
**One honest limit of this binding.** The engine states your reach as capability classes; this host's
|
|
40
|
+
allow-list is coarser. `Bash` is a single grant covering both running a verify recipe and running
|
|
41
|
+
`gh pr merge`, so the tool list cannot express the Auto/Gated line by itself. The line is held by the
|
|
42
|
+
gate map you read in step 1 and by the repository's platform floor — branch protection and required
|
|
43
|
+
checks — not by this frontmatter. Treat the gate map as binding regardless of what this host permits.
|