@onlooker-community/ecosystem 0.33.0 → 0.34.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.
Files changed (57) hide show
  1. package/.agents/skills/beads/SKILL.md +80 -0
  2. package/.agents/skills/beads/agents/openai.yaml +4 -0
  3. package/.claude/settings.json +13 -0
  4. package/.claude-plugin/plugin.json +1 -1
  5. package/.codex/config.toml +2 -0
  6. package/.codex/hooks.json +51 -0
  7. package/.markdownlint.json +3 -0
  8. package/.release-please-manifest.json +8 -8
  9. package/AGENTS.md +135 -0
  10. package/CHANGELOG.md +14 -0
  11. package/CLAUDE.md +56 -1
  12. package/docs/lesson-promotion-pipeline.md +210 -0
  13. package/docs/superpowers/plans/2026-08-09-lesson-transform.md +1537 -0
  14. package/docs/superpowers/specs/2026-08-09-lesson-transform-design.md +261 -0
  15. package/package.json +3 -2
  16. package/plugins/archivist/scripts/lib/archivist-config.sh +10 -34
  17. package/plugins/assayer/.claude-plugin/plugin.json +1 -1
  18. package/plugins/assayer/CHANGELOG.md +7 -0
  19. package/plugins/assayer/scripts/lib/assayer-config.sh +39 -62
  20. package/plugins/cartographer/scripts/lib/cartographer-config.sh +11 -29
  21. package/plugins/compass/scripts/lib/compass-config.sh +16 -46
  22. package/plugins/counsel/scripts/lib/counsel-config.sh +15 -46
  23. package/plugins/curator/.claude-plugin/plugin.json +1 -1
  24. package/plugins/curator/CHANGELOG.md +7 -0
  25. package/plugins/curator/scripts/lib/curator-config.sh +19 -44
  26. package/plugins/echo/scripts/lib/echo-config.sh +30 -59
  27. package/plugins/governor/scripts/lib/governor-config.sh +11 -41
  28. package/plugins/historian/scripts/lib/historian-config.sh +9 -33
  29. package/plugins/inspector/.claude-plugin/plugin.json +1 -1
  30. package/plugins/inspector/CHANGELOG.md +7 -0
  31. package/plugins/inspector/scripts/lib/inspector-config.sh +39 -63
  32. package/plugins/librarian/.claude-plugin/plugin.json +1 -1
  33. package/plugins/librarian/CHANGELOG.md +7 -0
  34. package/plugins/librarian/config.json +4 -0
  35. package/plugins/librarian/schema/PROVENANCE.json +7 -0
  36. package/plugins/librarian/schema/lesson-applies-to.subschema.json +74 -0
  37. package/plugins/librarian/schema/lesson-evidence.subschema.json +36 -0
  38. package/plugins/librarian/scripts/hooks/librarian-session-end.sh +26 -0
  39. package/plugins/librarian/scripts/lib/librarian-config.sh +10 -34
  40. package/plugins/librarian/scripts/lib/librarian-lesson-storage.sh +135 -0
  41. package/plugins/librarian/scripts/lib/librarian-lesson-transform.sh +311 -0
  42. package/plugins/librarian/scripts/lib/librarian-lesson-validate.sh +140 -0
  43. package/plugins/lineage/.claude-plugin/plugin.json +1 -1
  44. package/plugins/lineage/CHANGELOG.md +7 -0
  45. package/plugins/lineage/scripts/lib/lineage-config.sh +17 -53
  46. package/plugins/scribe/.claude-plugin/plugin.json +1 -1
  47. package/plugins/scribe/CHANGELOG.md +7 -0
  48. package/plugins/scribe/scripts/lib/scribe-config.sh +17 -47
  49. package/plugins/tribunal/.claude-plugin/plugin.json +1 -1
  50. package/plugins/tribunal/CHANGELOG.md +7 -0
  51. package/plugins/tribunal/scripts/lib/tribunal-config.sh +25 -63
  52. package/plugins/warden/scripts/lib/warden-config.sh +17 -54
  53. package/scripts/lib/config-loader.sh +8 -1
  54. package/scripts/lint/check-lesson-schema-drift.mjs +36 -0
  55. package/test/bats/librarian-lesson-transform.bats +609 -0
  56. package/test/node/lesson-schema-drift.test.mjs +28 -0
  57. package/test/node/lesson-validate-agreement.test.mjs +154 -0
@@ -0,0 +1,80 @@
1
+ ---
2
+ name: beads
3
+ description: Use when working in a repository that uses bd or Beads for durable project task tracking, issue dependencies, blocker management, multi-session handoff, or shared work memory. Trigger when the user asks to find ready work, claim or close tasks, create follow-up work, inspect blockers, recover project context, or choose between local planning and persistent project tracking.
4
+ ---
5
+
6
+ # Beads
7
+
8
+ Use Beads as the shared project task system. Local plans, scratch files, and personal memories are useful, but they are not the durable source of truth for project work.
9
+
10
+ ## First Step
11
+
12
+ Run:
13
+
14
+ ```bash
15
+ bd prime
16
+ ```
17
+
18
+ If that prints nothing, check whether the repository has an active Beads workspace:
19
+
20
+ ```bash
21
+ bd where
22
+ ```
23
+
24
+ ## Preferred Route
25
+
26
+ Use the `bd` CLI when shell access is available. It is the most compact and direct Beads interface.
27
+
28
+ ## Core CLI Workflow
29
+
30
+ 1. Find work:
31
+
32
+ ```bash
33
+ bd ready
34
+ bd list --status=open
35
+ bd list --status=in_progress
36
+ ```
37
+
38
+ 2. Inspect before editing:
39
+
40
+ ```bash
41
+ bd show <id>
42
+ ```
43
+
44
+ 3. Claim work atomically:
45
+
46
+ ```bash
47
+ bd update <id> --claim
48
+ ```
49
+
50
+ 4. Create durable follow-up work when implementation reveals new tasks:
51
+
52
+ ```bash
53
+ bd create "Short title" --description="Why this exists and what needs to be done" --type=task --priority=2
54
+ ```
55
+
56
+ 5. Close completed work:
57
+
58
+ ```bash
59
+ bd close <id> --reason="Completed"
60
+ ```
61
+
62
+ ## What Belongs In Beads
63
+
64
+ Use Beads for:
65
+
66
+ - shared project tasks
67
+ - blockers and dependencies
68
+ - discovered follow-up work
69
+ - work that must survive thread reset, compaction, or handoff
70
+ - status that another person or agent should be able to resume
71
+
72
+ Use agent-local planning tools only for the current turn's execution checklist. Do not treat them as shared project state.
73
+
74
+ ## Rules
75
+
76
+ - Do not create markdown TODO files as the source of truth when Beads is available.
77
+ - Do not use `bd edit`; it opens an interactive editor. Use `bd update` flags instead.
78
+ - Prefer `--json` when parsing `bd` output programmatically.
79
+ - If hooks are installed, `bd prime` may already be injected. Run it manually when context is missing.
80
+ - Do not auto-close or mutate tasks unless the work is actually complete.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Beads"
3
+ short_description: "Project task tracking with bd"
4
+ default_prompt: "Use $beads to inspect ready work and manage durable project tasks."
@@ -1,5 +1,18 @@
1
1
  {
2
2
  "enabledPlugins": {
3
3
  "ecosystem@onlooker-community": true
4
+ },
5
+ "hooks": {
6
+ "SessionStart": [
7
+ {
8
+ "hooks": [
9
+ {
10
+ "command": "bd prime --hook-json",
11
+ "type": "command"
12
+ }
13
+ ],
14
+ "matcher": ""
15
+ }
16
+ ]
4
17
  }
5
18
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ecosystem",
3
- "version": "0.33.0",
3
+ "version": "0.34.0",
4
4
  "description": "Observability substrate for Claude Code. Provides the shared $ONLOOKER_DIR storage root (default $HOME/.onlooker), canonical schema-validated event emission, session and tool tracking hooks, and prompt rules. Required by all other Onlooker plugins.",
5
5
  "author": {
6
6
  "name": "Onlooker Community",
@@ -0,0 +1,2 @@
1
+ [features]
2
+ hooks = true
@@ -0,0 +1,51 @@
1
+ {
2
+ "hooks": {
3
+ "PostCompact": [
4
+ {
5
+ "hooks": [
6
+ {
7
+ "command": "bd codex-hook PostCompact",
8
+ "statusMessage": "Scheduling Beads context refresh",
9
+ "type": "command"
10
+ }
11
+ ],
12
+ "matcher": "manual|auto"
13
+ }
14
+ ],
15
+ "PreCompact": [
16
+ {
17
+ "hooks": [
18
+ {
19
+ "command": "bd codex-hook PreCompact",
20
+ "statusMessage": "Checking Beads context",
21
+ "type": "command"
22
+ }
23
+ ],
24
+ "matcher": "manual|auto"
25
+ }
26
+ ],
27
+ "SessionStart": [
28
+ {
29
+ "hooks": [
30
+ {
31
+ "command": "bd codex-hook SessionStart",
32
+ "statusMessage": "Loading Beads context",
33
+ "type": "command"
34
+ }
35
+ ],
36
+ "matcher": "startup|resume|clear"
37
+ }
38
+ ],
39
+ "UserPromptSubmit": [
40
+ {
41
+ "hooks": [
42
+ {
43
+ "command": "bd codex-hook UserPromptSubmit",
44
+ "statusMessage": "Refreshing Beads context",
45
+ "type": "command"
46
+ }
47
+ ]
48
+ }
49
+ ]
50
+ }
51
+ }
@@ -13,5 +13,8 @@
13
13
  "MD060": false,
14
14
  "MD024": {
15
15
  "siblings_only": true
16
+ },
17
+ "MD010": {
18
+ "code_blocks": false
16
19
  }
17
20
  }
@@ -1,19 +1,19 @@
1
1
  {
2
- ".": "0.33.0",
2
+ ".": "0.34.0",
3
3
  "plugins/archivist": "0.3.1",
4
- "plugins/tribunal": "1.1.1",
4
+ "plugins/tribunal": "1.1.2",
5
5
  "plugins/echo": "0.3.1",
6
6
  "plugins/cartographer": "0.3.1",
7
7
  "plugins/governor": "0.3.2",
8
8
  "plugins/compass": "0.4.1",
9
- "plugins/scribe": "0.4.1",
9
+ "plugins/scribe": "0.4.2",
10
10
  "plugins/counsel": "0.5.1",
11
11
  "plugins/warden": "0.3.1",
12
- "plugins/librarian": "0.6.1",
13
- "plugins/curator": "0.2.1",
12
+ "plugins/librarian": "0.7.0",
13
+ "plugins/curator": "0.2.2",
14
14
  "plugins/historian": "0.3.2",
15
- "plugins/assayer": "1.1.1",
15
+ "plugins/assayer": "1.1.2",
16
16
  "plugins/bursar": "0.3.0",
17
- "plugins/lineage": "0.2.1",
18
- "plugins/inspector": "0.3.1"
17
+ "plugins/lineage": "0.2.2",
18
+ "plugins/inspector": "0.3.2"
19
19
  }
package/AGENTS.md ADDED
@@ -0,0 +1,135 @@
1
+ # Agent Instructions
2
+
3
+ This project uses **bd** (beads) for issue tracking. Run `bd prime` for full workflow context.
4
+
5
+ > **Architecture in one line:** Issues live in a local Dolt database
6
+ > (`.beads/dolt/`); cross-machine sync uses `bd dolt push/pull` (a
7
+ > git-compatible protocol), stored under `refs/dolt/data` on your git
8
+ > remote — separate from `refs/heads/*` where your code lives.
9
+ > `.beads/issues.jsonl` is a passive export, not the wire protocol.
10
+ >
11
+ > See [SYNC_CONCEPTS.md](https://github.com/gastownhall/beads/blob/main/docs/SYNC_CONCEPTS.md)
12
+ > for the one-screen overview and anti-patterns (don't treat JSONL as the
13
+ > source of truth; don't `bd import` during normal operation; don't
14
+ > reach for third-party Dolt hosting before trying the default).
15
+
16
+ ## Quick Reference
17
+
18
+ ```bash
19
+ bd ready # Find available work
20
+ bd show <id> # View issue details
21
+ bd update <id> --claim # Claim work atomically
22
+ bd close <id> # Complete work
23
+ bd dolt push # Push beads data to remote
24
+ ```
25
+
26
+ ## Non-Interactive Shell Commands
27
+
28
+ **ALWAYS use non-interactive flags** with file operations to avoid hanging on confirmation prompts.
29
+
30
+ Shell commands like `cp`, `mv`, and `rm` may be aliased to include `-i` (interactive) mode on some systems, causing the agent to hang indefinitely waiting for y/n input.
31
+
32
+ **Use these forms instead:**
33
+ ```bash
34
+ # Force overwrite without prompting
35
+ cp -f source dest # NOT: cp source dest
36
+ mv -f source dest # NOT: mv source dest
37
+ rm -f file # NOT: rm file
38
+
39
+ # For recursive operations
40
+ rm -rf directory # NOT: rm -r directory
41
+ cp -rf source dest # NOT: cp -r source dest
42
+ ```
43
+
44
+ **Other commands that may prompt:**
45
+ - `scp` - use `-o BatchMode=yes` for non-interactive
46
+ - `ssh` - use `-o BatchMode=yes` to fail instead of prompting
47
+ - `apt-get` - use `-y` flag
48
+ - `brew` - use `HOMEBREW_NO_AUTO_UPDATE=1` env var
49
+
50
+ <!-- BEGIN BEADS INTEGRATION v:1 profile:minimal hash:970c3bf2 -->
51
+ ## Beads Issue Tracker
52
+
53
+ This project uses **bd (beads)** for issue tracking. Run `bd prime` to see full workflow context and commands.
54
+
55
+ ### Quick Reference
56
+
57
+ ```bash
58
+ bd ready # Find available work
59
+ bd show <id> # View issue details
60
+ bd update <id> --claim # Claim work
61
+ bd close <id> # Complete work
62
+ ```
63
+
64
+ ### Rules
65
+
66
+ - Use `bd` for ALL task tracking — do NOT use TodoWrite, TaskCreate, or markdown TODO lists
67
+ - Run `bd prime` for detailed command reference and session close protocol
68
+ - Use `bd remember` for persistent knowledge — do NOT use MEMORY.md files
69
+
70
+ **Architecture in one line:** issues live in a local Dolt DB; sync uses `refs/dolt/data` on your git remote; `.beads/issues.jsonl` is a passive export. See <https://github.com/gastownhall/beads/blob/main/docs/SYNC_CONCEPTS.md> for details and anti-patterns.
71
+
72
+ ## Agent Context Profiles
73
+
74
+ The managed Beads block is task-tracking guidance, not permission to override repository, user, or orchestrator instructions.
75
+
76
+ - **Conservative (default)**: Use `bd` for task tracking. Do not run git commits, git pushes, or Dolt remote sync unless explicitly asked. At handoff, report changed files, validation, and suggested next commands.
77
+ - **Minimal**: Keep tool instruction files as pointers to `bd prime`; use the same conservative git policy unless active instructions say otherwise.
78
+ - **Team-maintainer**: Only when the repository explicitly opts in, agents may close beads, run quality gates, commit, and push as part of session close. A current "do not commit" or "do not push" instruction still wins.
79
+
80
+ ## Session Completion
81
+
82
+ This protocol applies when ending a Beads implementation workflow. It is subordinate to explicit user, repository, and orchestrator instructions.
83
+
84
+ 1. **File issues for remaining work** - Create beads for anything that needs follow-up
85
+ 2. **Run quality gates** (if code changed) - Tests, linters, builds
86
+ 3. **Update issue status** - Close finished work, update in-progress items
87
+ 4. **Handle git/sync by active profile**:
88
+ ```bash
89
+ # Conservative/minimal/default: report status and proposed commands; wait for approval.
90
+ git status
91
+
92
+ # Team-maintainer opt-in only, unless current instructions forbid it:
93
+ git pull --rebase
94
+ bd dolt push
95
+ git push
96
+ git status
97
+ ```
98
+ 5. **Hand off** - Summarize changes, validation, issue status, and any blocked sync/commit/push step
99
+
100
+ **Critical rules:**
101
+ - Explicit user or orchestrator instructions override this Beads block.
102
+ - Do not commit or push without clear authority from the active profile or the current user request.
103
+ - If a required sync or push is blocked, stop and report the exact command and error.
104
+ <!-- END BEADS INTEGRATION -->
105
+
106
+ <!-- The Codex block below repeats the "Beads Issue Tracker" heading from the
107
+ integration block above. Both are generated and re-synced by different `bd`
108
+ subcommands, so neither heading can be renamed by hand without breaking
109
+ idempotent regeneration. These comments sit outside the BEGIN/END markers
110
+ so `bd` does not clobber them when it rewrites the block. -->
111
+ <!-- markdownlint-disable MD024 -->
112
+ <!-- BEGIN BEADS CODEX SETUP: generated by bd setup codex -->
113
+ ## Beads Issue Tracker
114
+
115
+ Use Beads (`bd`) for durable task tracking in repositories that include it. Use the `beads` skill at `.agents/skills/beads/SKILL.md` (project install) or `~/.agents/skills/beads/SKILL.md` (global install) for Beads workflow guidance, then use the `bd` CLI for issue operations.
116
+
117
+ ### Quick Reference
118
+
119
+ ```bash
120
+ bd ready # Find available work
121
+ bd show <id> # View issue details
122
+ bd update <id> --claim # Claim work
123
+ bd close <id> # Complete work
124
+ bd prime # Refresh Beads context
125
+ ```
126
+
127
+ ### Rules
128
+
129
+ - Use `bd` for all task tracking; do not create markdown TODO lists.
130
+ - Run `bd prime` when Beads context is missing or stale. Codex 0.129.0+ can load Beads context automatically through native hooks; use `/hooks` to inspect or toggle them.
131
+ - Keep persistent project memory in Beads via `bd remember`; do not create ad hoc memory files.
132
+
133
+ **Architecture in one line:** issues live in a local Dolt DB; sync uses `refs/dolt/data` on your git remote; `.beads/issues.jsonl` is a passive export. See <https://github.com/gastownhall/beads/blob/main/docs/SYNC_CONCEPTS.md> for details and anti-patterns.
134
+ <!-- END BEADS CODEX SETUP -->
135
+ <!-- markdownlint-enable MD024 -->
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.34.0](https://github.com/onlooker-community/ecosystem/compare/ecosystem-v0.33.1...ecosystem-v0.34.0) (2026-08-09)
4
+
5
+
6
+ ### Features
7
+
8
+ * **librarian:** transform artifacts into shareable lesson candidates :microscope: ([#132](https://github.com/onlooker-community/ecosystem/issues/132)) ([48adbc7](https://github.com/onlooker-community/ecosystem/commit/48adbc7ec572b96b47f1be5f92810088c98702c6))
9
+
10
+ ## [0.33.1](https://github.com/onlooker-community/ecosystem/compare/ecosystem-v0.33.0...ecosystem-v0.33.1) (2026-08-02)
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * restore config convenience functions & refactor execution plugins to shared loader ([#128](https://github.com/onlooker-community/ecosystem/issues/128)) ([4b3660c](https://github.com/onlooker-community/ecosystem/commit/4b3660c5a8b234187ec1e71c37b63e6a3d305c98))
16
+
3
17
  ## [0.33.0](https://github.com/onlooker-community/ecosystem/compare/ecosystem-v0.32.2...ecosystem-v0.33.0) (2026-08-02)
4
18
 
5
19
 
package/CLAUDE.md CHANGED
@@ -94,7 +94,7 @@ Tests use an isolated temp home; nothing writes to your real `~/.onlooker/`.
94
94
  Workflow:
95
95
  1. Create a feature branch: `git switch -c <type>/<short-description>`
96
96
  2. Commit using `/commit`
97
- 3. Push the branch and open a PR using `/git:gh-pr-create`
97
+ 3. Push the branch and open a PR using `/git-workflow:pr`
98
98
  4. Wait for CI to pass before merging
99
99
 
100
100
  ## Conventions
@@ -104,3 +104,58 @@ Workflow:
104
104
  - Event types follow `<plugin>.<noun>.<verb>` — e.g. `compass.check.skipped`, `tribunal.gate.blocked`.
105
105
  - ULIDs everywhere for IDs (not UUIDs). Each plugin ships its own `*_ulid` helper (e.g. `archivist-ulid.sh`, `tribunal-ulid.sh`); there is no shared ecosystem helper. Copy `plugins/tribunal/scripts/lib/tribunal-ulid.sh` as a starting point and rename the function prefix.
106
106
  - Config defaults live in `config.json`. User overrides go in `~/.claude/settings.json` (global) or `.claude/settings.json` (per-project) under the plugin's namespace key (e.g. `"compass"`, `"tribunal"`). See ADR-004.
107
+
108
+ <!-- BEGIN BEADS INTEGRATION v:1 profile:minimal hash:6cd5cc61 -->
109
+ ## Beads Issue Tracker
110
+
111
+ This project uses **bd (beads)** for issue tracking. Run `bd prime` to see full workflow context and commands.
112
+
113
+ ### Quick Reference
114
+
115
+ ```bash
116
+ bd ready # Find available work
117
+ bd show <id> # View issue details
118
+ bd update <id> --claim # Claim work
119
+ bd close <id> # Complete work
120
+ ```
121
+
122
+ ### Rules
123
+
124
+ - Use `bd` for ALL task tracking — do NOT use TodoWrite, TaskCreate, or markdown TODO lists
125
+ - Run `bd prime` for detailed command reference and session close protocol
126
+ - Use `bd remember` for persistent knowledge — do NOT use MEMORY.md files
127
+
128
+ **Architecture in one line:** issues live in a local Dolt DB; sync uses `refs/dolt/data` on your git remote; `.beads/issues.jsonl` is a passive export. See <https://github.com/gastownhall/beads/blob/main/docs/SYNC_CONCEPTS.md> for details and anti-patterns.
129
+
130
+ ## Agent Context Profiles
131
+
132
+ The managed Beads block is task-tracking guidance, not permission to override repository, user, or orchestrator instructions.
133
+
134
+ - **Conservative (default)**: Use `bd` for task tracking. Do not run git commits, git pushes, or Dolt remote sync unless explicitly asked. At handoff, report changed files, validation, and suggested next commands.
135
+ - **Minimal**: Keep tool instruction files as pointers to `bd prime`; use the same conservative git policy unless active instructions say otherwise.
136
+ - **Team-maintainer**: Only when the repository explicitly opts in, agents may close beads, run quality gates, commit, and push as part of session close. A current "do not commit" or "do not push" instruction still wins.
137
+
138
+ ## Session Completion
139
+
140
+ This protocol applies when ending a Beads implementation workflow. It is subordinate to explicit user, repository, and orchestrator instructions.
141
+
142
+ 1. **File issues for remaining work** - Create beads for anything that needs follow-up
143
+ 2. **Run quality gates** (if code changed) - Tests, linters, builds
144
+ 3. **Update issue status** - Close finished work, update in-progress items
145
+ 4. **Handle git/sync by active profile**:
146
+ ```bash
147
+ # Conservative/minimal/default: report status and proposed commands; wait for approval.
148
+ git status
149
+
150
+ # Team-maintainer opt-in only, unless current instructions forbid it:
151
+ git pull --rebase
152
+ git push
153
+ git status
154
+ ```
155
+ 5. **Hand off** - Summarize changes, validation, issue status, and any blocked sync/commit/push step
156
+
157
+ **Critical rules:**
158
+ - Explicit user or orchestrator instructions override this Beads block.
159
+ - Do not commit or push without clear authority from the active profile or the current user request.
160
+ - If a required sync or push is blocked, stop and report the exact command and error.
161
+ <!-- END BEADS INTEGRATION -->
@@ -0,0 +1,210 @@
1
+ # Lesson Promotion Pipeline
2
+
3
+ **Status:** Not started. Design is settled; implementation lives in this repo.
4
+ **Tracked by:** `onlooker-97e` in the onlooker beads tracker.
5
+ **Authoritative design:** `docs/superpowers/specs/2026-08-08-promotion-pipeline-design.md`
6
+ in the [onlooker](https://github.com/onlooker-community/onlooker) repo, Sections 2 and 3.
7
+ Read that before making design decisions — this document is orientation, not the spec.
8
+
9
+ ---
10
+
11
+ ## What we are building
12
+
13
+ A fourth destination for archivist artifacts: a **shared** pool of lessons that
14
+ can cross machines and people, rather than the local, per-machine typed memory
15
+ store librarian writes to today.
16
+
17
+ This is easy to misread as "another memory type." It is not. Compare with
18
+ [memory-architecture.md](memory-architecture.md):
19
+
20
+ | | destination | scope | who sees it |
21
+ |---|---|---|---|
22
+ | librarian → typed memory store | `~/.claude/projects/<encoded>/memory/` | one machine | you |
23
+ | **librarian → lesson pool** | `~/.onlooker/librarian/<project-key>/lessons/` | shared, eventually cross-person | you, your org, or the public |
24
+
25
+ Everything upstream is unchanged. Artifacts are still captured by archivist,
26
+ still filtered for durability, still classified, still deduped. The new work
27
+ hangs off the end of that existing chain.
28
+
29
+ ## The shape
30
+
31
+ ```
32
+ archivist artifacts EXISTS session-scoped facts
33
+ └→ durability filter EXISTS cheap, pre-LLM
34
+ └→ type classifier (Haiku) EXISTS user/feedback/project/reference
35
+ └→ conflict/dup detect (Jaccard) EXISTS keeps the queue high-signal
36
+ ══════════════════════════════════════
37
+ └→ lesson transform (Haiku) NEW claim, rationale, applies_to
38
+ └→ human picks + visibility NEW propose-only, per librarian ADR-001
39
+ └→ tribunal gate NEW one-shot, visibility-scoped
40
+ └→ approved pool NEW local; the sync service drains it later
41
+ ```
42
+
43
+ Three new steps, in two existing plugins. **No new plugin.** Librarian already
44
+ owns the artifact reader, the durability filter, the classifier, the dedup pass
45
+ and the proposal queue — the transform is a fifth stage on a chain that exists,
46
+ and its `last_scan.json` watermark already tracks which artifacts have been
47
+ considered. A separate plugin would need a second copy of that state, free to
48
+ drift.
49
+
50
+ Tribunal contributes a rubric and reuses `tribunal-judge-security`, which it
51
+ already ships disabled by default.
52
+
53
+ ## Why lessons rot, and what the contract does about it
54
+
55
+ The design exists because of a real artifact in this repo's own storage: a
56
+ vitest/vite version-mismatch decision that was true when captured and is false
57
+ now. Shared and auto-injected, it would send someone else down a dead end.
58
+
59
+ So staleness is **structural**, not procedural. A lesson carries version ranges,
60
+ and a session outside those ranges simply never matches it. No review queue, no
61
+ expiry job, nothing to forget to run. The contract enforces this by construction:
62
+ `applies_to.scope` is a tagged union, and the branch that claims version
63
+ independence must carry a written justification the tribunal scores. A transform
64
+ that failed to infer versions has nothing to put there, so it cannot silently
65
+ mint a lesson that never expires.
66
+
67
+ ## The contract
68
+
69
+ Defined in `packages/lesson-contract` in the onlooker repo and **published as
70
+ JSON Schema**:
71
+
72
+ - `packages/lesson-contract/schema/lesson.schema.json`
73
+ - `packages/lesson-contract/schema/counter-observation.schema.json`
74
+
75
+ Currently `schema_version: 2`.
76
+
77
+ **The producing side cannot import the definition.** Plugins here are
78
+ bash-based and live in a different repo; the zod source is not available to
79
+ them. Validate against the published JSON Schema, or simply conform to it. The
80
+ sync endpoint in `apps/api` is the real enforcement boundary and validates
81
+ regardless, so client-side validation is a convenience, not a trust boundary.
82
+
83
+ Fields worth knowing before you start:
84
+
85
+ | Field | Note |
86
+ |---|---|
87
+ | `claim` / `rationale` | what is asserted, and why it follows |
88
+ | `evidence.resolution` | **required.** "this breaks" without "and this fixed it" is a warning, not a lesson |
89
+ | `evidence.project_key` | the opaque hash, never the repo name |
90
+ | `applies_to.scope` | `{kind: "versioned", versions}` or `{kind: "version_independent", justification}` |
91
+ | `applies_to.stack` | every key of `scope.versions` must name an entry here — see cross-field rules below |
92
+ | `author_key` | 32 lowercase hex, `HMAC(user_secret, scope)`, derived **per visibility scope** so org and public identities are unlinkable |
93
+ | `visibility` | `private` / `org` / `public` |
94
+ | `status` | `active` / `refuted` / `superseded` / `retracted`. There is deliberately no `expired` |
95
+
96
+ **Cross-field rules the schema cannot express**, documented in the contract's
97
+ `.describe()` text and enforced at ingest. Worth self-checking before emitting:
98
+
99
+ - `consensus.agreed <= consensus.judges`
100
+ - every key of `applies_to.scope.versions` names an entry in `applies_to.stack`
101
+
102
+ ## What is already decided
103
+
104
+ Do not re-litigate these; they came out of a full design cycle and are recorded
105
+ with reasoning in the spec.
106
+
107
+ **The gate is one-shot.** `max_iterations: 1`. Below threshold, a candidate is
108
+ dropped rather than repaired. Refutation should be cheaper to trigger than
109
+ promotion — a wrong lesson actively misleads, a missing one merely fails to
110
+ help. Fail toward removal. This also bounds token cost per promotion and stops
111
+ the transform learning to satisfy judges rather than the evidence.
112
+
113
+ **The human confirms before judging, not after.** The transform is Haiku and
114
+ cheap; the jury is Opus and not. Splitting the filters this way means the human
115
+ judges *intent* ("do I want to share anything about this?"), which only they can
116
+ do and which costs nothing, and the jury judges *quality*, which only it can do
117
+ and which costs real money. Opus tokens are then only ever spent on candidates
118
+ someone already wants shared.
119
+
120
+ **Gating is scoped by visibility.** Not every lesson passes a jury:
121
+
122
+ | visibility | gate | why |
123
+ |---|---|---|
124
+ | `private` | none | you are the only consumer |
125
+ | `org` | `lesson-promotion` rubric | the org boundary already implies trust |
126
+ | `public` | rubric + disclosure lens | self-reported consensus is gameable by a modified client |
127
+
128
+ **The rubric**, in tribunal's existing `config.json` shape:
129
+
130
+ | criterion | weight | `min_pass` | asks |
131
+ |---|---|---|---|
132
+ | `grounding` | 0.45 | 0.7 | does the claim follow from `evidence` and `resolution`? |
133
+ | `scope_accuracy` | 0.35 | 0.7 | does `applies_to` correctly bound the claim? |
134
+ | `generality` | 0.20 | 0.6 | is this a lesson, or a session-scoped fact? |
135
+
136
+ `score_threshold: 0.75`, `gate_policy: majority`, `aggregation_method:
137
+ weighted_mean`, `judge_types: ["standard", "adversarial"]` — all tribunal
138
+ defaults. The only override is `max_iterations: 1`.
139
+
140
+ For `public`, add the disclosure lens using the already-shipped
141
+ `tribunal-judge-security`:
142
+
143
+ | criterion | weight | `min_pass` | asks |
144
+ |---|---|---|---|
145
+ | `disclosure` | 0.30 | **0.9** | leaks a secret or identity, or advocates a harmful practice? |
146
+
147
+ The high floor is deliberate. Correctness rots and `applies_to` retires it;
148
+ harm does not. A leaked credential never expires on its own, so disclosure gets
149
+ a floor a strong weighted mean cannot average away.
150
+
151
+ **State layout**, under librarian's existing project key:
152
+
153
+ ```
154
+ ~/.onlooker/librarian/<project-key>/
155
+ lessons/approved/<ulid>.json jury passed; awaiting sync
156
+ lessons/declined.jsonl artifact_id + verdict + reason
157
+ ```
158
+
159
+ The declined ledger matters more than it looks. The watermark advances past a
160
+ rejected artifact, so without a record a drop is either silently permanent or —
161
+ on a rescan — re-pays Opus tokens to re-judge the same failures every session.
162
+ Append-only, never re-judged automatically.
163
+
164
+ **"Judged and failed" is not "could not judge."** Only real verdicts go in
165
+ `declined.jsonl`. A tribunal API error, or a jury below quorum, leaves the
166
+ candidate in proposals untouched. Conflating them lets one transient outage
167
+ permanently bury good lessons behind a watermark that has already moved.
168
+
169
+ ## Conventions this repo imposes
170
+
171
+ From [CLAUDE.md](../CLAUDE.md) — these differ from the onlooker repo:
172
+
173
+ - **Hooks are bash.** No Python or Node entry points in hook scripts, though they
174
+ may shell out to `node` for event emission or heavy lifting.
175
+ - **Event names** follow `<plugin>.<noun>.<verb>`. Likely additions here:
176
+ `librarian.lesson.proposed`, `librarian.lesson.approved`,
177
+ `librarian.lesson.declined`, `tribunal.lesson.judged`.
178
+ - **ULIDs, not UUIDs**, and each plugin ships its own helper. Librarian will need
179
+ one for lesson ids if it does not have one — copy
180
+ `plugins/tribunal/scripts/lib/tribunal-ulid.sh` and rename the prefix.
181
+ - **Config defaults** live in the plugin's `config.json`; user overrides go under
182
+ the plugin's namespace key in settings. See ADR-004.
183
+
184
+ ## Out of scope
185
+
186
+ **Counter-observations and re-judgment.** They need consumers of shared
187
+ lessons, which needs the sync service and retrieval. The contract already
188
+ defines `ZCounterObservation`, and the counter-observation threshold is
189
+ explicitly still an open number — do not invent one.
190
+
191
+ **Publishing anywhere.** The pipeline stops at the local approved pool. Nothing
192
+ crosses the network. The sync service drains that queue later, and does not
193
+ exist yet.
194
+
195
+ **The server-side re-judge for public lessons.** Local consensus for public
196
+ lessons runs here; the pool records the intended visibility so the server knows
197
+ what still needs independent judging.
198
+
199
+ ## Open questions
200
+
201
+ - **Where the human confirmation surfaces.** Librarian already has a proposal
202
+ queue and a SessionStart surfacer for memory promotions. Reuse it, or keep
203
+ lesson proposals separate so the two kinds of confirmation are not confused?
204
+ - **`author_key` derivation.** The contract pins the format — 32 hex,
205
+ `HMAC(user_secret, scope)` — but nothing derives it yet. Where does
206
+ `user_secret` live, and how is it created on first use?
207
+ - **Whether the transform self-validates** against the published JSON Schema
208
+ before writing to the pool, or leaves all validation to ingest. Validating
209
+ locally catches a bad transform earlier; it also means fetching and caching
210
+ a schema from another repo.