geneseed 3.8.0 → 3.9.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/CHANGELOG.md +39 -0
- package/DESIGN.md +13 -10
- package/README.md +4 -4
- package/SHIPPED.md +3 -3
- package/adapters/opencode/GLOBAL-HARNESS-SPEC.md +1 -1
- package/adapters/opencode/README.md +3 -3
- package/adapters/opencode/plugins/geneseed-guard.js +9 -9
- package/adapters/opencode/plugins/geneseed-workflow.js +1 -1
- package/adapters/opencode/workflows/_runtime.js +2 -2
- package/adapters/opencode/workflows/dispatch.js +1 -1
- package/docs/extending.md +72 -40
- package/docs/web/harnesses.md +2 -2
- package/docs/web/plugin-guard.md +2 -2
- package/docs/web/rules.md +1 -1
- package/docs/web/themes-author.md +2 -2
- package/docs/web-ui.md +1 -1
- package/harness.config.json +1 -1
- package/js/README.md +4 -3
- package/js/build/render.mjs +6 -3
- package/js/build/source.mjs +105 -1
- package/js/build/stubs.mjs +7 -2
- package/js/cli-table.json +3 -3
- package/js/hosts/hooks.mjs +5 -5
- package/js/hosts/native.mjs +1 -1
- package/js/inspect/checks-authoring.mjs +149 -116
- package/js/inspect/inventory.mjs +1 -2
- package/js/ui/tui.mjs +1 -1
- package/js/web/api.mjs +6 -1
- package/package.json +1 -1
- package/registry.json +7 -0
- package/src/AGENT.md.tmpl +19 -15
- package/src/agents/_template.md +3 -3
- package/src/agents/advocate.md +3 -3
- package/src/agents/architect.md +3 -3
- package/src/agents/developer.md +4 -4
- package/src/agents/docs.md +3 -3
- package/src/agents/empiricist.md +4 -4
- package/src/agents/explorer.md +4 -4
- package/src/agents/framer.md +3 -3
- package/src/agents/historian.md +3 -3
- package/src/agents/operator.md +3 -3
- package/src/agents/pragmatist.md +3 -3
- package/src/agents/researcher.md +7 -7
- package/src/agents/reviewer.md +3 -3
- package/src/agents/security.md +3 -3
- package/src/agents/skeptic.md +3 -3
- package/src/agents/steward.md +3 -3
- package/src/agents/tester.md +3 -3
- package/src/agents/user-advocate.md +3 -3
- package/src/agents/visionary.md +3 -3
- package/src/doctrines/README.md +4 -3
- package/src/doctrines/comms.md +4 -4
- package/src/doctrines/craft.md +20 -20
- package/src/doctrines/ops.md +19 -19
- package/src/doctrines/process.md +20 -20
- package/src/doctrines/rigor.md +22 -22
- package/src/laws/universal.md +23 -44
- package/src/memory/README.md +3 -3
- package/src/modes/foreman.md +1 -1
- package/src/notebook/README.md +1 -1
- package/src/ontology/universal.md +7 -9
- package/src/postures/artisan.md +2 -2
- package/src/skills/_self-improvement.md +4 -4
- package/src/skills/_template.md +1 -1
- package/src/skills/brainstorm.md +3 -3
- package/src/skills/bruno-collection-generator.md +6 -6
- package/src/skills/bruno-test-writer.md +5 -5
- package/src/skills/ci-fix.md +4 -4
- package/src/skills/commit.md +11 -10
- package/src/skills/consolidate-memory.md +4 -4
- package/src/skills/council.md +2 -2
- package/src/skills/debug.md +4 -4
- package/src/skills/deps-audit.md +3 -3
- package/src/skills/develop.md +7 -7
- package/src/skills/document-project.md +6 -6
- package/src/skills/explain-changes/SKILL.md +69 -0
- package/src/skills/explain-changes/VENDOR.md +20 -0
- package/src/skills/explain-changes/scripts/render_changes.mjs +558 -0
- package/src/skills/forge-mcp.md +4 -4
- package/src/skills/fresh-eyes.md +4 -4
- package/src/skills/frontend-design.md +1 -1
- package/src/skills/geneseed.md +3 -3
- package/src/skills/git-archaeology.md +5 -5
- package/src/skills/git-rescue.md +7 -7
- package/src/skills/handoff.md +3 -3
- package/src/skills/ingest.md +5 -5
- package/src/skills/migrate.md +8 -8
- package/src/skills/parallel-agents.md +2 -2
- package/src/skills/pipeline.md +2 -2
- package/src/skills/plan.md +3 -3
- package/src/skills/ponytail.md +2 -2
- package/src/skills/profile.md +2 -2
- package/src/skills/prose.md +1 -1
- package/src/skills/prototype.md +1 -1
- package/src/skills/refactor.md +3 -3
- package/src/skills/release.md +5 -5
- package/src/skills/repo-map.md +4 -4
- package/src/skills/research.md +9 -9
- package/src/skills/review-response.md +4 -4
- package/src/skills/rule.md +3 -3
- package/src/skills/security-audit.md +5 -5
- package/src/skills/ship.md +5 -5
- package/src/skills/skill-forge.md +4 -4
- package/src/skills/wiki.md +5 -5
- package/src/skills/workflow.md +2 -3
- package/src/skills/worktree.md +4 -4
- package/themes/_TEMPLATE.json +37 -39
- package/themes/biker.json +37 -39
- package/themes/commentator.json +37 -39
- package/themes/cyberpunk.json +37 -39
- package/themes/gamer.json +37 -39
- package/themes/imperial.json +37 -39
- package/themes/joker.json +37 -39
- package/themes/marvin.json +37 -39
- package/themes/mean.json +37 -39
- package/themes/military.json +37 -39
- package/themes/neutral.json +37 -39
- package/themes/pirate.json +37 -39
- package/themes/sports.json +37 -39
- package/themes/verstappen.json +37 -39
- package/themes/wizard.json +37 -39
- package/web/dist/assets/Activity-DAzV-qQj.js +1 -0
- package/web/dist/assets/ActivityDetail-CwEwMtKl.js +1 -0
- package/web/dist/assets/Dashboard-C2ELBW-X.js +2 -0
- package/web/dist/assets/{Docs-DrJNDPwI.js → Docs-iZrvQP8J.js} +2 -2
- package/web/dist/assets/FilterInput-CVyqmYWM.js +1 -0
- package/web/dist/assets/GreenhouseView-Bq1QmaGO.js +2 -0
- package/web/dist/assets/Installs-BiqR8xdO.js +2 -0
- package/web/dist/assets/JournalView-6wilG5Zd.js +1 -0
- package/web/dist/assets/Laws-D8YXD_XE.js +3 -0
- package/web/dist/assets/Library-DwuTZ2-L.js +1 -0
- package/web/dist/assets/{Markdown-BQAvN8xx.js → Markdown-CkFyfgNf.js} +14 -14
- package/web/dist/assets/OperatorHudView-B-HVBqfY.js +2 -0
- package/web/dist/assets/Personal-BbUTmZQR.js +1 -0
- package/web/dist/assets/Tabs-_pjUFIEI.js +1 -0
- package/web/dist/assets/drawable-CoIulEH2.js +1 -0
- package/web/dist/assets/geist-mono-latin-400-normal-DTRLJnHl.woff2 +0 -0
- package/web/dist/assets/geist-mono-latin-500-normal-YINYabwD.woff2 +0 -0
- package/web/dist/assets/index-BMwSp8BP.js +2 -0
- package/web/dist/assets/index-CDPDk2vj.css +1 -0
- package/web/dist/assets/{react-DbkvxWG5.js → react-B9Z_tXRV.js} +1 -1
- package/web/dist/assets/sections-GalMS0Zv.js +1 -0
- package/web/dist/assets/usePoll-O0sJEw1Y.js +1 -0
- package/web/dist/index.html +4 -4
- package/web/src/pages/Laws.jsx +616 -361
- package/web/dist/assets/Activity-CH-7cPIM.js +0 -1
- package/web/dist/assets/ActivityDetail-DZvz0xS5.js +0 -1
- package/web/dist/assets/CatalogRow-DftXpZHY.js +0 -1
- package/web/dist/assets/Diff-DvwdG0L9.js +0 -2
- package/web/dist/assets/Doctor-OTmwmYZg.js +0 -1
- package/web/dist/assets/FilterInput-BakJLvaV.js +0 -1
- package/web/dist/assets/GreenhouseView-XxrAdriX.js +0 -2
- package/web/dist/assets/Harness-C_LYNk5c.js +0 -1
- package/web/dist/assets/JournalView-BcuyeEaR.js +0 -1
- package/web/dist/assets/Laws-CWHrTKY4.js +0 -3
- package/web/dist/assets/Library-CA9IHghn.js +0 -1
- package/web/dist/assets/OperatorHudView-BMRY1Tt4.js +0 -2
- package/web/dist/assets/Profile-wceET1JY.js +0 -1
- package/web/dist/assets/Rules-BEXvY4Tx.js +0 -1
- package/web/dist/assets/Settings-DS2zF0Ez.js +0 -1
- package/web/dist/assets/Skills-DahlOJuI.js +0 -1
- package/web/dist/assets/StatusBadge-Cg6j-NJL.js +0 -1
- package/web/dist/assets/activity-iWaWVtsR.js +0 -1
- package/web/dist/assets/audiowide-latin-400-normal-6GFCX7ni.woff2 +0 -0
- package/web/dist/assets/drawable-BTHjTzF7.js +0 -1
- package/web/dist/assets/geist-mono-latin-400-normal-DKaoCDn5.woff2 +0 -0
- package/web/dist/assets/geist-mono-latin-500-normal-C3sF8Y1B.woff2 +0 -0
- package/web/dist/assets/geist-mono-latin-600-normal-BHzjB6_C.woff2 +0 -0
- package/web/dist/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
- package/web/dist/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
- package/web/dist/assets/ibm-plex-mono-latin-600-normal-BgSNZQsw.woff2 +0 -0
- package/web/dist/assets/ibm-plex-serif-latin-400-normal-BIGslYFI.woff2 +0 -0
- package/web/dist/assets/ibm-plex-serif-latin-500-normal-REKAfBVG.woff2 +0 -0
- package/web/dist/assets/ibm-plex-serif-latin-600-normal-DAxitmSu.woff2 +0 -0
- package/web/dist/assets/index-AN5Emnrg.js +0 -2
- package/web/dist/assets/index-Ruh93A3A.css +0 -1
- package/web/dist/assets/inter-latin-400-normal-C38fXH4l.woff2 +0 -0
- package/web/dist/assets/inter-latin-500-normal-Cerq10X2.woff2 +0 -0
- package/web/dist/assets/inter-latin-600-normal-LgqL8muc.woff2 +0 -0
- package/web/dist/assets/inter-latin-700-normal-Yt3aPRUw.woff2 +0 -0
- package/web/dist/assets/lawCats-Btjp3Hk_.js +0 -1
- package/web/dist/assets/oswald-latin-400-normal-BAFo8sP8.woff2 +0 -0
- package/web/dist/assets/oswald-latin-500-normal-B-eyT0Dw.woff2 +0 -0
- package/web/dist/assets/oswald-latin-600-normal-plFmSr5g.woff2 +0 -0
- package/web/dist/assets/oswald-latin-700-normal-vy6hmKSr.woff2 +0 -0
- package/web/dist/assets/poppins-latin-400-normal-cpxAROuN.woff2 +0 -0
- package/web/dist/assets/poppins-latin-500-normal-C8OXljZJ.woff2 +0 -0
- package/web/dist/assets/poppins-latin-600-normal-zEkxB9Mr.woff2 +0 -0
- package/web/dist/assets/poppins-latin-700-normal-Qrb0O0WB.woff2 +0 -0
- package/web/dist/assets/rolldown-runtime-CbXtAM7H.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,45 @@ label. For the capability ↔ spec map, see [SHIPPED.md](SHIPPED.md).
|
|
|
10
10
|
|
|
11
11
|
_Nothing yet._
|
|
12
12
|
|
|
13
|
+
## [3.9.0] — 2026-09-30
|
|
14
|
+
|
|
15
|
+
**Upgrading:** re-emit after installing. Laws IX and XI are gone and Echo the Intent is now
|
|
16
|
+
**Law IX**: a note, memory or commit that says "Law IX" or "Law XI" from before this release
|
|
17
|
+
means the retired External Gate (now a rigor rule) or Absence Is a Claim (folded into Verify
|
|
18
|
+
Before Asserting). Nothing in the harness cites a rule by number any more.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
- **Stable rule ids.** Every law and doctrine rule is declared by a permanent id on its heading
|
|
22
|
+
(`### {{LAW:verify-before-asserting}} Verify Before Asserting`) and cited by it. The number is
|
|
23
|
+
the rule's position, computed at render time, so removing or reordering a rule rewires no
|
|
24
|
+
citation. Theme title keys are keyed by id too (`LEX_VERIFY_BEFORE_ASSERTING`,
|
|
25
|
+
`DOC_CONSENT_BEFORE_PUSH`), so a renumber never touches a theme.
|
|
26
|
+
- **Citations render as principle names.** Every cross-reference in AGENT.md, the laws, the
|
|
27
|
+
doctrines, skills and agents now reads *Verify Before Asserting* rather than "Rule III" — the
|
|
28
|
+
same in every voice. The hook and guard-plugin messages name the principle too. Numbers remain
|
|
29
|
+
only on each rule's own heading.
|
|
30
|
+
- The memory section of AGENT.md (always on, both footprints) tells the agent to cite a rule by
|
|
31
|
+
its principle, never its number, in anything that outlives the session.
|
|
32
|
+
- **Web console redesign (Slate + Graphite).** New Overview (health, three charts, what needs
|
|
33
|
+
you), Constitution, Library, Personal and Installs pages; global and per-project installs are
|
|
34
|
+
shown apart; skill types head the Library as a full-width banner (#162). The console's flavours
|
|
35
|
+
are cut to Cultivar, Operator, Matrix and Atlas (#161). The Overview view choice now lives only
|
|
36
|
+
in the Appearance palette, not in the page header.
|
|
37
|
+
|
|
38
|
+
### Removed
|
|
39
|
+
- Laws IX (External Gate, a rigor rule since 3.x) and XI (Absence Is a Claim, folded into Law III),
|
|
40
|
+
both retired in place until now. Their ids are recorded in `RETIRED_RULE_IDS` and can never be
|
|
41
|
+
reused.
|
|
42
|
+
|
|
43
|
+
### Added
|
|
44
|
+
- **`explain-changes` folder skill — a visual walkthrough of a diff before it is committed**:
|
|
45
|
+
the agent writes a short brief (intent, risks, logical units) and
|
|
46
|
+
`scripts/render_changes.mjs` renders one offline HTML page with the exact git diff side by
|
|
47
|
+
side, then opens it. Offered by the `commit` skill and the git-gate prompt; never a gate.
|
|
48
|
+
- `doctor` refuses a citation by number, an unknown id, a duplicate id, a rule heading with no id,
|
|
49
|
+
a retired id declared again, a console `LAW_META`/`DOCTRINE_META` row pinned to a different rule
|
|
50
|
+
than its number now holds, and a hook-gated rule moving away from the address its hook keys.
|
|
51
|
+
|
|
13
52
|
## [3.8.0] — 2026-09-30
|
|
14
53
|
|
|
15
54
|
**Upgrading:** re-emit (or `geneseed rebuild-all`) after installing, so each install carries the
|
package/DESIGN.md
CHANGED
|
@@ -44,7 +44,7 @@ vault or a specific tool's hooks.
|
|
|
44
44
|
and the prose words the docs use: the core nouns `LAW(S)`/`DOCTRINE(S)`/`ONTOLOGY`/
|
|
45
45
|
`AGENT(S)`/`SKILL(S)`/`MEMORY`/`NOTEBOOK`/`VAULT`/`WIKI`, plus `TAGLINE`,
|
|
46
46
|
`LOADED_SIGIL`, `EPI_*`, `BENEDICTION`, `DESC_*`, `ROAST_PERSONA`, the invariant
|
|
47
|
-
titles `
|
|
47
|
+
titles `LEX_<ID>`, the 28 doctrine-rule titles `DOC_<ID>` (keyed by stable rule id), the five pack
|
|
48
48
|
names `PACK_CRAFT`/`PACK_RIGOR`/`PACK_OPS`/`PACK_PROCESS`/`PACK_COMMS`, and the section intros
|
|
49
49
|
`INTRO_*`. Each theme defines its own nouns; **neutral keeps the plain words** (Rule,
|
|
50
50
|
Doctrine, Agent, Skill, Memory, Workspace), so neutral output is unchanged.
|
|
@@ -98,11 +98,13 @@ vault or a specific tool's hooks.
|
|
|
98
98
|
and tier by reversibility; show the real forks), **Conduct** (answer what was asked,
|
|
99
99
|
once). It absorbed the Pact, which is now stated *inside* Telos rather than standing
|
|
100
100
|
as a peer of the rules.
|
|
101
|
-
- **Invariants** (`src/laws/universal.md`) — *what is never traded*.
|
|
102
|
-
|
|
103
|
-
|
|
101
|
+
- **Invariants** (`src/laws/universal.md`) — *what is never traded*. Nine Rules, `I`..`IX`,
|
|
102
|
+
each declared `### {{LAW:<id>}} <Principle>` with a permanent id; the numeral is its
|
|
103
|
+
position, computed at render time (the retired IX and XI were removed on 2026-09-30, and
|
|
104
|
+
Echo the Intent became IX without a single citation changing).
|
|
104
105
|
- **Doctrines** (`src/doctrines/{craft,rigor,ops,process,comms}.md`) — *how work is done
|
|
105
|
-
here*. Practice rules addressed by pack and
|
|
106
|
+
here*. Practice rules addressed by pack and position (`process 5`), declared and cited by
|
|
107
|
+
id the same way; a citation of any rule renders as its principle's name.
|
|
106
108
|
`PACK_ORDER` (`js/build/source.mjs`) fixes the order craft → rigor → ops → process → comms, which
|
|
107
109
|
is narrative and deliberately not alphabetical.
|
|
108
110
|
|
|
@@ -145,12 +147,12 @@ vault or a specific tool's hooks.
|
|
|
145
147
|
|
|
146
148
|
| Satellite | A new invariant | A new doctrine rule | A whole new pack |
|
|
147
149
|
|---|---|---|---|
|
|
148
|
-
| body |
|
|
149
|
-
| themed title | `LEX_<
|
|
150
|
+
| body | `### {{LAW:<id>}} <Principle>` in `src/laws/universal.md`; citations resolve by id, so no position rewires one | `### {{DOCTRINE:<id>}} <Principle>` in `src/doctrines/<pack>.md`; the number is its position | a new `src/doctrines/<pack>.md` with its `**Name** — lead line` |
|
|
151
|
+
| themed title | `LEX_<ID>` in all 15 theme files | `DOC_<ID>` in all 15 theme files | `PACK_<NAME>` in all 15, plus each rule's `DOC_*` |
|
|
150
152
|
| class | `LAW_CLASS` in `js/inspect/inventory.mjs`, one of the six in `LAW_CLASSES` | **none** — a doctrine rule's class *is* its pack, and there is no second taxonomy over it | — |
|
|
151
153
|
| console copy | a `LAW_META` row in `web/src/pages/Laws.jsx` (keyed by arabic number) | a `DOCTRINE_META` row in the same file (keyed `<pack>.<n>`) | one `DOCTRINE_META` row per rule |
|
|
152
154
|
| registration | the numeral is the registration | the number is the registration | the pack name in `PACK_ORDER`, `js/build/source.mjs` |
|
|
153
|
-
| renumber risk |
|
|
155
|
+
| renumber risk | none for citations (by id); `LAW_META`/`LAW_CLASS` are number-keyed and doctor-pinned, so append by preference | none for citations; `DOCTRINE_META`, exclusions and hook ledger keys are `<pack>.<n>` — append by preference | none |
|
|
154
156
|
| counts | README badge + the `N universal laws` prose, `SHIPPED.md`'s triple, the web onboarding copy | **none** — the console spends the `N_PACKS` / `N_PACKS_ACTIVE` / `N_DOCTRINE_RULES` count tokens, all computed at request time | none, same reason |
|
|
155
157
|
| changelog | `CHANGELOG.md` | `CHANGELOG.md` | `CHANGELOG.md` |
|
|
156
158
|
|
|
@@ -164,8 +166,9 @@ vault or a specific tool's hooks.
|
|
|
164
166
|
Almost all of it is gated, across six named checks in `js/inspect/checks-build.mjs` —
|
|
165
167
|
`themeParityProblems` (key parity across the voices), `lawMetaProblems` and
|
|
166
168
|
`doctrineMetaProblems` (the console's Principle column, in both directions),
|
|
167
|
-
`constitutionProblems` (
|
|
168
|
-
`DOC_*` vocabulary, and every `{{DOCTRINE}}`
|
|
169
|
+
`constitutionProblems` (rule ids declared, unique and never retired, `LEX_*` as an *equality*,
|
|
170
|
+
the `DOC_*` vocabulary, the hook-gated addresses, and every `{{LAW:…}}`/`{{DOCTRINE:…}}`
|
|
171
|
+
citation in `src/` — a citation by number is refused), and
|
|
169
172
|
`countTableProblems` / `proseMirrorProblems` (badges and prose). So `geneseed doctor
|
|
170
173
|
--all` is the check; the table above only says what it will ask for. `CHANGELOG.md` has
|
|
171
174
|
no gate and never has.
|
package/README.md
CHANGED
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
[](package.json)
|
|
11
11
|
[](package.json)
|
|
12
12
|
[](themes/)
|
|
13
|
-
[](src/skills/)
|
|
14
14
|
[](src/agents/)
|
|
15
|
-
[](src/laws/universal.md)
|
|
16
16
|
[](adapters/opencode/plugins/)
|
|
17
17
|
[](#-supported-harnesses)
|
|
18
18
|
|
|
@@ -163,10 +163,10 @@ The harness ships as a small set of layers, and the web console's rail is the sa
|
|
|
163
163
|
| Layer | What it is |
|
|
164
164
|
| --- | --- |
|
|
165
165
|
| **🧭 Ethos** (`ontology/`) | the mind the rules govern, in four prose sections — **Telos** (the Pact: three ranked laws — protect the user, serve their intent, keep your own honesty), **Evidence** (every claim graded by how it was obtained), **Decisions** (classify and tier by reversibility, show the real forks), **Conduct** (answer what was asked, once). Always in force, never toggleable |
|
|
166
|
-
| **🛡️ Rules** (`laws/`) |
|
|
166
|
+
| **🛡️ Rules** (`laws/`) | 9 universal laws — always in force, never toggleable: sealed-secrets, one-intent-one-act, verify-before-asserting, deletion-is-deliberate, surface-failures, data-not-orders, least-privilege, cure-the-cause, echo-the-intent. Each rule has a permanent id; its number is only its position, and the harness cites rules by name |
|
|
167
167
|
| **📐 Doctrines** (`doctrines/`) | practice packs, chosen per install at build time: **craft** (how code is written), **rigor** (how work is proven), **ops** (how the machine is operated), **process** (how a task is run), **comms** (how answers are presented). A doctrine rule may tighten a Rule, never repeal one, and the user's own `user-rules.md` outranks it. Pick with `geneseed-build --doctrines craft,rigor` (or `none`), a single rule with `--exclude-rules "process 7"`, in the setup wizard, or through the switches on the console's Constitution page; all five pack files ship on disk either way, so a citation into a pack you left out still resolves |
|
|
168
168
|
| **🤖 Agents** (18) | capability specialists: `reviewer`, `tester`, `architect`, `docs`, `security`, `explorer`, `researcher`, `developer` — plus a debate **council** the `council` skill convenes: `advocate`, `skeptic`, `pragmatist`, `steward`, `visionary`, `user-advocate`, `framer`, `empiricist`, `operator`, `historian` |
|
|
169
|
-
| **🛠 Skills** (
|
|
169
|
+
| **🛠 Skills** (53) | repeatable workflows: brainstorm · plan · **codebase-design** · **domain-modeling** · **wayfinder** · **tickets** · **develop** · **worktree** · debug · **prototype** · refactor · **ponytail** · **forge-mcp** · **bruno-collection-generator** · **bruno-test-writer** · geneseed-code-review · **fresh-eyes** · **security-audit** · **ci-fix** · **deps-audit** · **review-response** · commit · **ship** · **release** · **migrate** · **git-archaeology** · **git-rescue** · repo-map · document-project · **frontend-design** · **prose** · **ingest** · **research** · **teach** · **quiz** · handoff · roast-me · **council** · parallel-agents · **workflow** · **wiki** · **geneseed** · **rule** · **profile** · **consolidate-memory** · **skill-forge** · **opencode-theme** · **herdr** · **pipeline** · **daydream** · **react-view-transitions** · **token-report** · **explain-changes** |
|
|
170
170
|
| **🔌 Plugins** (OpenCode) | `geneseed-context` injects project docs *and your machine wiki* every session (and across compaction); `geneseed-learn` distils memory at session end; `geneseed-guard` enforces the safety Laws and protected wiki folders at the tool boundary; `geneseed-workflow` registers the `workflow` tool that runs saved orchestration scripts; `geneseed-notify` sends a native OS notification when a long run finishes; `geneseed-ponytail` holds a minimal-code mode (`/ponytail lite\|full\|ultra\|off`), opt-in, injecting the laziest-that-works ruleset every turn so it doesn't drift; `geneseed-activity` streams what each session is doing to the web console's Activity view |
|
|
171
171
|
| **🧠 Memory** (`memory/`) | one-fact-per-file durable knowledge, indexed by `MEMORY.md` (git-ignored, personal) |
|
|
172
172
|
| **📓 Notebook** (`notebook/`) | the agent's sovereign space — any medium (code, tools, data, notes), self-ruled via a seed-once charter, always git-ignored; only its `.gitignore` is build-asserted |
|
package/SHIPPED.md
CHANGED
|
@@ -20,7 +20,7 @@ historical references, not files distributed with the repo.
|
|
|
20
20
|
> **On version numbers.** [`harness.config.json`](harness.config.json)'s `version` is a
|
|
21
21
|
> human-readable label only. The canonical identity of an installed harness is the
|
|
22
22
|
> **source fingerprint** stamped in `.geneseed-version` (see `geneseed version`), not the
|
|
23
|
-
> string. Current label: **3.
|
|
23
|
+
> string. Current label: **3.9.0**.
|
|
24
24
|
|
|
25
25
|
## Capabilities
|
|
26
26
|
|
|
@@ -29,8 +29,8 @@ Every row below is present in the tree today; "Spec" names the design record.
|
|
|
29
29
|
| Capability | What it is | Spec |
|
|
30
30
|
| --- | --- | --- |
|
|
31
31
|
| **Themed generator** | One neutral `src/` → 14 themed bundles via `geneseed-build` (zero dependencies); structure stays theme-independent | [DESIGN.md](DESIGN.md) |
|
|
32
|
-
| **Laws / Agents / Skills / Memory / Notebook** |
|
|
33
|
-
| **Three-tier constitution** | The governance surface splits into an always-on **Ontology** (Telos, Evidence, Decisions, Conduct — the Pact absorbed into Telos), the
|
|
32
|
+
| **Laws / Agents / Skills / Memory / Notebook** | 9 laws, 18 agents, 53 skills, the memory convention, and the agent's sovereign notebook | `2026-06-11-notebook-sovereign-space` · `2026-06-10-notebook-agent-own-space` |
|
|
33
|
+
| **Three-tier constitution** | The governance surface splits into an always-on **Ontology** (Telos, Evidence, Decisions, Conduct — the Pact absorbed into Telos), the nine always-on **Invariants**, and five toggleable **Doctrine** packs (craft, rigor, ops, process, comms) addressed `<pack> <n>`. Every rule carries a permanent id; its number is its position, computed at render time, and a citation renders as the rule's principle name. Packs are chosen at build time with `--doctrines` or the setup wizard; the whole catalogue ships on disk either way, so a citation into an inactive pack still resolves. Precedence, in order: Ontology + Invariants, then the user's `user-rules.md`, then the active Doctrines, then `PROFILE.md`. `doctor`'s `constitutionProblems` gates rule ids (declared, unique, never a retired one), the per-rule Principle column, every `{{LAW:<id>}}` / `{{DOCTRINE:<id>}}` citation in `src/`, and the rule that an always-on tier may never cite a toggleable one | `2026-08-19-three-tier-constitution-design` |
|
|
34
34
|
| **`doctor`** | One check: unresolved tokens, dead/non-hermetic links, theme-key parity, authoring gates, rendered-bundle drift | `2026-06-07-theme-aware-doctor-diff` |
|
|
35
35
|
| **`diff` + improvements export** | Deployed-vs-source drift report; export an `improvements.md` back-port | `2026-06-12-improvements-export` |
|
|
36
36
|
| **`status` / `version`** | Headless dashboard + fingerprint verdict (no TUI needed) | `2026-06-07-status-command` · `2026-06-07-version-and-uninstall` |
|
|
@@ -276,7 +276,7 @@ It is not one now: the invariants are a closed set of nine, and project-context
|
|
|
276
276
|
discovery is one of the two old laws absorbed into AGENT.md's own **§9 Context**
|
|
277
277
|
section, which every build carries as prose. Nothing an adapter spec writes is
|
|
278
278
|
added to the invariants. The text below survives as the *instruction* tier behind
|
|
279
|
-
the *injection* tier, and `{{DOCTRINE}}
|
|
279
|
+
the *injection* tier, and `{{DOCTRINE:read-the-docs-first}}` (Read the Docs First) is its
|
|
280
280
|
nearest live citation:
|
|
281
281
|
|
|
282
282
|
> **Rule (Project Context Discovery).** When project context has not already been
|
|
@@ -384,7 +384,7 @@ behaviour** — nothing changes the machine's current agent/model unless you opt
|
|
|
384
384
|
`2026-06-17-opencode-color-themes` spec).
|
|
385
385
|
- **Runtime guard plugin** (`geneseed-guard.js`, installed with the others). Enforces
|
|
386
386
|
the safety Laws at the tool boundary: **blocks** writes to private-key/credential
|
|
387
|
-
files (
|
|
387
|
+
files (Sealed Secrets), catastrophic shell like `rm -rf /` (Deletion Is Deliberate), and any mutation under
|
|
388
388
|
a declared wiki's `protected` folders (AGENT.md §8, from `wiki.jsonc`); **warns** on
|
|
389
389
|
`.env` writes and force-push. `GENESEED_GUARD=off` disables it, `=warn` downgrades
|
|
390
390
|
blocks to warnings. Every **block** appends one line to the install's
|
|
@@ -400,7 +400,7 @@ behaviour** — nothing changes the machine's current agent/model unless you opt
|
|
|
400
400
|
- **Default permissions.** A fresh `opencode.json` gets a minimal policy that **asks**
|
|
401
401
|
before `rm -rf *` and a force-push — those are **Rule IV**'s territory and are in every
|
|
402
402
|
build — and, **on an install that built the `process` pack in**, before every
|
|
403
|
-
`git commit` and `git push` (the host-level backstop for **
|
|
403
|
+
`git commit` and `git push` (the host-level backstop for **Consent Before Push**: the
|
|
404
404
|
agent never records or shares code unprompted, on any branch). Build with
|
|
405
405
|
`--doctrines` leaving `process` out and those two entries are simply not written.
|
|
406
406
|
The whole block is added only when you have no `permission` key; an existing policy is
|
|
@@ -534,7 +534,7 @@ install `jsonc-parser` yourself — you lose OCX's dependency management and
|
|
|
534
534
|
auto-updates, and you own the upgrade-by-re-copy. Prefer the OCX path.
|
|
535
535
|
|
|
536
536
|
**Consent note.** `worktree_delete` auto-commits before removal. The harness's
|
|
537
|
-
consent-before-commit rule (**
|
|
537
|
+
consent-before-commit rule (**Consent Before Push**, when the `process` pack is built in)
|
|
538
538
|
is enforced for *shell* `git commit` via `opencode.json`
|
|
539
539
|
permissions, but this plugin commits through its own tool path — so review what it
|
|
540
540
|
will commit before invoking delete, or keep the worktree and commit yourself.
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
//
|
|
3
3
|
// Enforces the safety Laws at the tool boundary (`tool.execute.before`), the same
|
|
4
4
|
// "enforce by injection, don't just instruct" stance as the context plugin:
|
|
5
|
-
// -
|
|
6
|
-
// -
|
|
7
|
-
// -
|
|
5
|
+
// - Sealed Secrets: block writes to private-key / credential files.
|
|
6
|
+
// - Deletion Is Deliberate: block catastrophic shell commands.
|
|
7
|
+
// - Persist Insight (rule vs memory): speed-bump the first write to user-rules.md
|
|
8
8
|
// memory file — that choice belongs to the user, via the rule skill.
|
|
9
9
|
// - Wiki (AGENT.md §8): block mutations under a declared wiki's `protected`
|
|
10
10
|
// folders — the user's knowledge base sets its own no-go zones in wiki.jsonc.
|
|
@@ -238,7 +238,7 @@ async function protectedPrefixes() {
|
|
|
238
238
|
return prefixes
|
|
239
239
|
}
|
|
240
240
|
|
|
241
|
-
// ---- the rule / memory stores (
|
|
241
|
+
// ---- the rule / memory stores (Persist Insight) --------------------------------
|
|
242
242
|
// Whether something the user wants kept is a standing rule or a durable fact is THEIR
|
|
243
243
|
// call, settled through the rule skill. `tool.execute.before` can only allow or throw —
|
|
244
244
|
// it has no "ask the user" tier like the Claude/Bob rule-gate hook —
|
|
@@ -285,13 +285,13 @@ export const GeneseedGuard = async () => {
|
|
|
285
285
|
try {
|
|
286
286
|
if (hasAny(tool, WRITE_TOOLS)) {
|
|
287
287
|
const p = pickPath(args)
|
|
288
|
-
if (p && SECRET_RE.some((re) => re.test(p))) { await deny(`write to secret/key file ${p} (
|
|
289
|
-
if (p && SECRET_WARN_RE.some((re) => re.test(p))) log(`WARN: writing ${p} — keep secrets out of tracked files (
|
|
288
|
+
if (p && SECRET_RE.some((re) => re.test(p))) { await deny(`write to secret/key file ${p} (Sealed Secrets)`, "law-1"); return }
|
|
289
|
+
if (p && SECRET_WARN_RE.some((re) => re.test(p))) log(`WARN: writing ${p} — keep secrets out of tracked files (Sealed Secrets)`)
|
|
290
290
|
const store = p && ruleStoreTarget(p)
|
|
291
291
|
if (store && !RULE_STORE_BUMPED.has(p)) {
|
|
292
292
|
RULE_STORE_BUMPED.add(p)
|
|
293
293
|
await deny(`writing to ${store} — a standing rule, or a fact to remember? That ` +
|
|
294
|
-
`choice is the user's (
|
|
294
|
+
`choice is the user's (Persist Insight). Settle it through the rule skill, ` +
|
|
295
295
|
`then re-issue this write`, "process-1")
|
|
296
296
|
return
|
|
297
297
|
}
|
|
@@ -309,8 +309,8 @@ export const GeneseedGuard = async () => {
|
|
|
309
309
|
// classes, and the shell check must still run after the write check.
|
|
310
310
|
if (hasAny(tool, SHELL_TOOLS)) {
|
|
311
311
|
const c = pickCommand(args)
|
|
312
|
-
if (c && SHELL_BLOCK_RE.some((re) => re.test(c))) { await deny(`catastrophic command (
|
|
313
|
-
if (c && SHELL_WARN_RE.some((re) => re.test(c))) log(`WARN: irreversible op — confirm intent (
|
|
312
|
+
if (c && SHELL_BLOCK_RE.some((re) => re.test(c))) { await deny(`catastrophic command (Deletion Is Deliberate): ${c.slice(0, 80)}`, "law-4"); return }
|
|
313
|
+
if (c && SHELL_WARN_RE.some((re) => re.test(c))) log(`WARN: irreversible op — confirm intent (Deletion Is Deliberate): ${c.slice(0, 80)}`)
|
|
314
314
|
}
|
|
315
315
|
} catch (err) {
|
|
316
316
|
// Our own deny must propagate; any inspection error must never break a tool call.
|
|
@@ -89,7 +89,7 @@ function summarize(name, result, stats, tracePath) {
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
// Kept worktrees are work awaiting review, and an overlap is a conflict awaiting ONE
|
|
92
|
-
// merger (
|
|
92
|
+
// merger (One Writer Per File) — both are said out loud, never left for the trace to hold.
|
|
93
93
|
function isolationReport(stats) {
|
|
94
94
|
const kept = stats.worktrees || []
|
|
95
95
|
if (!kept.length) return ""
|
|
@@ -182,8 +182,8 @@ async function runChildSession(client, { prompt, agent, model, title, directory
|
|
|
182
182
|
|
|
183
183
|
// ---- worktree isolation ------------------------------------------------------
|
|
184
184
|
// `agent(prompt, { isolation: "worktree" })` — the same option Claude Code's Workflow
|
|
185
|
-
// takes. Parallel editors in one tree lose each other's writes (
|
|
186
|
-
//
|
|
185
|
+
// takes. Parallel editors in one tree lose each other's writes (One Writer Per File),
|
|
186
|
+
// so each isolated agent gets its own branch + worktree off the root's HEAD, and
|
|
187
187
|
// the files it changed are recorded for `overlaps()`. A worktree with no change is
|
|
188
188
|
// removed with its branch; one with changes is KEPT for the parent to review and merge —
|
|
189
189
|
// the runtime never merges, commits, or deletes work. `git(argv, cwd)` is injected by the
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
// The model-driven fallback is the parallel-agents skill; this runs the same
|
|
5
5
|
// shape on rails: the script, not the model, enforces routing and the handoff
|
|
6
|
-
// envelope (context in, output contract back, no commits —
|
|
6
|
+
// envelope (context in, output contract back, no commits — Consent Before Push stays with
|
|
7
7
|
// the caller).
|
|
8
8
|
//
|
|
9
9
|
// args: { goal: string, context?: string, agents?: string[] }
|
package/docs/extending.md
CHANGED
|
@@ -155,36 +155,43 @@ Notes that matter:
|
|
|
155
155
|
|
|
156
156
|
## 2 — Changing the constitution
|
|
157
157
|
|
|
158
|
-
Three tiers, four different costs.
|
|
159
|
-
|
|
160
|
-
|
|
158
|
+
Three tiers, four different costs. Every law and doctrine rule has a **permanent id** — kebab-case,
|
|
159
|
+
derived from its English principle when it is created (`verify-before-asserting`,
|
|
160
|
+
`consent-before-push`) — declared by its heading, `### {{LAW:<id>}} <Principle Name>` or
|
|
161
|
+
`### {{DOCTRINE:<id>}} <Principle Name>`, and cited by it: `{{LAW:<id>}}`, `{{DOCTRINE:<id>}}`.
|
|
162
|
+
**The number is not stored anywhere.** `ruleCanon` in `js/build/source.mjs` computes it from the
|
|
163
|
+
rule's position (Roman in `laws/universal.md`, Arabic within its pack) at render time; the heading
|
|
164
|
+
renders `Rule III — <themed title>` and a citation renders as the principle's name, in italics,
|
|
165
|
+
identical in every voice — the same string an agent is told to write into its memory. So adding,
|
|
166
|
+
removing or reordering a rule rewires nothing. `constitutionProblems` refuses a citation by number,
|
|
167
|
+
an unknown id, a duplicate id, a heading with no id, and a retired id declared again. The ontology is
|
|
168
|
+
cited by section name, and adding a section to it is not a checklist, it is a design change.
|
|
161
169
|
|
|
162
170
|
To count the cross-references either tier already carries, from the repo root:
|
|
163
171
|
|
|
164
172
|
```bash
|
|
165
|
-
grep -rhoE "\{\{LAW
|
|
166
|
-
grep -rhoE "\{\{DOCTRINE
|
|
173
|
+
grep -rhoE "\{\{LAW:[a-z0-9-]+\}\}" src/ | wc -l
|
|
174
|
+
grep -rhoE "\{\{DOCTRINE:[a-z0-9-]+\}\}" src/ | wc -l
|
|
167
175
|
```
|
|
168
176
|
|
|
169
|
-
|
|
170
|
-
|
|
177
|
+
Both numbers move on every wave of editing, which is why the commands are here and the answers are
|
|
178
|
+
not.
|
|
171
179
|
|
|
172
180
|
### 2a — Adding a DOCTRINE RULE (the common case)
|
|
173
181
|
|
|
174
182
|
Five files, plus the written-out rule totals in four test files. This is the slot most new
|
|
175
183
|
material belongs in, and it is cheap on purpose so that the invariant slot stays scarce.
|
|
176
184
|
|
|
177
|
-
1. `src/doctrines/<pack>.md` —
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
(`js/
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
2. `themes/_TEMPLATE.json` — add `DOC_<PACK>_<n>`. ⚠ **This file *is* gated for this key family.**
|
|
185
|
+
1. `src/doctrines/<pack>.md` — add `### {{DOCTRINE:<new-id>}} <Principle Name>` plus the body,
|
|
186
|
+
wrapped in a `LEAN` block with **both halves authored** — the heading stays outside the block,
|
|
187
|
+
the full text goes in `LEAN:begin`, and the lean half is the rule *and its mechanism*, no maxims
|
|
188
|
+
(the style rule is in `src/doctrines/README.md`, and `leanBlockProblems` refuses a rule with no
|
|
189
|
+
block or an empty half). The id is kebab-case, unique across laws **and** doctrines, and never
|
|
190
|
+
one listed in `RETIRED_RULE_IDS` (`js/build/source.mjs`). Where it goes in the file decides its
|
|
191
|
+
number; appending is still the kind move, because `excludeRules`, `DOCTRINE_META` and the
|
|
192
|
+
hook-gated addresses are keyed `<pack>.<n>` (see §2e).
|
|
193
|
+
2. `themes/_TEMPLATE.json` — add `DOC_<ID>` (`consent-before-push` → `DOC_CONSENT_BEFORE_PUSH`).
|
|
194
|
+
⚠ **This file *is* gated for this key family.**
|
|
188
195
|
`themeFiles()` filters `_`-prefixed names and theme parity never sees the template, but
|
|
189
196
|
`constitutionProblems` reads it alongside the fourteen voices for `DOC_*` and `LEX_*`
|
|
190
197
|
specifically — because it is what `--sync-themes` seeds the *next* voice from. Every other key
|
|
@@ -199,7 +206,9 @@ material belongs in, and it is cheap on purpose so that the invariant slot stays
|
|
|
199
206
|
is one of the two. See §7.2 before you copy a command from anywhere else. Then restyle all
|
|
200
207
|
fourteen by hand: `--sync-themes` writes the template's placeholder and only *prints*
|
|
201
208
|
`RESTYLE these`; a shipped placeholder passes every gate.
|
|
202
|
-
4. `web/src/pages/Laws.jsx` — a `DOCTRINE_META` row keyed `'<pack>.<n>'
|
|
209
|
+
4. `web/src/pages/Laws.jsx` — a `DOCTRINE_META` row keyed `'<pack>.<n>'`, whose third field is the
|
|
210
|
+
rule's id — `doctrineMetaProblems` holds that pin to the canon, so a row left behind by a
|
|
211
|
+
renumber is a failure rather than a description of the neighbour. Its first field is the
|
|
203
212
|
**pack**, not one of `LAW_CLASSES`' six; `doctrineMetaProblems` requires an *equality* between
|
|
204
213
|
that field and the key's own pack, which catches the copy error a six-way vocabulary cannot — a
|
|
205
214
|
row pasted from the pack above it, keeping the wrong pack. Its second field is the one-line
|
|
@@ -213,19 +222,18 @@ material belongs in, and it is cheap on purpose so that the invariant slot stays
|
|
|
213
222
|
there is no second taxonomy over it.
|
|
214
223
|
- **No count in the product.** No badge, no `SHIPPED.md` triple, no prose mirror. The console spends
|
|
215
224
|
`{N_PACKS}` / `{N_PACKS_ACTIVE}` / `{N_DOCTRINE_RULES}`, all computed at request time.
|
|
216
|
-
- **No
|
|
225
|
+
- **No citation to rewire.** But there *are* written-out rule totals to bump — expected values are
|
|
217
226
|
written out, never recorded — in `tests/unit/emit_smoke.test.mjs`, `harness.test.mjs`,
|
|
218
227
|
`setup.test.mjs` and `web_api.test.mjs`. Each fails loudly with the new count; change the
|
|
219
228
|
number *and* the comment that explains it. A rule in **craft** moves more: `setup` and
|
|
220
229
|
`web_api` also pin the craft-only narrowed counts, `generate.test.mjs` excludes every craft
|
|
221
|
-
rule by address to empty the pack
|
|
222
|
-
the first free craft id — the doctrine twin of §2c step 8. Grep `tests/` for the previous
|
|
230
|
+
rule by address to empty the pack. Grep `tests/` for the previous
|
|
223
231
|
rule's address before trusting this list. A rule long enough to matter can also breach the
|
|
224
232
|
`full` carrier ceiling in `emit_smoke` — raise it with a dated note there, as every earlier
|
|
225
233
|
move did.
|
|
226
234
|
|
|
227
235
|
⚠ **Cite only downward.** An always-on tier may never reference a toggleable one:
|
|
228
|
-
`constitutionProblems` refuses a `{{DOCTRINE}}` token anywhere under `src/ontology/` or
|
|
236
|
+
`constitutionProblems` refuses a `{{DOCTRINE:…}}` token anywhere under `src/ontology/` or
|
|
229
237
|
`src/laws/`, because a `--doctrines craft` build would then ship an invariant pointing at text its
|
|
230
238
|
`AGENT.md` does not contain. Doctrine→doctrine citations are fine and stay — every pack file ships
|
|
231
239
|
on disk whether or not it was built in. If the build's own default is narrowed,
|
|
@@ -248,26 +256,25 @@ Steps 1 and 9 of §2c, plus `LAW_META` if the Principle line moved. Two cautions
|
|
|
248
256
|
Nine steps, and only the first is the rule itself. This is the expensive one, and it should be:
|
|
249
257
|
the bar is in `DESIGN.md` Decision 7, and most candidates belong in a doctrine pack instead.
|
|
250
258
|
|
|
251
|
-
1. `src/laws/universal.md` —
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
in every file and parity was silent — they were absent from nowhere.
|
|
259
|
+
1. `src/laws/universal.md` — add `### {{LAW:<new-id>}} <Principle Name>` plus the body. Citations
|
|
260
|
+
are by id and resolve against the canon, so position is safe to choose — but append unless the
|
|
261
|
+
order is the point: `LAW_CLASS` and `LAW_META` are keyed by the rendered number (see §2e).
|
|
262
|
+
2. `themes/_TEMPLATE.json` — add `LEX_<ID>` in template order. Gated, as in §2a step 2:
|
|
263
|
+
`constitutionProblems` holds the `LEX_*` keys as an **equality** with the declared law ids across
|
|
264
|
+
all fifteen files (the fourteen voices and the template), so both a missing key *and* a leftover
|
|
265
|
+
one are reported. That arm exists because an old renumber left `LEX_XXII`, `LEX_XXIII`,
|
|
266
|
+
`LEX_XXIV` and `LEX_XXXVI` behind in every file and parity was silent.
|
|
260
267
|
3. `--sync-themes`, then restyle all fourteen by hand (§2a step 3).
|
|
261
268
|
4. `LAW_CLASS` in `js/inspect/inventory.mjs` — one of the six in `LAW_CLASSES` beside it.
|
|
262
|
-
5. `LAW_META` in `web/src/pages/Laws.jsx` — same class,
|
|
263
|
-
is keyed by **arabic** number where
|
|
269
|
+
5. `LAW_META` in `web/src/pages/Laws.jsx` — same class, the one-line Principle, and the rule's id
|
|
270
|
+
as the pin. Note the map is keyed by **arabic** number where the heading renders a Roman numeral. **This copy
|
|
264
271
|
exists nowhere else**; a rule absent here renders with a blank description. It is why that one
|
|
265
272
|
React file ships alone out of `web/src` in `package.json` — `doctor` regex-parses its literal.
|
|
266
273
|
6. `README.md` — badge `badge/laws-N` and the `N universal laws` sentence.
|
|
267
274
|
7. `SHIPPED.md` — the `N laws, N agents, N skills` triple.
|
|
268
|
-
8. `tests/unit/harness.test.mjs` — the negative fixture for the `LAW_CLASS` gate
|
|
269
|
-
the
|
|
270
|
-
|
|
275
|
+
8. `tests/unit/harness.test.mjs` — the negative fixture for the `LAW_CLASS` gate appends a law and
|
|
276
|
+
expects the next numeral (`X` while there are nine), and `ROMANS` there and in `emit_smoke`
|
|
277
|
+
lists the numerals written out. Bump both.
|
|
271
278
|
9. `CHANGELOG.md`, then rebuild and commit `web/dist` (step 5 touched `web/src`).
|
|
272
279
|
|
|
273
280
|
⚠ While restyling, `{{LAW}}` must stay a **single word** in every theme (and so must
|
|
@@ -288,8 +295,8 @@ the only configuration it can speak for.
|
|
|
288
295
|
Rare, and mechanical. On top of §2a for each rule the pack carries:
|
|
289
296
|
|
|
290
297
|
1. `src/doctrines/<pack>.md`, opening with its lead line — `**{{PACK_<NAME>}}** — how … .` A pack
|
|
291
|
-
file `PACK_ORDER` names but cannot read, or one
|
|
292
|
-
|
|
298
|
+
file `PACK_ORDER` names but cannot read, or one declaring no `### {{DOCTRINE:<id>}}` rule at
|
|
299
|
+
all, is a refusal.
|
|
293
300
|
2. `PACK_ORDER` in `js/build/source.mjs` — the registration, and the render order. It is **narrative,
|
|
294
301
|
not alphabetical** (craft → rigor → ops → process → comms); discovery sorts alphabetically and the
|
|
295
302
|
renderer refuses a `.md` under `src/doctrines/` that `PACK_ORDER` does not name, rather than
|
|
@@ -315,6 +322,31 @@ Rare, and mechanical. On top of §2a for each rule the pack carries:
|
|
|
315
322
|
|
|
316
323
|
---
|
|
317
324
|
|
|
325
|
+
### 2e — Removing, retiring or reordering a rule
|
|
326
|
+
|
|
327
|
+
Delete the rule's heading and both LEAN halves, and every rule after it renumbers on the next
|
|
328
|
+
render — no citation moves, because none names a number. Then:
|
|
329
|
+
|
|
330
|
+
1. `RETIRED_RULE_IDS` in `js/build/source.mjs` — add the id with what it was and where its text
|
|
331
|
+
went. `constitutionProblems` refuses a retired id declared again, so an id that meant one rule in
|
|
332
|
+
someone's notes can never come back meaning another. `liveAs` names the one tier that may still
|
|
333
|
+
declare it (Law IX's `external-gate` lives on as a rigor rule).
|
|
334
|
+
2. Every citation of the removed id — the doctor names each one; point it at the rule that now
|
|
335
|
+
carries the text.
|
|
336
|
+
3. Its `LEX_<ID>`/`DOC_<ID>` key in all fifteen theme files (the equality arm names each).
|
|
337
|
+
4. The number-keyed tables, which the doctor checks against the canon: `LAW_CLASS`
|
|
338
|
+
(`js/inspect/inventory.mjs`), `LAW_META`/`DOCTRINE_META` (their id pins fail on every shifted
|
|
339
|
+
row), and — only if a hook-gated rule moved — `HOOK_PINNED` in `checks-authoring.mjs` names the
|
|
340
|
+
ledger keys, `CONSENT_RULE` and `HOOK_GATED` to move with it. `--exclude-rules` addresses are
|
|
341
|
+
`<pack>.<n>` too, and an install that excluded a shifted doctrine rule excludes its neighbour
|
|
342
|
+
after a re-emit: prefer appending in a pack, and say so in the CHANGELOG when you cannot.
|
|
343
|
+
5. The count mirrors: README badge and prose, `SHIPPED.md`, and the written-out totals in tests.
|
|
344
|
+
|
|
345
|
+
Laws IX (External Gate) and XI (Absence Is a Claim) were removed this way on 2026-09-30; Echo the
|
|
346
|
+
Intent became IX.
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
318
350
|
## 3 — Adding a SKILL or an AGENT
|
|
319
351
|
|
|
320
352
|
**Order matters at the first two steps.** `missingReferencedSpecs` (in `js/build/bundle.mjs`) *aborts the
|
|
@@ -574,7 +606,7 @@ only, at best, on its presence.
|
|
|
574
606
|
|---|---|---|
|
|
575
607
|
| `§N` cross-references into `AGENT.md`'s anatomy | `src/skills/*`, `src/agents/*`, `adapters/**` | **range only.** `constitutionProblems` refuses a `§N` the template declares no section for — which catches a pointer past the end, the shape *removing* a section leaves. It cannot catch one that still resolves and now means something else, which is the shape *inserting* a section leaves, and is what actually happened when `## 2. Doctrines` pushed every later section down one. **Renumbering the anatomy means `grep -rn '§' src/ adapters/` and reading every hit.** Four satellites and a live OpenCode deny message shipped stale because the sweep stopped at `AGENT.md.tmpl` |
|
|
576
608
|
| Per-law Principle lines | `web/src/pages/Laws.jsx` | presence and class only, never accuracy |
|
|
577
|
-
| 588 themed constitution titles (42 keys × 14 voices) — `
|
|
609
|
+
| 588 themed constitution titles (42 keys × 14 voices) — `LEX_<ID>` (one per law), `DOC_<ID>` (one per doctrine rule), `PACK_<NAME>` | `themes/*.json` | key presence only — a shipped placeholder is green. `LEX_*` and `DOC_*` are held across the template too, and in both directions; `PACK_*` only across the voices |
|
|
578
610
|
| The README keyword enumerations | `README.md`, `docs/web/rules.md` | nothing |
|
|
579
611
|
| The plugin capability enumeration | `docs/web/model.md` | nothing (the number substitutes; the list does not) |
|
|
580
612
|
| Section labels and page subtitles | `web/src/lib/sections.js`, `web/src/pages/Docs/index.jsx` | nothing |
|
package/docs/web/harnesses.md
CHANGED
|
@@ -13,7 +13,7 @@ The harness *content* — the constitution (Ethos, Rules, Doctrines), Agents, Sk
|
|
|
13
13
|
| Agents · Skills · Memory | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
14
14
|
| Context injection | ⚙️ plugin | 🪝 hook | 🪝 hook¹ | 📄 preamble | 🪝 hook² |
|
|
15
15
|
| Memory write-back (learn) | ⚙️ plugin | 🪝 hook | 🪝 hook¹ | 📄 preamble | 🪝 hook² |
|
|
16
|
-
| Git-gate consent (
|
|
16
|
+
| Git-gate consent (Consent Before Push) | ⚙️ plugin | 🪝 hook | 🪝 hook¹ | 📄 preamble | 🪝 hook² |
|
|
17
17
|
| Sovereign-repo excludes | ⚙️ plugin | ✅ | ✅ | ➖ | ✅ |
|
|
18
18
|
| MCP server wiring | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
19
19
|
| Colour themes | ✅ | ➖ | ➖ | ➖ | ➖ |
|
|
@@ -21,7 +21,7 @@ The harness *content* — the constitution (Ethos, Rules, Doctrines), Agents, Sk
|
|
|
21
21
|
|
|
22
22
|
✅ native · ⚙️ OpenCode plugin · 🪝 `settings.json` hook · 📄 preamble prose only · ➖ no host mechanism (harness discipline still applies). ¹ Bob honours Claude-dialect hooks best-effort — inert if unsupported, harness still holds via the preamble. ² OpenClaude is a Claude Code fork: Claude's hooks verbatim, under `~/.openclaude` or a repo's `.openclaude/`.
|
|
23
23
|
|
|
24
|
-
**The git-gate row is the one capability that is not always present**, on any host. It implements **
|
|
24
|
+
**The git-gate row is the one capability that is not always present**, on any host. It implements **Consent Before Push** (`process 5`), so it is wired only on an install that built the **process** [doctrine pack](#/docs/setup-choices) in — drop that pack and the boundary drops with it, because a gate that keeps asking for a rule the install never adopted is a gate arguing with its own harness. One asymmetry: on OpenCode that holds for a *fresh* install, but a pack-off rebuild of an install whose `opencode.json` already carries a `git commit*` entry leaves it in place and reports it — Geneseed cannot tell its own entry from one you typed, so it removes neither ([doctrine packs](#/docs/setup-choices)). The invariant-territory refusals in the same neighbourhood (`rm -rf`, a force-push) are the Rules' territory, not the pack's, and stay in every build.
|
|
25
25
|
|
|
26
26
|
**No host drops an Agent, Skill, or the memory convention.** The asymmetry is otherwise entirely in *automation mechanism*: OpenCode's plugins and Claude/Bob/OpenClaude's hooks enforce a few of these rules for you at the tool boundary, where **Copilot** (no hook mechanism) enforces them through preamble discipline. The OpenCode-only extras (themes, LSP, workflow runner, primary-agent) have no analogue on a Claude-shaped host.
|
|
27
27
|
|
package/docs/web/plugin-guard.md
CHANGED
|
@@ -6,9 +6,9 @@ kind: "concept"
|
|
|
6
6
|
---
|
|
7
7
|
Enforces the safety Laws at the tool boundary (`tool.execute.before`) — the same *enforce by injection, don't just instruct* stance as the context plugin. The guard ships whole on every install, whatever [doctrine packs](#/docs/setup-choices) it built in — its blocking arms are **invariant** territory, and the speed-bump below is about which store a note belongs in, which is your call either way. The one boundary that does follow a pack is the commit/push consent gate, and that lives in the permission block rather than here. High-confidence patterns only, so legitimate work is never caught:
|
|
8
8
|
|
|
9
|
-
- **Blocks** — writes to private-key / credential files (**
|
|
9
|
+
- **Blocks** — writes to private-key / credential files (**Sealed Secrets**), catastrophic shell like `rm -rf /` (**Deletion Is Deliberate**), and any mutation under a declared wiki's `protected` folders (AGENT.md §8, from `wiki.jsonc`).
|
|
10
10
|
- **Warns** (logged, allowed) — `.env` writes and force-push.
|
|
11
|
-
- **Speed-bumps** — the *first* write to `user-rules.md` or a memory file is refused, naming **
|
|
11
|
+
- **Speed-bumps** — the *first* write to `user-rules.md` or a memory file is refused, naming **Persist Insight**: a standing rule or a durable fact is the user's call, settled through the rule skill. A re-issued write goes through, so a legitimate write is never trapped. (On Claude Code and Bob the same guard is a `geneseed-hook rule-gate` hook, which can *ask* the user instead of refusing — OpenCode's `tool.execute.before` has no ask tier.)
|
|
12
12
|
|
|
13
13
|
### Install
|
|
14
14
|
|
package/docs/web/rules.md
CHANGED
|
@@ -13,7 +13,7 @@ The agent's standing rules come in **three tiers**, and the tier decides how a r
|
|
|
13
13
|
|
|
14
14
|
### Invariants — always on
|
|
15
15
|
|
|
16
|
-
{N_LAWS} rules in `src/laws/universal.md`, numbered in Roman from `I`: sealed secrets, one intent per act, verify before asserting, deliberate deletion, surface failures, data not orders, least privilege, cure the cause, and the
|
|
16
|
+
{N_LAWS} rules in `src/laws/universal.md`, numbered in Roman from `I`: sealed secrets, one intent per act, verify before asserting, deliberate deletion, surface failures, data not orders, least privilege, cure the cause, and echo the intent. They hold in every task and every repository, they are never traded away, and no install can switch one off. Cited by name — *Deletion Is Deliberate* — never by numeral: the numeral is only the rule's position, and it moves when a rule before it is removed.
|
|
17
17
|
|
|
18
18
|
### Doctrines — chosen at build time
|
|
19
19
|
|
|
@@ -11,8 +11,8 @@ A theme is one JSON file under `themes/` declaring voice tokens only: `BANNER`,
|
|
|
11
11
|
|
|
12
12
|
Every rule in the constitution gets its title from a theme key, and a theme that omits one ships a rule with a blank heading:
|
|
13
13
|
|
|
14
|
-
- `
|
|
15
|
-
- `DOC_
|
|
14
|
+
- `LEX_<ID>` — one title per invariant, keyed by the law's permanent id (`LEX_VERIFY_BEFORE_ASSERTING`), never by its number. `doctor` holds this to an **equality**, not mere presence: a `LEX_*` no law declares is a title for a rule that does not exist and fails the check too.
|
|
15
|
+
- `DOC_<ID>` — one title per doctrine rule, keyed by its id (`DOC_AUTOMATE_REPETITION`, `DOC_CONSENT_BEFORE_PUSH`, …). `doctor` reads the pack files under `src/doctrines/` and requires exactly the set they declare — a missing one is a blank heading, an extra one is a dead key. A title is the rule's heading only: a citation of the rule renders as its English principle name in every voice.
|
|
16
16
|
- `PACK_*` — one name per pack (`PACK_CRAFT`, `PACK_RIGOR`, `PACK_OPS`, `PACK_PROCESS`, `PACK_COMMS`), used for the pack's own sub-heading.
|
|
17
17
|
|
|
18
18
|
The Ethos section names are **not** theme keys: a citation reads `({{ONTOLOGY}}: {{ONT_TELOS}})`, token on both sides, so heading and reference always move together. They live in the build's fixed structure table and you neither declare nor rename them.
|
package/docs/web-ui.md
CHANGED
|
@@ -160,7 +160,7 @@ streams the output of background jobs and keeps their history across reloads.
|
|
|
160
160
|
global harness goes dormant (hooks stay silent, the global preamble never loads);
|
|
161
161
|
add or remove one here, the web mirror of `harness exclude add|remove|list`.
|
|
162
162
|
- **Settings** (`#/settings`) — a **Console direction** picker (the visual flavour of the
|
|
163
|
-
console) with a **Dashboard layout** control (Auto follows each theme's designed Status
|
|
163
|
+
console: Cultivar, Operator, Matrix or Atlas) with a **Dashboard layout** control (Auto follows each theme's designed Status
|
|
164
164
|
lens; Cultivar / Greenhouse / Operator / Journal force one regardless of skin), the
|
|
165
165
|
install snapshot (deployed/target/theme/version/memory store), a Maintenance card (PATH
|
|
166
166
|
link/unlink, uninstall), an offline package download, server controls (Stop), and the
|
package/harness.config.json
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
"_comment": "version is a human-readable release label only; the canonical identity of an installed harness is the source fingerprint stamped in .geneseed-version (see `harness version`), not this string.",
|
|
3
3
|
"theme": "neutral",
|
|
4
4
|
"product": "Geneseed",
|
|
5
|
-
"version": "3.
|
|
5
|
+
"version": "3.9.0"
|
|
6
6
|
}
|
package/js/README.md
CHANGED
|
@@ -37,7 +37,7 @@ as a per-host install at project or global scope.
|
|
|
37
37
|
|
|
38
38
|
| module | owns |
|
|
39
39
|
|---|---|
|
|
40
|
-
| `source.mjs` | Where the SOURCE is: `ROOT`/`SRC`/`THEMES`/`CONFIG`, `PACK_ORDER`, rule ids, the cfg object |
|
|
40
|
+
| `source.mjs` | Where the SOURCE is: `ROOT`/`SRC`/`THEMES`/`CONFIG`, `PACK_ORDER`, the rule canon (stable ids → positional numbers, citations → names), the cfg object |
|
|
41
41
|
| `render.mjs` | The pure text pipeline: theme load, `INCLUDE` inlining, CATALOG blocks, `{{TOKENS}}`, dest paths |
|
|
42
42
|
| `bundle.mjs` | `build` — render a theme into a bundle dir, plus the source-completeness refusal. Sits UNDER both emits |
|
|
43
43
|
| `emit-claude.mjs` | The Claude/Bob/Copilot/OpenClaude emit — the render half plus the settings + CLAUDE.md managed-block wire |
|
|
@@ -182,8 +182,9 @@ and inline lists are held against a surface list written out in
|
|
|
182
182
|
|
|
183
183
|
| I want to | open first | then |
|
|
184
184
|
|---|---|---|
|
|
185
|
-
| a doctrine rule | `src/doctrines/<pack>.md` —
|
|
186
|
-
| a law (invariant) | `src/laws/universal.md` —
|
|
185
|
+
| a doctrine rule | `src/doctrines/<pack>.md` — `### {{DOCTRINE:<id>}} <Principle>`; the number is its position | `docs/extending.md` §2a — five files, `--sync-themes`, restyle 14 voices by hand. Author BOTH LEAN halves |
|
|
186
|
+
| a law (invariant) | `src/laws/universal.md` — `### {{LAW:<id>}} <Principle>`; cite by id, never by number | `docs/extending.md` §2c. Author both LEAN halves: the lean footprint ships nothing else |
|
|
187
|
+
| to remove or retire a rule | `docs/extending.md` §2e | `RETIRED_RULE_IDS` in `js/build/source.mjs` — a retired id is never reused |
|
|
187
188
|
| a skill or an agent | `src/skills/<name>.md` or `src/agents/<name>.md` | `docs/extending.md` §3 — eight steps. Write the FILE before the table row or the build aborts |
|
|
188
189
|
| a doctor check | `js/inspect/checks-{build,repo,authoring}.mjs` | register with `ran(...)` in `doctor.mjs`, then a PLANTED FAULT in `tests/unit/harness.test.mjs` |
|
|
189
190
|
| a web endpoint | GET → `js/web/api.mjs`; POST → `js/web/actions.mjs` | declare it in `js/web/routes.mjs`; the partition test probes the real handler |
|