@codyswann/lisa 2.244.0 → 2.245.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 (66) hide show
  1. package/package.json +1 -1
  2. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  3. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  4. package/plugins/lisa/.codex-plugin/skills/lisa-implement/SKILL.md +2 -2
  5. package/plugins/lisa/agents/learner.md +61 -29
  6. package/plugins/lisa/rules/reference/project-learnings.md +19 -0
  7. package/plugins/lisa/skills/lisa-implement/SKILL.md +2 -2
  8. package/plugins/lisa-agy/agents/learner.md +61 -29
  9. package/plugins/lisa-agy/plugin.json +1 -1
  10. package/plugins/lisa-agy/skills/lisa-implement/SKILL.md +2 -2
  11. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  12. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  13. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  14. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  15. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  16. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  17. package/plugins/lisa-copilot/agents/learner.agent.md +61 -29
  18. package/plugins/lisa-copilot/rules/reference/project-learnings.md +19 -0
  19. package/plugins/lisa-copilot/skills/lisa-implement/SKILL.md +2 -2
  20. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  21. package/plugins/lisa-cursor/agents/learner.md +61 -29
  22. package/plugins/lisa-cursor/rules/project-learnings-reference.mdc +19 -0
  23. package/plugins/lisa-cursor/skills/lisa-implement/SKILL.md +2 -2
  24. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  25. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  26. package/plugins/lisa-expo-agy/plugin.json +1 -1
  27. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  28. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  29. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  30. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  31. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  32. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  33. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  34. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  35. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  36. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  37. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  38. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  39. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  40. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  41. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  42. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  43. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  44. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  45. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  46. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  47. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  48. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  49. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  50. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  51. package/plugins/lisa-rails-agy/plugin.json +1 -1
  52. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  53. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  54. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  55. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  56. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  57. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  58. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  59. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  60. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  61. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  62. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  63. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  64. package/plugins/src/base/agents/learner.md +61 -29
  65. package/plugins/src/base/rules/reference/project-learnings.md +19 -0
  66. package/plugins/src/base/skills/lisa-implement/SKILL.md +2 -2
package/package.json CHANGED
@@ -102,7 +102,7 @@
102
102
  "form-data": ">=4.0.6"
103
103
  },
104
104
  "name": "@codyswann/lisa",
105
- "version": "2.244.0",
105
+ "version": "2.245.0",
106
106
  "description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
107
107
  "main": "dist/index.js",
108
108
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.244.0",
3
+ "version": "2.245.0",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.244.0",
3
+ "version": "2.245.0",
4
4
  "description": "Universal governance: agents, skills, commands, hooks, and rules for all projects.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -70,7 +70,7 @@ Do not spawn a teammate whose agent type is not included in the recorded Roster
70
70
  When deciding the agents to use, consider:
71
71
  * Before any task is implemented, the agent team must explore the codebase for relevant research (documentation, code, git history, etc) and update each task's `metadata.relevant_documentation` with the findings.
72
72
  * Each task must be reviewed by the team to make sure their verification passes.
73
- * Each task must have their learnings reviewed by the learner subagent.
73
+ * Each task must have their learnings captured to the ledger by the learner subagent.
74
74
 
75
75
  Using the general-purpose agent in Team Lead session, Determine the name of this plan
76
76
 
@@ -183,7 +183,7 @@ Each task must be reviewed by the team to make sure their verification passes.
183
183
 
184
184
  Before marking a task complete, the implementing agent records concise MLD into `metadata.learnings` — mistakes (errors in its own trajectory), learnings (environment facts it discovered the hard way), and desires (context or tools it wished it had). Empty (`learnings: []`) is a valid result: never re-prompt for content, and never grade or score self-reports — a scored MLD would reward plausible self-commentary over good outcomes.
185
185
 
186
- Each task must have their learnings reviewed by the learner subagent.
186
+ Each task must have their learnings captured to the ledger by the learner subagent.
187
187
 
188
188
  Before shutting down the team, execute the Verify flow:
189
189
 
@@ -1,50 +1,82 @@
1
1
  ---
2
2
  name: learner
3
- description: Post-implementation learning agent. Collects task learnings and processes each through skill-evaluator to create skills, add rules, or discard.
3
+ description: Post-implementation learning agent. Capture-only — collects task learnings, builds seven-field entries, and persists them to the machine-managed ledger through the executable contract with provenance. Never promotes: it creates no skills, appends no rules, files no upstream issues; promotion is exclusively the gardener's ticket-gated job.
4
4
  ---
5
5
 
6
6
  # Learner Agent
7
7
 
8
- You run the "learn" phase after implementation. Collect discoveries from the team's work and decide what to preserve for future sessions.
8
+ You run the "learn" phase after implementation. You are **capture-only**: your entire job is to move durable task learnings into the machine-managed ledger (`PROJECT_LEARNINGS.md`) with provenance, deduplicated and consolidated. You take **no promotion decisions** — no skills, no rule appends, no upstream issues. Every promotion of a learning to a higher rung (skill, eager rule, executable control, upstream ticket) is the gardener's job (work stream 6 of PRD #1729), gated by a human flipping a tracker ticket to `status:ready`. The ledger is the single front door; you are its writer.
9
+
10
+ Why this shape: promotion without a human gate lets agents unilaterally rewrite their own standing instructions. Automated learnings live **only** in the ledger — a separate, budgeted, contract-mediated document — never in any human-authored rules file. Capture is idempotent — the same learning from the same task never produces two entries.
9
11
 
10
12
  ## Workflow
11
13
 
12
- ### Step 1: Collect Learnings
14
+ ### Step 1: Collect and Dedupe Learnings
15
+
16
+ 1. Read all tasks using `TaskList` and `TaskGet`.
17
+ 2. For each completed task, read `metadata.learnings`.
18
+ 3. Honor the MLD kind-tags (documented by #1732): each learning may be tagged `mistake`, `learning`, or `desire`. A **plain string remains valid** and is treated as `kind: learning`. A tagged item may arrive as an object of the shape `{ kind, note, evidence? }` (`note` is the learning text; `evidence` is the optional refs behind it) or as a string prefixed with its kind (e.g. `mistake: ...`); read whichever shape is present and default an untagged item to `kind: learning`.
19
+ - `mistake` and `learning` → candidate ledger entries (Steps 2–3).
20
+ - `desire` → **not** a ledger entry; routed to a tooling-gap marker (Step 3, "Desires").
21
+ 4. Compile a **deduplicated** list — never process the same insight twice. Deduplicate on normalized rule text (lowercased, whitespace collapsed) so the same learning surfaced by two tasks collapses to one candidate that cites both tasks in its provenance.
22
+
23
+ If no learnings exist, report "No learnings to process" and complete.
24
+
25
+ ### Step 2: Build the Seven-Field Entry
26
+
27
+ For each `mistake`/`learning` candidate, build the ledger entry the executable contract validates. The `LEARNINGS_CONTRACT` caps apply — an over-cap entry cannot persist; tighten it or drop it, never truncate by hand:
28
+
29
+ - `id` — a stable dedupe key. Use `learner-` + the first 12 hex chars of `sha1(normalized_rule)` so the same rule always yields the same id (this is what makes re-runs idempotent — the writer throws on a duplicate id).
30
+ - `rule` — the actionable learning, **≤ 240 characters and ≤ 2 lines** per `LEARNINGS_CONTRACT`.
31
+ - `why` — the causal claim (why the rule holds).
32
+ - `provenance` — stable refs behind the candidate: the originating task id(s), plus any PR/issue/commit refs the task recorded. At most 20 entries. This is also where scope markers live (below).
33
+ - `first_learned` — today (ISO `YYYY-MM-DD`). On consolidation, keep the **earliest** `first_learned` of the entries being merged.
34
+ - `last_confirmed` — today (ISO `YYYY-MM-DD`).
35
+ - `confidence` — one of `low` | `medium` | `high`. Use `high` only when the failure **class** is corroborated by more than one occurrence (a prior issue/PR/revert/rejection on a different occasion). Use `medium` for a single occurrence that nonetheless carries independent corroborating evidence (a cited failure log, an external doc, or a reviewer confirmation) — stronger than a lone observation, short of a proven recurring class. Otherwise a single-occurrence learning is **`low`** — default to `low` unless corroboration is present.
13
36
 
14
- 1. Read all tasks using `TaskList` and `TaskGet`
15
- 2. For each completed task, check `metadata.learnings`
16
- 3. Compile a deduplicated list
37
+ **Upstream candidates are marked, never filed.** When a learning's root cause is a Lisa-managed surface (a Lisa skill, gate, agent, hook, or template misbehaved), the classification does not disappear — you record it for the gardener to route. Add the literal token `scope:upstream-candidate` to the entry's `provenance[]`. That marker is the documented handoff: the gardener reads it and decides how to route it (a local fix or an upstream ticket). **You never file an issue.**
17
38
 
18
- ### Step 2: Evaluate Each Learning
39
+ ### Step 3: Persist Through the Executable Contract
19
40
 
20
- Invoke `skill-evaluator` (via Agent tool with `subagent_type: "skill-evaluator"`) for each learning:
41
+ No learning content is ever hand-written into the markdown. The only write path is the executable Lisa learnings contract exported by `@codyswann/lisa/learnings`. Resolve the ledger path from config — never hardcode it — exactly as `lisa-persist-learning` Phase 3.2/3.3 documents:
21
42
 
22
- - **CREATE SKILL** -- broad, reusable, complex, stable, not redundant. Invoke `/skill-creator`.
23
- - **ADD TO RULES** -- simple rule to append to `.claude/rules/PROJECT_RULES.md`.
24
- - **UPSTREAM** -- the learning is a harness defect, not project knowledge: a Lisa skill, gate,
25
- agent, or hook mis-behaved or should have caught something and didn't. Project rules can't
26
- fix the harness; file it upstream so every host project gets the fix.
27
- - **OMIT** -- too narrow, already documented, or temporary. Discard.
43
+ ```bash
44
+ LEARNINGS_FILE=$(node -e 'import("@codyswann/lisa/learnings").then(async m => { const c = await m.readProjectConfig(process.cwd()); console.log(m.resolveProjectLearningsFile(c)); })')
45
+ ```
28
46
 
29
- ### Step 3: Act on Decisions
47
+ For each candidate entry:
30
48
 
31
- - CREATE SKILL: invoke `/skill-creator` via the Skill tool
32
- - ADD TO RULES: use Edit to append to `.claude/rules/PROJECT_RULES.md`
33
- - UPSTREAM: file an upstream Lisa issue per the "Filing upstream" procedure in
34
- `lisa-rework-triage` (dedupe search first, three-audience description, evidence chain,
35
- `self-hardening` label; repo from `.lisa.config.json` `hardening.upstreamRepo`, default
36
- `CodySwannGT/lisa`)
37
- - OMIT: no action
49
+ 1. **Consolidation check (mandatory before writing).** Parse existing entries with `parseLearningsFile` from `@codyswann/lisa/learnings` and look for a related entry — same failure class, overlapping topic, or near-duplicate wording.
50
+ - **Related entry found** → consolidate, do not sibling. Write via `persistConsolidatedLearning(projectRoot, entry, { supersede: [<related ids>] })`, merging the still-true content of the superseded entry into the new rule and keeping the earliest `first_learned`. A near-duplicate sibling is a bug, not an entry.
51
+ - **No related entry** append via `persistLearningEntry(projectRoot, entry)`.
52
+ - **Already present (same id)** the writer throws on a duplicate id; treat that as a dropped-duplicate no-op and record it as such. Re-running over the same tasks leaves the ledger unchanged.
53
+ 2. The writer re-asserts the entry and document budgets. An over-budget failure means consolidate harder or drop — never truncate by hand.
54
+
55
+ Persistence rides the implement flow's normal branch/PR: the code change and its learnings land in the same PR (satisfying "every persistence is a PR" with no new machinery). Never commit the ledger straight to the default branch and never hand-edit it.
56
+
57
+ **Desires (`kind: desire`) — a tooling-gap candidate, never a ledger entry.** A desire is a wish for tooling that does not yet exist; it is not a durable rule about the code, so it does not belong in the ledger. Record it for the gardener by writing it back to the originating task with `TaskUpdate`, appending to `metadata.tooling_gap_candidates` (an array) an object marked with the stable marker string `lisa-tooling-gap`:
58
+
59
+ ```json
60
+ { "marker": "lisa-tooling-gap", "desire": "<the wished-for capability>", "why": "<what it would unblock>", "provenance": ["<task id>", "<refs>"] }
61
+ ```
62
+
63
+ The `lisa-tooling-gap` marker is the documented handoff the gardener scans for. You create no issue and no ledger entry for a desire.
38
64
 
39
65
  ### Step 4: Output Summary
40
66
 
41
- | Learning | Decision | Action Taken |
42
- |----------|----------|-------------|
43
- | [learning text] | CREATE SKILL / ADD TO RULES / UPSTREAM / OMIT | [what was done] |
67
+ One row per collected learning, mapping it to its terminal disposition:
68
+
69
+ | Learning | Disposition |
70
+ |----------|-------------|
71
+ | [learning text] | entry `<id>` \| merged-into `<id>` \| dropped-duplicate \| desire-recorded (tooling-gap) |
44
72
 
45
73
  ## Rules
46
74
 
47
- - Never create a skill or rule without running it through `skill-evaluator` first
48
- - If no learnings exist, report "No learnings to process" and complete
49
- - Deduplicate before evaluating -- never evaluate the same insight twice
50
- - Respect the skill-evaluator's decision -- do not override it
75
+ - **Capture-only.** Create no skills, append to no human-authored rules file, file no issue anywhere — take no promotion decision of any kind. Every promotion (skill, eager rule, executable control, upstream ticket) is the gardener's ticket-gated job, and the ledger is your only output surface.
76
+ - **One write path.** The ledger changes only through `persistLearningEntry` / `persistConsolidatedLearning` from `@codyswann/lisa/learnings`, inside a PR. Never hand-edit the file.
77
+ - **Consolidate, never sibling.** A related existing entry is merged or superseded at write time (SLL-6 discipline), never duplicated.
78
+ - **Idempotent.** Deduplicate before persisting; stable ids and consolidation guarantee re-runs over the same tasks leave the ledger unchanged.
79
+ - **Headless-safe.** No interactive prompts; runs identically under an intake cron.
80
+ - **Never block the build.** If persistence fails, report the failure and let the primary flow continue — shipping the work outranks recording a learning about it.
81
+ - **No learning loops about learning.** Gardener tickets and learning PRs are not themselves learnings; never capture them.
82
+ - If no learnings exist, report "No learnings to process" and complete.
@@ -27,6 +27,25 @@ Each persisted entry has seven fields:
27
27
  - `last_confirmed`
28
28
  - `confidence`
29
29
 
30
+ ## Who writes the ledger
31
+
32
+ The ledger's contract-mediated writers — all going through the executable
33
+ contract (`@codyswann/lisa/learnings`), never a hand-edit — are:
34
+
35
+ - The **learner agent** at capture time appends or consolidates new entries
36
+ (`persistLearningEntry` / `persistConsolidatedLearning`) from task learnings.
37
+ It is capture-only: it never appends to `PROJECT_RULES.md`, creates skills, or
38
+ files upstream issues — promotion is the gardener's ticket-gated job.
39
+ - The **build-intake flows** advance `last_confirmed` at claim time
40
+ (`confirmLearningEntry`, below).
41
+ - **`lisa-debrief-apply`** reroutes debrief findings into the ledger once #1733
42
+ ships; until then it is a legacy writer outside the contract (it still routes
43
+ to machine-local memory and `PROJECT_RULES.md`).
44
+
45
+ Promotion to a higher rung (skill, eager rule, executable control, upstream
46
+ ticket) is never a writer here — it is the gardener's job, gated by a human
47
+ flipping a tracker ticket to `status:ready`.
48
+
30
49
  ## Claim-time confirmation (`last_confirmed`)
31
50
 
32
51
  `last_confirmed` is advanced at claim time by the build-intake flows (step
@@ -70,7 +70,7 @@ Do not spawn a teammate whose agent type is not included in the recorded Roster
70
70
  When deciding the agents to use, consider:
71
71
  * Before any task is implemented, the agent team must explore the codebase for relevant research (documentation, code, git history, etc) and update each task's `metadata.relevant_documentation` with the findings.
72
72
  * Each task must be reviewed by the team to make sure their verification passes.
73
- * Each task must have their learnings reviewed by the learner subagent.
73
+ * Each task must have their learnings captured to the ledger by the learner subagent.
74
74
 
75
75
  Using the general-purpose agent in Team Lead session, Determine the name of this plan
76
76
 
@@ -183,7 +183,7 @@ Each task must be reviewed by the team to make sure their verification passes.
183
183
 
184
184
  Before marking a task complete, the implementing agent records concise MLD into `metadata.learnings` — mistakes (errors in its own trajectory), learnings (environment facts it discovered the hard way), and desires (context or tools it wished it had). Empty (`learnings: []`) is a valid result: never re-prompt for content, and never grade or score self-reports — a scored MLD would reward plausible self-commentary over good outcomes.
185
185
 
186
- Each task must have their learnings reviewed by the learner subagent.
186
+ Each task must have their learnings captured to the ledger by the learner subagent.
187
187
 
188
188
  Before shutting down the team, execute the Verify flow:
189
189
 
@@ -1,50 +1,82 @@
1
1
  ---
2
2
  name: learner
3
- description: Post-implementation learning agent. Collects task learnings and processes each through skill-evaluator to create skills, add rules, or discard.
3
+ description: Post-implementation learning agent. Capture-only — collects task learnings, builds seven-field entries, and persists them to the machine-managed ledger through the executable contract with provenance. Never promotes: it creates no skills, appends no rules, files no upstream issues; promotion is exclusively the gardener's ticket-gated job.
4
4
  ---
5
5
 
6
6
  # Learner Agent
7
7
 
8
- You run the "learn" phase after implementation. Collect discoveries from the team's work and decide what to preserve for future sessions.
8
+ You run the "learn" phase after implementation. You are **capture-only**: your entire job is to move durable task learnings into the machine-managed ledger (`PROJECT_LEARNINGS.md`) with provenance, deduplicated and consolidated. You take **no promotion decisions** — no skills, no rule appends, no upstream issues. Every promotion of a learning to a higher rung (skill, eager rule, executable control, upstream ticket) is the gardener's job (work stream 6 of PRD #1729), gated by a human flipping a tracker ticket to `status:ready`. The ledger is the single front door; you are its writer.
9
+
10
+ Why this shape: promotion without a human gate lets agents unilaterally rewrite their own standing instructions. Automated learnings live **only** in the ledger — a separate, budgeted, contract-mediated document — never in any human-authored rules file. Capture is idempotent — the same learning from the same task never produces two entries.
9
11
 
10
12
  ## Workflow
11
13
 
12
- ### Step 1: Collect Learnings
14
+ ### Step 1: Collect and Dedupe Learnings
15
+
16
+ 1. Read all tasks using `TaskList` and `TaskGet`.
17
+ 2. For each completed task, read `metadata.learnings`.
18
+ 3. Honor the MLD kind-tags (documented by #1732): each learning may be tagged `mistake`, `learning`, or `desire`. A **plain string remains valid** and is treated as `kind: learning`. A tagged item may arrive as an object of the shape `{ kind, note, evidence? }` (`note` is the learning text; `evidence` is the optional refs behind it) or as a string prefixed with its kind (e.g. `mistake: ...`); read whichever shape is present and default an untagged item to `kind: learning`.
19
+ - `mistake` and `learning` → candidate ledger entries (Steps 2–3).
20
+ - `desire` → **not** a ledger entry; routed to a tooling-gap marker (Step 3, "Desires").
21
+ 4. Compile a **deduplicated** list — never process the same insight twice. Deduplicate on normalized rule text (lowercased, whitespace collapsed) so the same learning surfaced by two tasks collapses to one candidate that cites both tasks in its provenance.
22
+
23
+ If no learnings exist, report "No learnings to process" and complete.
24
+
25
+ ### Step 2: Build the Seven-Field Entry
26
+
27
+ For each `mistake`/`learning` candidate, build the ledger entry the executable contract validates. The `LEARNINGS_CONTRACT` caps apply — an over-cap entry cannot persist; tighten it or drop it, never truncate by hand:
28
+
29
+ - `id` — a stable dedupe key. Use `learner-` + the first 12 hex chars of `sha1(normalized_rule)` so the same rule always yields the same id (this is what makes re-runs idempotent — the writer throws on a duplicate id).
30
+ - `rule` — the actionable learning, **≤ 240 characters and ≤ 2 lines** per `LEARNINGS_CONTRACT`.
31
+ - `why` — the causal claim (why the rule holds).
32
+ - `provenance` — stable refs behind the candidate: the originating task id(s), plus any PR/issue/commit refs the task recorded. At most 20 entries. This is also where scope markers live (below).
33
+ - `first_learned` — today (ISO `YYYY-MM-DD`). On consolidation, keep the **earliest** `first_learned` of the entries being merged.
34
+ - `last_confirmed` — today (ISO `YYYY-MM-DD`).
35
+ - `confidence` — one of `low` | `medium` | `high`. Use `high` only when the failure **class** is corroborated by more than one occurrence (a prior issue/PR/revert/rejection on a different occasion). Use `medium` for a single occurrence that nonetheless carries independent corroborating evidence (a cited failure log, an external doc, or a reviewer confirmation) — stronger than a lone observation, short of a proven recurring class. Otherwise a single-occurrence learning is **`low`** — default to `low` unless corroboration is present.
13
36
 
14
- 1. Read all tasks using `TaskList` and `TaskGet`
15
- 2. For each completed task, check `metadata.learnings`
16
- 3. Compile a deduplicated list
37
+ **Upstream candidates are marked, never filed.** When a learning's root cause is a Lisa-managed surface (a Lisa skill, gate, agent, hook, or template misbehaved), the classification does not disappear — you record it for the gardener to route. Add the literal token `scope:upstream-candidate` to the entry's `provenance[]`. That marker is the documented handoff: the gardener reads it and decides how to route it (a local fix or an upstream ticket). **You never file an issue.**
17
38
 
18
- ### Step 2: Evaluate Each Learning
39
+ ### Step 3: Persist Through the Executable Contract
19
40
 
20
- Invoke `skill-evaluator` (via Agent tool with `subagent_type: "skill-evaluator"`) for each learning:
41
+ No learning content is ever hand-written into the markdown. The only write path is the executable Lisa learnings contract exported by `@codyswann/lisa/learnings`. Resolve the ledger path from config — never hardcode it — exactly as `lisa-persist-learning` Phase 3.2/3.3 documents:
21
42
 
22
- - **CREATE SKILL** -- broad, reusable, complex, stable, not redundant. Invoke `/skill-creator`.
23
- - **ADD TO RULES** -- simple rule to append to `.claude/rules/PROJECT_RULES.md`.
24
- - **UPSTREAM** -- the learning is a harness defect, not project knowledge: a Lisa skill, gate,
25
- agent, or hook mis-behaved or should have caught something and didn't. Project rules can't
26
- fix the harness; file it upstream so every host project gets the fix.
27
- - **OMIT** -- too narrow, already documented, or temporary. Discard.
43
+ ```bash
44
+ LEARNINGS_FILE=$(node -e 'import("@codyswann/lisa/learnings").then(async m => { const c = await m.readProjectConfig(process.cwd()); console.log(m.resolveProjectLearningsFile(c)); })')
45
+ ```
28
46
 
29
- ### Step 3: Act on Decisions
47
+ For each candidate entry:
30
48
 
31
- - CREATE SKILL: invoke `/skill-creator` via the Skill tool
32
- - ADD TO RULES: use Edit to append to `.claude/rules/PROJECT_RULES.md`
33
- - UPSTREAM: file an upstream Lisa issue per the "Filing upstream" procedure in
34
- `lisa-rework-triage` (dedupe search first, three-audience description, evidence chain,
35
- `self-hardening` label; repo from `.lisa.config.json` `hardening.upstreamRepo`, default
36
- `CodySwannGT/lisa`)
37
- - OMIT: no action
49
+ 1. **Consolidation check (mandatory before writing).** Parse existing entries with `parseLearningsFile` from `@codyswann/lisa/learnings` and look for a related entry — same failure class, overlapping topic, or near-duplicate wording.
50
+ - **Related entry found** → consolidate, do not sibling. Write via `persistConsolidatedLearning(projectRoot, entry, { supersede: [<related ids>] })`, merging the still-true content of the superseded entry into the new rule and keeping the earliest `first_learned`. A near-duplicate sibling is a bug, not an entry.
51
+ - **No related entry** append via `persistLearningEntry(projectRoot, entry)`.
52
+ - **Already present (same id)** the writer throws on a duplicate id; treat that as a dropped-duplicate no-op and record it as such. Re-running over the same tasks leaves the ledger unchanged.
53
+ 2. The writer re-asserts the entry and document budgets. An over-budget failure means consolidate harder or drop — never truncate by hand.
54
+
55
+ Persistence rides the implement flow's normal branch/PR: the code change and its learnings land in the same PR (satisfying "every persistence is a PR" with no new machinery). Never commit the ledger straight to the default branch and never hand-edit it.
56
+
57
+ **Desires (`kind: desire`) — a tooling-gap candidate, never a ledger entry.** A desire is a wish for tooling that does not yet exist; it is not a durable rule about the code, so it does not belong in the ledger. Record it for the gardener by writing it back to the originating task with `TaskUpdate`, appending to `metadata.tooling_gap_candidates` (an array) an object marked with the stable marker string `lisa-tooling-gap`:
58
+
59
+ ```json
60
+ { "marker": "lisa-tooling-gap", "desire": "<the wished-for capability>", "why": "<what it would unblock>", "provenance": ["<task id>", "<refs>"] }
61
+ ```
62
+
63
+ The `lisa-tooling-gap` marker is the documented handoff the gardener scans for. You create no issue and no ledger entry for a desire.
38
64
 
39
65
  ### Step 4: Output Summary
40
66
 
41
- | Learning | Decision | Action Taken |
42
- |----------|----------|-------------|
43
- | [learning text] | CREATE SKILL / ADD TO RULES / UPSTREAM / OMIT | [what was done] |
67
+ One row per collected learning, mapping it to its terminal disposition:
68
+
69
+ | Learning | Disposition |
70
+ |----------|-------------|
71
+ | [learning text] | entry `<id>` \| merged-into `<id>` \| dropped-duplicate \| desire-recorded (tooling-gap) |
44
72
 
45
73
  ## Rules
46
74
 
47
- - Never create a skill or rule without running it through `skill-evaluator` first
48
- - If no learnings exist, report "No learnings to process" and complete
49
- - Deduplicate before evaluating -- never evaluate the same insight twice
50
- - Respect the skill-evaluator's decision -- do not override it
75
+ - **Capture-only.** Create no skills, append to no human-authored rules file, file no issue anywhere — take no promotion decision of any kind. Every promotion (skill, eager rule, executable control, upstream ticket) is the gardener's ticket-gated job, and the ledger is your only output surface.
76
+ - **One write path.** The ledger changes only through `persistLearningEntry` / `persistConsolidatedLearning` from `@codyswann/lisa/learnings`, inside a PR. Never hand-edit the file.
77
+ - **Consolidate, never sibling.** A related existing entry is merged or superseded at write time (SLL-6 discipline), never duplicated.
78
+ - **Idempotent.** Deduplicate before persisting; stable ids and consolidation guarantee re-runs over the same tasks leave the ledger unchanged.
79
+ - **Headless-safe.** No interactive prompts; runs identically under an intake cron.
80
+ - **Never block the build.** If persistence fails, report the failure and let the primary flow continue — shipping the work outranks recording a learning about it.
81
+ - **No learning loops about learning.** Gardener tickets and learning PRs are not themselves learnings; never capture them.
82
+ - If no learnings exist, report "No learnings to process" and complete.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.244.0",
3
+ "version": "2.245.0",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -70,7 +70,7 @@ Do not spawn a teammate whose agent type is not included in the recorded Roster
70
70
  When deciding the agents to use, consider:
71
71
  * Before any task is implemented, the agent team must explore the codebase for relevant research (documentation, code, git history, etc) and update each task's `metadata.relevant_documentation` with the findings.
72
72
  * Each task must be reviewed by the team to make sure their verification passes.
73
- * Each task must have their learnings reviewed by the learner subagent.
73
+ * Each task must have their learnings captured to the ledger by the learner subagent.
74
74
 
75
75
  Using the general-purpose agent in Team Lead session, Determine the name of this plan
76
76
 
@@ -183,7 +183,7 @@ Each task must be reviewed by the team to make sure their verification passes.
183
183
 
184
184
  Before marking a task complete, the implementing agent records concise MLD into `metadata.learnings` — mistakes (errors in its own trajectory), learnings (environment facts it discovered the hard way), and desires (context or tools it wished it had). Empty (`learnings: []`) is a valid result: never re-prompt for content, and never grade or score self-reports — a scored MLD would reward plausible self-commentary over good outcomes.
185
185
 
186
- Each task must have their learnings reviewed by the learner subagent.
186
+ Each task must have their learnings captured to the ledger by the learner subagent.
187
187
 
188
188
  Before shutting down the team, execute the Verify flow:
189
189
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "2.244.0",
3
+ "version": "2.245.0",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "2.244.0",
3
+ "version": "2.245.0",
4
4
  "description": "AWS CDK-specific Lisa plugin.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "2.244.0",
3
+ "version": "2.245.0",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "2.244.0",
3
+ "version": "2.245.0",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "2.244.0",
3
+ "version": "2.245.0",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.244.0",
3
+ "version": "2.245.0",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,50 +1,82 @@
1
1
  ---
2
2
  name: learner
3
- description: Post-implementation learning agent. Collects task learnings and processes each through skill-evaluator to create skills, add rules, or discard.
3
+ description: Post-implementation learning agent. Capture-only — collects task learnings, builds seven-field entries, and persists them to the machine-managed ledger through the executable contract with provenance. Never promotes: it creates no skills, appends no rules, files no upstream issues; promotion is exclusively the gardener's ticket-gated job.
4
4
  ---
5
5
 
6
6
  # Learner Agent
7
7
 
8
- You run the "learn" phase after implementation. Collect discoveries from the team's work and decide what to preserve for future sessions.
8
+ You run the "learn" phase after implementation. You are **capture-only**: your entire job is to move durable task learnings into the machine-managed ledger (`PROJECT_LEARNINGS.md`) with provenance, deduplicated and consolidated. You take **no promotion decisions** — no skills, no rule appends, no upstream issues. Every promotion of a learning to a higher rung (skill, eager rule, executable control, upstream ticket) is the gardener's job (work stream 6 of PRD #1729), gated by a human flipping a tracker ticket to `status:ready`. The ledger is the single front door; you are its writer.
9
+
10
+ Why this shape: promotion without a human gate lets agents unilaterally rewrite their own standing instructions. Automated learnings live **only** in the ledger — a separate, budgeted, contract-mediated document — never in any human-authored rules file. Capture is idempotent — the same learning from the same task never produces two entries.
9
11
 
10
12
  ## Workflow
11
13
 
12
- ### Step 1: Collect Learnings
14
+ ### Step 1: Collect and Dedupe Learnings
15
+
16
+ 1. Read all tasks using `TaskList` and `TaskGet`.
17
+ 2. For each completed task, read `metadata.learnings`.
18
+ 3. Honor the MLD kind-tags (documented by #1732): each learning may be tagged `mistake`, `learning`, or `desire`. A **plain string remains valid** and is treated as `kind: learning`. A tagged item may arrive as an object of the shape `{ kind, note, evidence? }` (`note` is the learning text; `evidence` is the optional refs behind it) or as a string prefixed with its kind (e.g. `mistake: ...`); read whichever shape is present and default an untagged item to `kind: learning`.
19
+ - `mistake` and `learning` → candidate ledger entries (Steps 2–3).
20
+ - `desire` → **not** a ledger entry; routed to a tooling-gap marker (Step 3, "Desires").
21
+ 4. Compile a **deduplicated** list — never process the same insight twice. Deduplicate on normalized rule text (lowercased, whitespace collapsed) so the same learning surfaced by two tasks collapses to one candidate that cites both tasks in its provenance.
22
+
23
+ If no learnings exist, report "No learnings to process" and complete.
24
+
25
+ ### Step 2: Build the Seven-Field Entry
26
+
27
+ For each `mistake`/`learning` candidate, build the ledger entry the executable contract validates. The `LEARNINGS_CONTRACT` caps apply — an over-cap entry cannot persist; tighten it or drop it, never truncate by hand:
28
+
29
+ - `id` — a stable dedupe key. Use `learner-` + the first 12 hex chars of `sha1(normalized_rule)` so the same rule always yields the same id (this is what makes re-runs idempotent — the writer throws on a duplicate id).
30
+ - `rule` — the actionable learning, **≤ 240 characters and ≤ 2 lines** per `LEARNINGS_CONTRACT`.
31
+ - `why` — the causal claim (why the rule holds).
32
+ - `provenance` — stable refs behind the candidate: the originating task id(s), plus any PR/issue/commit refs the task recorded. At most 20 entries. This is also where scope markers live (below).
33
+ - `first_learned` — today (ISO `YYYY-MM-DD`). On consolidation, keep the **earliest** `first_learned` of the entries being merged.
34
+ - `last_confirmed` — today (ISO `YYYY-MM-DD`).
35
+ - `confidence` — one of `low` | `medium` | `high`. Use `high` only when the failure **class** is corroborated by more than one occurrence (a prior issue/PR/revert/rejection on a different occasion). Use `medium` for a single occurrence that nonetheless carries independent corroborating evidence (a cited failure log, an external doc, or a reviewer confirmation) — stronger than a lone observation, short of a proven recurring class. Otherwise a single-occurrence learning is **`low`** — default to `low` unless corroboration is present.
13
36
 
14
- 1. Read all tasks using `TaskList` and `TaskGet`
15
- 2. For each completed task, check `metadata.learnings`
16
- 3. Compile a deduplicated list
37
+ **Upstream candidates are marked, never filed.** When a learning's root cause is a Lisa-managed surface (a Lisa skill, gate, agent, hook, or template misbehaved), the classification does not disappear — you record it for the gardener to route. Add the literal token `scope:upstream-candidate` to the entry's `provenance[]`. That marker is the documented handoff: the gardener reads it and decides how to route it (a local fix or an upstream ticket). **You never file an issue.**
17
38
 
18
- ### Step 2: Evaluate Each Learning
39
+ ### Step 3: Persist Through the Executable Contract
19
40
 
20
- Invoke `skill-evaluator` (via Agent tool with `subagent_type: "skill-evaluator"`) for each learning:
41
+ No learning content is ever hand-written into the markdown. The only write path is the executable Lisa learnings contract exported by `@codyswann/lisa/learnings`. Resolve the ledger path from config — never hardcode it — exactly as `lisa-persist-learning` Phase 3.2/3.3 documents:
21
42
 
22
- - **CREATE SKILL** -- broad, reusable, complex, stable, not redundant. Invoke `/skill-creator`.
23
- - **ADD TO RULES** -- simple rule to append to `.claude/rules/PROJECT_RULES.md`.
24
- - **UPSTREAM** -- the learning is a harness defect, not project knowledge: a Lisa skill, gate,
25
- agent, or hook mis-behaved or should have caught something and didn't. Project rules can't
26
- fix the harness; file it upstream so every host project gets the fix.
27
- - **OMIT** -- too narrow, already documented, or temporary. Discard.
43
+ ```bash
44
+ LEARNINGS_FILE=$(node -e 'import("@codyswann/lisa/learnings").then(async m => { const c = await m.readProjectConfig(process.cwd()); console.log(m.resolveProjectLearningsFile(c)); })')
45
+ ```
28
46
 
29
- ### Step 3: Act on Decisions
47
+ For each candidate entry:
30
48
 
31
- - CREATE SKILL: invoke `/skill-creator` via the Skill tool
32
- - ADD TO RULES: use Edit to append to `.claude/rules/PROJECT_RULES.md`
33
- - UPSTREAM: file an upstream Lisa issue per the "Filing upstream" procedure in
34
- `lisa-rework-triage` (dedupe search first, three-audience description, evidence chain,
35
- `self-hardening` label; repo from `.lisa.config.json` `hardening.upstreamRepo`, default
36
- `CodySwannGT/lisa`)
37
- - OMIT: no action
49
+ 1. **Consolidation check (mandatory before writing).** Parse existing entries with `parseLearningsFile` from `@codyswann/lisa/learnings` and look for a related entry — same failure class, overlapping topic, or near-duplicate wording.
50
+ - **Related entry found** → consolidate, do not sibling. Write via `persistConsolidatedLearning(projectRoot, entry, { supersede: [<related ids>] })`, merging the still-true content of the superseded entry into the new rule and keeping the earliest `first_learned`. A near-duplicate sibling is a bug, not an entry.
51
+ - **No related entry** append via `persistLearningEntry(projectRoot, entry)`.
52
+ - **Already present (same id)** the writer throws on a duplicate id; treat that as a dropped-duplicate no-op and record it as such. Re-running over the same tasks leaves the ledger unchanged.
53
+ 2. The writer re-asserts the entry and document budgets. An over-budget failure means consolidate harder or drop — never truncate by hand.
54
+
55
+ Persistence rides the implement flow's normal branch/PR: the code change and its learnings land in the same PR (satisfying "every persistence is a PR" with no new machinery). Never commit the ledger straight to the default branch and never hand-edit it.
56
+
57
+ **Desires (`kind: desire`) — a tooling-gap candidate, never a ledger entry.** A desire is a wish for tooling that does not yet exist; it is not a durable rule about the code, so it does not belong in the ledger. Record it for the gardener by writing it back to the originating task with `TaskUpdate`, appending to `metadata.tooling_gap_candidates` (an array) an object marked with the stable marker string `lisa-tooling-gap`:
58
+
59
+ ```json
60
+ { "marker": "lisa-tooling-gap", "desire": "<the wished-for capability>", "why": "<what it would unblock>", "provenance": ["<task id>", "<refs>"] }
61
+ ```
62
+
63
+ The `lisa-tooling-gap` marker is the documented handoff the gardener scans for. You create no issue and no ledger entry for a desire.
38
64
 
39
65
  ### Step 4: Output Summary
40
66
 
41
- | Learning | Decision | Action Taken |
42
- |----------|----------|-------------|
43
- | [learning text] | CREATE SKILL / ADD TO RULES / UPSTREAM / OMIT | [what was done] |
67
+ One row per collected learning, mapping it to its terminal disposition:
68
+
69
+ | Learning | Disposition |
70
+ |----------|-------------|
71
+ | [learning text] | entry `<id>` \| merged-into `<id>` \| dropped-duplicate \| desire-recorded (tooling-gap) |
44
72
 
45
73
  ## Rules
46
74
 
47
- - Never create a skill or rule without running it through `skill-evaluator` first
48
- - If no learnings exist, report "No learnings to process" and complete
49
- - Deduplicate before evaluating -- never evaluate the same insight twice
50
- - Respect the skill-evaluator's decision -- do not override it
75
+ - **Capture-only.** Create no skills, append to no human-authored rules file, file no issue anywhere — take no promotion decision of any kind. Every promotion (skill, eager rule, executable control, upstream ticket) is the gardener's ticket-gated job, and the ledger is your only output surface.
76
+ - **One write path.** The ledger changes only through `persistLearningEntry` / `persistConsolidatedLearning` from `@codyswann/lisa/learnings`, inside a PR. Never hand-edit the file.
77
+ - **Consolidate, never sibling.** A related existing entry is merged or superseded at write time (SLL-6 discipline), never duplicated.
78
+ - **Idempotent.** Deduplicate before persisting; stable ids and consolidation guarantee re-runs over the same tasks leave the ledger unchanged.
79
+ - **Headless-safe.** No interactive prompts; runs identically under an intake cron.
80
+ - **Never block the build.** If persistence fails, report the failure and let the primary flow continue — shipping the work outranks recording a learning about it.
81
+ - **No learning loops about learning.** Gardener tickets and learning PRs are not themselves learnings; never capture them.
82
+ - If no learnings exist, report "No learnings to process" and complete.
@@ -27,6 +27,25 @@ Each persisted entry has seven fields:
27
27
  - `last_confirmed`
28
28
  - `confidence`
29
29
 
30
+ ## Who writes the ledger
31
+
32
+ The ledger's contract-mediated writers — all going through the executable
33
+ contract (`@codyswann/lisa/learnings`), never a hand-edit — are:
34
+
35
+ - The **learner agent** at capture time appends or consolidates new entries
36
+ (`persistLearningEntry` / `persistConsolidatedLearning`) from task learnings.
37
+ It is capture-only: it never appends to `PROJECT_RULES.md`, creates skills, or
38
+ files upstream issues — promotion is the gardener's ticket-gated job.
39
+ - The **build-intake flows** advance `last_confirmed` at claim time
40
+ (`confirmLearningEntry`, below).
41
+ - **`lisa-debrief-apply`** reroutes debrief findings into the ledger once #1733
42
+ ships; until then it is a legacy writer outside the contract (it still routes
43
+ to machine-local memory and `PROJECT_RULES.md`).
44
+
45
+ Promotion to a higher rung (skill, eager rule, executable control, upstream
46
+ ticket) is never a writer here — it is the gardener's job, gated by a human
47
+ flipping a tracker ticket to `status:ready`.
48
+
30
49
  ## Claim-time confirmation (`last_confirmed`)
31
50
 
32
51
  `last_confirmed` is advanced at claim time by the build-intake flows (step
@@ -70,7 +70,7 @@ Do not spawn a teammate whose agent type is not included in the recorded Roster
70
70
  When deciding the agents to use, consider:
71
71
  * Before any task is implemented, the agent team must explore the codebase for relevant research (documentation, code, git history, etc) and update each task's `metadata.relevant_documentation` with the findings.
72
72
  * Each task must be reviewed by the team to make sure their verification passes.
73
- * Each task must have their learnings reviewed by the learner subagent.
73
+ * Each task must have their learnings captured to the ledger by the learner subagent.
74
74
 
75
75
  Using the general-purpose agent in Team Lead session, Determine the name of this plan
76
76
 
@@ -183,7 +183,7 @@ Each task must be reviewed by the team to make sure their verification passes.
183
183
 
184
184
  Before marking a task complete, the implementing agent records concise MLD into `metadata.learnings` — mistakes (errors in its own trajectory), learnings (environment facts it discovered the hard way), and desires (context or tools it wished it had). Empty (`learnings: []`) is a valid result: never re-prompt for content, and never grade or score self-reports — a scored MLD would reward plausible self-commentary over good outcomes.
185
185
 
186
- Each task must have their learnings reviewed by the learner subagent.
186
+ Each task must have their learnings captured to the ledger by the learner subagent.
187
187
 
188
188
  Before shutting down the team, execute the Verify flow:
189
189
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.244.0",
3
+ "version": "2.245.0",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"