@codyswann/lisa 2.246.0 → 2.247.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 (107) hide show
  1. package/all/create-only/.claude/rules/PROJECT_RULES.md +9 -1
  2. package/package.json +1 -1
  3. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  4. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  5. package/plugins/lisa/.codex-plugin/skills/lisa-learnings-audit/SKILL.md +349 -0
  6. package/plugins/lisa/.codex-plugin/skills/lisa-learnings-audit/agents/openai.yaml +4 -0
  7. package/plugins/lisa/.codex-plugin/skills/lisa-parity-skill-creator/SKILL.md +3 -1
  8. package/plugins/lisa/.codex-plugin/skills/lisa-persist-learning/SKILL.md +1 -1
  9. package/plugins/lisa/.codex-plugin/skills/lisa-rework-triage/SKILL.md +25 -8
  10. package/plugins/lisa/.codex-plugin/skills/lisa-setup-automations/SKILL.md +23 -3
  11. package/plugins/lisa/agents/learning-judge.md +1 -1
  12. package/plugins/lisa/agents/skill-evaluator.md +135 -175
  13. package/plugins/lisa/commands/learnings/audit.md +6 -0
  14. package/plugins/lisa/rules/eager/promotion-contract.md +18 -0
  15. package/plugins/lisa/rules/reference/promotion-contract.md +126 -0
  16. package/plugins/lisa/skills/lisa-learnings-audit/SKILL.md +349 -0
  17. package/plugins/lisa/skills/lisa-learnings-audit/agents/openai.yaml +4 -0
  18. package/plugins/lisa/skills/lisa-parity-skill-creator/SKILL.md +3 -1
  19. package/plugins/lisa/skills/lisa-persist-learning/SKILL.md +1 -1
  20. package/plugins/lisa/skills/lisa-rework-triage/SKILL.md +25 -8
  21. package/plugins/lisa/skills/lisa-setup-automations/SKILL.md +24 -4
  22. package/plugins/lisa-agy/agents/learning-judge.md +1 -1
  23. package/plugins/lisa-agy/agents/skill-evaluator.md +135 -175
  24. package/plugins/lisa-agy/commands/lisa/learnings/audit.md +6 -0
  25. package/plugins/lisa-agy/plugin.json +1 -1
  26. package/plugins/lisa-agy/skills/lisa-learnings-audit/SKILL.md +349 -0
  27. package/plugins/lisa-agy/skills/lisa-parity-skill-creator/SKILL.md +3 -1
  28. package/plugins/lisa-agy/skills/lisa-persist-learning/SKILL.md +1 -1
  29. package/plugins/lisa-agy/skills/lisa-rework-triage/SKILL.md +25 -8
  30. package/plugins/lisa-agy/skills/lisa-setup-automations/SKILL.md +24 -4
  31. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  32. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  33. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  34. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  35. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  36. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  37. package/plugins/lisa-copilot/agents/learning-judge.agent.md +1 -1
  38. package/plugins/lisa-copilot/agents/skill-evaluator.agent.md +135 -175
  39. package/plugins/lisa-copilot/commands/lisa/learnings/audit.md +6 -0
  40. package/plugins/lisa-copilot/rules/eager/promotion-contract.md +18 -0
  41. package/plugins/lisa-copilot/rules/reference/promotion-contract.md +126 -0
  42. package/plugins/lisa-copilot/skills/lisa-learnings-audit/SKILL.md +349 -0
  43. package/plugins/lisa-copilot/skills/lisa-parity-skill-creator/SKILL.md +3 -1
  44. package/plugins/lisa-copilot/skills/lisa-persist-learning/SKILL.md +1 -1
  45. package/plugins/lisa-copilot/skills/lisa-rework-triage/SKILL.md +25 -8
  46. package/plugins/lisa-copilot/skills/lisa-setup-automations/SKILL.md +24 -4
  47. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  48. package/plugins/lisa-cursor/agents/learning-judge.md +1 -1
  49. package/plugins/lisa-cursor/agents/skill-evaluator.md +135 -175
  50. package/plugins/lisa-cursor/commands/lisa/learnings/audit.md +6 -0
  51. package/plugins/lisa-cursor/rules/promotion-contract-reference.mdc +131 -0
  52. package/plugins/lisa-cursor/rules/promotion-contract.mdc +23 -0
  53. package/plugins/lisa-cursor/skills/lisa-learnings-audit/SKILL.md +349 -0
  54. package/plugins/lisa-cursor/skills/lisa-parity-skill-creator/SKILL.md +3 -1
  55. package/plugins/lisa-cursor/skills/lisa-persist-learning/SKILL.md +1 -1
  56. package/plugins/lisa-cursor/skills/lisa-rework-triage/SKILL.md +25 -8
  57. package/plugins/lisa-cursor/skills/lisa-setup-automations/SKILL.md +24 -4
  58. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  59. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  60. package/plugins/lisa-expo-agy/plugin.json +1 -1
  61. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  62. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  63. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  64. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  65. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  66. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  67. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  68. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  69. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  70. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  71. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  72. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  73. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  74. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  75. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  76. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  77. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  78. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  79. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  80. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  81. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  82. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  83. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  84. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  85. package/plugins/lisa-rails-agy/plugin.json +1 -1
  86. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  87. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  88. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  89. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  90. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  91. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  92. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  93. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  94. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  95. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  96. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  97. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  98. package/plugins/src/base/agents/learning-judge.md +1 -1
  99. package/plugins/src/base/agents/skill-evaluator.md +135 -175
  100. package/plugins/src/base/commands/learnings/audit.md +6 -0
  101. package/plugins/src/base/rules/eager/promotion-contract.md +18 -0
  102. package/plugins/src/base/rules/reference/promotion-contract.md +126 -0
  103. package/plugins/src/base/skills/lisa-learnings-audit/SKILL.md +349 -0
  104. package/plugins/src/base/skills/lisa-parity-skill-creator/SKILL.md +3 -1
  105. package/plugins/src/base/skills/lisa-persist-learning/SKILL.md +1 -1
  106. package/plugins/src/base/skills/lisa-rework-triage/SKILL.md +25 -8
  107. package/plugins/src/base/skills/lisa-setup-automations/SKILL.md +24 -4
@@ -0,0 +1,18 @@
1
+ # Promotion Contract (load-bearing)
2
+
3
+ When implementing a learnings-ladder **promotion ticket** — turning prose
4
+ knowledge into an executable control (lint / ast-grep / type / test / hook /
5
+ `package.lisa.json` force) — the change must be **atomic**: one PR that
6
+ **enables the control**, **fixes the existing violation population**, **ships a
7
+ remediation-teaching diagnostic** (violated invariant + why + concrete fix),
8
+ and **deletes the superseded prose**. A PR missing any of the four is
9
+ **rejected by rule** — promote-without-remove double-pays forever;
10
+ remove-without-diagnostic strands agents.
11
+
12
+ Eager-tier admission is **demotion-biased** and earned only by repeated-miss
13
+ evidence; the gardener audits the eager tier every run, including Lisa's own
14
+ shipped eager rules.
15
+
16
+ Full contract, diagnostic-quality bar, and the AC template the gardener embeds
17
+ in EXECUTABLE-CONTROL promotion tickets:
18
+ [reference/promotion-contract.md](../reference/promotion-contract.md).
@@ -0,0 +1,126 @@
1
+ # Promotion Contract
2
+
3
+ When a learnings-ladder promotion ticket (PRD #1729) is implemented — turning a
4
+ prose learning, rule section, or ledger entry into an **executable control**
5
+ (lint, ast-grep, type constraint, test, hook, or `package.lisa.json` force) —
6
+ the implementing PR is governed by this contract. The gardener
7
+ (`lisa-learnings-audit`) files the tickets; a human gates them by flipping
8
+ `status:ready`; the factory implements them like any other work item. This rule
9
+ is what makes the resulting PR reviewable **by rule, not by reviewer taste**.
10
+
11
+ ## The atomic promote-and-delete contract
12
+
13
+ A promotion PR must do **all four** of the following, in **one atomic PR**:
14
+
15
+ 1. **Enable the control.** The lint rule, ast-grep pattern, type constraint,
16
+ test, hook, or `package.lisa.json` force entry is active and blocking (CI
17
+ and/or local gates), not merely added in a warn-only or disabled state.
18
+ 2. **Fix the existing violation population.** Every current violation of the
19
+ new control in the repository is migrated in the same PR, so the control
20
+ lands green. Enabling a control against a red population either blocks all
21
+ unrelated work or forces a blanket ignore — both defeat the promotion.
22
+ 3. **Ship a remediation-teaching diagnostic.** The control's failure message
23
+ meets the diagnostic-quality bar below. The prose being deleted is not
24
+ lost — its content is **relocated into the error message**, so the agent
25
+ that trips the control learns the rule at exactly the moment it matters.
26
+ 4. **Delete the superseded prose.** The ledger entry, rules-file section,
27
+ memory note, or wiki duplication that the control replaces is removed in
28
+ the same PR. Keeping both means every session keeps paying context tax for
29
+ knowledge the machine already enforces.
30
+
31
+ **A PR missing any of the four is rejected by rule.** Reviewers (human, bot,
32
+ or verification lifecycle) cite this contract and reject — no case-by-case
33
+ judgment call is needed. The failure modes are structural, not stylistic:
34
+
35
+ - **Promote-without-remove double-pays forever**: the control enforces the
36
+ invariant while the prose keeps taxing every session, and the two drift
37
+ apart over time.
38
+ - **Remove-without-diagnostic strands agents**: the prose is gone, the control
39
+ fires, and the violator has no idea what invariant it tripped or how to
40
+ repair it.
41
+ - **Enable-without-population-fix** reds the build for everyone or breeds
42
+ blanket ignores that hollow the control out.
43
+
44
+ The same atomicity applies in reverse to **retirements** the gardener batches:
45
+ a prose deletion whose invariant is claimed to be mechanically owned must cite
46
+ the owning control (rule name, config location) in the deleting PR.
47
+
48
+ ## The diagnostic-quality bar
49
+
50
+ The error message must **teach the repair**, because it is the only surface
51
+ the violating agent will see. Every promoted control's diagnostic states:
52
+
53
+ 1. **The violated invariant** — what rule was broken, named precisely.
54
+ 2. **Why the invariant holds** — the causal story that used to live in the
55
+ prose (the incident, the failure class, the platform behavior).
56
+ 3. **The concrete fix** — what to change, ideally with the typical corrected
57
+ form inline.
58
+
59
+ Example shape (from this repo's own lint conventions):
60
+
61
+ > "Direct `process.env` access is forbidden. Config values bypass validation
62
+ > and typing when read ad hoc (past incidents: silent `undefined` in Lambda
63
+ > cold starts). Use the config module: `getStandaloneConfig().myValue`."
64
+
65
+ A diagnostic that merely restates the rule name ("no-direct-env: direct env
66
+ access is not allowed") fails the bar and fails the promotion PR with it.
67
+
68
+ ## Eager-tier admission policy (demotion-biased)
69
+
70
+ The eager rules tier (auto-loaded rules trees) charges **every session,
71
+ unconditionally**. Admission is therefore **earned, never defaulted**:
72
+
73
+ - A rule enters (or stays in) the eager tier only on cited **repeated-miss
74
+ evidence** — the knowledge was already retrievable (ledger, wiki, skill,
75
+ reference body) and agents still failed repeatedly because they did not
76
+ know to look. Absent that evidence, the content belongs on a cheaper rung.
77
+ - The policy is **demotion-biased**: when in doubt, move down the ladder.
78
+ A wrongly demoted rule earns its way back with fresh failure evidence; a
79
+ wrongly admitted rule taxes every session until someone notices.
80
+ - The gardener audits the eager tier **every run** — and that audit includes
81
+ **Lisa's own shipped eager rules**, not just host-project additions. No
82
+ rule is grandfathered; kernel rules demonstrating no repeated-miss evidence
83
+ get demotion tickets like any other candidate, filed upstream
84
+ (`template-candidate` or `self-hardening` lane as applicable).
85
+
86
+ ## AC template for EXECUTABLE-CONTROL promotion tickets
87
+
88
+ The gardener embeds the following snippet **verbatim** (markers included) into
89
+ the acceptance criteria of every EXECUTABLE-CONTROL promotion ticket, so
90
+ implementing agents receive the contract inside the work item itself:
91
+
92
+ <!-- promotion-contract-ac-template:start -->
93
+ ### Acceptance Criteria (promotion-to-control contract)
94
+
95
+ One atomic PR that satisfies all four legs — a PR missing any of the four is
96
+ rejected by rule (see the `promotion-contract` rule):
97
+
98
+ - [ ] **Enables the control** — the lint / ast-grep / type constraint / test /
99
+ hook / `package.lisa.json` force entry is active and blocking.
100
+ - [ ] **Fixes the existing violation population** — every current violation is
101
+ migrated in this same PR, so the control lands green with no blanket
102
+ ignores.
103
+ - [ ] **Ships a remediation-teaching diagnostic** — the failure message states
104
+ the violated invariant, why it holds, and the concrete fix.
105
+ - [ ] **Deletes the superseded prose** — the ledger entry / rules section this
106
+ control replaces is removed in this same PR, citing the new mechanical
107
+ owner.
108
+ <!-- promotion-contract-ac-template:end -->
109
+
110
+ Do not paraphrase, reorder, or partially quote the snippet when embedding it —
111
+ verbatim embedding is what keeps the contract identical across every ticket
112
+ and lets reviewers diff against a single source of truth.
113
+
114
+ ## Who consumes this rule
115
+
116
+ - **Implementing agents** working a promotion ticket: structure the PR around
117
+ the four legs before writing code.
118
+ - **Review flows** (human, CodeRabbit, `lisa-pull-request-review`,
119
+ verification lifecycle): reject a promotion PR missing any leg, citing this
120
+ rule.
121
+ - **The gardener** (`lisa-learnings-audit`): embeds the AC template above into
122
+ EXECUTABLE-CONTROL promotion tickets and applies the eager-tier admission
123
+ policy when auditing.
124
+ - **PROJECT_RULES.md owners**: that file is human-authored only; machine
125
+ writes go to the learnings ledger, and promotions out of it arrive as
126
+ gardener tickets governed by this contract.
@@ -0,0 +1,349 @@
1
+ ---
2
+ name: lisa-learnings-audit
3
+ description: "The gardener of the learnings ladder (PRD #1729). Periodically audits every knowledge surface — ledger, rules trees (including Lisa's own shipped eager rules), skills, wiki index, and mechanical-control surfaces — gathers evidence per item (recurrence, staleness, redundancy, contradiction, budget pressure), classifies each candidate through the ladder router (skill-evaluator, advisory), and communicates exclusively through the tracker: one evidence-bearing ticket per PROMOTE/DEMOTE, one batch ticket per run for CONFIRM/RETIRE, upstream Lisa issues for upstream-scoped patterns. Everything is human-gated at v1 — the skill only files tickets; humans gate by flipping status:ready or closing as rejected, and rejections are remembered. Cron-able via lisa-setup-automations and runnable on demand via /lisa:learnings:audit."
4
+ allowed-tools: ["Skill", "Bash", "Read", "Glob", "Grep"]
5
+ ---
6
+
7
+ # Learnings Audit (the gardener): $ARGUMENTS
8
+
9
+ Run one audit cycle over this project's knowledge surfaces and convert what the
10
+ evidence supports into **human-gated tracker tickets** — nothing else. The
11
+ gardener is the only flow in Lisa that takes knowledge *back out* or moves it
12
+ *up* the ladder; it closes the loop that capture (learner, debrief-apply, MLD)
13
+ opens.
14
+
15
+ `$ARGUMENTS` (all optional): `max_candidates=<n>` (default **10** — cap on
16
+ per-item PROMOTE/DEMOTE tickets filed per run, following the
17
+ `lisa-repair-intake` bounded-cycle precedent; CONFIRM/RETIRE batch rows are
18
+ not capped), `surface=<ledger|rules|skills|wiki|all>` (default `all`),
19
+ `dry_run=true` (report what would be filed, file nothing).
20
+
21
+ ## Intent
22
+
23
+ Keep the knowledge system from silting up: every learning lives at the
24
+ cheapest rung that still prevents the mistake (per the six-rung ladder,
25
+ PRD #1729), prose never duplicates a mechanical owner, the eager tier shrinks
26
+ over time, and every change to "what the agents believe" is approved by a
27
+ human through the tracker. A quiet run with nothing to propose is a healthy
28
+ outcome and says so in its one-line summary.
29
+
30
+ ## Sources of truth
31
+
32
+ Inventory these surfaces each run — discover dynamically, never from a
33
+ memorized list:
34
+
35
+ 1. **The ledger** — resolve via `.lisa.config.json` (`learnings.file`, default
36
+ `.lisa/PROJECT_LEARNINGS.md`) and read it ONLY through the executable
37
+ contract from `@codyswann/lisa/learnings`: `parseLearningsFile` for the
38
+ **full parse** (the gardener is the maintenance loop — auditing requires
39
+ every entry, and the contract-mediated full parse is its documented
40
+ exemption from projection-only serving) plus `projectLearnings` for the
41
+ bounded projection (to measure **budget pressure**: how many entries the
42
+ projection omits). Never hand-parse or hand-edit the raw file.
43
+ 2. **Rules trees** — the plugin `rules/eager/` + `rules/reference/` pairs AND
44
+ the host project's `.claude/rules/` (e.g. `PROJECT_RULES.md`, which is
45
+ human-authored only — its existing sections are still audit candidates;
46
+ first-run candidates come from exactly there).
47
+ 3. **Skills** — `.claude/skills/` and the plugin skill roots the runtime
48
+ exposes (descriptions are eager context; bodies load on invoke).
49
+ 4. **The wiki index** — `wiki/index.md` when the project has a wiki.
50
+ 5. **Mechanical-control surfaces** — lint configs (ESLint/oxlint), ast-grep
51
+ rules, git hooks, test suites, and `package.lisa.json` force sections:
52
+ the surfaces that answer "does a mechanical owner already exist?".
53
+ 6. **The tracker** — prior gardener tickets (open, done, and closed-rejected)
54
+ are its memory; see Idempotency.
55
+
56
+ ## Candidate-selection rules
57
+
58
+ A surface item becomes a candidate only when evidence supports a change.
59
+ Gather, per item, the five evidence axes:
60
+
61
+ | Axis | Question | How |
62
+ |------|----------|-----|
63
+ | **Recurrence** | Has the same failure class recurred since the entry's `last_confirmed` (or the rule's last touch)? | Search issues/PRs/commits since that date — reuse the `git-history-analyzer` agent for commit/PR archaeology; tracker search for issue recurrence. |
64
+ | **Staleness** | Does the item reference files, flags, versions, or tools that no longer exist? | Glob/Grep the referenced paths and configs. |
65
+ | **Redundancy** | Does a mechanical owner already enforce the invariant? (The double-payment hunter.) | Check lint/ast-grep/hook/test/force surfaces for the same invariant. |
66
+ | **Contradiction** | Does the item contradict another rule, skill, config, or observed current behavior? | Cross-reference the inventoried surfaces. |
67
+ | **Budget pressure** | Is the ledger projection omitting entries, or the eager tier growing? | `projectLearnings` omission count; eager-tree token/size trend. |
68
+
69
+ Selection outcomes per candidate: **PROMOTE** (up the ladder), **DEMOTE**
70
+ (down the ladder), **CONFIRM** (evidence the entry demonstrably applied —
71
+ a `last_confirmed` bump), **RETIRE** (provably redundant/stale — proof, not
72
+ vibes), or leave alone. No evidence ⇒ no candidate; the gardener never files
73
+ a recommendation it cannot evidence.
74
+
75
+ **The eager tier is audited every run** — including
76
+ **Lisa's own shipped eager rules**, not just host additions. Admission is demotion-biased and
77
+ earned only by repeated-miss evidence (see the `promotion-contract` rule);
78
+ an eager rule without that evidence gets a DEMOTE candidate citing the
79
+ admission policy, scoped upstream when the rule ships with the kernel.
80
+
81
+ **Exclusions (no learning loops about learning).** Never candidates, never
82
+ evidence:
83
+
84
+ - The gardener's own tickets, PRs, and comments (anything carrying the
85
+ `[lisa-gardener]` marker).
86
+ - All learning-machinery artifacts: items carrying `[lisa-learning-drop]`,
87
+ `[lisa-learning-pr]`, `[lisa-learning-upstream-handoff]` (any
88
+ `[lisa-learning-*]` marker), `[lisa-rejection-candidate]`, or
89
+ `[lisa-archaeology-candidate]`, and the `learning:needs-triage` label.
90
+
91
+ ## Scope
92
+
93
+ - **In scope**: recommending placement changes for knowledge on any
94
+ inventoried surface, in this repository (`project` scope) or upstream in
95
+ `CodySwannGT/lisa` (`upstream` scope).
96
+ - **Out of scope**: executing any promotion/demotion/retirement (the factory
97
+ does, per flipped tickets), editing any knowledge surface, auto-apply modes
98
+ (v1 is fully gated), and the capture streams (learner, debrief, MLD).
99
+
100
+ ## Proof
101
+
102
+ A run is proven, not asserted. The per-run report (and the run ticket, when
103
+ one exists) must show:
104
+
105
+ - The surfaces inventoried, with counts (ledger entries parsed, rules files,
106
+ skills, wiki pages, mechanical controls).
107
+ - Per filed ticket: the fingerprint marker, the evidence refs behind it, and
108
+ the router's rung — so any reviewer can replay the reasoning from links
109
+ alone.
110
+ - Per skipped candidate: which dedupe hit suppressed it (open ticket URL,
111
+ done ticket, or rejection date).
112
+ - For `nothing-needed`: the thresholds nothing met, in one line.
113
+
114
+ The tickets themselves are the durable artifacts; the report is how a human
115
+ audits the auditor without re-running it.
116
+
117
+ ## The audit cycle
118
+
119
+ 1. **Inventory** the sources of truth above.
120
+ 2. **Evidence** — gather the five axes per item; drop items with none.
121
+ 3. **Classify** — pass each candidate (`rule`, `why`, `provenance`,
122
+ `evidence`) to the ladder router (the `skill-evaluator` agent). The router
123
+ is **advisory**: it returns `rung`, `scope`, `rationale`, and
124
+ `drafted_artifact`; the gardener decides whether the evidence clears the
125
+ filing bar and attaches the router's draft to the ticket.
126
+ 4. **Emit** (see Ticket emission).
127
+ 5. **Report** the terminal state and one-line summary.
128
+
129
+ ## Ticket emission
130
+
131
+ All project-tracker writes go through **`lisa-tracker-write`** so gardener
132
+ tickets pass the same validation gates as all factory work. Nothing is created
133
+ `status:ready` — the human flips.
134
+
135
+ **Per-item tickets — PROMOTE / DEMOTE** (`issue_type: Task`; GitHub trackers
136
+ carry the `type:Task` label) — one ticket per recommendation, capped by
137
+ `max_candidates`:
138
+
139
+ - A **three-audience description** (operator: what changes about what the
140
+ agents believe and why it is safe; engineering: the surface, the invariant,
141
+ the destination rung; QA: how to verify the move) with **evidence links**
142
+ (the recurrence issues/PRs/commits, the staleness proof, the mechanical
143
+ owner).
144
+ - The router's **`drafted_artifact`** verbatim (the lint/hook sketch +
145
+ diagnostic text, proposed rule text, skill outline, page outline, or
146
+ redundancy proof).
147
+ - For **EXECUTABLE-CONTROL** promotions, embed the promotion-contract AC
148
+ template below **verbatim** (markers included — do not paraphrase, reorder,
149
+ or partially quote it; it is the single source of truth from the
150
+ `promotion-contract` rule):
151
+
152
+ <!-- promotion-contract-ac-template:start -->
153
+ ### Acceptance Criteria (promotion-to-control contract)
154
+
155
+ One atomic PR that satisfies all four legs — a PR missing any of the four is
156
+ rejected by rule (see the `promotion-contract` rule):
157
+
158
+ - [ ] **Enables the control** — the lint / ast-grep / type constraint / test /
159
+ hook / `package.lisa.json` force entry is active and blocking.
160
+ - [ ] **Fixes the existing violation population** — every current violation is
161
+ migrated in this same PR, so the control lands green with no blanket
162
+ ignores.
163
+ - [ ] **Ships a remediation-teaching diagnostic** — the failure message states
164
+ the violated invariant, why it holds, and the concrete fix.
165
+ - [ ] **Deletes the superseded prose** — the ledger entry / rules section this
166
+ control replaces is removed in this same PR, citing the new mechanical
167
+ owner.
168
+ <!-- promotion-contract-ac-template:end -->
169
+
170
+ **One batch ticket per run — CONFIRM + RETIRE** (`issue_type: Task`): a single
171
+ ticket listing every CONFIRM row (`last_confirmed` bump, with the evidence the
172
+ entry demonstrably applied) and every **provably-redundant** RETIRE row (with
173
+ the mechanical owner / staleness proof per row). Rows are individually
174
+ strikeable — the human deletes rows they reject, then flips the ticket ready.
175
+ The gardener **never bumps `last_confirmed` itself**: the bumps are executed
176
+ by the **implementing factory run** that picks up the flipped batch ticket.
177
+ Embed the following execution contract **verbatim** (markers included — do
178
+ not paraphrase, reorder, or partially quote it) in every batch ticket, so the
179
+ implementing run receives its instructions inside the work item:
180
+
181
+ <!-- gardener-batch-ticket-template:start -->
182
+ ### Execution contract (CONFIRM/RETIRE batch)
183
+
184
+ - Apply each surviving CONFIRM row via `confirmLearningEntry` from
185
+ `@codyswann/lisa/learnings` — never hand-edit the ledger.
186
+ - Implement each surviving RETIRE row as a proof-citing deletion PR per the
187
+ `promotion-contract` rule's reverse-atomicity clause: the deleting PR must
188
+ cite the row's mechanical owner or staleness proof.
189
+ - Struck/deleted rows are human rejections — skip them; they are not re-filed
190
+ without new postdating evidence.
191
+ <!-- gardener-batch-ticket-template:end -->
192
+
193
+ **Upstream scope** → an issue on `CodySwannGT/lisa` (resolve via
194
+ `hardening.upstreamRepo`, default `CodySwannGT/lisa`), following the
195
+ `lisa-rework-triage` "Filing upstream" procedure and its two lanes:
196
+ `self-hardening` for defects, `template-candidate` for generalizable patterns
197
+ (with the required `## Proposed template change` section). Same dedupe-marker
198
+ + evidence-chain discipline; the gardener's fingerprint marker (below) rides
199
+ in the issue body.
200
+
201
+ ## Idempotency
202
+
203
+ Every recommendation carries a stable fingerprint embedded as an HTML comment
204
+ marker in the ticket/issue body:
205
+
206
+ ```
207
+ <!-- [lisa-gardener] key=<surface>+<invariant-hash> -->
208
+ ```
209
+
210
+ where `<surface>` names the audited artifact (e.g. `ledger:<entry-id>`,
211
+ `rules-eager:<file>#<section>`, `skill:<name>`) and `<invariant-hash>` is
212
+ computed **deterministically — never estimated by the model**:
213
+
214
+ 1. **Normalize** the invariant text: trim leading/trailing whitespace,
215
+ collapse every internal whitespace run to a single space, lowercase.
216
+ 2. **Hash** in Bash: `printf '%s' "$normalized" | shasum -a 256 | cut -c1-12`.
217
+
218
+ The same knowledge item therefore always produces the same key across runs,
219
+ regardless of which session computes it.
220
+
221
+ Before filing anything, search the tracker for the marker in
222
+ **open AND closed** issues — and key the search on the deterministic
223
+ `<surface>` prefix **first**, using the hash as disambiguation only, so even
224
+ a hash discrepancy can never cause a duplicate for the same surface:
225
+
226
+ ```bash
227
+ gh search issues "[lisa-gardener] key=<surface>" --repo <upstream-or-tracker-repo> # searches open AND closed by default; --state all is NOT a valid gh search flag
228
+ ```
229
+
230
+ plus a body-enumeration fallback for search-index lag (`gh issue list …
231
+ --json number,body` and grep bodies for `[lisa-gardener] key=<surface>`).
232
+ Among prefix hits, compare hashes to distinguish genuinely different
233
+ invariants on the same surface; a prefix hit with a mismatched hash is
234
+ resolved by reading the ticket, never by filing a sibling blind. Then:
235
+
236
+ - **Open** with the marker → do not re-file; append new evidence as a comment
237
+ only if it is materially new.
238
+ - **Closed via merged work** → done; a genuine regression later is new
239
+ evidence and a new ticket.
240
+ - **Closed unmerged / rejected** → the human declined. **Do NOT re-file**
241
+ unless new evidence **postdates the rejection** — and when re-filing, state
242
+ the postdating evidence explicitly in the ticket ("rejected <date>; recurred
243
+ <date> in <ref>"). Closed-as-rejected tickets ARE the gardener's memory of
244
+ declined recommendations.
245
+
246
+ Re-runs are quiet no-ops: same surfaces + same evidence ⇒ zero new tickets.
247
+
248
+ ## Autonomous-vs-approval boundary
249
+
250
+ **Everything is human-gated at v1 — this skill only files tickets.** The
251
+ gardener never edits, writes, or deletes any rule, skill, wiki page, ledger
252
+ entry, lint config, or hook itself; it never merges, transitions, or flips
253
+ anything to `status:ready`; it never bumps `last_confirmed`. Autonomous
254
+ actions are limited to: reading surfaces, gathering evidence, invoking the
255
+ advisory router, and creating/commenting marker-deduped tickets. Humans gate
256
+ by flipping a ticket to `status:ready` (the factory then executes it like any
257
+ work item, honoring the `promotion-contract` rule) or closing it as rejected.
258
+ A future `learnings.autoApply` config may widen this; v1 ships none.
259
+
260
+ ## Escalation
261
+
262
+ Headless-safe: this skill **never prompts** — it is a cron target. When it
263
+ cannot proceed (tracker unreachable, contradictory config, ledger contract
264
+ error that blocks the parse), it labels its own run ticket — or, when it
265
+ cannot create one, reports in its summary — `status:blocked` + `human-needed`
266
+ with an **operator-readable** reason: what it was trying to do, what it
267
+ observed, and the smallest human action that unblocks it, in plain language a
268
+ non-technical operator standing at the gate can act on.
269
+
270
+ ## Recovery
271
+
272
+ Every external write is marker-deduped, so a crashed or interrupted run
273
+ leaves no cleanup debt: re-running is the recovery procedure. A partial run's
274
+ already-filed tickets are found by their markers and not duplicated; a batch
275
+ ticket from an interrupted run is reused (append missing rows as a comment)
276
+ rather than reissued. **Filing order**: file the per-item PROMOTE/DEMOTE
277
+ tickets first and the CONFIRM/RETIRE **batch ticket last** — the batch is the
278
+ run's completion signal, so a crash mid-run leaves individually
279
+ marker-recoverable per-item tickets and a missing (not half-filled) batch:
280
+ the most recoverable state. Never attempt to "roll back" filed tickets —
281
+ close-out decisions belong to humans.
282
+
283
+ ## Terminal states
284
+
285
+ Exactly one per run: **`nothing-needed | candidates-proposed | blocked`**
286
+
287
+ - `nothing-needed` — no candidate met any recommendation threshold. Healthy.
288
+ Report one line: surfaces scanned, entries seen, "nothing to propose".
289
+ - `candidates-proposed` — tickets filed. Report each ticket URL, its
290
+ recommendation (PROMOTE/DEMOTE + rung), and the batch ticket URL with its
291
+ row count.
292
+ - `blocked` — could not complete; escalated per Escalation with the
293
+ operator-readable reason.
294
+
295
+ ## Retirement condition
296
+
297
+ The loop retires itself by the same discipline it applies to everything else,
298
+ and the condition is **stateless — derived from the tracker, never from a
299
+ counter or state file** (there is no durable home for a run counter, and a
300
+ tracker-derived condition is headless- and concurrent-safe by construction).
301
+ Propose retirement when BOTH hold:
302
+
303
+ 1. **Quiet trailing window** — a date-filtered search finds NO
304
+ `[lisa-gardener]` ticket created in the
305
+ **trailing six-week window** (six runs at the weekly cadence), e.g.
306
+ `gh search issues '"[lisa-gardener] key="' --created ">=<six-weeks-ago>"`.
307
+ 2. **This run proposes nothing** — the current run's inventory yields zero
308
+ candidates (it is terminating `nothing-needed`).
309
+
310
+ When both hold, the gardener files ONE (marker-deduped) ticket proposing to
311
+ lengthen its cadence or tear down its automation (`/tear-down-automations`),
312
+ with the date-filtered search result and this run's summary as evidence. It
313
+ keeps running until a human flips that ticket — retirement is a
314
+ recommendation like any other, never a self-executed exit.
315
+
316
+ ## Scheduling
317
+
318
+ Register as an **optional** recurring loop through `lisa-setup-automations`
319
+ (the `lisa-auto-<project>-*` naming convention): automation
320
+ `lisa-auto-<project>-learnings-audit`, running `/lisa:learnings:audit`, once
321
+ a **week** (Codex `rrule`: `FREQ=WEEKLY;INTERVAL=1`) — opt-in, created only
322
+ when the operator asks for the gardener loop, unlike the six default
323
+ automations. **Single-scheduled-runner assumption**: register at most ONE
324
+ learnings-audit automation per project. Also runnable on demand — but before
325
+ a manual `/lisa:learnings:audit`, confirm the scheduled automation is not due
326
+ or currently running (check the scheduler's last-run/next-run state) and
327
+ prefer waiting over racing it.
328
+
329
+ **Concurrency honesty.** Marker dedupe is search-then-write, not an atomic
330
+ claim: two truly concurrent runs can each miss the other's in-flight ticket
331
+ and file a transient duplicate. Dedupe therefore guarantees
332
+ **convergence, not mutual exclusion** — a duplicate is found and closed by
333
+ the next run's marker search (or by the human triaging the pair), and because
334
+ rejection memory keys on the surface prefix, a duplicate never multiplies.
335
+ This is an accepted trade-off for a weekly advisory loop; a tracker-side
336
+ locking protocol would be disproportionate to the risk.
337
+
338
+ ## Rules
339
+
340
+ - Tracker-only output: no file edits, no PRs, no label flips beyond the
341
+ gardener's own run-ticket escalation labels.
342
+ - Evidence or nothing: every recommendation cites concrete refs; RETIRE
343
+ requires proof of redundancy/staleness, not vibes.
344
+ - One batch ticket per run, at most `max_candidates` per-item tickets.
345
+ - All ticket writes via `lisa-tracker-write` (or `gh` for the upstream repo,
346
+ per the rework-triage upstream procedure) — never raw unvalidated creation.
347
+ - Never classify without the router, never file without the dedupe search,
348
+ never re-file over a rejection without postdating evidence.
349
+ - No learning loops about learning: the exclusion registry is absolute.
@@ -32,7 +32,9 @@ reimplement a semver-versioned upstream plugin.
32
32
 
33
33
  If the knowledge is narrow or one-off, prefer a rule in `.claude/rules/` instead
34
34
  — skills are for broad, repeatable capabilities. When unsure whether content
35
- warrants a skill, run it past the `skill-evaluator` agent first.
35
+ warrants a skill, run it past the `skill-evaluator` agent first — it is the
36
+ six-rung ladder router, a skill is only one rung, and it may recommend a
37
+ cheaper or stronger destination instead.
36
38
 
37
39
  ## Where skills live
38
40
 
@@ -39,7 +39,7 @@ FP="sll4-$(printf '%s\n%s' "$NORM" "$TRIGGERING_ISSUE" | shasum -a 1 | cut -c1-1
39
39
 
40
40
  ## Phase 1 — Judge (mandatory, never skipped)
41
41
 
42
- Invoke the `learning-judge` agent (via the Agent/Task tool with `subagent_type: "learning-judge"` — the same invoke pattern `learner` uses for `skill-evaluator`) with the full candidate including the fingerprint. It returns a verdict: `classification`, `cited_evidence[]`, `rationale`, `confidence` (durable only), `disposition`.
42
+ Invoke the `learning-judge` agent (via the Agent/Task tool with `subagent_type: "learning-judge"` — the same invoke pattern the gardener uses for the `skill-evaluator` ladder router) with the full candidate including the fingerprint. It returns a verdict: `classification`, `cited_evidence[]`, `rationale`, `confidence` (durable only), `disposition`.
43
43
 
44
44
  **Respect the verdict — do not override it.** Never re-run the judge hoping for a different answer, and never persist anything the judge did not classify `durable-learning`.
45
45
 
@@ -115,16 +115,33 @@ Upstream issues target the Lisa repository itself so the harness gets fixed for
115
115
  project at once. Resolve the repo from `.lisa.config.json` `hardening.upstreamRepo`;
116
116
  default `CodySwannGT/lisa`.
117
117
 
118
+ There are **two upstream lanes**, distinguished by what the filing proposes. Both share
119
+ the same dedupe-marker and evidence-chain discipline below; only the label and one body
120
+ section differ:
121
+
122
+ | Lane | Label | When | Extra body section |
123
+ |------|-------|------|--------------------|
124
+ | Defect | `self-hardening` | A Lisa gate/skill/template did something wrong — a harness bug the kernel must fix. | none |
125
+ | Contribution | `template-candidate` | A generalizable pattern discovered downstream that would benefit every host project — not a defect, a proposed improvement to Lisa's templates/rules/skills. | `## Proposed template change` |
126
+
118
127
  1. **Dedupe first.** `gh issue list -R <upstream> --state open --search "<fingerprint terms>"`
119
- — if an open issue already covers this failure class, comment the new occurrence on it
120
- (evidence compounds; duplicates dilute) and link it instead of filing.
121
- 2. **File with the same bar as any ticket:** a three-audience description (what failed for
122
- the operator, what the harness did wrong, what to change), the verbatim evidence chain
123
- (PRD text → ticket AC → QA failure → gate that passed it), and a `self-hardening` label:
124
- `gh issue create -R <upstream> --title "<gate/skill>: <failure class>" --label self-hardening`.
128
+ — if an open issue already covers this failure class or pattern, comment the new
129
+ occurrence on it (evidence compounds; duplicates dilute) and link it instead of filing.
130
+ 2. **File with the same bar as any ticket:** a three-audience description (what failed or
131
+ improved for the operator, what the harness did or could do, what to change), the
132
+ verbatim evidence chain (PRD text → ticket AC → QA failure → gate that passed it; for
133
+ patterns, the downstream occurrences proving generality), and the lane's label:
134
+ `gh issue create -R <upstream> --title "<gate/skill>: <failure class>" --label self-hardening`
135
+ for defects, or
136
+ `gh issue create -R <upstream> --title "<template surface>: <pattern>" --label template-candidate`
137
+ for contributions. A `template-candidate` filing MUST include a
138
+ `## Proposed template change` section naming the Lisa template/rule/skill surface to
139
+ change (e.g. `typescript/package-lisa/package.lisa.json`, a `plugins/src/base` rule)
140
+ and the proposed content or diff sketch, so Lisa-side intake can triage it as a
141
+ contribution rather than a defect.
125
142
  3. **Close the loop.** Reference the upstream issue URL in the triage comment. The upstream
126
- repo's own build intake implements it; the next kernel release ships the hardening to
127
- every host project.
143
+ repo's own build intake implements it; the next kernel release ships the hardening (or
144
+ the generalized pattern) to every host project.
128
145
 
129
146
  ## Verdict
130
147
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: lisa-setup-automations
3
- description: "Set up the recurring Lisa automations on the local workstation using the CURRENT runtime's native scheduler — Codex automations (the native automations / automation_update mechanism) or, on Claude, /schedule. This skill is a declarative specification: it states WHICH automations to create, how often, and with which parameters; it does not template schedule files or run scheduling code itself — the runtime's native automation mechanism does the creating. Creates six automations: intake-repair (every 60 min), intake PRD (every 60 min), intake tickets (every 10 min), exploratory-bugs (once a day), exploratory-prds (once a day), monitor (once a day). Two flags auto-start-prds and auto-start-tickets control whether the ideated PRDs / filed bug tickets are created auto-pickup-ready (prd_ready / ready, default true) or left for human review. Tear down with /tear-down-automations."
3
+ description: "Set up the recurring Lisa automations on the local workstation using the CURRENT runtime's native scheduler — Codex automations (the native automations / automation_update mechanism) or, on Claude, /schedule. This skill is a declarative specification: it states WHICH automations to create, how often, and with which parameters; it does not template schedule files or run scheduling code itself — the runtime's native automation mechanism does the creating. Creates six default automations: intake-repair (every 60 min), intake PRD (every 60 min), intake tickets (every 10 min), exploratory-bugs (once a day), exploratory-prds (once a day), monitor (once a day) — plus opt-in learnings-audit (once a week, the gardener). Three flags: auto-start-prds and auto-start-tickets control whether ideated PRDs / filed bug tickets are created auto-pickup-ready (prd_ready / ready, default true) or left for human review; learnings-audit (default false) opts into the weekly gardener loop. Tear down with /tear-down-automations."
4
4
  allowed-tools: ["Skill", "Bash", "Read"]
5
5
  ---
6
6
 
@@ -38,10 +38,16 @@ create them; invoke the runtime's automation tool with the spec below.
38
38
  automation. `true` → filed bug/usability tickets are created build-ready (auto-picked-up by ticket
39
39
  intake); `false` → created in the backlog for human triage.
40
40
 
41
+ - `learnings-audit` (default **false**) — opt-in: when `true`, additionally create the weekly
42
+ `lisa-auto-<project>-learnings-audit` automation running `/lisa:learnings:audit` (the gardener —
43
+ see "Optional automation" below). Default `false` because the gardener's output is human-gated
44
+ tracker tickets: a project opts into the recurring audit stream deliberately rather than
45
+ receiving recommendation tickets by surprise.
46
+
41
47
  The defaults are autonomous by design — the factory model wants inputs flowing through the gates
42
48
  without a human between the loops and the pipeline. Pass `false` explicitly to opt a project into
43
- human triage. The two flags affect **only** the two exploratory automations; the intake gates'
44
- adversarial validation remains the quality control either way.
49
+ human triage. The two auto-start flags affect **only** the two exploratory automations; the intake
50
+ gates' adversarial validation remains the quality control either way.
45
51
 
46
52
  ## The automations to create
47
53
 
@@ -67,7 +73,21 @@ report the exact conflicting path(s).
67
73
  | **monitor** | `/lisa:monitor` | **once a day** |
68
74
 
69
75
  For a Codex `rrule`: every 60 min → `FREQ=HOURLY;INTERVAL=1`; every 10 min →
70
- `FREQ=MINUTELY;INTERVAL=10`; once a day → `FREQ=DAILY;INTERVAL=1`.
76
+ `FREQ=MINUTELY;INTERVAL=10`; once a day → `FREQ=DAILY;INTERVAL=1`; once a week →
77
+ `FREQ=WEEKLY;INTERVAL=1`.
78
+
79
+ **Optional automation — the gardener.** When the operator opts in
80
+ (`learnings-audit=true`; default **false** — this one is opt-in, unlike the six
81
+ defaults above), additionally create `lisa-auto-<project>-learnings-audit`
82
+ running `/lisa:learnings:audit` once a **week**. It audits the project's
83
+ knowledge surfaces (learnings ledger, rules trees, skills, wiki) and files
84
+ human-gated promote/demote/confirm/retire tickets per the
85
+ `lisa-learnings-audit` skill. Register at most ONE learnings-audit automation
86
+ per project — the gardener's marker dedupe assumes a single scheduled runner
87
+ and guarantees convergence (a transient duplicate from a concurrent run is
88
+ closed by the next run's dedupe or the human), not mutual exclusion; manual
89
+ runs should first confirm the cron is not due or running. Tear-down removes
90
+ it with the rest of the `lisa-auto-<project>-*` set.
71
91
 
72
92
  **Exploratory PRD pressure gate.** `auto-start-prds=true` means "create PRDs in the ready PRD
73
93
  lifecycle when the PRD queue has capacity," not "always create a new ready PRD." The