@ersbeth/codelife 0.0.0-bootstrap.0 → 0.11.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.
Files changed (214) hide show
  1. package/.claude-plugin/plugin.json +19 -0
  2. package/LICENSE +21 -0
  3. package/README.md +66 -0
  4. package/agents/evaluate.md +97 -0
  5. package/agents/ground.md +49 -0
  6. package/agents/implementer.md +49 -0
  7. package/agents/judge.md +128 -0
  8. package/agents/planner.md +45 -0
  9. package/agents/prerequisites.md +62 -0
  10. package/agents/reader.md +40 -0
  11. package/agents/reproduce.md +65 -0
  12. package/bin/codelife +4 -0
  13. package/package.json +40 -1
  14. package/presets/tsconfig.json +14 -0
  15. package/presets/vite.config.d.mts +3 -0
  16. package/presets/vite.config.mjs +49 -0
  17. package/scripts/audit/cadence.mjs +24 -0
  18. package/scripts/audit/close.mjs +57 -0
  19. package/scripts/audit/file.mjs +70 -0
  20. package/scripts/audit/fold.mjs +48 -0
  21. package/scripts/audit/lib.mjs +93 -0
  22. package/scripts/audit/prepare.mjs +180 -0
  23. package/scripts/audit/table.mjs +65 -0
  24. package/scripts/brainstorm/decided.mjs +6 -0
  25. package/scripts/brainstorm/lib.mjs +33 -0
  26. package/scripts/brainstorm/named.mjs +9 -0
  27. package/scripts/changelog.mjs +100 -0
  28. package/scripts/check-tag.mjs +19 -0
  29. package/scripts/checks.mjs +53 -0
  30. package/scripts/codelife.mjs +42 -0
  31. package/scripts/commit-msg.mjs +43 -0
  32. package/scripts/contract.mjs +179 -0
  33. package/scripts/former-form.mjs +170 -0
  34. package/scripts/git/branches.mjs +6 -0
  35. package/scripts/git/commit.mjs +40 -0
  36. package/scripts/git/diff.mjs +17 -0
  37. package/scripts/git/diff_lines.mjs +5 -0
  38. package/scripts/git/held.mjs +53 -0
  39. package/scripts/git/is_ancestor.mjs +28 -0
  40. package/scripts/git/lib.mjs +20 -0
  41. package/scripts/git/log_since.mjs +27 -0
  42. package/scripts/git/parent.mjs +51 -0
  43. package/scripts/git/show.mjs +4 -0
  44. package/scripts/git/status.mjs +25 -0
  45. package/scripts/git/submodules.mjs +5 -0
  46. package/scripts/init.mjs +21 -0
  47. package/scripts/install.mjs +32 -0
  48. package/scripts/lenses/A11Y.md +91 -0
  49. package/scripts/lenses/ARCH.md +90 -0
  50. package/scripts/lenses/BUG.md +52 -0
  51. package/scripts/lenses/BUILD.md +40 -0
  52. package/scripts/lenses/COMPAT.md +67 -0
  53. package/scripts/lenses/CONF.md +49 -0
  54. package/scripts/lenses/DEPS.md +43 -0
  55. package/scripts/lenses/DOC.md +73 -0
  56. package/scripts/lenses/FAIL.md +57 -0
  57. package/scripts/lenses/GOV.md +56 -0
  58. package/scripts/lenses/GUARD.md +47 -0
  59. package/scripts/lenses/INTENT.md +52 -0
  60. package/scripts/lenses/LEAN.md +49 -0
  61. package/scripts/lenses/LINES.md +48 -0
  62. package/scripts/lenses/PERF.md +61 -0
  63. package/scripts/lenses/PKG.md +58 -0
  64. package/scripts/lenses/SEC.md +49 -0
  65. package/scripts/lenses/STANDARDS.md +62 -0
  66. package/scripts/lenses/TYPE.md +56 -0
  67. package/scripts/lenses/VERIF.md +81 -0
  68. package/scripts/link.mjs +40 -0
  69. package/scripts/methods/cause.md +21 -0
  70. package/scripts/methods/comments.md +157 -0
  71. package/scripts/methods/description.md +67 -0
  72. package/scripts/methods/message.md +24 -0
  73. package/scripts/methods/red-green.md +28 -0
  74. package/scripts/methods/refusal.md +22 -0
  75. package/scripts/mr/open.mjs +219 -0
  76. package/scripts/node-floor.mjs +19 -0
  77. package/scripts/onboard/prep.mjs +93 -0
  78. package/scripts/overview/codelife-line.mjs +33 -0
  79. package/scripts/overview/next.mjs +76 -0
  80. package/scripts/overview/overview.mjs +308 -0
  81. package/scripts/package-manager.mjs +20 -0
  82. package/scripts/port/item.mjs +94 -0
  83. package/scripts/port/lib.mjs +194 -0
  84. package/scripts/port/prep.mjs +33 -0
  85. package/scripts/port/version.mjs +50 -0
  86. package/scripts/pre-commit.mjs +43 -0
  87. package/scripts/pre-push.mjs +53 -0
  88. package/scripts/prepare-lib.mjs +81 -0
  89. package/scripts/read-roadmap/lib.mjs +116 -0
  90. package/scripts/read-roadmap/moved.mjs +70 -0
  91. package/scripts/read-roadmap/range.mjs +15 -0
  92. package/scripts/release/cut.mjs +120 -0
  93. package/scripts/release/entry.mjs +52 -0
  94. package/scripts/release/lib.mjs +136 -0
  95. package/scripts/release/prep.mjs +58 -0
  96. package/scripts/review-mr/prepare.mjs +163 -0
  97. package/scripts/roadmap/assemble.mjs +269 -0
  98. package/scripts/roadmap/cut.mjs +88 -0
  99. package/scripts/roadmap/prepare.mjs +249 -0
  100. package/scripts/roadmap/roadmap.md +30 -0
  101. package/scripts/roadmap/write.mjs +53 -0
  102. package/scripts/search.mjs +29 -0
  103. package/scripts/setup/contract.mjs +25 -0
  104. package/scripts/setup/item.mjs +166 -0
  105. package/scripts/setup/lib.mjs +205 -0
  106. package/scripts/setup/prep.mjs +106 -0
  107. package/scripts/spec-form.mjs +444 -0
  108. package/scripts/spec.mjs +56 -0
  109. package/scripts/tags.mjs +27 -0
  110. package/scripts/target/target-app.md +134 -0
  111. package/scripts/target/target-base.md +127 -0
  112. package/scripts/target/target-lib.md +143 -0
  113. package/scripts/target/templates/audit/README.md +21 -0
  114. package/scripts/target/templates/characterisation/bundle.test.ts +43 -0
  115. package/scripts/target/templates/characterisation/declarations.test.ts +44 -0
  116. package/scripts/target/templates/characterisation/entries.ts +50 -0
  117. package/scripts/target/templates/characterisation/examples.test.ts +18 -0
  118. package/scripts/target/templates/characterisation/import.test.ts +22 -0
  119. package/scripts/target/templates/characterisation/surface.test.ts +68 -0
  120. package/scripts/target/templates/cliff.toml +61 -0
  121. package/scripts/target/templates/githooks/commit-msg +9 -0
  122. package/scripts/target/templates/githooks/pre-commit +9 -0
  123. package/scripts/target/templates/githooks/pre-push +9 -0
  124. package/scripts/target/templates/playground/index.html +11 -0
  125. package/scripts/target/templates/playground/main.ts +9 -0
  126. package/scripts/target/templates/spec/README.md +35 -0
  127. package/scripts/target/templates/spec/capability.md +36 -0
  128. package/scripts/target/templates/spec/glossary.md +5 -0
  129. package/scripts/target/templates/spec/journey.md +29 -0
  130. package/scripts/target/templates/spec/principles.md +15 -0
  131. package/scripts/target/templates/spec/users.md +15 -0
  132. package/scripts/target/templates/tsconfig.json +9 -0
  133. package/scripts/target/templates/vite.config.ts +4 -0
  134. package/scripts/text.mjs +6 -0
  135. package/scripts/tracker/account.mjs +5 -0
  136. package/scripts/tracker/auth.mjs +9 -0
  137. package/scripts/tracker/cli.version.mjs +5 -0
  138. package/scripts/tracker/close.mjs +20 -0
  139. package/scripts/tracker/create.mjs +47 -0
  140. package/scripts/tracker/issue.section.mjs +25 -0
  141. package/scripts/tracker/issue.update.mjs +13 -0
  142. package/scripts/tracker/issue.view.mjs +16 -0
  143. package/scripts/tracker/lib.mjs +130 -0
  144. package/scripts/tracker/list.mjs +14 -0
  145. package/scripts/tracker/list.whole.mjs +20 -0
  146. package/scripts/tracker/lot.row.mjs +42 -0
  147. package/scripts/tracker/mr.checkout_command.mjs +5 -0
  148. package/scripts/tracker/mr.comments.mjs +50 -0
  149. package/scripts/tracker/mr.create.mjs +12 -0
  150. package/scripts/tracker/mr.description.mjs +8 -0
  151. package/scripts/tracker/mr.fetch_head.mjs +5 -0
  152. package/scripts/tracker/mr.find_for_branch.mjs +9 -0
  153. package/scripts/tracker/mr.post.mjs +40 -0
  154. package/scripts/tracker/mr.update_description.mjs +8 -0
  155. package/scripts/tracker/mr.verdict.mjs +34 -0
  156. package/scripts/tracker/mr.view.mjs +20 -0
  157. package/scripts/tracker/none.mjs +79 -0
  158. package/scripts/tracker/note.mjs +12 -0
  159. package/scripts/tracker/reopen.mjs +8 -0
  160. package/scripts/tracker/search.mjs +8 -0
  161. package/scripts/tracker/search_id.mjs +18 -0
  162. package/scripts/tracker/templates/bug.md +35 -0
  163. package/scripts/tracker/templates/feature.md +40 -0
  164. package/scripts/tracker/templates/lot.md +46 -0
  165. package/scripts/tracker/title.join.mjs +6 -0
  166. package/scripts/tracker/title.leave.mjs +7 -0
  167. package/scripts/tracker/title.lot_of.mjs +8 -0
  168. package/scripts/tracker/title.search_id_filter.mjs +17 -0
  169. package/scripts/tracker/title.sentence_of.mjs +5 -0
  170. package/scripts/tracker/view.mjs +25 -0
  171. package/scripts/verbs.mjs +579 -0
  172. package/scripts/verify/BUILD.mjs +33 -0
  173. package/scripts/verify/DEPS.mjs +15 -0
  174. package/scripts/verify/GOV.mjs +34 -0
  175. package/scripts/verify/GUARD.mjs +34 -0
  176. package/scripts/verify/LINES.mjs +22 -0
  177. package/scripts/verify/PKG.mjs +56 -0
  178. package/scripts/verify/TYPE.mjs +34 -0
  179. package/scripts/verify/cut.mjs +73 -0
  180. package/scripts/verify/history.mjs +32 -0
  181. package/scripts/verify/lib.mjs +129 -0
  182. package/scripts/verify/report.mjs +104 -0
  183. package/scripts/verify/timing.mjs +19 -0
  184. package/scripts/verify.mjs +29 -0
  185. package/scripts/work/branch.mjs +81 -0
  186. package/scripts/work/close.mjs +74 -0
  187. package/scripts/work/member.mjs +73 -0
  188. package/scripts/work/prepare.mjs +116 -0
  189. package/scripts/work/reopen.mjs +40 -0
  190. package/scripts/work-feedback/prepare.mjs +96 -0
  191. package/skills/audit/SKILL.md +110 -0
  192. package/skills/audit/templates/index.md +36 -0
  193. package/skills/audit/templates/lens.md +44 -0
  194. package/skills/brainstorm/SKILL.md +144 -0
  195. package/skills/brainstorm/references/exit.md +57 -0
  196. package/skills/brainstorm/templates/note.md +79 -0
  197. package/skills/commit/SKILL.md +68 -0
  198. package/skills/mr/SKILL.md +82 -0
  199. package/skills/new-issue/SKILL.md +87 -0
  200. package/skills/onboard/SKILL.md +103 -0
  201. package/skills/onboard/templates/CLAUDE.md +31 -0
  202. package/skills/onboard/templates/CONTRIBUTING.md +34 -0
  203. package/skills/onboard/templates/README.md +30 -0
  204. package/skills/onboard/templates/SKILL.md +24 -0
  205. package/skills/onboard/templates/package-CLAUDE.md +15 -0
  206. package/skills/overview/SKILL.md +59 -0
  207. package/skills/port-toolchain/SKILL.md +127 -0
  208. package/skills/release/SKILL.md +78 -0
  209. package/skills/review-mr/SKILL.md +106 -0
  210. package/skills/review-mr/templates/pass.md +29 -0
  211. package/skills/roadmap/SKILL.md +137 -0
  212. package/skills/setup/SKILL.md +112 -0
  213. package/skills/work/SKILL.md +139 -0
  214. package/skills/work-feedback/SKILL.md +113 -0
@@ -0,0 +1,57 @@
1
+ # Lens FAIL — Silent failures
2
+
3
+ ## Objective
4
+
5
+ Say where a failure stays silent — swallowed, unawaited, hidden behind a fallback, or lost as it
6
+ crosses a boundary. A failure that reports itself is a bug someone will fix; one that returns the
7
+ same value as success is a bug nobody sees until its consequence arrives somewhere else.
8
+
9
+ ## Questions
10
+
11
+ - **Does any `catch` swallow?** An empty handler, one that logs and carries on as if nothing
12
+ happened, one that catches everything to handle one case. Whatever file it is in — a build
13
+ script, a test's cleanup, a hook — the failure it hides is this lens's.
14
+ - **Is every promise awaited, every status read?** A call whose rejection nobody observes, an exit
15
+ code nobody checks, a `|| true` that turns a failure into a pass.
16
+ - **Does a fallback hide an error?** A default returned when the real value could not be read is a
17
+ decision; returned without saying so, it is a failure wearing the shape of success.
18
+ - **Does a failure stay a failure as it crosses a boundary** — a subshell, a pipe, a callback, a
19
+ worker, a process? A flag set where nobody reads it is the classic form.
20
+ - Is anything **guarded by a comment instead of by code** — *must be called after init*, *do not
21
+ pass null* — so that breaking it fails nowhere?
22
+ - Are the **known limits written where a user meets them**? A documented limit is a decision; an
23
+ undocumented one is a failure nobody will report.
24
+
25
+ ## Probes
26
+
27
+ - **The shell scripts this repository ships** — the tracked files whose first line is a shell
28
+ shebang, `^#!.*sh`: the subject of the next two. None → FAIL's shell probes have no subject, said
29
+ under `Limits` — finding nothing in no script is the wrong answer wearing the shape of "every
30
+ script is armed".
31
+ - **Does every shipped script arm itself against unset variables and failed pipes?** — the scripts
32
+ in which `set -[a-z]*u` is not found.
33
+ - **The failure that does not cross the boundary** — `\| *while` in those scripts: a `while` on the
34
+ right of a pipe runs in a subshell under bash, so a flag set inside it is lost when the loop ends.
35
+ - **Failures turned into passes**, in every tracked file — `\|\| *(true|:)( |$)`.
36
+ - **Handlers that swallow**, in the languages the tree carries —
37
+ `catch *(\([^)]*\))? *\{ *\}|except[^:]*: *pass`.
38
+
39
+ ## For a change
40
+
41
+ A change adds no path that can fail without saying so — a `catch` that swallows, a promise not
42
+ awaited, a `|| true`, a fallback that returns a default where it used to throw — and widens no
43
+ `catch` that was narrow. A call it moves across a boundary — into a callback, a subshell, a worker
44
+ — still reports its failure to the caller. A test's setup or cleanup is code like any other: a
45
+ restore that can fail silently is this lens's, not VERIF's.
46
+
47
+ ## Signals learned
48
+
49
+ - **`| while` is codelife's own recurring defect**, and a shape worth looking for anywhere.
50
+ Campaign A1 filed it as T-4 — a `ko` setting `fail=1` inside a pipeline subshell, so the script
51
+ printed FAIL and exited 0. It was fixed, and then written again in one of the plugin's own suites
52
+ in the very session that fixed it. Read from a redirect: `done < <(…)`.
53
+ - A variant worth its own look: a pipeline that **swallows its own diagnostics**. The same file
54
+ piped its FAIL lines into `grep -q`, so the check fired correctly and never showed which line
55
+ triggered it. A guard that cannot say *where* costs as much as one that does not fire.
56
+ - `set -euo pipefail` at the top of every script is a good sign and not a conclusion — `-e` does not
57
+ survive a function called in a condition, which is where the interesting failures live.
@@ -0,0 +1,56 @@
1
+ # Lens GOV — Governance & release
2
+
3
+ ## Objective
4
+
5
+ Say whether every branch has a status, every version a tag, and the licence a decision. This lens
6
+ looks at what the repository says about itself as a project rather than as code — and its findings
7
+ are usually things nobody owns, which is why they accumulate.
8
+
9
+ ## Questions
10
+
11
+ Whether a merged branch is still a head on `origin`, a name falls outside the model, the shipped
12
+ version has no tag, a licence is missing, and this clone keeps refs the forge deleted, is the
13
+ script's to say. A branch list nobody prunes is a list nobody reads, and the one stale branch that
14
+ matters hides in it.
15
+
16
+ - **Does every branch have a status?** Unmerged and untouched for months, or kept for a reason
17
+ nobody wrote down.
18
+ - **Does every tag have a release entry?**
19
+ - **Who may merge to `main` and `develop`?** A default branch anyone with push rights can merge
20
+ to, or force-push, is a release nobody reviewed.
21
+ - Is the **licence decided and consistent** — the same identifier in `LICENSE`, the manifest and the
22
+ published artefact?
23
+
24
+ ## Probes
25
+
26
+ `GOV.mjs`, run by `verify` before the lenses, whose lines you are handed. Read
27
+ from `origin` — a remote-tracking ref outlives the branch's deletion at merge — it
28
+ reports each head merged into `develop` and still there, an `origin` with no `develop`, each name
29
+ outside the model, the version of the contract's `release.version_file` with no tag, no `LICENSE`,
30
+ that manifest with no `license`, each ref this clone keeps for a branch the forge deleted, and
31
+ `fetch.prune` not set to `true`. With `origin` unreachable it could not tell — never an empty
32
+ list, which would read as *no merged branch left*.
33
+
34
+ The forge's own settings — its protected branches and who may merge or push to each — are read by
35
+ no one: say so in one *Limits* line.
36
+
37
+ ## For a change
38
+
39
+ **No** — a change says nothing about the branch list, the tag history or the licence.
40
+
41
+ ## Signals learned
42
+
43
+ - **The forge's harvest and the clone's drift are two numbers, and only one of them is this
44
+ lens's.** Measured on codelife, at its campaign A3: `origin` held four heads, of which one was
45
+ merged into `develop` and still present, while this clone carried six remote-tracking refs for
46
+ branches the forge had already deleted at merge. The script takes the first from `git ls-remote`
47
+ and the second from the difference; a probe that reads `refs/remotes` for the first reports the second and
48
+ calls it the first.
49
+ - **Zero tags with a `0.0.0` version is a coherent state**, not a defect: nothing has been released.
50
+ Say so rather than filing a missing-tag finding — the defect would be a bumped version *without*
51
+ a tag.
52
+ - **The manifest that must name the licence is the one the artefact ships with** — the contract's
53
+ `release.version_file` — and a root `package.json` that is private and unpublished has no consumer
54
+ to decide it for: its missing `license` key is not a finding. On codelife, a finding was filed
55
+ against exactly that, from a probe that read `package.json` while the shipping manifest agreed
56
+ with `LICENSE`.
@@ -0,0 +1,47 @@
1
+ # Lens GUARD — CI and guards
2
+
3
+ ## Objective
4
+
5
+ Say what actually stops a regression from shipping, and whether the guards check facts or merely
6
+ declare intentions. A hook that runs a script that runs nothing is a guard with nothing behind it,
7
+ and it looks green.
8
+
9
+ ## Questions
10
+
11
+ Whether the hooks are wired and executable, the tiers exist and run something, and every guard of
12
+ the contract resolves, is the script's to say; a guard pointing at a deleted script never fires and
13
+ never says so.
14
+
15
+ - **What runs, and when?** Map each hook to the script it calls and each script to what it
16
+ actually executes, reading them. Follow it to the end: a tier that runs something may still run
17
+ nothing that matters.
18
+ - Are the hooks **versioned**? `.githooks/` in the repository, `core.hooksPath` set by
19
+ `postinstall` — or a hook that exists only in one developer's `.git/hooks/`, which protects
20
+ nobody else.
21
+ - Does **CI run what the hooks run**? A check that exists only locally is bypassed by anyone who
22
+ pushes from another machine; a check that exists only in CI lets a red commit into the branch.
23
+ - Can a guard be **bypassed silently**? `--no-verify` is always available — the question is
24
+ whether the repository notices afterwards.
25
+
26
+ ## Probes
27
+
28
+ `GUARD.mjs`, run by `verify` before the lenses, whose lines you are handed — the
29
+ tiers themselves are the campaign's baseline, already run. It reports `core.hooksPath` unset or
30
+ naming nothing, each hook that is not executable, a `verify:commit` or `verify:push` absent or
31
+ hollow — nothing but `echo` — and each `guards[].run` command not found.
32
+
33
+ ## For a change
34
+
35
+ A change weakens no guard — no hook shortened, no check removed, no threshold raised — and a hook it touches checks a fact, not a declaration. A
36
+ weakened guard costs nothing to the change that weakens it, which stays green, and everything to
37
+ the next one.
38
+
39
+ ## Signals learned
40
+
41
+ - **A tier that prints `nothing to run` passes.** Found on codelife: `verify:push` guarded the
42
+ moment code leaves the machine and proved nothing. Always follow a script to what it executes,
43
+ never stop at its exit code.
44
+ - A `pre-commit` that reformats files without re-staging them leaves the commit missing the
45
+ formatting it just applied.
46
+ - Hooks wired by `postinstall` only protect someone who has run an install. A fresh clone that is
47
+ read, edited and committed without installing has no hooks at all.
@@ -0,0 +1,52 @@
1
+ # Lens INTENT — Intent
2
+
3
+ ## Objective
4
+
5
+ Say whether the code does what was asked of it — what its issues asked of a change, what `docs/spec/`
6
+ specifies of a tree. A change can be correct, tested and clean and still not be the change anyone
7
+ wanted; nothing else in a campaign reads the code against the request.
8
+
9
+ ## Questions
10
+
11
+ - **What is missing?** A requirement the request states, a case it cites, something the author
12
+ announces as done — in the description, a commit, a comment — that the code does not do.
13
+ - **What is extra?** Behaviour the request did not ask for, slipped in beside what it did. Not
14
+ wrong by itself: unasked, so unreviewed against any intention.
15
+ - **What is misunderstood?** The code does something close to what was asked and not it — the
16
+ right case under the wrong condition, the rule applied to the wrong set.
17
+ - **Is each verifiable claim of the author true?** *Fixes X*, *covers every caller*, *no behaviour
18
+ change*: each one checked against the code, never taken as given.
19
+ - **In tree scope, does the tree do what the specification states?** Read a rule and its cases,
20
+ then the code or the skill that should do it, and say whether they agree.
21
+
22
+ A drift **quotes both sides and chooses neither**: which one is wrong is the author's decision —
23
+ the specification is obsolete, and a new note records the change, or the implementation is wrong,
24
+ and it gets a fix. The recommendation says so, and is always **untried**: choosing the side is the
25
+ author's.
26
+ Whether a document's *verifiable statements* —
27
+ a command, a path, a version — are true is DOC's; whether the behaviour it *specifies* is done is
28
+ this lens's.
29
+
30
+ ## Probes
31
+
32
+ - **The specification's rules and cases**, the referential of a tree-scope run —
33
+ `^#{3,4} [A-Z]+-[0-9]+ — ` over `docs/spec/`. No `docs/spec/` among the tracked files → nothing is
34
+ specified: say so under `Limits`, never compare against a README instead.
35
+ - **What implements a rule** — where a rule names a skill, a command or a file, that name as a whole
36
+ word, a fixed string, outside `docs/spec/`.
37
+
38
+ The probes list what is specified; the method is reading each rule beside its implementation.
39
+ Name in *Method* which rules were read — a campaign cannot read every one, and the ones it did not
40
+ read are a line of *Limits*.
41
+
42
+ ## For a change
43
+
44
+ **The issue first** — what it asks, and the rules and cases it cites. A change meets each
45
+ requirement and each cited case, at a place the plan names; adds nothing the issue does not ask;
46
+ and makes no claim, in its commits or its description, that is not true. A requirement no file of
47
+ the plan can meet is said at the plan, before any code.
48
+
49
+ ## Signals learned
50
+
51
+ - **This lens ships without campaign history**, written when the specification moved the merge
52
+ request's intention out of DOC's duties. Its first campaigns will write this section.
@@ -0,0 +1,49 @@
1
+ # Lens LEAN — Code that should not exist
2
+
3
+ ## Objective
4
+
5
+ Say what code the repository carries that it does not need — dead, duplicating what the platform
6
+ or a dependency already does, abstracted for a second case that never came, or longer than the
7
+ logic it says. Every line is a line the next reader reads and the next review searches; the
8
+ cheapest code to keep true is the code that is gone.
9
+
10
+ ## Questions
11
+
12
+ - **What is dead?** A function nothing calls, a branch no input reaches, a flag never set, a file
13
+ nothing references. Not style: dead code is a statement about intent that no longer holds.
14
+ - **What does the standard library, the platform or an installed dependency already do?** A
15
+ hand-written helper beside the built-in that does the same, a second library for one function of
16
+ the first.
17
+ - **Which abstraction has one implementation?** An interface with one class, a factory with one
18
+ product, a parameter every caller passes the same value — an indirection a reader pays for and
19
+ nothing uses.
20
+ - **What shorter form says the same logic?** A loop that is a `map`, a chain of conditions that is
21
+ a table, two near-identical functions that are one with a parameter.
22
+
23
+ A point here is a finding only when its fix removes code: the fix's balance decides, as for every
24
+ lens, and a shorter form that adds a dependency or a layer is not lean.
25
+
26
+ ## Probes
27
+
28
+ - **Files nothing references** — a first pass, by name: for each tracked `*.sh`, `*.mjs`, `*.js` or
29
+ `*.ts`, its basename as a whole word, a fixed string, in every other file. Read each file with no
30
+ hit before reporting it: a file can be loaded by a pattern, a manifest or a tool's convention
31
+ rather than by its name.
32
+ - **Exported names used nowhere but their own file** — `export (function|const|class) [A-Za-z0-9_]+`,
33
+ then each name as a whole word, the files that carry it listed. The export syntax is the
34
+ language's: name the one you used in *Method*.
35
+ - **The names that mean "nowhere else to put this"** — tracked paths through a `utils`, `helpers`,
36
+ `misc` or `common` directory; their contents are often a platform's function written again.
37
+
38
+ ## For a change
39
+
40
+ A change adds no code that should not exist — a helper the platform already has, an abstraction
41
+ with one implementation, a branch nothing can reach, a longer form of logic the file already says
42
+ shortly — and leaves nothing dead of what it replaced: no old function still there, no flag no
43
+ longer read.
44
+
45
+ ## Signals learned
46
+
47
+ - **This lens ships without campaign history**, written when the specification made a
48
+ simplification a finding whichever lens finds it. Its first campaigns will write
49
+ this section.
@@ -0,0 +1,48 @@
1
+ # Lens LINES — Release lines
2
+
3
+ ## Objective
4
+
5
+ Say which release lines exist, how far each has drifted from the one that ships — **in both
6
+ directions** — and what carries a fix across them. A line nobody ports to is a line whose users are
7
+ on their own; a line whose divergence nobody has measured is worse, because the decision to keep it
8
+ was never re-taken.
9
+
10
+ ## Questions
11
+
12
+ Which older lines exist on the forge and how far each has diverged from `main`, in both directions,
13
+ is the script's to say. What the counts are made of — fixes or features — it does not say, and a
14
+ line of *Limits* says so rather than a guess.
15
+
16
+ - For each older line, **what does it have that the shipping line does not, and what does the
17
+ shipping line have that it does not?** Both directions, always: the second is the backlog of
18
+ unported fixes, the first is what deleting the line would lose.
19
+ - **What ports a fix across** — a written procedure, a habit visible in the history, or nothing? A
20
+ cherry-pick nobody documented is a procedure one person knows.
21
+ - **Is each line's head tagged**, and does its tag agree with the version its manifest declares?
22
+ - **Which lines are supported**, and is that written where a consumer reads it rather than where a
23
+ maintainer remembers it?
24
+ - A line that has diverged in **neither** direction can be closed; a line that has diverged in
25
+ **one** has been abandoned in the other, and which one it is decides who is hurt.
26
+
27
+ ## Probes
28
+
29
+ `LINES.mjs`, run by `verify` before the lenses, whose lines you are handed. Read
30
+ from `origin`, it measures each `support/*` line against `main` in both directions and reports a
31
+ line diverged one way only, with its two counts, and a line diverged in neither, which can be
32
+ closed. With `origin` unreachable, or one release line, it could not tell.
33
+
34
+ ## For a change
35
+
36
+ **No** — a change lands on one line and says nothing about the distance between lines.
37
+
38
+ ## Signals learned
39
+
40
+ - **This lens ships without campaign history**, its subject being a repository with more than one
41
+ release line and the plugin's own having one. Grow it from the first campaign that runs it.
42
+ - **Divergence in one direction only is the finding.** Equal counts both ways are two lines being
43
+ maintained; commits only on the shipping line are an abandoned older line whose users still
44
+ install it. Report the direction, never a single distance.
45
+ - **The porting procedure is the real subject.** Where none is written, the finding is the absence
46
+ and not the arithmetic — the numbers will be different next campaign and the gap will not.
47
+ - A tag that disagrees with its line's manifest is a release nobody can reproduce; it belongs here
48
+ when it is about a line, and to GOV when it is about the repository as a whole.
@@ -0,0 +1,61 @@
1
+ # Lens PERF — Performance & memory
2
+
3
+ ## Objective
4
+
5
+ Say what is measured, and whether a regression would be seen. Where nothing is measured, say the
6
+ absence: a number invented to fill this lens becomes a baseline the next campaign compares against,
7
+ and a delta measured from a figure nobody produced is worse than no figure at all.
8
+
9
+ ## Questions
10
+
11
+ - **What has a recorded duration or size today, and where is it recorded?** A figure in a commit
12
+ message is not a baseline; a file another campaign reads is one.
13
+ - **Would a regression be seen?** By what — a threshold something enforces, or a person who happens
14
+ to notice the wait? The second is not detection.
15
+ - **What does a contributor wait for**, and what does a consumer wait for? They are rarely the same
16
+ thing, and only one of them is usually measured.
17
+ - **What grows without a bound** — a cache with no eviction, a log nothing rotates, a structure that
18
+ accumulates for the life of the process, an input read whole into memory?
19
+ - Is a **budget pinned** anywhere — a size limit, a timeout, a threshold a guard reads — or is every
20
+ number descriptive?
21
+ - Where the repository is **already slow on purpose**, is the reason written? A deliberate cost
22
+ nobody recorded is indistinguishable from a regression.
23
+
24
+ ## Probes
25
+
26
+ - **What a contributor waits for** — the timings `verify` took before the lenses, under `PERF` in
27
+ its block: each script's median and runs, with its command. A timing it *could not tell* is a line
28
+ of `Limits`, with its reason.
29
+ - **What the repository carries, by weight** — the largest tracked files and the whole tree's size,
30
+ from the count, the total and the largest the cut reports in `verify`'s block.
31
+ - **Whether any threshold is enforced anywhere, as opposed to observed** —
32
+ `(timeout|budget|max[-_]?(size|bytes|time)|--max|ulimit)` across the tree. A budget is a number
33
+ compared against something; a number only printed is a measurement.
34
+ - **Is there a baseline file at all** — something a later campaign re-reads: the tracked paths
35
+ matching `baseline|benchmark|perf`, or the line saying nothing in the tree is named as one.
36
+
37
+ A probe whose subject comes back empty is *not applicable* under `Limits`, never a zero: a
38
+ repository with no runtime code has nothing for this lens, and saying so is a measurement.
39
+
40
+ ## For a change
41
+
42
+ A change adds no work to a path something already waits on, and removes no number a regression
43
+ would be seen against. Timing the change against its target branch is no objective: two runs on
44
+ one machine, minutes apart, differ by more than most of what it would call a regression.
45
+
46
+ ## Signals learned
47
+
48
+ - **This lens ships without campaign history.** It was written when the eleven implemented lenses had
49
+ already run three campaigns and it had run none, so the section below carries what the corpus
50
+ argues rather than what a report measured. Grow it from the first campaign that runs PERF.
51
+ - **The absence is the finding.** *Nothing is measured, so no regression can be seen* is a real
52
+ result with a real consequence, and it is written as a finding rather than left to *Limits* when
53
+ something depends on the speed — a hook a contributor runs at every commit, a build a consumer
54
+ waits for. Where nothing depends on it, it is an observation.
55
+ - **A slow command is not a finding on its own.** What makes it one is a dependency: the command
56
+ runs in a hook, or in a path a person is blocked on. A command nobody waits for being slow is a
57
+ fact, not a defect.
58
+ - **Measure the tier, not the suite.** The thing a contributor actually waits for is whatever the
59
+ contract's verification tiers run, and those are named in the contract rather than guessed.
60
+ - Do not report a number without the command beside it. A duration is the most re-measured figure
61
+ an audit produces and the easiest to produce differently.
@@ -0,0 +1,58 @@
1
+ # Lens PKG — Packaging & tarball
2
+
3
+ ## Objective
4
+
5
+ Say whether what a consumer installs is correct: the entry points the manifest declares resolve to
6
+ files the tarball actually contains, the tarball carries nothing private, and nothing executes on
7
+ the consumer's machine at install time without a reason. This lens is the only one that looks at
8
+ the artefact rather than at the repository, and they differ more often than anyone expects.
9
+
10
+ ## Questions
11
+
12
+ Whether every entry point is in the tree and in the tarball, whether a lifecycle script runs at
13
+ install time, and whether a tracked file carries a secret, is the script's to say; a
14
+ lifecycle script is read here for its reason — *it builds the package* is a reason that says the
15
+ build should have shipped instead.
16
+
17
+ - **What is in the tarball** that should not be? Something private in it is the finding that costs
18
+ the most.
19
+ - **Are the export conditions complete** — a default present, no condition reachable only by
20
+ accident? (The position of `types` is TYPE's.)
21
+ - **Are the dependency classes right?** A runtime dependency in `devDependencies` breaks the
22
+ consumer's install; a peer expressed as a dependency gives them two copies of it.
23
+ - **Does the committed build match its source**, where the build is versioned? BUILD's script
24
+ reports a tracked file a fresh build changes; a tag whose artefact is behind its source ships old
25
+ code from a repository whose history says otherwise.
26
+
27
+ ## Probes
28
+
29
+ `PKG.mjs`, run by `verify` before the lenses, whose lines you are handed. Against
30
+ `npm pack --dry-run --ignore-scripts`, it reports each entry point — `main`, `module`, `types`,
31
+ `typings`, `browser`, `bin`, every `exports` leaf — absent from the tree or left out of the
32
+ tarball; each `preinstall`, `install`, `postinstall` or `prepare` script; each tracked file named
33
+ like a secret; and each line of a tracked file — fixtures and tests included, the history not —
34
+ holding a credential's shape: a private-key header, a GitLab, GitHub or npm token. It prints such
35
+ a value's first four characters and nothing more. With no `package.json` it could not tell.
36
+
37
+ ## For a change
38
+
39
+ A change alters what a consumer receives only where the plan says so — an added or removed
40
+ `exports` condition, a moved entry point, a dependency that changed class, a lifecycle script that
41
+ appeared. No path it deletes or renames is one the manifest's `files` or entry points still reach:
42
+ a file leaving the tarball is a break no test catches, because every test runs against the
43
+ repository and not against the artefact, so the pack dry run checks it.
44
+
45
+ A change that touches neither the manifest nor a packaged path has no objective here.
46
+
47
+ ## Signals learned
48
+
49
+ - **This lens ships without campaign history**, the plugin's own repository being `kind: none` and
50
+ publishing no package. Grow it from the first library campaign.
51
+ - **Resolution in the repository is not resolution in the tarball.** The two checks are different
52
+ and the second is the one that matters; a probe that only stats the path answers the wrong
53
+ question.
54
+ - **A `prepare` script that builds is a finding, not a convenience.** It moves the build onto the
55
+ consumer's machine, where the toolchain may be absent and the result is unverified — the reason
56
+ a versioned build exists at all.
57
+ - Do not report a missing `exports` map as a defect on its own. Report what a consumer cannot reach
58
+ because of it, or say it is deliberate.
@@ -0,0 +1,49 @@
1
+ # Lens SEC — Security
2
+
3
+ ## Objective
4
+
5
+ Say what comes from outside, what it reaches, and what defends it. A security defect is a path
6
+ from an input someone else controls to something they should not touch, with nothing in between;
7
+ the lens traces that path rather than listing vulnerability names.
8
+
9
+ ## Questions
10
+
11
+ - **What are the entries?** A request, an argument, an environment variable, a file the code
12
+ imports or parses, a message, a URL a user supplies — anything whose content the repository does
13
+ not write.
14
+ - **What does each entry reach?** A shell, a query, a path on disk, an HTML sink, a deserialiser,
15
+ a redirect, an `eval` — followed through the code, not guessed from a name.
16
+ - **What defends it on the way?** Validation, escaping, an allow-list, a parameterised call, a
17
+ permission check — and does the defence sit on every path, or only the one its author tested?
18
+ - **Where do secrets go?** Read from where, logged where, sent where, kept in memory how long. A
19
+ secret printed into a log or an error message is a leak whatever file it is in.
20
+ - **What does the repository trust that it should not?** A file it downloads and runs, a lockfile
21
+ it does not check, a hook a contributor's machine executes.
22
+
23
+ A secret's *shape* in a tracked file is a fact PKG's script already reports, and an advisory on a
24
+ dependency is DEPS's: this lens asks what the code does with what comes from outside. A finding
25
+ here carries `Affects: consumers` when what ships is exposed, and `critical` when it is exploitable.
26
+
27
+ ## Probes
28
+
29
+ - **Sinks worth tracing back to an entry**, in the languages the tree carries —
30
+ `\beval\(|new Function\(|child_process|exec(Sync)?\(|spawn\(|innerHTML|dangerouslySetInnerHTML|\bsh -c\b`.
31
+ - **Shell scripts that run what they download**, or expand an input unquoted into a command —
32
+ `curl[^|]*\| *(ba)?sh|wget[^|]*\| *(ba)?sh`.
33
+ - **Secrets read from the environment, and the lines that print or send them** —
34
+ `process\.env\.[A-Z_]*(TOKEN|SECRET|KEY|PASS)|\$\{?[A-Z_]*(TOKEN|SECRET|KEY|PASS)`.
35
+
36
+ The probes list sinks and secrets; the method is the trace from each back to an entry, or the
37
+ statement that none reaches it. Name in *Method* which sinks were traced.
38
+
39
+ ## For a change
40
+
41
+ An entry, a sink, or a path between them that a change adds — a new argument reaching a shell, a
42
+ parsed file reaching the disk, a value reaching HTML — has a defence the objective names. The
43
+ change removes and narrows no defence — no validation deleted, no escape bypassed, no check moved
44
+ after the use — even above a sink it leaves untouched, and prints, logs or sends no secret.
45
+
46
+ ## Signals learned
47
+
48
+ - **This lens ships without campaign history.** Its first campaigns will write this
49
+ section.
@@ -0,0 +1,62 @@
1
+ # Lens STANDARDS — Standards
2
+
3
+ ## Objective
4
+
5
+ Say whether the code breaks a rule an authority document states, and whether new code has one
6
+ possible shape. A rule written down and not followed is worse than no rule: the next contributor
7
+ reads it, trusts it, and meets code that contradicts it.
8
+
9
+ ## Questions
10
+
11
+ - **Which rules do the authority documents state about code?** The `CLAUDE.md`, or whatever file an
12
+ agent reads first, the principles, the glossary — *every HTTP call goes through `src/lib/http.ts`*,
13
+ *a skill never assumes a path*, *a term means one thing*. Only those: a working instruction — how
14
+ to name a branch, how to title a commit, which tone to answer in — guides an agent writing code and
15
+ is not a standard the code can break.
16
+ - **Does the code break one?** A candidate cites the rule, its file and line, and the code that
17
+ breaks it — never a rule paraphrased, never a preference no document states.
18
+ - **Take the newest file and the oldest of a kind. Are they the same shape?** Same error handling,
19
+ same naming, same layout, same way of reporting a result.
20
+ - Where two shapes coexist, is the **boundary written** — a date, a directory, a note saying *the
21
+ old form stays until X*? A migration nobody declared is indistinguishable from an inconsistency.
22
+ - Could a contributor **derive the shape from the code**, or would they need a person to tell them?
23
+ Is a shape **enforced by anything** — a template, a test, a lint rule — or only by whoever reviews?
24
+
25
+ Whether the authority document is itself true is DOC's question; whether the code does what the
26
+ specification asks is INTENT's. This lens reads the documents only for the rules they impose on
27
+ code.
28
+
29
+ ## Probes
30
+
31
+ - **The authority documents, and the rules they state about code** — which of `CLAUDE.md`,
32
+ `AGENTS.md`, `docs/spec/principles.md` and `docs/spec/glossary.md` the tracked files hold, and in
33
+ the first two `^\s*[-*0-9.]+ .*\b(never|always|must|only|every)\b`.
34
+ - **One kind of artefact, every instance, the same structural markers** — the kind this repository
35
+ ships most, as a glob over the tracked files, and the markers its instances are supposed to
36
+ share, both read from the tree and named in *Method*: the markers counted in each instance. No
37
+ instance → this probe has no subject, said under `Limits`.
38
+ - **Two instances side by side** — the one carrying the fewest markers beside one carrying them all:
39
+ what the first lacks is the drift.
40
+
41
+ ## For a change
42
+
43
+ A change breaks no rule an authority document states about code — the objective cites the rule —
44
+ and adds no second shape for something the repository already has a shape for: every file it adds
45
+ reads like its sibling. The commits, the branch and the description are working instructions, not
46
+ code, and no objective of this lens bears on them.
47
+
48
+ ## Signals learned
49
+
50
+ - **Uniformity is a finding too, and a good one.** Measured on codelife itself, whose two kinds
51
+ filled the shape probe as `kind='*.test.mjs'` with
52
+ `^import assert from 'node:assert/strict'|from 'node:test'|from './lib.mjs'`,
53
+ and `kind='*/SKILL.md'` with `^## `: every suite carried the same three markers. Report it;
54
+ a lens that only ever speaks when something is wrong teaches a reader nothing about what is
55
+ right.
56
+ - The strongest signal is **age against shape**: two files written a week apart that look different
57
+ say more than twenty files that look alike.
58
+ - A shape enforced by a **test** rather than by review is the difference between a convention and a
59
+ rule. codelife asserts its skills' anatomy in a suite of its own; that is why the answer there
60
+ was short.
61
+ - Do not report naming preferences. This lens is about a rule someone wrote and a contributor's
62
+ ability to *derive* the next file, not about which name you would have chosen.
@@ -0,0 +1,56 @@
1
+ # Lens TYPE — Public surface & types
2
+
3
+ ## Objective
4
+
5
+ Say whether the declarations a consumer receives describe the surface the documentation promises,
6
+ and whether they resolve under every module resolution a consumer may have configured. A package
7
+ whose types resolve under one setting and vanish under another is untyped for half its users, and
8
+ nothing in the repository notices.
9
+
10
+ ## Questions
11
+
12
+ Whether a types entry exists, whether its condition comes first wherever it is declared, and
13
+ whether a declaration entry imports a package the consumer does not receive, is the script's to say.
14
+
15
+ - **What does the package export, according to the emitted declarations?** Enumerate it — names,
16
+ and for each whether it is a value, a type, or both — reading the declaration files the manifest
17
+ names, never a path literal.
18
+ - **Does that set match the documented surface**, in both directions? A name in the declarations
19
+ and in no document is surface nobody was told about and everybody may now depend on; a name in a
20
+ document and not in the declarations is a promise the package does not keep. The two differences
21
+ are two findings with different severities: undocumented surface is a `low` that grows, and
22
+ documented surface that does not exist is a `high` the first consumer meets.
23
+ - **Is any exported type effectively opaque** — an `any`, an unexported alias that leaks, a
24
+ parameter typed only by inference from a private shape? Read in context, never counted.
25
+ - **Are the declarations emitted or written by hand?** Hand-written ones drift from the
26
+ implementation silently, and the drift is found by a consumer.
27
+
28
+ ## Probes
29
+
30
+ `TYPE.mjs`, run by `verify` before the lenses, whose lines you are handed. It reports
31
+ a package with no types entry, each `exports` object whose `types` condition is not first, and each
32
+ package a declaration entry imports that is in neither `dependencies` nor `peerDependencies`. With
33
+ no `package.json` it could not tell.
34
+
35
+ ## For a change
36
+
37
+ A change to the public surface changes the documentation with it. The declarations are the
38
+ subject, not the implementation: a refactor that changes no exported name has no objective here
39
+ however large it is, and a one-line signature change has one. An exported name removed or renamed
40
+ in the files the manifest's `types` and `exports` reach carries a `breaking` marker — the break
41
+ this lens exists to catch.
42
+
43
+ ## Signals learned
44
+
45
+ - **This lens ships without campaign history**, the plugin's own repository publishing no
46
+ declarations. Grow it from the first library campaign.
47
+ - **The position of the types condition is the defect, not its absence.** A types condition listed
48
+ after a runtime one is skipped by whichever resolver reads conditions in order, so the package is
49
+ typed for some consumers and not others — and every check that runs inside the repository passes.
50
+ - **Compare against the documentation, not against the implementation.** The implementation and the
51
+ declarations agree by construction when the declarations are emitted; what nothing checks is
52
+ whether either matches what a reader was told.
53
+ - **An emitted declaration file with commits of its own is a contradiction worth reporting**: either
54
+ it is not emitted, or someone has been editing generated output.
55
+ - Do not report an internal type as missing from the surface. This lens asks whether the surface is
56
+ described, never whether it is large enough.