@codyswann/lisa 2.259.3 → 2.260.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 (101) hide show
  1. package/dist/cli/file-upstream-cmd.d.ts +28 -0
  2. package/dist/cli/file-upstream-cmd.d.ts.map +1 -0
  3. package/dist/cli/file-upstream-cmd.js +231 -0
  4. package/dist/cli/file-upstream-cmd.js.map +1 -0
  5. package/dist/cli/gate-commands.d.ts +17 -0
  6. package/dist/cli/gate-commands.d.ts.map +1 -0
  7. package/dist/cli/gate-commands.js +47 -0
  8. package/dist/cli/gate-commands.js.map +1 -0
  9. package/dist/cli/index.d.ts +3 -0
  10. package/dist/cli/index.d.ts.map +1 -1
  11. package/dist/cli/index.js +6 -27
  12. package/dist/cli/index.js.map +1 -1
  13. package/dist/core/upstream-attribution-body.d.ts +38 -25
  14. package/dist/core/upstream-attribution-body.d.ts.map +1 -1
  15. package/dist/core/upstream-attribution-body.js +515 -155
  16. package/dist/core/upstream-attribution-body.js.map +1 -1
  17. package/dist/core/upstream-evidence-manifest.d.ts +7 -0
  18. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -0
  19. package/dist/core/upstream-evidence-manifest.js +11623 -0
  20. package/dist/core/upstream-evidence-manifest.js.map +1 -0
  21. package/package.json +4 -1
  22. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  23. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  24. package/plugins/lisa/.codex-plugin/skills/lisa-github-build-intake/SKILL.md +1 -1
  25. package/plugins/lisa/.codex-plugin/skills/lisa-jira-build-intake/SKILL.md +1 -1
  26. package/plugins/lisa/.codex-plugin/skills/lisa-linear-build-intake/SKILL.md +1 -1
  27. package/plugins/lisa/.codex-plugin/skills/lisa-persist-learning/SKILL.md +32 -8
  28. package/plugins/lisa/agents/learning-judge.md +1 -1
  29. package/plugins/lisa/skills/lisa-github-build-intake/SKILL.md +1 -1
  30. package/plugins/lisa/skills/lisa-jira-build-intake/SKILL.md +1 -1
  31. package/plugins/lisa/skills/lisa-linear-build-intake/SKILL.md +1 -1
  32. package/plugins/lisa/skills/lisa-persist-learning/SKILL.md +32 -8
  33. package/plugins/lisa-agy/agents/learning-judge.md +1 -1
  34. package/plugins/lisa-agy/plugin.json +1 -1
  35. package/plugins/lisa-agy/skills/lisa-github-build-intake/SKILL.md +1 -1
  36. package/plugins/lisa-agy/skills/lisa-jira-build-intake/SKILL.md +1 -1
  37. package/plugins/lisa-agy/skills/lisa-linear-build-intake/SKILL.md +1 -1
  38. package/plugins/lisa-agy/skills/lisa-persist-learning/SKILL.md +32 -8
  39. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  40. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  41. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  42. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  43. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  44. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  45. package/plugins/lisa-copilot/agents/learning-judge.agent.md +1 -1
  46. package/plugins/lisa-copilot/skills/lisa-github-build-intake/SKILL.md +1 -1
  47. package/plugins/lisa-copilot/skills/lisa-jira-build-intake/SKILL.md +1 -1
  48. package/plugins/lisa-copilot/skills/lisa-linear-build-intake/SKILL.md +1 -1
  49. package/plugins/lisa-copilot/skills/lisa-persist-learning/SKILL.md +32 -8
  50. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  51. package/plugins/lisa-cursor/agents/learning-judge.md +1 -1
  52. package/plugins/lisa-cursor/skills/lisa-github-build-intake/SKILL.md +1 -1
  53. package/plugins/lisa-cursor/skills/lisa-jira-build-intake/SKILL.md +1 -1
  54. package/plugins/lisa-cursor/skills/lisa-linear-build-intake/SKILL.md +1 -1
  55. package/plugins/lisa-cursor/skills/lisa-persist-learning/SKILL.md +32 -8
  56. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  57. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  58. package/plugins/lisa-expo-agy/plugin.json +1 -1
  59. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  60. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  61. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  62. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  63. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  64. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  65. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  66. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  67. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  68. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  69. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  70. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  71. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  72. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  73. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  74. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  75. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  76. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  77. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  78. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  79. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  80. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  81. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  82. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  83. package/plugins/lisa-rails-agy/plugin.json +1 -1
  84. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  85. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  86. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  87. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  88. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  89. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  90. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  91. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  92. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  93. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  94. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  95. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  96. package/plugins/src/base/agents/learning-judge.md +1 -1
  97. package/plugins/src/base/skills/lisa-github-build-intake/SKILL.md +1 -1
  98. package/plugins/src/base/skills/lisa-jira-build-intake/SKILL.md +1 -1
  99. package/plugins/src/base/skills/lisa-linear-build-intake/SKILL.md +1 -1
  100. package/plugins/src/base/skills/lisa-persist-learning/SKILL.md +32 -8
  101. package/scripts/generate-upstream-evidence-manifest.mjs +157 -0
@@ -90,19 +90,19 @@ This disposition completes the SLL-5 loop (#1583): on a Lisa-attributed failure
90
90
  root-cause-key = <lisa-surface>#<failure-class>
91
91
  ```
92
92
 
93
- - `<lisa-surface>` — the Lisa-relative path of the surface at fault (e.g. `plugins/src/base/skills/lisa-doctor/SKILL.md`, `typescript/copy-overwrite/.github/workflows/quality.yml`), or the canonical rule/skill/hook name when no single file applies (e.g. `lisa-doctor`, `block-no-verify`).
94
- - `<failure-class>` — a short lowercase hyphen-slug for the class of failure (e.g. `pagination-truncation`, `stale-artifact-overwrite`).
93
+ - `<lisa-surface>` — the exact public Lisa-relative path of the surface at fault (e.g. `plugins/src/base/skills/lisa-doctor/SKILL.md`, `typescript/copy-overwrite/.github/workflows/quality.yml`). Canonical names, aliases, host paths, and unmanifested paths are prohibited.
94
+ - `<failure-class>` — exactly one exported closed value: `access-control-failure`, `agent-parity-regression`, `configuration-regression`, `data-integrity-failure`, `dependency-regression`, `generated-artifact-regression`, `installation-regression`, `observability-gap`, `pagination-truncation`, `performance-regression`, `public-data-exposure`, `release-regression`, `runtime-regression`, `stale-artifact-overwrite`, `test-coverage-gap`, `validation-gap`, or `workflow-contract-violation`.
95
95
  - Normalize: lowercase, trim, collapse every whitespace run to a single `-`. The key must contain no host-project name, no local issue number, and no fingerprint — those vary per project and would defeat fleet-wide dedupe.
96
96
 
97
97
  4. **Enforce the per-run cap.** Resolve `hardening.maxUpstreamFilingsPerRun` from `.lisa.config.json` (default `5` — a conservative bound modeled on `lisa-repair-intake`'s `max_candidates` precedent). Count every upstream create **and** update this run performs; once the cap is reached, drop the remaining candidates and **note each dropped candidate visibly** (in the run summary, naming its root-cause key) — never queue a spam burst and never drop silently. A later run picks the dropped candidates up idempotently.
98
98
 
99
- 5. **Evidence redaction (binding).** The upstream repo is PUBLIC by default (`hardening.upstreamRepo` → `CodySwannGT/lisa`) and this filing runs headless on crons — treat every drafted upstream body and comment as world-readable:
99
+ 5. **Evidence redaction (binding).** The upstream repo is PUBLIC by default (`hardening.upstreamRepo` → `CodySwannGT/lisa`) and this filing runs headless on crons — treat every drafted upstream body and comment as world-readable. The PRIMARY control is the **allowlist projection** in step 6: `bunx @codyswann/lisa file-upstream` calls the sole `buildUpstreamAttributionIssueBody` export from `@codyswann/lisa/learnings`, so content outside its enumerated fields is structurally incapable of reaching the public document. The rules below bind the FIELDS supplied to that command; the closing scan is a defense-in-depth backstop, never the primary control:
100
100
 
101
101
  - Quote ONLY Lisa-owned surface text: template/rule/skill/hook excerpts and upstream commit references. The reproduction must be REDACTED — generic placeholders, never the host project's real values.
102
102
  - Never paste host environment values, tokens/credentials, connection strings, API keys, PII (names, emails, customer data), or proprietary host code/payloads.
103
- - The evidence chain names the Lisa surface and the failure class — never project payloads. When host context is essential to understand the failure, LINK the host-project issue instead of quoting it.
104
- - Before filing or commenting, scan the drafted body for common secret shapes — `key=value` pairs with high-entropy values, token prefixes (`AKIA`, `ghp_`, `xox`), email addresses — and strip on match. When in doubt, leave it out: a thinner upstream ticket is recoverable; a leaked secret is not.
105
- - Compose the public upstream issue body through the executable allowlist builder, never by free-form prose assembly. Import `buildUpstreamAttributionIssueBody` from `@codyswann/lisa/learnings` and pass only its typed fields: marker key, Lisa surface, failure class, operator impact, harness fault, requested Lisa change, affected project name, host issue link, Lisa-owned excerpts, attribution evidence, and upstream refs. Non-allowlisted fields must reject before filing; do not "drop" unknown host context silently. The deny-list scan above remains a backstop after the builder returns.
103
+ - The evidence chain names the Lisa surface and the failure class — never project payloads. Keep any host-project issue link only in the private local trace; it is never supplied to or emitted by the public builder.
104
+ - Use only these exact generic placeholders: `<host-project>`, `<env-value>`, `<credential>`, `<connection-string>`, `<pii>`, `<host-payload>`, `<path>`, `<identifier>`. A project-specific placeholder is host prose and must be rejected.
105
+ - **Backstop (defense in depth, never the primary control).** Before filing or commenting, scan the projected document for common secret shapes — `key=value` pairs with high-entropy values, token prefixes (`AKIA`, `ghp_`, `xox`), email addresses and reject on a match. To strip on match, remove the offending INPUT field and re-run `file-upstream`; never strip or edit the generated output itself. Non-allowlisted fields must reject before filing rather than be silently dropped. When in doubt, leave it out: a thinner upstream document is recoverable; a leaked secret is not.
106
106
 
107
107
  6. **Dedupe by marker, then file or update.** The upstream marker is:
108
108
 
@@ -112,8 +112,32 @@ This disposition completes the SLL-5 loop (#1583): on a Lisa-attributed failure
112
112
 
113
113
  Resolve the upstream repo from `.lisa.config.json` `hardening.upstreamRepo` (default `CodySwannGT/lisa`). Search **all issue states** for an existing issue carrying the marker — a closed marker-bearing ticket still owns this root cause, and searching only open issues would mint a duplicate the moment the original closes. Match on the **MARKER, never the title** — with the same eventual-consistency guard as above (`gh issue list -R <upstream> --state all --search '"<marker>" in:body' --json number,state,url`, and when the search index returns nothing, also `gh issue list -R <upstream> --state all --json number,state,body` and grep the bodies for the marker before concluding no ticket exists).
114
114
 
115
- - **No existing ticket** → file via `lisa-github-write-issue` targeting the upstream repo, following the `lisa-rework-triage` "Filing upstream" discipline. The body must be the exact output of `buildUpstreamAttributionIssueBody`, which provides the three-audience description (what failed for the operator, what the harness did wrong, what to change), the redacted evidence chain (Lisa-owned text only, per step 5: defect → Lisa surface → attribution evidence → redacted reproduction), the affected project name/link, and **exactly one** dedupe marker. Apply the `self-hardening` label. **Never write a markerless body** — it permanently breaks all future dedupe.
116
- - **Existing ticket (open or closed)** → this is a repeat encounter: comment the new occurrence on the existing issue with this project's evidence, marker-deduped per occurrence via `<!-- [lisa-upstream-attribution-occurrence] key=<fingerprint> -->` so re-runs never duplicate the occurrence comment. Never open a second issue, and never match on the title — evidence compounds on one ticket. When the match is **CLOSED**, still comment the occurrence there and reference it in the local trace instead of filing a duplicate; do not reopen it yourself — recurrence evidence on a closed ticket signals the shipped fix may not cover this case, and reopening is the upstream maintainer's call.
115
+ - **No existing ticket** → compose the body EXCLUSIVELY through the executable builder, then file its stdout verbatim via `lisa-github-write-issue` targeting the upstream repo with the `self-hardening` label:
116
+
117
+ ```bash
118
+ bunx @codyswann/lisa file-upstream --input filing-event.json # or pipe the JSON on stdin
119
+ ```
120
+
121
+ **Never assemble the public body as free-form prose.** Public composition happens through the builder, never by free-form prose assembly. The builder owns the three-audience description and the redacted evidence chain (Lisa-owned text only). Do not hand-write either section, name an affected project in prose, or edit the builder's output after generation. Supply only this JSON shape; host-project issue URLs remain private local-trace data and are never accepted by the public builder:
122
+
123
+ ```json
124
+ {
125
+ "documentKind": "issue",
126
+ "lisaSurface": "plugins/src/base/skills/lisa-doctor/SKILL.md",
127
+ "failureClass": "stale-artifact-overwrite",
128
+ "lisaOwnedExcerpts": [
129
+ {
130
+ "file": "plugins/src/base/skills/lisa-doctor/SKILL.md",
131
+ "text": "<verbatim Lisa-owned text>"
132
+ }
133
+ ],
134
+ "upstreamCommitRefs": ["<full 40-character public-origin SHA>"],
135
+ "redactedPlaceholders": ["<host-project>", "<env-value>"]
136
+ }
137
+ ```
138
+
139
+ Every excerpt is verified against the installed package's Lisa-owned source and every commit against the public origin. Callers cannot supply a verifier or Lisa root. Anything outside the allowlist is REJECTED by field name with empty stdout and a non-zero exit; fix or remove the offending input field and re-run the command, never route around it. The builder emits **exactly one** dedupe marker; **never write a markerless body** — it permanently breaks all future dedupe.
140
+ - **Existing ticket (open or closed)** → this is a repeat encounter: comment the new occurrence on the existing issue with this project's evidence. The comment is projected through the same builder: run `bunx @codyswann/lisa file-upstream` with the same allowlisted fields plus exactly `"documentKind": "occurrence"` and `"occurrenceFingerprint": "<fingerprint>"`. The supplied fingerprint is only a validated seed: the builder hashes it and emits a different deterministic `sll4-<12 lowercase hex>` marker. Use the marker in the builder's stdout — never the supplied literal — to search existing issue comments for a duplicate, then post stdout verbatim only when that emitted marker is absent. Free-form occurrence prose is prohibited, and post-generation edits are prohibited. Never open a second issue, and never match on the title — evidence compounds on one ticket. When the match is **CLOSED**, still comment the occurrence there and reference it in the local trace instead of filing a duplicate; do not reopen it yourself — recurrence evidence on a closed ticket signals the shipped fix may not cover this case, and reopening is the upstream maintainer's call.
117
141
 
118
142
  7. **Leave the local trace — a note, never a rule.** Post one follow-up comment on the triggering issue linking the upstream ticket:
119
143
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -5,7 +5,7 @@ description: Skeptical judgment gate for candidate learnings. Classifies each ca
5
5
 
6
6
  # Learning Judge Agent
7
7
 
8
- You are the quality bar between a claimed learning and the project learnings surface. That surface is loaded eagerly in every session by every agent, so a wrong or trivial entry poisons every future session. Your primary responsibility is to **prevent rule pollution** by dropping most candidates.
8
+ You are the quality bar between a claimed learning and the project learnings surface. That surface reaches every agent's session through the contract's bounded projection, so a wrong or trivial entry poisons every future session. Your primary responsibility is to **prevent rule pollution** by dropping most candidates.
9
9
 
10
10
  ## Core Philosophy
11
11
 
@@ -331,7 +331,7 @@ This path is distinct from `BLOCKED`: ambiguity, open blockers, and duplicate-of
331
331
 
332
332
  Run this at the end of 3c, after the lifecycle outcome is recorded and before 3d. It keeps the decay pass safe: a genuinely useful learning that keeps applying stays fresh, while dead weight ages out.
333
333
 
334
- 1. **Identify which learnings demonstrably applied.** Resolve the learnings surface with `resolveProjectLearningsFile` and parse it with `parseLearningsFile` from `@codyswann/lisa/learnings` (never hardcode the path; a missing file skips this step silently). An entry counts as applied ONLY when its rule was explicitly cited or observably followed in this claim's plan, diff, or review responses — the plan quotes the rule or its id, or the diff does specifically what the rule mandates where the default behavior would have differed. **Presence in context is NOT application**: the ledger is loaded eagerly into every session, so counting "it was loaded" would confirm every entry on every claim and defeat decay entirely. A run that produced no plan or diff has nothing to confirm.
334
+ 1. **Identify which learnings demonstrably applied.** Resolve the learnings surface with `resolveProjectLearningsFile` and parse it with `parseLearningsFile` from `@codyswann/lisa/learnings` (never hardcode the path; a missing file skips this step silently). An entry counts as applied ONLY when its rule was explicitly cited or observably followed in this claim's plan, diff, or review responses — the plan quotes the rule or its id, or the diff does specifically what the rule mandates where the default behavior would have differed. **Presence in context is NOT application**: entries reach a session only through the contract's bounded projection, so counting "it was projected" would confirm every projected entry on every claim and defeat decay entirely. A run that produced no plan or diff has nothing to confirm.
335
335
  2. **Bump each applied entry exactly once** via the surgical writer:
336
336
 
337
337
  ```bash
@@ -263,7 +263,7 @@ This path is distinct from `BLOCKED`: ambiguity, open blockers, and duplicate-of
263
263
 
264
264
  Run this at the end of 3c, after the lifecycle outcome is recorded and before 3d. It keeps the decay pass safe: a genuinely useful learning that keeps applying stays fresh, while dead weight ages out.
265
265
 
266
- 1. **Identify which learnings demonstrably applied.** Resolve the learnings surface with `resolveProjectLearningsFile` and parse it with `parseLearningsFile` from `@codyswann/lisa/learnings` (never hardcode the path; a missing file skips this step silently). An entry counts as applied ONLY when its rule was explicitly cited or observably followed in this claim's plan, diff, or review responses — the plan quotes the rule or its id, or the diff does specifically what the rule mandates where the default behavior would have differed. **Presence in context is NOT application**: the ledger is loaded eagerly into every session, so counting "it was loaded" would confirm every entry on every claim and defeat decay entirely. A run that produced no plan or diff has nothing to confirm.
266
+ 1. **Identify which learnings demonstrably applied.** Resolve the learnings surface with `resolveProjectLearningsFile` and parse it with `parseLearningsFile` from `@codyswann/lisa/learnings` (never hardcode the path; a missing file skips this step silently). An entry counts as applied ONLY when its rule was explicitly cited or observably followed in this claim's plan, diff, or review responses — the plan quotes the rule or its id, or the diff does specifically what the rule mandates where the default behavior would have differed. **Presence in context is NOT application**: entries reach a session only through the contract's bounded projection, so counting "it was projected" would confirm every projected entry on every claim and defeat decay entirely. A run that produced no plan or diff has nothing to confirm.
267
267
  2. **Bump each applied entry exactly once** via the surgical writer:
268
268
 
269
269
  ```bash
@@ -256,7 +256,7 @@ This path is distinct from `BLOCKED`: ambiguity, open blockers, and duplicate-of
256
256
 
257
257
  Run this at the end of 3c, after the lifecycle outcome is recorded and before 3d. It keeps the decay pass safe: a genuinely useful learning that keeps applying stays fresh, while dead weight ages out.
258
258
 
259
- 1. **Identify which learnings demonstrably applied.** Resolve the learnings surface with `resolveProjectLearningsFile` and parse it with `parseLearningsFile` from `@codyswann/lisa/learnings` (never hardcode the path; a missing file skips this step silently). An entry counts as applied ONLY when its rule was explicitly cited or observably followed in this claim's plan, diff, or review responses — the plan quotes the rule or its id, or the diff does specifically what the rule mandates where the default behavior would have differed. **Presence in context is NOT application**: the ledger is loaded eagerly into every session, so counting "it was loaded" would confirm every entry on every claim and defeat decay entirely. A run that produced no plan or diff has nothing to confirm.
259
+ 1. **Identify which learnings demonstrably applied.** Resolve the learnings surface with `resolveProjectLearningsFile` and parse it with `parseLearningsFile` from `@codyswann/lisa/learnings` (never hardcode the path; a missing file skips this step silently). An entry counts as applied ONLY when its rule was explicitly cited or observably followed in this claim's plan, diff, or review responses — the plan quotes the rule or its id, or the diff does specifically what the rule mandates where the default behavior would have differed. **Presence in context is NOT application**: entries reach a session only through the contract's bounded projection, so counting "it was projected" would confirm every projected entry on every claim and defeat decay entirely. A run that produced no plan or diff has nothing to confirm.
260
260
  2. **Bump each applied entry exactly once** via the surgical writer:
261
261
 
262
262
  ```bash
@@ -90,19 +90,19 @@ This disposition completes the SLL-5 loop (#1583): on a Lisa-attributed failure
90
90
  root-cause-key = <lisa-surface>#<failure-class>
91
91
  ```
92
92
 
93
- - `<lisa-surface>` — the Lisa-relative path of the surface at fault (e.g. `plugins/src/base/skills/lisa-doctor/SKILL.md`, `typescript/copy-overwrite/.github/workflows/quality.yml`), or the canonical rule/skill/hook name when no single file applies (e.g. `lisa-doctor`, `block-no-verify`).
94
- - `<failure-class>` — a short lowercase hyphen-slug for the class of failure (e.g. `pagination-truncation`, `stale-artifact-overwrite`).
93
+ - `<lisa-surface>` — the exact public Lisa-relative path of the surface at fault (e.g. `plugins/src/base/skills/lisa-doctor/SKILL.md`, `typescript/copy-overwrite/.github/workflows/quality.yml`). Canonical names, aliases, host paths, and unmanifested paths are prohibited.
94
+ - `<failure-class>` — exactly one exported closed value: `access-control-failure`, `agent-parity-regression`, `configuration-regression`, `data-integrity-failure`, `dependency-regression`, `generated-artifact-regression`, `installation-regression`, `observability-gap`, `pagination-truncation`, `performance-regression`, `public-data-exposure`, `release-regression`, `runtime-regression`, `stale-artifact-overwrite`, `test-coverage-gap`, `validation-gap`, or `workflow-contract-violation`.
95
95
  - Normalize: lowercase, trim, collapse every whitespace run to a single `-`. The key must contain no host-project name, no local issue number, and no fingerprint — those vary per project and would defeat fleet-wide dedupe.
96
96
 
97
97
  4. **Enforce the per-run cap.** Resolve `hardening.maxUpstreamFilingsPerRun` from `.lisa.config.json` (default `5` — a conservative bound modeled on `lisa-repair-intake`'s `max_candidates` precedent). Count every upstream create **and** update this run performs; once the cap is reached, drop the remaining candidates and **note each dropped candidate visibly** (in the run summary, naming its root-cause key) — never queue a spam burst and never drop silently. A later run picks the dropped candidates up idempotently.
98
98
 
99
- 5. **Evidence redaction (binding).** The upstream repo is PUBLIC by default (`hardening.upstreamRepo` → `CodySwannGT/lisa`) and this filing runs headless on crons — treat every drafted upstream body and comment as world-readable:
99
+ 5. **Evidence redaction (binding).** The upstream repo is PUBLIC by default (`hardening.upstreamRepo` → `CodySwannGT/lisa`) and this filing runs headless on crons — treat every drafted upstream body and comment as world-readable. The PRIMARY control is the **allowlist projection** in step 6: `bunx @codyswann/lisa file-upstream` calls the sole `buildUpstreamAttributionIssueBody` export from `@codyswann/lisa/learnings`, so content outside its enumerated fields is structurally incapable of reaching the public document. The rules below bind the FIELDS supplied to that command; the closing scan is a defense-in-depth backstop, never the primary control:
100
100
 
101
101
  - Quote ONLY Lisa-owned surface text: template/rule/skill/hook excerpts and upstream commit references. The reproduction must be REDACTED — generic placeholders, never the host project's real values.
102
102
  - Never paste host environment values, tokens/credentials, connection strings, API keys, PII (names, emails, customer data), or proprietary host code/payloads.
103
- - The evidence chain names the Lisa surface and the failure class — never project payloads. When host context is essential to understand the failure, LINK the host-project issue instead of quoting it.
104
- - Before filing or commenting, scan the drafted body for common secret shapes — `key=value` pairs with high-entropy values, token prefixes (`AKIA`, `ghp_`, `xox`), email addresses — and strip on match. When in doubt, leave it out: a thinner upstream ticket is recoverable; a leaked secret is not.
105
- - Compose the public upstream issue body through the executable allowlist builder, never by free-form prose assembly. Import `buildUpstreamAttributionIssueBody` from `@codyswann/lisa/learnings` and pass only its typed fields: marker key, Lisa surface, failure class, operator impact, harness fault, requested Lisa change, affected project name, host issue link, Lisa-owned excerpts, attribution evidence, and upstream refs. Non-allowlisted fields must reject before filing; do not "drop" unknown host context silently. The deny-list scan above remains a backstop after the builder returns.
103
+ - The evidence chain names the Lisa surface and the failure class — never project payloads. Keep any host-project issue link only in the private local trace; it is never supplied to or emitted by the public builder.
104
+ - Use only these exact generic placeholders: `<host-project>`, `<env-value>`, `<credential>`, `<connection-string>`, `<pii>`, `<host-payload>`, `<path>`, `<identifier>`. A project-specific placeholder is host prose and must be rejected.
105
+ - **Backstop (defense in depth, never the primary control).** Before filing or commenting, scan the projected document for common secret shapes — `key=value` pairs with high-entropy values, token prefixes (`AKIA`, `ghp_`, `xox`), email addresses and reject on a match. To strip on match, remove the offending INPUT field and re-run `file-upstream`; never strip or edit the generated output itself. Non-allowlisted fields must reject before filing rather than be silently dropped. When in doubt, leave it out: a thinner upstream document is recoverable; a leaked secret is not.
106
106
 
107
107
  6. **Dedupe by marker, then file or update.** The upstream marker is:
108
108
 
@@ -112,8 +112,32 @@ This disposition completes the SLL-5 loop (#1583): on a Lisa-attributed failure
112
112
 
113
113
  Resolve the upstream repo from `.lisa.config.json` `hardening.upstreamRepo` (default `CodySwannGT/lisa`). Search **all issue states** for an existing issue carrying the marker — a closed marker-bearing ticket still owns this root cause, and searching only open issues would mint a duplicate the moment the original closes. Match on the **MARKER, never the title** — with the same eventual-consistency guard as above (`gh issue list -R <upstream> --state all --search '"<marker>" in:body' --json number,state,url`, and when the search index returns nothing, also `gh issue list -R <upstream> --state all --json number,state,body` and grep the bodies for the marker before concluding no ticket exists).
114
114
 
115
- - **No existing ticket** → file via `lisa-github-write-issue` targeting the upstream repo, following the `lisa-rework-triage` "Filing upstream" discipline. The body must be the exact output of `buildUpstreamAttributionIssueBody`, which provides the three-audience description (what failed for the operator, what the harness did wrong, what to change), the redacted evidence chain (Lisa-owned text only, per step 5: defect → Lisa surface → attribution evidence → redacted reproduction), the affected project name/link, and **exactly one** dedupe marker. Apply the `self-hardening` label. **Never write a markerless body** — it permanently breaks all future dedupe.
116
- - **Existing ticket (open or closed)** → this is a repeat encounter: comment the new occurrence on the existing issue with this project's evidence, marker-deduped per occurrence via `<!-- [lisa-upstream-attribution-occurrence] key=<fingerprint> -->` so re-runs never duplicate the occurrence comment. Never open a second issue, and never match on the title — evidence compounds on one ticket. When the match is **CLOSED**, still comment the occurrence there and reference it in the local trace instead of filing a duplicate; do not reopen it yourself — recurrence evidence on a closed ticket signals the shipped fix may not cover this case, and reopening is the upstream maintainer's call.
115
+ - **No existing ticket** → compose the body EXCLUSIVELY through the executable builder, then file its stdout verbatim via `lisa-github-write-issue` targeting the upstream repo with the `self-hardening` label:
116
+
117
+ ```bash
118
+ bunx @codyswann/lisa file-upstream --input filing-event.json # or pipe the JSON on stdin
119
+ ```
120
+
121
+ **Never assemble the public body as free-form prose.** Public composition happens through the builder, never by free-form prose assembly. The builder owns the three-audience description and the redacted evidence chain (Lisa-owned text only). Do not hand-write either section, name an affected project in prose, or edit the builder's output after generation. Supply only this JSON shape; host-project issue URLs remain private local-trace data and are never accepted by the public builder:
122
+
123
+ ```json
124
+ {
125
+ "documentKind": "issue",
126
+ "lisaSurface": "plugins/src/base/skills/lisa-doctor/SKILL.md",
127
+ "failureClass": "stale-artifact-overwrite",
128
+ "lisaOwnedExcerpts": [
129
+ {
130
+ "file": "plugins/src/base/skills/lisa-doctor/SKILL.md",
131
+ "text": "<verbatim Lisa-owned text>"
132
+ }
133
+ ],
134
+ "upstreamCommitRefs": ["<full 40-character public-origin SHA>"],
135
+ "redactedPlaceholders": ["<host-project>", "<env-value>"]
136
+ }
137
+ ```
138
+
139
+ Every excerpt is verified against the installed package's Lisa-owned source and every commit against the public origin. Callers cannot supply a verifier or Lisa root. Anything outside the allowlist is REJECTED by field name with empty stdout and a non-zero exit; fix or remove the offending input field and re-run the command, never route around it. The builder emits **exactly one** dedupe marker; **never write a markerless body** — it permanently breaks all future dedupe.
140
+ - **Existing ticket (open or closed)** → this is a repeat encounter: comment the new occurrence on the existing issue with this project's evidence. The comment is projected through the same builder: run `bunx @codyswann/lisa file-upstream` with the same allowlisted fields plus exactly `"documentKind": "occurrence"` and `"occurrenceFingerprint": "<fingerprint>"`. The supplied fingerprint is only a validated seed: the builder hashes it and emits a different deterministic `sll4-<12 lowercase hex>` marker. Use the marker in the builder's stdout — never the supplied literal — to search existing issue comments for a duplicate, then post stdout verbatim only when that emitted marker is absent. Free-form occurrence prose is prohibited, and post-generation edits are prohibited. Never open a second issue, and never match on the title — evidence compounds on one ticket. When the match is **CLOSED**, still comment the occurrence there and reference it in the local trace instead of filing a duplicate; do not reopen it yourself — recurrence evidence on a closed ticket signals the shipped fix may not cover this case, and reopening is the upstream maintainer's call.
117
141
 
118
142
  7. **Leave the local trace — a note, never a rule.** Post one follow-up comment on the triggering issue linking the upstream ticket:
119
143
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "Expo and React Native-specific skills, agents, rules, and MCP servers.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "Harper/Fabric-specific Lisa rules for TypeScript component apps.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "NestJS-specific skills and migration write-protection hooks.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, across Claude and Codex.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "Ruby on Rails-specific skills and hooks for RuboCop and ast-grep scanning on edit.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "TypeScript-specific hooks for formatting, linting, and ast-grep scanning on edit.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "Distributable LLM Wiki kernel — ingest, query, lint, and maintain a git-native markdown knowledge base across Claude and Codex.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.259.3",
3
+ "version": "2.260.0",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -5,7 +5,7 @@ description: Skeptical judgment gate for candidate learnings. Classifies each ca
5
5
 
6
6
  # Learning Judge Agent
7
7
 
8
- You are the quality bar between a claimed learning and the project learnings surface. That surface is loaded eagerly in every session by every agent, so a wrong or trivial entry poisons every future session. Your primary responsibility is to **prevent rule pollution** by dropping most candidates.
8
+ You are the quality bar between a claimed learning and the project learnings surface. That surface reaches every agent's session through the contract's bounded projection, so a wrong or trivial entry poisons every future session. Your primary responsibility is to **prevent rule pollution** by dropping most candidates.
9
9
 
10
10
  ## Core Philosophy
11
11