@sleepy_panda_srl/portulan 0.4.0 → 0.4.1
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 +4 -3
- package/cli/README.md +1 -1
- package/cli/drills.mjs +2 -2
- package/cli/finish.mjs +1 -0
- package/cli/form.mjs +1 -1
- package/cli/portulan.mjs +7 -2
- package/cli/vendor.mjs +3 -1
- package/evals/releases/0.4.1.json +154 -0
- package/evals/releases/0.4.1.md +69 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,13 +20,13 @@ workspaces and premium packs delivered as private-marketplace plugins.
|
|
|
20
20
|
|
|
21
21
|
## Status
|
|
22
22
|
|
|
23
|
-
**Current release: `0.4.
|
|
23
|
+
**Current release: `0.4.1`** — recorded in [`CHANGELOG.md`](CHANGELOG.md), which is also the honest
|
|
24
24
|
account of what the release does *not* contain.
|
|
25
25
|
|
|
26
26
|
This is pre-release software. The leading `0.` is meant literally: nothing here is stable yet, and
|
|
27
27
|
the surface may change between minor versions. What is authored today is the engine in [`core/`](core/),
|
|
28
28
|
the Workspace Definition in [`spec/`](spec/), two complete workspaces, the CLI in [`cli/`](cli/) with
|
|
29
|
-
|
|
29
|
+
every subcommand, the enforcement compiler, the memory lifecycle and the plugin packaging. The remaining directories
|
|
30
30
|
fill in milestone by milestone; [`docs/plan.md`](docs/plan.md) is the living map of that work.
|
|
31
31
|
|
|
32
32
|
The repository is **public** — reading, cloning, forking and installing the plugin need no account of
|
|
@@ -131,8 +131,9 @@ commit, refusing any packed file that differs from its source.
|
|
|
131
131
|
| [`upgrade`](cli/upgrade.mjs) | Migrate a workspace across Workspace Definition versions |
|
|
132
132
|
| [`new`](cli/new.mjs) | Scaffold a skill, persona, pack, workspace, gate policy or repo card |
|
|
133
133
|
| [`feedback`](cli/feedback.mjs) | File a bug, improvement or feedback issue you previewed first |
|
|
134
|
+
| [`finish`](cli/finish.mjs) | Close a change in one call: commit and push only when every verify recipe passes |
|
|
134
135
|
|
|
135
|
-
Beside
|
|
136
|
+
Beside these sit tools that are deliberately not subcommands, and the compiled-hook runners, which
|
|
136
137
|
are not subcommands at all. [`cli/README.md`](cli/README.md), rendered from the code, lists that wider roster.
|
|
137
138
|
|
|
138
139
|
## Repository layout
|
package/cli/README.md
CHANGED
|
@@ -29,6 +29,7 @@ in [`../.portulan/verify/`](../.portulan/verify/), and its operator tooling in
|
|
|
29
29
|
| [`upgrade.mjs`](upgrade.mjs) | `portulan upgrade`: migrate a workspace: the Workspace Definition steps it owes, and the repairs a rewriter owes it. |
|
|
30
30
|
| [`new.mjs`](new.mjs) | `portulan new`: scaffold a skill, persona, pack, workspace, gate policy or repo card from a core template. |
|
|
31
31
|
| [`feedback.mjs`](feedback.mjs) | `portulan feedback`: file an issue from a report you previewed, seam-scanned before it leaves the machine. |
|
|
32
|
+
| [`finish.mjs`](finish.mjs) | `portulan finish`: close a change in one call, committing and pushing only when every verify recipe passes. |
|
|
32
33
|
|
|
33
34
|
### Hook runners
|
|
34
35
|
|
|
@@ -58,7 +59,6 @@ Run as `node cli/<file>.mjs`, or imported by the files above.
|
|
|
58
59
|
| [`discover.mjs`](discover.mjs) | Host plugin-cache discovery: reads a host's installed-plugin record to resolve a pointer and find pack roots. |
|
|
59
60
|
| [`drills.mjs`](drills.mjs) | The forced-red drill harness — every rail broken on purpose, and required to fire. |
|
|
60
61
|
| [`eval-bundle.mjs`](eval-bundle.mjs) | Cut a named-recipient evaluation bundle of Portulan from a commit. Not shipped. |
|
|
61
|
-
| [`finish.mjs`](finish.mjs) | The finishing command — one call closes a change: its recipes, its changelog fragment, its commit, its push. |
|
|
62
62
|
| [`form.mjs`](form.mjs) | `form` — which form a consumer's records and boot are in, and the files that move them to the new one. |
|
|
63
63
|
| [`frontmatter.mjs`](frontmatter.mjs) | Flat frontmatter for plugin components and host bindings. |
|
|
64
64
|
| [`fuzz-shell.mjs`](fuzz-shell.mjs) | Grammar-aware fuzzing over this repository's two shell segmenters. |
|
package/cli/drills.mjs
CHANGED
|
@@ -271,7 +271,7 @@ export const DRILLS = [
|
|
|
271
271
|
rail: "pack-identity",
|
|
272
272
|
perturb: {
|
|
273
273
|
file: "README.md",
|
|
274
|
-
find: "**Current release: `0.4.
|
|
274
|
+
find: "**Current release: `0.4.1`**",
|
|
275
275
|
replace: "**Current release: `0.1.3`** <!-- the drill edited this and did not stage it -->",
|
|
276
276
|
},
|
|
277
277
|
stage: false,
|
|
@@ -355,7 +355,7 @@ export const DRILLS = [
|
|
|
355
355
|
rail: "version-carriers",
|
|
356
356
|
perturb: {
|
|
357
357
|
file: "README.md",
|
|
358
|
-
find: "**Current release: `0.4.
|
|
358
|
+
find: "**Current release: `0.4.1`**",
|
|
359
359
|
replace: "**Current release: `0.1.3`**",
|
|
360
360
|
},
|
|
361
361
|
// Staged: this rail reads the index (`git show :<path>`), so an unstaged edit is invisible to it.
|
package/cli/finish.mjs
CHANGED
|
@@ -28,6 +28,7 @@ const GIT_TIMEOUT_MS = 2 * 60 * 1000;
|
|
|
28
28
|
const USAGE = [
|
|
29
29
|
"usage: node cli/finish.mjs -m <subject> [-m <paragraph>]... [options]",
|
|
30
30
|
" node cli/finish.mjs -F <file | -> [options]",
|
|
31
|
+
" portulan finish <the same arguments>, where the package is installed",
|
|
31
32
|
"",
|
|
32
33
|
" -m <text> a paragraph of the commit message, the first its subject, as git takes -m",
|
|
33
34
|
" -F <file | -> the whole commit message, from a file or from standard input",
|
package/cli/form.mjs
CHANGED
|
@@ -543,7 +543,7 @@ export function draftCard(manifest, read, { workspace, inTree, repoCards = [] })
|
|
|
543
543
|
}
|
|
544
544
|
section(
|
|
545
545
|
"Records",
|
|
546
|
-
'Close a change with `git add <new files> &&
|
|
546
|
+
'Close a change with `git add <new files> && portulan finish -m "<subject>" -m "<why>"` after writing its changelog entry, a one-bullet file `changes/<slug>.<section>.md`: it commits and pushes only when every verify recipe passes. Where `portulan` is not on the path, run `npx @sleepy_panda_srl/portulan finish` instead, and do not search the disk for it.',
|
|
547
547
|
...(slots.handoffs ? [`A session ending with work not committed and pushed leaves a dated handoff in ${shown(slots.handoffs)}.`] : []),
|
|
548
548
|
);
|
|
549
549
|
section(
|
package/cli/portulan.mjs
CHANGED
|
@@ -55,6 +55,11 @@ export const SUBCOMMANDS = [
|
|
|
55
55
|
module: "feedback.mjs",
|
|
56
56
|
summary: "file an issue from a report you previewed, seam-scanned before it leaves the machine",
|
|
57
57
|
},
|
|
58
|
+
{
|
|
59
|
+
name: "finish",
|
|
60
|
+
module: "finish.mjs",
|
|
61
|
+
summary: "close a change in one call, committing and pushing only when every verify recipe passes",
|
|
62
|
+
},
|
|
58
63
|
];
|
|
59
64
|
|
|
60
65
|
export function find(name) {
|
|
@@ -77,8 +82,8 @@ export function usage() {
|
|
|
77
82
|
"",
|
|
78
83
|
"Exit codes: 0 succeeded · 1 a red verdict · 2 could not run.",
|
|
79
84
|
"",
|
|
80
|
-
"Other tools live in cli/ and are deliberately not here — docs/vision.md names these
|
|
81
|
-
"
|
|
85
|
+
"Other tools live in cli/ and are deliberately not here — docs/vision.md names these subcommands",
|
|
86
|
+
"and is human-owned, so another is the maintainer's call. cli/README.md lists them.",
|
|
82
87
|
);
|
|
83
88
|
return lines.join("\n");
|
|
84
89
|
}
|
package/cli/vendor.mjs
CHANGED
|
@@ -540,7 +540,9 @@ export function agentsMd(manifest, host, kernel = null, guidance = null) {
|
|
|
540
540
|
"- **A resolved pointer.** Nothing here fetches anything.",
|
|
541
541
|
...(cardText?.includes("<plugin root>")
|
|
542
542
|
? ["- **The Portulan package.** The card's `<plugin root>` is where it is installed, which this copy is not."]
|
|
543
|
-
:
|
|
543
|
+
: cardText?.includes("portulan finish")
|
|
544
|
+
? ["- **The Portulan package.** The card's `portulan finish` runs from it, and this copy does not carry it."]
|
|
545
|
+
: []),
|
|
544
546
|
"",
|
|
545
547
|
"Run `portulan doctor .portulan` to see where this stands.",
|
|
546
548
|
"",
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
{
|
|
2
|
+
"portulan": {
|
|
3
|
+
"releaseEval": "1"
|
|
4
|
+
},
|
|
5
|
+
"version": "0.4.1",
|
|
6
|
+
"captured": "2026-11-11",
|
|
7
|
+
"source": {
|
|
8
|
+
"commit": "a83966a56af78bd76a63c48afdce457aa3c5b0d5",
|
|
9
|
+
"clean": true
|
|
10
|
+
},
|
|
11
|
+
"host": {
|
|
12
|
+
"node": "v26.13.0",
|
|
13
|
+
"platform": "darwin"
|
|
14
|
+
},
|
|
15
|
+
"recipes": [
|
|
16
|
+
{
|
|
17
|
+
"id": "cache-stability",
|
|
18
|
+
"exit": 0
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": "docs",
|
|
22
|
+
"exit": 0
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"id": "json",
|
|
26
|
+
"exit": 0
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "doctor",
|
|
30
|
+
"exit": 0
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"id": "tests",
|
|
34
|
+
"exit": 0
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"id": "plugin",
|
|
38
|
+
"exit": 0
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"id": "compile",
|
|
42
|
+
"exit": 0
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"id": "workflow-filters",
|
|
46
|
+
"exit": 0
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"id": "index",
|
|
50
|
+
"exit": 0
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"id": "context",
|
|
54
|
+
"exit": 0
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"id": "ledger",
|
|
58
|
+
"exit": 0
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"id": "control-chars",
|
|
62
|
+
"exit": 0
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"id": "comments",
|
|
66
|
+
"exit": 0
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"id": "rule-carriers",
|
|
70
|
+
"exit": 0
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"id": "pack-version",
|
|
74
|
+
"exit": 0
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"id": "pack-identity",
|
|
78
|
+
"exit": 0
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"id": "payload",
|
|
82
|
+
"exit": 0
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"id": "eval-bundle",
|
|
86
|
+
"exit": 0
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"id": "goldens",
|
|
90
|
+
"exit": 0
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"id": "mutants",
|
|
94
|
+
"exit": 0
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"id": "fuzz-shell",
|
|
98
|
+
"exit": 0
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"id": "version-carriers",
|
|
102
|
+
"exit": 0
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"id": "skill-goldens",
|
|
106
|
+
"exit": 0
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"id": "review-loop",
|
|
110
|
+
"exit": 0
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"id": "telemetry",
|
|
114
|
+
"exit": 0
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"id": "drills",
|
|
118
|
+
"exit": 0
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"id": "ab",
|
|
122
|
+
"exit": 0
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"id": "ab-grade",
|
|
126
|
+
"exit": 0
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"id": "ab-run",
|
|
130
|
+
"exit": 0
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"id": "tools/github:actions-pinned",
|
|
134
|
+
"exit": 0
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"id": "tools/local-llm:runner-rails",
|
|
138
|
+
"exit": 0
|
|
139
|
+
}
|
|
140
|
+
],
|
|
141
|
+
"excluded": [
|
|
142
|
+
{
|
|
143
|
+
"id": "release-eval",
|
|
144
|
+
"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."
|
|
145
|
+
}
|
|
146
|
+
],
|
|
147
|
+
"abBaseline": {
|
|
148
|
+
"snapshot": "evals/ab/baseline.json",
|
|
149
|
+
"register": "evals/ab/baseline.md",
|
|
150
|
+
"captured": "2026-08-31T09:05:32.699Z",
|
|
151
|
+
"commit": "a642d551eec6c146c67ef0acfe3f8ba535c5ce6e",
|
|
152
|
+
"clean": false
|
|
153
|
+
}
|
|
154
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Eval result — Portulan 0.4.1
|
|
2
|
+
|
|
3
|
+
> **Generated. Do not edit.** Rendered from [`evals/releases/0.4.1.json`](0.4.1.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.4.1` |
|
|
10
|
+
| Captured | 2026-11-11 |
|
|
11
|
+
| Commit | `a83966a56af78bd76a63c48afdce457aa3c5b0d5` |
|
|
12
|
+
| Tree at capture | clean |
|
|
13
|
+
| Node | `v26.13.0` |
|
|
14
|
+
| Platform | `darwin` |
|
|
15
|
+
|
|
16
|
+
## The rails, and what each returned
|
|
17
|
+
|
|
18
|
+
31 of the 32 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
|
+
| `cache-stability` | green |
|
|
23
|
+
| `docs` | green |
|
|
24
|
+
| `json` | green |
|
|
25
|
+
| `doctor` | green |
|
|
26
|
+
| `tests` | green |
|
|
27
|
+
| `plugin` | green |
|
|
28
|
+
| `compile` | green |
|
|
29
|
+
| `workflow-filters` | green |
|
|
30
|
+
| `index` | green |
|
|
31
|
+
| `context` | green |
|
|
32
|
+
| `ledger` | green |
|
|
33
|
+
| `control-chars` | green |
|
|
34
|
+
| `comments` | green |
|
|
35
|
+
| `rule-carriers` | green |
|
|
36
|
+
| `pack-version` | green |
|
|
37
|
+
| `pack-identity` | green |
|
|
38
|
+
| `payload` | green |
|
|
39
|
+
| `eval-bundle` | green |
|
|
40
|
+
| `goldens` | green |
|
|
41
|
+
| `mutants` | green |
|
|
42
|
+
| `fuzz-shell` | green |
|
|
43
|
+
| `version-carriers` | green |
|
|
44
|
+
| `skill-goldens` | green |
|
|
45
|
+
| `review-loop` | green |
|
|
46
|
+
| `telemetry` | green |
|
|
47
|
+
| `drills` | green |
|
|
48
|
+
| `ab` | green |
|
|
49
|
+
| `ab-grade` | green |
|
|
50
|
+
| `ab-run` | green |
|
|
51
|
+
| `tools/github:actions-pinned` | green |
|
|
52
|
+
| `tools/local-llm:runner-rails` | green |
|
|
53
|
+
|
|
54
|
+
**`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.
|
|
55
|
+
|
|
56
|
+
## The A/B baseline this release ships against
|
|
57
|
+
|
|
58
|
+
[`evals/ab/baseline.md`](https://github.com/sleepy-panda-srl/portulan/blob/v0.4.1/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**.
|
|
59
|
+
|
|
60
|
+
**Its figures are not repeated here.** They have one carrier and this is not it.
|
|
61
|
+
|
|
62
|
+
## What this record does not establish
|
|
63
|
+
|
|
64
|
+
- **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.
|
|
65
|
+
- **The recipes were not run at the tag.** They ran at `a83966a56af78bd76a63c48afdce457aa3c5b0d5`, 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.
|
|
66
|
+
- **`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.
|
|
67
|
+
- **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.
|
|
68
|
+
- **The tree was clean at capture**, so the commit named above is what was measured.
|
|
69
|
+
- **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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sleepy_panda_srl/portulan",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
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",
|