@natjswenson/devlog 0.13.0 → 0.14.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/CHANGELOG.md +30 -0
- package/README.md +230 -120
- package/SKILL.md +74 -24
- package/bin/devlog.js +108 -6
- package/config.example.json +1 -0
- package/image-style/style-guide.example.md +29 -26
- package/lib/compose_art_cover.mjs +144 -0
- package/lib/config_ops.mjs +1 -0
- package/lib/core.mjs +3 -0
- package/lib/guide_draft.mjs +134 -0
- package/lib/guide_preview.css +3 -0
- package/lib/publish_guide.mjs +124 -0
- package/package.json +4 -3
- package/references/codex-cover-art.md +119 -0
- package/references/concept-guides.md +148 -0
- package/references/cover-spec.md +40 -0
- package/references/guide-publishing.md +245 -0
- package/skill-invariants.json +34 -13
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
# Publishing one concept guide
|
|
2
|
+
|
|
3
|
+
`generationMode` is optional. Its absence and `"release"` retain the existing
|
|
4
|
+
release workflow, config shape and `publish-entry` behavior. Opt in with
|
|
5
|
+
`devlog set generationMode concept`; return with `devlog set generationMode release`.
|
|
6
|
+
The example config explicitly retains release mode. This setting selects the
|
|
7
|
+
agent workflow; it does not turn the legacy publisher into an evidence gate.
|
|
8
|
+
|
|
9
|
+
In concept mode, inspect the scan's genuine, eligible new final releases, then
|
|
10
|
+
choose at most one useful transferable outcome and one release anchor. Draft a
|
|
11
|
+
complete guide for the reader's project, with its exact copyable handoff first.
|
|
12
|
+
Do not manufacture a version/date to create a publishing slot. Verify that the
|
|
13
|
+
selected project/version/date matches the actual release before recording it.
|
|
14
|
+
If no candidate can meet the guide quality bar, publish zero guides and explain
|
|
15
|
+
what evidence or implementation is missing. The helper does not independently
|
|
16
|
+
verify Git tags and does not create a durable suppression ledger for other
|
|
17
|
+
candidates. A later scan can still return them.
|
|
18
|
+
|
|
19
|
+
Run structural lint, reproduce the guide, conduct an independent adaptation
|
|
20
|
+
trial in a disposable original project, and independently check the result.
|
|
21
|
+
Record observed commands/output and reviewer findings locally. For cover art,
|
|
22
|
+
open the full image and thumbnail and record semantic and visual observations
|
|
23
|
+
about the final PNG bytes. Fix blocking findings, regenerate the copy payload
|
|
24
|
+
and rerun affected checks after edits. Prepare these concrete artifacts before
|
|
25
|
+
publication; booleans asserting completion are insufficient.
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
## Complete a normal concept Generate run
|
|
29
|
+
|
|
30
|
+
First read [concept-guides.md](concept-guides.md) for the complete draft, handoff,
|
|
31
|
+
execution and independent adaptation contract. On Codex also read
|
|
32
|
+
[codex-cover-art.md](codex-cover-art.md): generate the reviewed cover with the
|
|
33
|
+
available native image-generation tool and locally compose its typography. Do not
|
|
34
|
+
substitute the legacy SVG workflow on Codex just to finish. On Claude, follow the
|
|
35
|
+
existing local cover workflow and the true-color conversion note in that reference.
|
|
36
|
+
A missing required agent, execution or art capability leaves a local draft with a
|
|
37
|
+
specific blocker; it does not authorize bypassing the evidence gate. Do not adopt
|
|
38
|
+
legacy Generate's optional-cover fallback for a requested concept cover.
|
|
39
|
+
|
|
40
|
+
Use the CLI bundled relative to the loaded SKILL.md only after its read-only
|
|
41
|
+
`--version` invocation succeeds with available runtime dependencies. The commands
|
|
42
|
+
below show that form. If the script or dependencies are missing (including a Git
|
|
43
|
+
plugin install without node_modules), or the installation is standalone, use the
|
|
44
|
+
exact version fallback specified in SKILL.md in place of `node '<skill-root>/bin/devlog.js'`. Replace every placeholder
|
|
45
|
+
with recorded paths or validated config values and quote each shell argument.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
node '<skill-root>/bin/devlog.js' scan --json --summary
|
|
49
|
+
node '<skill-root>/bin/devlog.js' scan --json --project '<selected-project>'
|
|
50
|
+
node '<skill-root>/bin/devlog.js' lint-guide '<article-path>' --voice
|
|
51
|
+
node '<skill-root>/bin/devlog.js' prepare-guide --article '<article-path>' --brand '<brand-json>' --out '<new-preview-directory>'
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Honor an explicit project filter when scanning. Display the selected single
|
|
55
|
+
outcome and genuine project/version/date anchor, including any decision to create
|
|
56
|
+
zero guides. Follow Generate's voice, research, private-source and truthful
|
|
57
|
+
Shipped/Changelog rules; other releases are evidence candidates, not additional
|
|
58
|
+
articles to write. Prepare the guide, actually run its examples and the fresh
|
|
59
|
+
agent adaptation, independently check the result, and inspect the rendered preview.
|
|
60
|
+
Store the reports described below against the final article and exact copied
|
|
61
|
+
payload. An article edit invalidates hash-bound reports; rerun affected work and
|
|
62
|
+
explain the scope of evidence you retain.
|
|
63
|
+
|
|
64
|
+
Generate, persist, compose and inspect cover art using codex-cover-art.md. Then
|
|
65
|
+
prepare a new final preview (these helpers refuse existing output directories):
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
node '<skill-root>/bin/devlog.js' prepare-guide --article '<article-path>' --brand '<brand-json>' --cover '<reviewed-cover.png>' --out '<new-final-preview-directory>'
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Open that preview and the full cover/thumbnail for the user. Confirm the copy
|
|
72
|
+
payload still matches the tested bytes. Hash final artifacts and write the execution,
|
|
73
|
+
adaptation and review reports plus `evidence.json`; these records stay in scratch,
|
|
74
|
+
outside the content repository. They must describe performed work, not planned work.
|
|
75
|
+
|
|
76
|
+
Clone the configured target branch into a new recorded scratch directory. The
|
|
77
|
+
clone root and content root are distinct when `targetDir` is set:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
mktemp -d
|
|
81
|
+
# Record that absolute directory as <run-root> before continuing.
|
|
82
|
+
git clone --depth=1 --branch '<branch>' 'https://github.com/<targetRepo>.git' '<run-root>/site'
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Record the clone, selected anchor and current artifact/report hashes in local
|
|
86
|
+
run-state. `<content-root>` means `<run-root>/site/<targetDir>` when configured,
|
|
87
|
+
otherwise `<run-root>/site`. Keep all Git operations at `<run-root>/site`.
|
|
88
|
+
Review the intended one-article content change, then stage it with the strict CLI:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
node '<skill-root>/bin/devlog.js' publish-guide --clone '<content-root>' --article '<article-path>' --evidence '<evidence-json>' --cover '<reviewed-cover.png>'
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The helper writes validated content only. Normal concept Generate must continue
|
|
95
|
+
through commit, push and deployment verification; do not end the run after this
|
|
96
|
+
command merely because it returned success. If it refuses an occupied or retired
|
|
97
|
+
identity, preserve that identity and report the collision. Do not use publish-entry
|
|
98
|
+
or manual copying to bypass it. Existing-post rewrite is a separate task.
|
|
99
|
+
|
|
100
|
+
Before committing, inspect the content diff and returned `firstEntryForProject`.
|
|
101
|
+
When true, follow SKILL.md Step 5b: register the project in the site's actual route
|
|
102
|
+
registry, build and prove the new route exists, then run relevant site tests.
|
|
103
|
+
For every concept guide, build/test the actual consumer as appropriate and inspect
|
|
104
|
+
the top handoff, code rendering, cover loading, feed thumbnail and link destinations.
|
|
105
|
+
The standalone preview alone does not prove site compatibility. Correct issues and
|
|
106
|
+
rerun relevant checks before push. If correcting article or cover bytes, regenerate
|
|
107
|
+
matching evidence and restart from a fresh clone rather than bypass immutability.
|
|
108
|
+
|
|
109
|
+
Stage only the article, cover, manifest and any required registry change, then
|
|
110
|
+
inspect the staged diff before committing. Use the configured Git identity and
|
|
111
|
+
existing target-repository conventions. Inspect the target repository's instructions
|
|
112
|
+
and branch/CI policy first. Where features must pass through `dev` and promotion,
|
|
113
|
+
create a feature branch from the required base and use that PR path; the configured
|
|
114
|
+
branch is the deployment destination, not permission to push past its policy.
|
|
115
|
+
The direct-push example below applies only when the target policy permits it:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
git -C '<run-root>/site' add -- '<article-relative-path>' '<cover-relative-path>' '<manifest-relative-path>'
|
|
119
|
+
# If needed, separately add the specific reviewed project-registry file.
|
|
120
|
+
git -C '<run-root>/site' diff --cached --stat
|
|
121
|
+
git -C '<run-root>/site' diff --cached
|
|
122
|
+
git -C '<run-root>/site' commit -m 'devlog: publish one concept guide'
|
|
123
|
+
git -C '<run-root>/site' push --no-tags origin '<branch>'
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Record the resulting commit and push outcome. If push fails, retain the clone,
|
|
127
|
+
report the error and stop; do not retry automatically, force-push or discard work.
|
|
128
|
+
After successful push, follow SKILL.md Step 6 for the configured site route. Poll
|
|
129
|
+
its actual article URL roughly every 45 seconds for at most five minutes:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
curl -s -o /dev/null -w '%{http_code}' -L '<actual-published-article-url>'
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
An HTTP 200 alone can be a fallback page: open/read the response to verify this
|
|
136
|
+
article's title and top handoff, then verify the actual cover/thumbnail URLs load
|
|
137
|
+
and inspect the deployed layout. Respect the site's route convention instead of
|
|
138
|
+
assuming a new URL shape. If the route remains absent, inspect registry/build
|
|
139
|
+
results and report it as not live. If `siteUrl` is unset, report pushed but
|
|
140
|
+
unverified with the repository link, not published success. Retain local run-state
|
|
141
|
+
and evidence until the outcome is recorded; never delete scratch before checking
|
|
142
|
+
push/deployment. Finish with the live article link when verified, observed checks,
|
|
143
|
+
and material limitations. No extra approval step is introduced for publication
|
|
144
|
+
already authorized by a normal Generate request; explicit drafts remain drafts.
|
|
145
|
+
|
|
146
|
+
## API and receipt
|
|
147
|
+
|
|
148
|
+
`publishGuide({ cloneDir, articlePath, evidencePath, coverPath? })` is exported
|
|
149
|
+
from `lib/publish_guide.mjs`. `cloneDir` is the existing content root inside the
|
|
150
|
+
publishing clone (including configured `targetDir`). `articlePath` and optional
|
|
151
|
+
`coverPath` are ordinary local paths relative to the invocation directory.
|
|
152
|
+
The API validates all evidence before writing content, then delegates to the
|
|
153
|
+
unchanged `publishEntry`. It never commits or pushes.
|
|
154
|
+
|
|
155
|
+
Evidence JSON schema 1:
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
{
|
|
159
|
+
"schema": 1,
|
|
160
|
+
"anchor": { "project": "example", "version": "v1.2.0", "date": "2026-09-09" },
|
|
161
|
+
"articleSha256": "<SHA-256 of exact article bytes>",
|
|
162
|
+
"agentPrompt": { "path": "agent-prompt.txt", "sha256": "<SHA-256>" },
|
|
163
|
+
"execution": { "path": "execution.json", "sha256": "<SHA-256>" },
|
|
164
|
+
"adaptation": { "path": "adaptation.json", "sha256": "<SHA-256>" },
|
|
165
|
+
"review": { "path": "review.json", "sha256": "<SHA-256>" },
|
|
166
|
+
"coverSha256": "<required only when supplying coverPath>"
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
All SHA-256 values are lowercase 64-character hex strings. Referenced files
|
|
171
|
+
resolve relative to the evidence file, not the current working directory.
|
|
172
|
+
`agent-prompt.txt` must exactly equal the preview helper's copy payload: prompt,
|
|
173
|
+
two newlines, `<reference-guide>`, the trimmed article with the handoff block
|
|
174
|
+
removed, and closing `</reference-guide>`, with the helper's newline placement.
|
|
175
|
+
Use the `prepare-guide` output; do not maintain a second hand-edited payload.
|
|
176
|
+
|
|
177
|
+
Every execution/adaptation/review JSON report must contain these common fields:
|
|
178
|
+
|
|
179
|
+
```json
|
|
180
|
+
{
|
|
181
|
+
"status": "passed",
|
|
182
|
+
"summary": "Concrete observations and scope of this run.",
|
|
183
|
+
"articleSha256": "<same exact article SHA-256>",
|
|
184
|
+
"agentPromptSha256": "<same exact payload SHA-256>"
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
The execution report additionally contains a nonempty `commands` array:
|
|
189
|
+
|
|
190
|
+
```json
|
|
191
|
+
{
|
|
192
|
+
"commands": [
|
|
193
|
+
{
|
|
194
|
+
"command": "node --test",
|
|
195
|
+
"exitCode": 0,
|
|
196
|
+
"output": { "path": "logs/tests.txt", "sha256": "<SHA-256>" }
|
|
197
|
+
}
|
|
198
|
+
]
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Output files resolve relative to the execution report. They must contain actual
|
|
203
|
+
observations and match their hashes. Include each required successful check;
|
|
204
|
+
retain failed attempts separately and describe corrections in the summary.
|
|
205
|
+
Do not invent a successful command or replace actual output with a claim.
|
|
206
|
+
|
|
207
|
+
The adaptation report additionally identifies the starting and resulting
|
|
208
|
+
fixture (paths, immutable revisions, or durable artifact identifiers), and
|
|
209
|
+
records a nonempty list of independently observed checks:
|
|
210
|
+
|
|
211
|
+
```json
|
|
212
|
+
{
|
|
213
|
+
"fixture": { "original": "fixtures/before", "result": "fixtures/after" },
|
|
214
|
+
"independentChecks": [
|
|
215
|
+
{ "check": "Existing public imports", "observation": "No side effects under invalid CLI arguments", "passed": true }
|
|
216
|
+
]
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
The review report additionally contains `reviewer` (nonempty identifier) and
|
|
221
|
+
`blockingFindings: []`. Explain the substantive review in its `summary`; an
|
|
222
|
+
empty findings array alone is not a review. When a cover is supplied, both the
|
|
223
|
+
evidence and review must contain its `coverSha256`, and the review must also
|
|
224
|
+
contain nonempty `coverReview` observations. The decoded cover must be a
|
|
225
|
+
single-frame true-color 1600×900 PNG. Changes to art invalidate its visual review.
|
|
226
|
+
|
|
227
|
+
These are consistency checks on local records. Hashes do not establish that a
|
|
228
|
+
command actually ran, that a reviewer was independent, or that observations are
|
|
229
|
+
correct. The agent must perform and inspect the work before writing the records.
|
|
230
|
+
Do not describe `evidenceValidated: true` as independent execution verification.
|
|
231
|
+
|
|
232
|
+
## Existing posts and failure behavior
|
|
233
|
+
|
|
234
|
+
This command refuses an occupied article, cover, manifest identity, or tombstone.
|
|
235
|
+
Even a manifest entry whose article is absent is occupied; use a deliberate
|
|
236
|
+
editorial repair workflow. Consolidating or rewriting published posts is a
|
|
237
|
+
separate explicitly scoped task that preserves URLs and existing identities.
|
|
238
|
+
There is no force option, migration, or change to old posts in this command.
|
|
239
|
+
|
|
240
|
+
Missing files, stale hashes, lint failures, failed/unobserved checks, anchor
|
|
241
|
+
mismatches and invalid covers fail before content mutation. After validation,
|
|
242
|
+
the existing publisher retains its existing article-then-manifest write behavior;
|
|
243
|
+
a disk failure is not an atomic rollback. Publish serially: neither helper
|
|
244
|
+
provides a multiprocess lock. Keep local evidence private unless deliberately
|
|
245
|
+
reviewed for inclusion in the public repository.
|
package/skill-invariants.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"comment": "Prose guardrails in SKILL.md that must survive edits (the `prose` array
|
|
2
|
+
"comment": "Prose guardrails in SKILL.md that must survive edits (the `prose` array \u2014 each pattern is a case-insensitive regex tested against the full SKILL.md text) and code-level guards elsewhere in this skill's source (the `code` array \u2014 each pattern is tested against the file named by its own `file` field, not SKILL.md). Both are checked by tests/skill_contract.test.mjs. If you intentionally change one, update it here in the same commit and say why in the PR.",
|
|
3
3
|
"prose": [
|
|
4
4
|
{
|
|
5
5
|
"id": "immutable-entries",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
{
|
|
20
20
|
"id": "gotchas-never-invented",
|
|
21
21
|
"pattern": "never invented",
|
|
22
|
-
"rationale": "Gotchas come from real history (fix commits, reverts, changelog)
|
|
22
|
+
"rationale": "Gotchas come from real history (fix commits, reverts, changelog) \u2014 fabricating them breaks the product's honesty."
|
|
23
23
|
},
|
|
24
24
|
{
|
|
25
25
|
"id": "reader-side-verify",
|
|
@@ -64,27 +64,27 @@
|
|
|
64
64
|
{
|
|
65
65
|
"id": "private-project-no-links",
|
|
66
66
|
"pattern": "no post ever[\\s\\S]{0,10}links a commit for it",
|
|
67
|
-
"rationale": "A private project's commits must never scan as public just because remoteMatches + branch-contains happen to hold
|
|
67
|
+
"rationale": "A private project's commits must never scan as public just because remoteMatches + branch-contains happen to hold \u2014 losing this line reopens the dead-link-to-a-private-repo path."
|
|
68
68
|
},
|
|
69
69
|
{
|
|
70
70
|
"id": "cover-composition-scope",
|
|
71
71
|
"pattern": "never the raw draft file, never[\\s\\S]{0,10}## Changelog",
|
|
72
|
-
"rationale": "Cover composition must draw only from title/tags/summary/## Shipped
|
|
72
|
+
"rationale": "Cover composition must draw only from title/tags/summary/## Shipped \u2014 never the raw draft or Changelog \u2014 losing this line reopens off-scope content leaking into an auto-composed image."
|
|
73
73
|
},
|
|
74
74
|
{
|
|
75
|
-
"id": "cover-
|
|
76
|
-
"pattern": "
|
|
77
|
-
"rationale": "A missing/uninstalled style guide must
|
|
75
|
+
"id": "cover-required-before-publish",
|
|
76
|
+
"pattern": "publication is[\\s\\S]{0,5}blocked",
|
|
77
|
+
"rationale": "A missing/uninstalled style guide must stop the release so Generate mode cannot publish an entry without its required cover."
|
|
78
78
|
},
|
|
79
79
|
{
|
|
80
80
|
"id": "cover-review-gate",
|
|
81
81
|
"pattern": "this interactive review IS the quality gate for the cover",
|
|
82
|
-
"rationale": "The rendered cover must be shown to the user before push, the same way Step 4 gates the prose
|
|
82
|
+
"rationale": "The rendered cover must be shown to the user before push, the same way Step 4 gates the prose \u2014 losing this line reopens publishing an unreviewed cover."
|
|
83
83
|
},
|
|
84
84
|
{
|
|
85
85
|
"id": "ground-truth-gate",
|
|
86
86
|
"pattern": "verify each one with a git command run NOW",
|
|
87
|
-
"rationale": "The 6-run audit found a post that published a provably false premise about the author's own repo (resume/v1.0.1: 'two of four packages never got tags'
|
|
87
|
+
"rationale": "The 6-run audit found a post that published a provably false premise about the author's own repo (resume/v1.0.1: 'two of four packages never got tags' \u2014 all four existed). Every repo-fact claim must be re-verified against git in-session before publish; losing this line reopens the fabricated-premise path."
|
|
88
88
|
},
|
|
89
89
|
{
|
|
90
90
|
"id": "no-unrun-output",
|
|
@@ -104,7 +104,17 @@
|
|
|
104
104
|
{
|
|
105
105
|
"id": "cover-custom-illustration",
|
|
106
106
|
"pattern": "cover that just re-renders the title in large text is a failure",
|
|
107
|
-
"rationale": "First shipped version of this feature produced a shared text-heavy template with a rotating stock shape
|
|
107
|
+
"rationale": "First shipped version of this feature produced a shared text-heavy template with a rotating stock shape \u2014 rejected as bland/repetitive. Losing this line reopens that regression. Independent of, not superseded by, the v0.9.0 geometry guard (cover-catalog-hero-overlap-guard, below): that guard is a mechanical check on an agent's rendered composition each time a cover is rendered; this line is a prose guardrail against a future SKILL.md/style-guide edit silently reintroducing the bland-template regression at the instruction level. Two different regression surfaces, both still worth guarding."
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"id": "concept-draft-only",
|
|
111
|
+
"pattern": "draft-only; never fall through to Generate or publish-entry",
|
|
112
|
+
"rationale": "Explicit concept requests must not fall into automatic release publication."
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"id": "native-art-no-implicit-fallback",
|
|
116
|
+
"pattern": "No implicit API fallback",
|
|
117
|
+
"rationale": "Optional Codex art must not create a new paid dependency or silently invoke a fallback."
|
|
108
118
|
}
|
|
109
119
|
],
|
|
110
120
|
"code": [
|
|
@@ -112,7 +122,7 @@
|
|
|
112
122
|
"id": "cover-catalog-hero-overlap-guard",
|
|
113
123
|
"file": "lib/render_cover.mjs",
|
|
114
124
|
"pattern": "(?:getBoundingClientRect[\\s\\S]{0,400}hero-zone|hero-zone[\\s\\S]{0,400}getBoundingClientRect)",
|
|
115
|
-
"rationale": "The catalog-icon/hero-zone overlap check must stay wired into renderCoverImage()
|
|
125
|
+
"rationale": "The catalog-icon/hero-zone overlap check must stay wired into renderCoverImage() \u2014 losing it silently reopens the gap where a catalog icon (or two, connected by a line) can stand in for the required bespoke hero illustration."
|
|
116
126
|
}
|
|
117
127
|
],
|
|
118
128
|
"cli_commands_referenced": [
|
|
@@ -128,7 +138,10 @@
|
|
|
128
138
|
"render-cover",
|
|
129
139
|
"tombstone",
|
|
130
140
|
"sync-entry",
|
|
131
|
-
"assemble-post"
|
|
141
|
+
"assemble-post",
|
|
142
|
+
"lint-guide",
|
|
143
|
+
"prepare-guide",
|
|
144
|
+
"compose-art-cover"
|
|
132
145
|
],
|
|
133
146
|
"_baseline_comment": "Baseline eval sets: deterministic, offline, $0 checks pinned against artifacts from real local runs. These gate `ci / devlog` alongside the unit tests. Every entry names the test that enforces it so tools/lint_baseline.py can verify the declaration is not aspirational.",
|
|
134
147
|
"baseline": [
|
|
@@ -138,7 +151,15 @@
|
|
|
138
151
|
"test": "tests/baseline.test.mjs",
|
|
139
152
|
"corpus_glob": "evals/baseline/published/*.md",
|
|
140
153
|
"min_corpus": 8,
|
|
141
|
-
"rationale": "tests/lint_post.test.mjs unit-tests each rule against small crafted inputs and tests/evals.test.mjs drives the good/bad/irreproducible fixtures through the judge. All of those are hand-authored to exercise the rules; none answers whether the linter still accepts the real thing. evals/baseline/published/ holds eight entries copied verbatim from natejswenson.io
|
|
154
|
+
"rationale": "tests/lint_post.test.mjs unit-tests each rule against small crafted inputs and tests/evals.test.mjs drives the good/bad/irreproducible fixtures through the judge. All of those are hand-authored to exercise the rules; none answers whether the linter still accepts the real thing. evals/baseline/published/ holds eight entries copied verbatim from natejswenson.io \u2014 posts that went through the full pipeline, were reviewed, and are live \u2014 so 'this passes' means 'a human shipped this and stands behind it'. A rule that grows too strict starts rejecting work like this, and the cost lands at publish time on a real release. Deliberately a CURATED subset: of 61 published entries only 17 satisfy today's contract, the rest predating rules that landed later (the 5-10 tags-count range especially). Those are stale, not bad \u2014 asserting over all 61 would encode 'the linter must accept its own history', a different and wrong requirement. Paired negative assertions (bad-post.md must still produce findings; the three required-section rules must still fire) stop the corpus passing vacuously against a linter that returned nothing."
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"id": "real-concept-handoff",
|
|
158
|
+
"kind": "corpus",
|
|
159
|
+
"test": "tests/guide_draft.test.mjs",
|
|
160
|
+
"corpus_glob": "tests/fixtures/guide/*.md",
|
|
161
|
+
"min_corpus": 1,
|
|
162
|
+
"rationale": "Frozen ESM consolidation pilot that completed an independent ledger-project adaptation. Exact full-payload and clipboard tests plus malformed-handoff mutations retain its delivery contract; this does not claim future semantic review passed."
|
|
142
163
|
}
|
|
143
164
|
]
|
|
144
165
|
}
|