@sleepy_panda_srl/portulan 0.1.3 → 0.3.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 +7 -6
- package/cli/README.md +145 -358
- package/cli/advisory.mjs +354 -0
- package/cli/comments.mjs +932 -0
- package/cli/compile.mjs +1719 -1699
- package/cli/context.mjs +883 -0
- package/cli/control-chars.mjs +12 -301
- package/cli/discover.mjs +17 -574
- package/cli/doctor.mjs +269 -1080
- package/cli/drills.mjs +92 -504
- package/cli/feedback.mjs +16 -237
- package/cli/finish.mjs +437 -0
- package/cli/form.mjs +644 -0
- package/cli/fuzz-shell.mjs +20 -305
- package/cli/gate.mjs +7 -199
- package/cli/goldens.mjs +26 -184
- package/cli/index.mjs +305 -655
- package/cli/init.mjs +243 -566
- package/cli/inside.mjs +3 -28
- package/cli/instructions.mjs +829 -0
- package/cli/ledger.mjs +882 -0
- package/cli/librarian.mjs +135 -599
- package/cli/manifest.mjs +2 -39
- package/cli/mutants.mjs +9 -170
- package/cli/new.mjs +12 -243
- package/cli/pack-identity.mjs +5 -74
- package/cli/pack-version.mjs +13 -255
- package/cli/plugin-lint.mjs +42 -658
- package/cli/portulan.mjs +6 -125
- package/cli/recipe-set.mjs +15 -245
- package/cli/release-eval.mjs +28 -348
- package/cli/review-meter.mjs +29 -265
- package/cli/rule-carriers.mjs +12 -175
- package/cli/sessions.mjs +82 -0
- package/cli/skill-goldens.mjs +10 -176
- package/cli/skills-set.mjs +12 -414
- package/cli/stop-gate.mjs +83 -514
- package/cli/symbols.mjs +1132 -0
- package/cli/telemetry.mjs +82 -505
- package/cli/upgrade.mjs +171 -314
- package/cli/vendor.mjs +146 -476
- package/cli/version-carriers.mjs +8 -86
- package/core/README.md +1 -1
- package/core/engine.md +3 -9
- package/core/operating/autonomy.md +1 -1
- package/core/operating/context.md +258 -0
- package/core/operating/evolution.md +3 -3
- package/core/operating/loop.md +13 -20
- package/core/operating/memory.md +12 -3
- package/core/operating/sessions.md +100 -0
- package/core/personas/README.md +33 -0
- package/core/personas/librarian.md +2 -2
- package/core/skills/clarify/SKILL.md +1 -1
- package/core/skills/consolidate/SKILL.md +5 -3
- package/core/templates/handoff.md +28 -15
- package/core/templates/memory-entry.md +1 -0
- package/evals/README.md +271 -845
- package/evals/releases/0.2.0.json +146 -0
- package/evals/releases/0.2.0.md +67 -0
- package/evals/releases/0.3.0.json +150 -0
- package/evals/releases/0.3.0.md +68 -0
- package/evals/releases/README.md +3 -3
- package/package.json +5 -2
- package/packs/.claude-plugin/plugin.json +2 -1
- package/packs/README.md +7 -4
- package/packs/rituals/checkpoints/README.md +1 -1
- package/packs/tools/README.md +8 -8
- package/packs/tools/github/verify/actions-pinned.sh +10 -55
- package/packs/tools/local-llm/README.md +136 -0
- package/packs/tools/local-llm/pack.json +32 -0
- package/packs/tools/local-llm/personas/local-worker.md +44 -0
- package/packs/tools/local-llm/runner/local-llm.mjs +1665 -0
- package/packs/tools/local-llm/skills/delegate-local/SKILL.md +64 -0
- package/packs/tools/local-llm/verify/README.md +18 -0
- package/spec/README.md +113 -6
- package/spec/migrations/0001-repository-declares-its-tree.mjs +1 -26
- package/spec/migrations/0002-bundle-fallback-path.mjs +13 -74
- package/spec/migrations/0003-handoff-index-not-kept.mjs +66 -0
- package/spec/migrations/0004-changelog-fragments.mjs +53 -0
- package/spec/migrations/0005-session-log-retired.mjs +69 -0
- package/spec/migrations/0006-boot-card.mjs +77 -0
- package/spec/migrations/0007-guidance-compiled.mjs +31 -0
- package/spec/migrations/0008-card-reading.mjs +55 -0
- package/spec/migrations/0009-instruction-sections-on-read.mjs +60 -0
- package/spec/migrations/0010-comment-rail.mjs +57 -0
- package/spec/migrations/README.md +45 -10
- package/spec/pack.schema.json +1 -1
- package/spec/slots.md +343 -27
- package/spec/workspace.schema.json +145 -4
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
{
|
|
2
|
+
"portulan": {
|
|
3
|
+
"releaseEval": "1"
|
|
4
|
+
},
|
|
5
|
+
"version": "0.2.0",
|
|
6
|
+
"captured": "2026-09-30",
|
|
7
|
+
"source": {
|
|
8
|
+
"commit": "0b150002910d34a0a79408e82439cb81e1a0a0b9",
|
|
9
|
+
"clean": true
|
|
10
|
+
},
|
|
11
|
+
"host": {
|
|
12
|
+
"node": "v26.9.0",
|
|
13
|
+
"platform": "darwin"
|
|
14
|
+
},
|
|
15
|
+
"recipes": [
|
|
16
|
+
{
|
|
17
|
+
"id": "docs",
|
|
18
|
+
"exit": 0
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": "json",
|
|
22
|
+
"exit": 0
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"id": "doctor",
|
|
26
|
+
"exit": 0
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "tests",
|
|
30
|
+
"exit": 0
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"id": "plugin",
|
|
34
|
+
"exit": 0
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"id": "compile",
|
|
38
|
+
"exit": 0
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"id": "workflow-filters",
|
|
42
|
+
"exit": 0
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"id": "index",
|
|
46
|
+
"exit": 0
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"id": "context",
|
|
50
|
+
"exit": 0
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"id": "ledger",
|
|
54
|
+
"exit": 0
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"id": "control-chars",
|
|
58
|
+
"exit": 0
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"id": "comments",
|
|
62
|
+
"exit": 0
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"id": "rule-carriers",
|
|
66
|
+
"exit": 0
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"id": "pack-version",
|
|
70
|
+
"exit": 0
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"id": "pack-identity",
|
|
74
|
+
"exit": 0
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"id": "payload",
|
|
78
|
+
"exit": 0
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"id": "eval-bundle",
|
|
82
|
+
"exit": 0
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"id": "goldens",
|
|
86
|
+
"exit": 0
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"id": "mutants",
|
|
90
|
+
"exit": 0
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"id": "fuzz-shell",
|
|
94
|
+
"exit": 0
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"id": "version-carriers",
|
|
98
|
+
"exit": 0
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"id": "skill-goldens",
|
|
102
|
+
"exit": 0
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"id": "review-loop",
|
|
106
|
+
"exit": 0
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"id": "telemetry",
|
|
110
|
+
"exit": 0
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"id": "drills",
|
|
114
|
+
"exit": 0
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"id": "ab",
|
|
118
|
+
"exit": 0
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"id": "ab-grade",
|
|
122
|
+
"exit": 0
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"id": "ab-run",
|
|
126
|
+
"exit": 0
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"id": "tools/github:actions-pinned",
|
|
130
|
+
"exit": 0
|
|
131
|
+
}
|
|
132
|
+
],
|
|
133
|
+
"excluded": [
|
|
134
|
+
{
|
|
135
|
+
"id": "release-eval",
|
|
136
|
+
"why": "a capture cannot be accurate about the record it is inside — captured before the record is written it is red for the record's absence, and captured after it is stale the moment the register is rendered. Its verdict for this release is the rail's own run on the pull request carrying this file."
|
|
137
|
+
}
|
|
138
|
+
],
|
|
139
|
+
"abBaseline": {
|
|
140
|
+
"snapshot": "evals/ab/baseline.json",
|
|
141
|
+
"register": "evals/ab/baseline.md",
|
|
142
|
+
"captured": "2026-08-31T09:05:32.699Z",
|
|
143
|
+
"commit": "a642d551eec6c146c67ef0acfe3f8ba535c5ce6e",
|
|
144
|
+
"clean": false
|
|
145
|
+
}
|
|
146
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Eval result — Portulan 0.2.0
|
|
2
|
+
|
|
3
|
+
> **Generated. Do not edit.** Rendered from [`evals/releases/0.2.0.json`](0.2.0.json) by [`cli/release-eval.mjs`](../../cli/release-eval.mjs) and byte-compared by the `release-eval` verify recipe. This is the eval result milestone 8 requires a release to carry — `docs/plan.md`, Protocol → Versioning.
|
|
4
|
+
|
|
5
|
+
## What this release was measured at
|
|
6
|
+
|
|
7
|
+
| | |
|
|
8
|
+
|---|---|
|
|
9
|
+
| Version | `0.2.0` |
|
|
10
|
+
| Captured | 2026-09-30 |
|
|
11
|
+
| Commit | `0b150002910d34a0a79408e82439cb81e1a0a0b9` |
|
|
12
|
+
| Tree at capture | clean |
|
|
13
|
+
| Node | `v26.9.0` |
|
|
14
|
+
| Platform | `darwin` |
|
|
15
|
+
|
|
16
|
+
## The rails, and what each returned
|
|
17
|
+
|
|
18
|
+
29 of the 30 recipes this workspace yielded at capture. The set is derived from [`cli/recipe-set.mjs`](../../cli/recipe-set.mjs) and never listed by hand.
|
|
19
|
+
|
|
20
|
+
| Recipe | Verdict |
|
|
21
|
+
|---|---|
|
|
22
|
+
| `docs` | green |
|
|
23
|
+
| `json` | green |
|
|
24
|
+
| `doctor` | green |
|
|
25
|
+
| `tests` | green |
|
|
26
|
+
| `plugin` | green |
|
|
27
|
+
| `compile` | green |
|
|
28
|
+
| `workflow-filters` | green |
|
|
29
|
+
| `index` | green |
|
|
30
|
+
| `context` | green |
|
|
31
|
+
| `ledger` | green |
|
|
32
|
+
| `control-chars` | green |
|
|
33
|
+
| `comments` | green |
|
|
34
|
+
| `rule-carriers` | green |
|
|
35
|
+
| `pack-version` | green |
|
|
36
|
+
| `pack-identity` | green |
|
|
37
|
+
| `payload` | green |
|
|
38
|
+
| `eval-bundle` | green |
|
|
39
|
+
| `goldens` | green |
|
|
40
|
+
| `mutants` | green |
|
|
41
|
+
| `fuzz-shell` | green |
|
|
42
|
+
| `version-carriers` | green |
|
|
43
|
+
| `skill-goldens` | green |
|
|
44
|
+
| `review-loop` | green |
|
|
45
|
+
| `telemetry` | green |
|
|
46
|
+
| `drills` | green |
|
|
47
|
+
| `ab` | green |
|
|
48
|
+
| `ab-grade` | green |
|
|
49
|
+
| `ab-run` | green |
|
|
50
|
+
| `tools/github:actions-pinned` | green |
|
|
51
|
+
|
|
52
|
+
**`release-eval` is excluded**, and the reason is printed rather than the row silently dropped: a capture cannot be accurate about the record it is inside — captured before the record is written it is red for the record's absence, and captured after it is stale the moment the register is rendered. Its verdict for this release is the rail's own run on the pull request carrying this file.
|
|
53
|
+
|
|
54
|
+
## The A/B baseline this release ships against
|
|
55
|
+
|
|
56
|
+
[`evals/ab/baseline.md`](https://github.com/sleepy-panda-srl/portulan/blob/v0.2.0/evals/ab/baseline.md), rendered from `evals/ab/baseline.json` — captured 2026-08-31T09:05:32.699Z at `a642d551eec6c146c67ef0acfe3f8ba535c5ce6e`, over a tree that was **not clean**.
|
|
57
|
+
|
|
58
|
+
**Its figures are not repeated here.** They have one carrier and this is not it.
|
|
59
|
+
|
|
60
|
+
## What this record does not establish
|
|
61
|
+
|
|
62
|
+
- **A green says this record agrees with its own capture — never that the release is good.** Every line below is what the recipes returned at one commit, and a recipe's own green establishes only what that recipe's documentation says it establishes.
|
|
63
|
+
- **The recipes were not run at the tag.** They ran at `0b150002910d34a0a79408e82439cb81e1a0a0b9`, and this record is committed *in* the cut change — so the tagged tree is this commit plus whatever that change still adds after the capture, the record itself at minimum. A record cannot be captured at a commit that does not exist yet, and printing the one it was captured at is the only honest form.
|
|
64
|
+
- **`release-eval` is excluded from the rows above**, because a capture cannot be accurate about the record it is inside. Its verdict for this release is the rail's own run on the pull request that carries this file.
|
|
65
|
+
- **This record measures the Portulan repository's own build**, at the commit named above — never the workspace, project or package this release is installed into. Nothing here has looked at your tree.
|
|
66
|
+
- **The tree was clean at capture**, so the commit named above is what was measured.
|
|
67
|
+
- **The A/B baseline's figures are NOT restated here.** This record names which baseline the release ships against; the figures and everything that may not be concluded from them live in that register alone.
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
{
|
|
2
|
+
"portulan": {
|
|
3
|
+
"releaseEval": "1"
|
|
4
|
+
},
|
|
5
|
+
"version": "0.3.0",
|
|
6
|
+
"captured": "2026-11-03",
|
|
7
|
+
"source": {
|
|
8
|
+
"commit": "c08515fee0693cb0fc07fc6077fb152aa46bc28b",
|
|
9
|
+
"clean": false
|
|
10
|
+
},
|
|
11
|
+
"host": {
|
|
12
|
+
"node": "v26.12.1",
|
|
13
|
+
"platform": "darwin"
|
|
14
|
+
},
|
|
15
|
+
"recipes": [
|
|
16
|
+
{
|
|
17
|
+
"id": "docs",
|
|
18
|
+
"exit": 0
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": "json",
|
|
22
|
+
"exit": 0
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"id": "doctor",
|
|
26
|
+
"exit": 0
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "tests",
|
|
30
|
+
"exit": 0
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"id": "plugin",
|
|
34
|
+
"exit": 0
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"id": "compile",
|
|
38
|
+
"exit": 0
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"id": "workflow-filters",
|
|
42
|
+
"exit": 0
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"id": "index",
|
|
46
|
+
"exit": 0
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"id": "context",
|
|
50
|
+
"exit": 0
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"id": "ledger",
|
|
54
|
+
"exit": 0
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"id": "control-chars",
|
|
58
|
+
"exit": 0
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"id": "comments",
|
|
62
|
+
"exit": 0
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"id": "rule-carriers",
|
|
66
|
+
"exit": 0
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"id": "pack-version",
|
|
70
|
+
"exit": 0
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"id": "pack-identity",
|
|
74
|
+
"exit": 0
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"id": "payload",
|
|
78
|
+
"exit": 0
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"id": "eval-bundle",
|
|
82
|
+
"exit": 0
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"id": "goldens",
|
|
86
|
+
"exit": 0
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"id": "mutants",
|
|
90
|
+
"exit": 0
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"id": "fuzz-shell",
|
|
94
|
+
"exit": 0
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"id": "version-carriers",
|
|
98
|
+
"exit": 0
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"id": "skill-goldens",
|
|
102
|
+
"exit": 0
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"id": "review-loop",
|
|
106
|
+
"exit": 0
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"id": "telemetry",
|
|
110
|
+
"exit": 0
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"id": "drills",
|
|
114
|
+
"exit": 0
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"id": "ab",
|
|
118
|
+
"exit": 0
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"id": "ab-grade",
|
|
122
|
+
"exit": 0
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"id": "ab-run",
|
|
126
|
+
"exit": 0
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"id": "tools/github:actions-pinned",
|
|
130
|
+
"exit": 0
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"id": "tools/local-llm:runner-rails",
|
|
134
|
+
"exit": 0
|
|
135
|
+
}
|
|
136
|
+
],
|
|
137
|
+
"excluded": [
|
|
138
|
+
{
|
|
139
|
+
"id": "release-eval",
|
|
140
|
+
"why": "a capture cannot be accurate about the record it is inside — captured before the record is written it is red for the record's absence, and captured after it is stale the moment the register is rendered. Its verdict for this release is the rail's own run on the pull request carrying this file."
|
|
141
|
+
}
|
|
142
|
+
],
|
|
143
|
+
"abBaseline": {
|
|
144
|
+
"snapshot": "evals/ab/baseline.json",
|
|
145
|
+
"register": "evals/ab/baseline.md",
|
|
146
|
+
"captured": "2026-08-31T09:05:32.699Z",
|
|
147
|
+
"commit": "a642d551eec6c146c67ef0acfe3f8ba535c5ce6e",
|
|
148
|
+
"clean": false
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Eval result — Portulan 0.3.0
|
|
2
|
+
|
|
3
|
+
> **Generated. Do not edit.** Rendered from [`evals/releases/0.3.0.json`](0.3.0.json) by [`cli/release-eval.mjs`](../../cli/release-eval.mjs) and byte-compared by the `release-eval` verify recipe. This is the eval result milestone 8 requires a release to carry — `docs/plan.md`, Protocol → Versioning.
|
|
4
|
+
|
|
5
|
+
## What this release was measured at
|
|
6
|
+
|
|
7
|
+
| | |
|
|
8
|
+
|---|---|
|
|
9
|
+
| Version | `0.3.0` |
|
|
10
|
+
| Captured | 2026-11-03 |
|
|
11
|
+
| Commit | `c08515fee0693cb0fc07fc6077fb152aa46bc28b` |
|
|
12
|
+
| Tree at capture | **not clean** |
|
|
13
|
+
| Node | `v26.12.1` |
|
|
14
|
+
| Platform | `darwin` |
|
|
15
|
+
|
|
16
|
+
## The rails, and what each returned
|
|
17
|
+
|
|
18
|
+
30 of the 31 recipes this workspace yielded at capture. The set is derived from [`cli/recipe-set.mjs`](../../cli/recipe-set.mjs) and never listed by hand.
|
|
19
|
+
|
|
20
|
+
| Recipe | Verdict |
|
|
21
|
+
|---|---|
|
|
22
|
+
| `docs` | green |
|
|
23
|
+
| `json` | green |
|
|
24
|
+
| `doctor` | green |
|
|
25
|
+
| `tests` | green |
|
|
26
|
+
| `plugin` | green |
|
|
27
|
+
| `compile` | green |
|
|
28
|
+
| `workflow-filters` | green |
|
|
29
|
+
| `index` | green |
|
|
30
|
+
| `context` | green |
|
|
31
|
+
| `ledger` | green |
|
|
32
|
+
| `control-chars` | green |
|
|
33
|
+
| `comments` | green |
|
|
34
|
+
| `rule-carriers` | green |
|
|
35
|
+
| `pack-version` | green |
|
|
36
|
+
| `pack-identity` | green |
|
|
37
|
+
| `payload` | green |
|
|
38
|
+
| `eval-bundle` | green |
|
|
39
|
+
| `goldens` | green |
|
|
40
|
+
| `mutants` | green |
|
|
41
|
+
| `fuzz-shell` | green |
|
|
42
|
+
| `version-carriers` | green |
|
|
43
|
+
| `skill-goldens` | green |
|
|
44
|
+
| `review-loop` | green |
|
|
45
|
+
| `telemetry` | green |
|
|
46
|
+
| `drills` | green |
|
|
47
|
+
| `ab` | green |
|
|
48
|
+
| `ab-grade` | green |
|
|
49
|
+
| `ab-run` | green |
|
|
50
|
+
| `tools/github:actions-pinned` | green |
|
|
51
|
+
| `tools/local-llm:runner-rails` | green |
|
|
52
|
+
|
|
53
|
+
**`release-eval` is excluded**, and the reason is printed rather than the row silently dropped: a capture cannot be accurate about the record it is inside — captured before the record is written it is red for the record's absence, and captured after it is stale the moment the register is rendered. Its verdict for this release is the rail's own run on the pull request carrying this file.
|
|
54
|
+
|
|
55
|
+
## The A/B baseline this release ships against
|
|
56
|
+
|
|
57
|
+
[`evals/ab/baseline.md`](https://github.com/sleepy-panda-srl/portulan/blob/v0.3.0/evals/ab/baseline.md), rendered from `evals/ab/baseline.json` — captured 2026-08-31T09:05:32.699Z at `a642d551eec6c146c67ef0acfe3f8ba535c5ce6e`, over a tree that was **not clean**.
|
|
58
|
+
|
|
59
|
+
**Its figures are not repeated here.** They have one carrier and this is not it.
|
|
60
|
+
|
|
61
|
+
## What this record does not establish
|
|
62
|
+
|
|
63
|
+
- **A green says this record agrees with its own capture — never that the release is good.** Every line below is what the recipes returned at one commit, and a recipe's own green establishes only what that recipe's documentation says it establishes.
|
|
64
|
+
- **The recipes were not run at the tag.** They ran at `c08515fee0693cb0fc07fc6077fb152aa46bc28b`, and this record is committed *in* the cut change — so the tagged tree is this commit plus whatever that change still adds after the capture, the record itself at minimum. A record cannot be captured at a commit that does not exist yet, and printing the one it was captured at is the only honest form.
|
|
65
|
+
- **`release-eval` is excluded from the rows above**, because a capture cannot be accurate about the record it is inside. Its verdict for this release is the rail's own run on the pull request that carries this file.
|
|
66
|
+
- **This record measures the Portulan repository's own build**, at the commit named above — never the workspace, project or package this release is installed into. Nothing here has looked at your tree.
|
|
67
|
+
- **The tree was NOT clean at capture** — the diff of the cut change is the only record of what was uncommitted, which is weaker than a sha and is printed rather than hidden.
|
|
68
|
+
- **The A/B baseline's figures are NOT restated here.** This record names which baseline the release ships against; the figures and everything that may not be concluded from them live in that register alone.
|
package/evals/releases/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# `evals/releases/`
|
|
2
2
|
|
|
3
|
-
The eval result each release carries, one pair per version — milestone 8's ninth clause. The
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
The eval result each release carries, one pair per version — milestone 8's ninth clause. The limits are
|
|
4
|
+
in [`../README.md`](../README.md); the argument, the mechanism and the two designs a fresh context
|
|
5
|
+
reversed are in [`../../cli/release-eval.mjs`](../../cli/release-eval.mjs). This file does not restate
|
|
6
6
|
either, because a rule with two carriers is obeyed at the narrower one.
|
|
7
7
|
|
|
8
8
|
- `<version>.json` — the **capture**: the verdict every recipe the workspace yielded returned, at a named
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sleepy_panda_srl/portulan",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Portulan — an agentic-engineering framework whose product is its files. The CLI wraps the file-based mechanics for hosts beyond Claude Code.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -26,7 +26,10 @@
|
|
|
26
26
|
"!cli/ab.mjs",
|
|
27
27
|
"!cli/ab-run.mjs",
|
|
28
28
|
"!cli/ab-grade.mjs",
|
|
29
|
-
"!cli/
|
|
29
|
+
"!cli/local-routing.mjs",
|
|
30
|
+
"!cli/warm.mjs",
|
|
31
|
+
"!cli/payload.mjs",
|
|
32
|
+
"!cli/roster.mjs"
|
|
30
33
|
],
|
|
31
34
|
"repository": {
|
|
32
35
|
"type": "git",
|
package/packs/README.md
CHANGED
|
@@ -31,7 +31,9 @@ registers nothing, silently, while a validator walking deeper counts three;
|
|
|
31
31
|
manifests therefore sit in this tree and they answer different questions: the repository's own at
|
|
32
32
|
[`../.claude-plugin/plugin.json`](../.claude-plugin/plugin.json), which declares
|
|
33
33
|
`./packs/rituals/checkpoints/skills/` because *its* root is the repository; and this one, whose root is
|
|
34
|
-
`packs/`. Neither is redundant, and the paths differ by exactly the prefix their roots differ by.
|
|
34
|
+
`packs/`. Neither is redundant, and the paths differ by exactly the prefix their roots differ by. Both
|
|
35
|
+
also declare `tools/local-llm`'s `skills/` root, the same way, since this repository's workspace composes
|
|
36
|
+
that pack too; the plugin's name and version here are the checkpoints pack's.
|
|
35
37
|
|
|
36
38
|
**The version here mirrors the pack's own** — `portulan.version` in
|
|
37
39
|
[`rituals/checkpoints/pack.json`](rituals/checkpoints/pack.json), which the Pack Definition names as how
|
|
@@ -45,7 +47,8 @@ observed through a *local* marketplace over a copy of this directory. The quoted
|
|
|
45
47
|
exists and the feed's pin moves to it. Until then the green is demonstrated on the payload and inferred
|
|
46
48
|
for the feed — a distinction this repository would rather write down than round off.
|
|
47
49
|
|
|
48
|
-
> **
|
|
49
|
-
> ritual;
|
|
50
|
-
>
|
|
50
|
+
> **Three packs exist.** [`rituals/checkpoints`](rituals/checkpoints/README.md), the supervised-build
|
|
51
|
+
> ritual; [`tools/github`](tools/github/README.md), one verify recipe; and
|
|
52
|
+
> [`tools/local-llm`](tools/local-llm/README.md), hybrid local-model execution under a zero-floor input
|
|
53
|
+
> budget and a verify-gated rollback loop. `stacks/` is still empty and says why.
|
|
51
54
|
|
|
@@ -100,7 +100,7 @@ under, and the checkpoint section of that project's own gate map.
|
|
|
100
100
|
|
|
101
101
|
**The evidence is that project's build record**, cited as provenance rather than as procedure: the
|
|
102
102
|
fresh-context checkpoints changed *designs* rather than wording at two consecutive milestones — the
|
|
103
|
-
story is in [milestone 4's record](https://github.com/sleepy-panda-srl/portulan/blob/
|
|
103
|
+
story is in [milestone 4's record](https://github.com/sleepy-panda-srl/portulan/blob/8a33f9b/docs/milestones/m04.md),
|
|
104
104
|
beside [the protocol itself](https://github.com/sleepy-panda-srl/portulan/blob/main/docs/plan.md) —
|
|
105
105
|
while adopters received no artifact for the ritual that produced them. This pack is that artifact.
|
|
106
106
|
|
package/packs/tools/README.md
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
Tool packs — integrations for the tools and MCP servers an agent drives (issue trackers, cloud
|
|
4
4
|
CLIs, design tools, databases), with the how-to and the gate classification for each.
|
|
5
5
|
|
|
6
|
-
> **
|
|
7
|
-
> host-neutral vocabulary, dispatched on by
|
|
8
|
-
> cascade's missing middle (`core < pack < workspace`)
|
|
9
|
-
> fragments are resolved and merged into the policy,
|
|
6
|
+
> **Two tool packs exist** — [`github/`](github/README.md) and [`local-llm/`](local-llm/README.md). The
|
|
7
|
+
> machinery that reads one is a gate policy in a host-neutral vocabulary, dispatched on by
|
|
8
|
+
> [`../../cli/compile.mjs`](../../cli/compile.mjs) — and the cascade's missing middle (`core < pack < workspace`)
|
|
9
|
+
> is bridged: a pack's `contributes.gates` fragments are resolved and merged into the policy,
|
|
10
|
+
> **tighten-only**, by the same compiler.
|
|
10
11
|
>
|
|
11
|
-
>
|
|
12
|
-
>
|
|
13
|
-
>
|
|
14
|
-
> a workspace here drives a tool that needs one.
|
|
12
|
+
> [`local-llm/`](local-llm/README.md) is the first tool pack to ship a gate classification
|
|
13
|
+
> (`local-llm-off-loopback` at `propose`) alongside a persona and an offline verify recipe,
|
|
14
|
+
> fulfilling the promise this file has carried since it was written.
|
|
@@ -1,34 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
3
2
|
# Every `uses:` in a GitHub Actions workflow is pinned to a full 40-character commit SHA.
|
|
4
|
-
#
|
|
5
|
-
# Exit 0 green · 1 red · 2 could not run. The third is load-bearing here, as everywhere in this
|
|
6
|
-
# project: a recipe that could not look must never report what a recipe that looked and found nothing
|
|
7
|
-
# reports. See `README.md` beside this file for what the check does NOT cover and why it exists at all
|
|
8
|
-
# given that GitHub can enforce pinning itself.
|
|
9
|
-
#
|
|
10
|
-
# Composed into an adopting workspace through `pack.json`'s `contributes.verify`, whose `run` names
|
|
11
|
-
# this file through `${PACK_ROOT}` — the pack does not know the adopter's layout and must not guess it.
|
|
3
|
+
# Exit 0 green · 1 red · 2 could not run.
|
|
12
4
|
|
|
13
5
|
set -uo pipefail
|
|
14
6
|
|
|
7
|
+
# Relative to the working directory, the adopter's root: where the pack sits says nothing about it.
|
|
15
8
|
WORKFLOWS=".github/workflows"
|
|
16
9
|
|
|
17
|
-
#
|
|
18
|
-
# The tools this recipe invokes, checked before it invokes them.
|
|
19
|
-
#
|
|
20
|
-
# Without this the failure is SILENT and GREEN: the two loops below read from process substitutions,
|
|
21
|
-
# so a missing `find` or `grep` yields no lines at all, every counter stays zero, `status` stays 0 —
|
|
22
|
-
# and the recipe reports a pass having examined nothing. That is the false green — "nothing looked"
|
|
23
|
-
# reported as "nothing wrong" — and it is precisely what `.portulan/memory/verify-preconditions-fail-closed.md`
|
|
24
|
-
# exists to refuse. The header below already cited that rule for the workflows DIRECTORY and did not
|
|
25
|
-
# apply it to the recipe's own dependencies: a rule obeyed at one of its two sites, in a file that
|
|
26
|
-
# quotes the rule. Copilot round 5.
|
|
27
|
-
#
|
|
28
|
-
# `requires` in `pack.json` declares the same list. Two carriers, deliberately — the manifest's is
|
|
29
|
-
# what a host reads to decide whether to run at all, this one is what fires when it ran anyway — and
|
|
30
|
-
# they are checked against each other by nothing, which is stated here rather than implied.
|
|
31
|
-
# ---------------------------------------------------------------------------------------------
|
|
10
|
+
# `pack.json`'s `requires` lists these tools too, and nothing checks that the two agree.
|
|
32
11
|
missing=""
|
|
33
12
|
for tool in find grep sed sort cut wc tr; do
|
|
34
13
|
command -v "$tool" >/dev/null 2>&1 || missing="$missing $tool"
|
|
@@ -40,16 +19,6 @@ if [ -n "$missing" ]; then
|
|
|
40
19
|
exit 2
|
|
41
20
|
fi
|
|
42
21
|
|
|
43
|
-
# ---------------------------------------------------------------------------------------------
|
|
44
|
-
# Preconditions fail closed. Enumeration is the precondition here exactly as it is in this project's
|
|
45
|
-
# own recipes (`.portulan/memory/verify-preconditions-fail-closed.md`): a green computed over a
|
|
46
|
-
# directory that was not there is a green about nothing.
|
|
47
|
-
#
|
|
48
|
-
# Both the absent directory and the present-but-empty one are could-not-run rather than vacuously
|
|
49
|
-
# green, and the distinction between them is kept in the MESSAGE rather than in the exit code —
|
|
50
|
-
# a workspace with no workflows has composed a pack that cannot do its job, and should hear that
|
|
51
|
-
# sentence rather than a green it might mistake for coverage.
|
|
52
|
-
# ---------------------------------------------------------------------------------------------
|
|
53
22
|
if [ ! -d "$WORKFLOWS" ]; then
|
|
54
23
|
printf 'actions-pinned: COULD NOT RUN — there is no %s directory in this repository.\n' "$WORKFLOWS" >&2
|
|
55
24
|
printf ' A workspace with no GitHub Actions workflows has nothing for this recipe to check;\n' >&2
|
|
@@ -57,8 +26,6 @@ if [ ! -d "$WORKFLOWS" ]; then
|
|
|
57
26
|
exit 2
|
|
58
27
|
fi
|
|
59
28
|
|
|
60
|
-
# `find` rather than a glob, so a directory holding only subdirectories is not mistaken for one
|
|
61
|
-
# holding workflows. Sorted so the report is stable between runs and between machines.
|
|
62
29
|
files=$(find "$WORKFLOWS" -maxdepth 1 -type f \( -name '*.yml' -o -name '*.yaml' \) | sort)
|
|
63
30
|
|
|
64
31
|
if [ -z "$files" ]; then
|
|
@@ -69,30 +36,21 @@ fi
|
|
|
69
36
|
status=0
|
|
70
37
|
examined=0
|
|
71
38
|
pinned=0
|
|
72
|
-
|
|
39
|
+
exempt=0
|
|
73
40
|
|
|
74
41
|
while IFS= read -r file; do
|
|
75
|
-
# One `uses:` per line
|
|
76
|
-
# spelling would slip past this, which is stated in README.md as a known limit rather than
|
|
77
|
-
# covered by a matcher that would claim more than it reads.
|
|
42
|
+
# One `uses:` per line: a folded or flow-mapping spelling is not seen.
|
|
78
43
|
while IFS= read -r line; do
|
|
79
44
|
value=$(printf '%s\n' "$line" | sed -E 's/^[[:space:]]*-?[[:space:]]*uses:[[:space:]]*//; s/[[:space:]]*(#.*)?$//; s/^["'"'"']//; s/["'"'"']$//')
|
|
80
45
|
[ -n "$value" ] || continue
|
|
81
46
|
|
|
82
|
-
# `examined` counts only references this recipe can actually judge, and the exempt ones are
|
|
83
|
-
# counted separately below. Counting them here made the summary print a ratio like `2 of 3
|
|
84
|
-
# pinned` on a run where every non-exempt reference WAS pinned — a green whose own number
|
|
85
|
-
# looked like a partial pass. Copilot round 2.
|
|
86
47
|
case "$value" in
|
|
87
48
|
./*)
|
|
88
|
-
|
|
89
|
-
# commit to pin, and demanding one would be a check that cannot be satisfied.
|
|
90
|
-
local_refs=$((local_refs + 1))
|
|
49
|
+
exempt=$((exempt + 1))
|
|
91
50
|
continue
|
|
92
51
|
;;
|
|
93
52
|
docker://*)
|
|
94
|
-
|
|
95
|
-
local_refs=$((local_refs + 1))
|
|
53
|
+
exempt=$((exempt + 1))
|
|
96
54
|
continue
|
|
97
55
|
;;
|
|
98
56
|
esac
|
|
@@ -102,10 +60,7 @@ while IFS= read -r file; do
|
|
|
102
60
|
if [ "$ref" = "$value" ]; then
|
|
103
61
|
printf ' UNPINNED %s: `uses: %s` carries no `@ref` at all\n' "$file" "$value" >&2
|
|
104
62
|
status=1
|
|
105
|
-
# Case-insensitive
|
|
106
|
-
# mixed-case SHA is a pinned SHA. Matching lowercase only would have reported a correctly
|
|
107
|
-
# pinned action as unpinned — a FALSE RED, which is the failure mode this project treats as
|
|
108
|
-
# worse than a missed catch, because it is the one that gets a check switched off.
|
|
63
|
+
# Case-insensitive, as hex is: an uppercase SHA is still a pinned one.
|
|
109
64
|
elif printf '%s' "$ref" | grep -Eqi '^[0-9a-f]{40}$'; then
|
|
110
65
|
pinned=$((pinned + 1))
|
|
111
66
|
else
|
|
@@ -120,8 +75,8 @@ count=$(printf '%s\n' "$files" | wc -l | tr -d ' ')
|
|
|
120
75
|
if [ "$status" -eq 0 ]; then
|
|
121
76
|
printf 'actions-pinned: %s of %s `uses:` reference(s) pinned to a full commit SHA across %s workflow file(s)' \
|
|
122
77
|
"$pinned" "$examined" "$count"
|
|
123
|
-
if [ "$
|
|
124
|
-
printf ', %s local or container reference(s) exempt' "$
|
|
78
|
+
if [ "$exempt" -gt 0 ]; then
|
|
79
|
+
printf ', %s local or container reference(s) exempt' "$exempt"
|
|
125
80
|
fi
|
|
126
81
|
printf '\n\nGREEN — verify recipe passed.\n'
|
|
127
82
|
else
|