@codyswann/lisa 4.86.1 → 4.87.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +26 -23
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/package.json +4 -4
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-confluence-to-tracker/SKILL.md +5 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-delivery-effectiveness/SKILL.md +7 -3
- package/plugins/lisa/.codex-plugin/skills/lisa-drive-pr-to-merge/SKILL.md +79 -22
- package/plugins/lisa/.codex-plugin/skills/lisa-github-to-tracker/SKILL.md +5 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-github-validate-issue/SKILL.md +2 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-implement/SKILL.md +2 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-validate-ticket/SKILL.md +2 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-learnings-audit/SKILL.md +9 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-to-tracker/SKILL.md +5 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-validate-issue/SKILL.md +2 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-notion-to-tracker/SKILL.md +5 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-persist-learning/SKILL.md +27 -8
- package/plugins/lisa/.codex-plugin/skills/lisa-plan/SKILL.md +2 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-pull-request-review/SKILL.md +8 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/SKILL.md +30 -5
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-human.mjs +3 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-usage.mjs +11 -5
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/human-needed.mjs +112 -5
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/session-manager.mjs +5 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-task-decomposition/SKILL.md +18 -0
- package/plugins/lisa/agents/learning-judge.md +34 -14
- package/plugins/lisa/rules/reference/ready-role-filing.md +4 -0
- package/plugins/lisa/rules/reference/work-item-definition-of-ready.md +8 -0
- package/plugins/lisa/skills/lisa-confluence-to-tracker/SKILL.md +5 -0
- package/plugins/lisa/skills/lisa-delivery-effectiveness/SKILL.md +7 -3
- package/plugins/lisa/skills/lisa-delivery-effectiveness/agents/openai.yaml +2 -2
- package/plugins/lisa/skills/lisa-drive-pr-to-merge/SKILL.md +79 -22
- package/plugins/lisa/skills/lisa-github-to-tracker/SKILL.md +5 -0
- package/plugins/lisa/skills/lisa-github-validate-issue/SKILL.md +2 -0
- package/plugins/lisa/skills/lisa-implement/SKILL.md +2 -0
- package/plugins/lisa/skills/lisa-jira-validate-ticket/SKILL.md +2 -0
- package/plugins/lisa/skills/lisa-learnings-audit/SKILL.md +9 -0
- package/plugins/lisa/skills/lisa-linear-to-tracker/SKILL.md +5 -0
- package/plugins/lisa/skills/lisa-linear-validate-issue/SKILL.md +2 -0
- package/plugins/lisa/skills/lisa-notion-to-tracker/SKILL.md +5 -0
- package/plugins/lisa/skills/lisa-persist-learning/SKILL.md +27 -8
- package/plugins/lisa/skills/lisa-plan/SKILL.md +2 -0
- package/plugins/lisa/skills/lisa-pull-request-review/SKILL.md +8 -0
- package/plugins/lisa/skills/lisa-session-manager/SKILL.md +30 -5
- package/plugins/lisa/skills/lisa-session-manager/scripts/cli-human.mjs +3 -1
- package/plugins/lisa/skills/lisa-session-manager/scripts/cli-usage.mjs +11 -5
- package/plugins/lisa/skills/lisa-session-manager/scripts/human-needed.mjs +112 -5
- package/plugins/lisa/skills/lisa-session-manager/scripts/session-manager.mjs +5 -1
- package/plugins/lisa/skills/lisa-task-decomposition/SKILL.md +18 -0
- package/plugins/lisa-agy/agents/learning-judge.md +34 -14
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/lisa-confluence-to-tracker/SKILL.md +5 -0
- package/plugins/lisa-agy/skills/lisa-delivery-effectiveness/SKILL.md +7 -3
- package/plugins/lisa-agy/skills/lisa-drive-pr-to-merge/SKILL.md +79 -22
- package/plugins/lisa-agy/skills/lisa-github-to-tracker/SKILL.md +5 -0
- package/plugins/lisa-agy/skills/lisa-github-validate-issue/SKILL.md +2 -0
- package/plugins/lisa-agy/skills/lisa-implement/SKILL.md +2 -0
- package/plugins/lisa-agy/skills/lisa-jira-validate-ticket/SKILL.md +2 -0
- package/plugins/lisa-agy/skills/lisa-learnings-audit/SKILL.md +9 -0
- package/plugins/lisa-agy/skills/lisa-linear-to-tracker/SKILL.md +5 -0
- package/plugins/lisa-agy/skills/lisa-linear-validate-issue/SKILL.md +2 -0
- package/plugins/lisa-agy/skills/lisa-notion-to-tracker/SKILL.md +5 -0
- package/plugins/lisa-agy/skills/lisa-persist-learning/SKILL.md +27 -8
- package/plugins/lisa-agy/skills/lisa-plan/SKILL.md +2 -0
- package/plugins/lisa-agy/skills/lisa-pull-request-review/SKILL.md +8 -0
- package/plugins/lisa-agy/skills/lisa-session-manager/SKILL.md +30 -5
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-human.mjs +3 -1
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-usage.mjs +11 -5
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/human-needed.mjs +112 -5
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/session-manager.mjs +5 -1
- package/plugins/lisa-agy/skills/lisa-task-decomposition/SKILL.md +18 -0
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/agents/learning-judge.agent.md +34 -14
- package/plugins/lisa-copilot/rules/reference/ready-role-filing.md +4 -0
- package/plugins/lisa-copilot/rules/reference/work-item-definition-of-ready.md +8 -0
- package/plugins/lisa-copilot/skills/lisa-confluence-to-tracker/SKILL.md +5 -0
- package/plugins/lisa-copilot/skills/lisa-delivery-effectiveness/SKILL.md +7 -3
- package/plugins/lisa-copilot/skills/lisa-drive-pr-to-merge/SKILL.md +79 -22
- package/plugins/lisa-copilot/skills/lisa-github-to-tracker/SKILL.md +5 -0
- package/plugins/lisa-copilot/skills/lisa-github-validate-issue/SKILL.md +2 -0
- package/plugins/lisa-copilot/skills/lisa-implement/SKILL.md +2 -0
- package/plugins/lisa-copilot/skills/lisa-jira-validate-ticket/SKILL.md +2 -0
- package/plugins/lisa-copilot/skills/lisa-learnings-audit/SKILL.md +9 -0
- package/plugins/lisa-copilot/skills/lisa-linear-to-tracker/SKILL.md +5 -0
- package/plugins/lisa-copilot/skills/lisa-linear-validate-issue/SKILL.md +2 -0
- package/plugins/lisa-copilot/skills/lisa-notion-to-tracker/SKILL.md +5 -0
- package/plugins/lisa-copilot/skills/lisa-persist-learning/SKILL.md +27 -8
- package/plugins/lisa-copilot/skills/lisa-plan/SKILL.md +2 -0
- package/plugins/lisa-copilot/skills/lisa-pull-request-review/SKILL.md +8 -0
- package/plugins/lisa-copilot/skills/lisa-session-manager/SKILL.md +30 -5
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-human.mjs +3 -1
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-usage.mjs +11 -5
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/human-needed.mjs +112 -5
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/session-manager.mjs +5 -1
- package/plugins/lisa-copilot/skills/lisa-task-decomposition/SKILL.md +18 -0
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/agents/learning-judge.md +34 -14
- package/plugins/lisa-cursor/rules/ready-role-filing-reference.mdc +4 -0
- package/plugins/lisa-cursor/rules/work-item-definition-of-ready-reference.mdc +8 -0
- package/plugins/lisa-cursor/skills/lisa-confluence-to-tracker/SKILL.md +5 -0
- package/plugins/lisa-cursor/skills/lisa-delivery-effectiveness/SKILL.md +7 -3
- package/plugins/lisa-cursor/skills/lisa-drive-pr-to-merge/SKILL.md +79 -22
- package/plugins/lisa-cursor/skills/lisa-github-to-tracker/SKILL.md +5 -0
- package/plugins/lisa-cursor/skills/lisa-github-validate-issue/SKILL.md +2 -0
- package/plugins/lisa-cursor/skills/lisa-implement/SKILL.md +2 -0
- package/plugins/lisa-cursor/skills/lisa-jira-validate-ticket/SKILL.md +2 -0
- package/plugins/lisa-cursor/skills/lisa-learnings-audit/SKILL.md +9 -0
- package/plugins/lisa-cursor/skills/lisa-linear-to-tracker/SKILL.md +5 -0
- package/plugins/lisa-cursor/skills/lisa-linear-validate-issue/SKILL.md +2 -0
- package/plugins/lisa-cursor/skills/lisa-notion-to-tracker/SKILL.md +5 -0
- package/plugins/lisa-cursor/skills/lisa-persist-learning/SKILL.md +27 -8
- package/plugins/lisa-cursor/skills/lisa-plan/SKILL.md +2 -0
- package/plugins/lisa-cursor/skills/lisa-pull-request-review/SKILL.md +8 -0
- package/plugins/lisa-cursor/skills/lisa-session-manager/SKILL.md +30 -5
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-human.mjs +3 -1
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-usage.mjs +11 -5
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/human-needed.mjs +112 -5
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/session-manager.mjs +5 -1
- package/plugins/lisa-cursor/skills/lisa-task-decomposition/SKILL.md +18 -0
- package/plugins/lisa-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-devin/agents/learning-judge.md +34 -14
- package/plugins/lisa-devin/rules/reference/ready-role-filing.md +4 -0
- package/plugins/lisa-devin/rules/reference/work-item-definition-of-ready.md +8 -0
- package/plugins/lisa-devin/skills/lisa-confluence-to-tracker/SKILL.md +5 -0
- package/plugins/lisa-devin/skills/lisa-delivery-effectiveness/SKILL.md +7 -3
- package/plugins/lisa-devin/skills/lisa-drive-pr-to-merge/SKILL.md +79 -22
- package/plugins/lisa-devin/skills/lisa-github-to-tracker/SKILL.md +5 -0
- package/plugins/lisa-devin/skills/lisa-github-validate-issue/SKILL.md +2 -0
- package/plugins/lisa-devin/skills/lisa-implement/SKILL.md +2 -0
- package/plugins/lisa-devin/skills/lisa-jira-validate-ticket/SKILL.md +2 -0
- package/plugins/lisa-devin/skills/lisa-learnings-audit/SKILL.md +9 -0
- package/plugins/lisa-devin/skills/lisa-linear-to-tracker/SKILL.md +5 -0
- package/plugins/lisa-devin/skills/lisa-linear-validate-issue/SKILL.md +2 -0
- package/plugins/lisa-devin/skills/lisa-notion-to-tracker/SKILL.md +5 -0
- package/plugins/lisa-devin/skills/lisa-persist-learning/SKILL.md +27 -8
- package/plugins/lisa-devin/skills/lisa-plan/SKILL.md +2 -0
- package/plugins/lisa-devin/skills/lisa-pull-request-review/SKILL.md +8 -0
- package/plugins/lisa-devin/skills/lisa-session-manager/SKILL.md +30 -5
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-human.mjs +3 -1
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-usage.mjs +11 -5
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/human-needed.mjs +112 -5
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/session-manager.mjs +5 -1
- package/plugins/lisa-devin/skills/lisa-task-decomposition/SKILL.md +18 -0
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/src/base/agents/learning-judge.md +34 -14
- package/plugins/src/base/rules/reference/ready-role-filing.md +4 -0
- package/plugins/src/base/rules/reference/work-item-definition-of-ready.md +8 -0
- package/plugins/src/base/skills/lisa-confluence-to-tracker/SKILL.md +5 -0
- package/plugins/src/base/skills/lisa-delivery-effectiveness/SKILL.md +7 -3
- package/plugins/src/base/skills/lisa-drive-pr-to-merge/SKILL.md +79 -22
- package/plugins/src/base/skills/lisa-github-to-tracker/SKILL.md +5 -0
- package/plugins/src/base/skills/lisa-github-validate-issue/SKILL.md +2 -0
- package/plugins/src/base/skills/lisa-implement/SKILL.md +2 -0
- package/plugins/src/base/skills/lisa-jira-validate-ticket/SKILL.md +2 -0
- package/plugins/src/base/skills/lisa-learnings-audit/SKILL.md +9 -0
- package/plugins/src/base/skills/lisa-linear-to-tracker/SKILL.md +5 -0
- package/plugins/src/base/skills/lisa-linear-validate-issue/SKILL.md +2 -0
- package/plugins/src/base/skills/lisa-notion-to-tracker/SKILL.md +5 -0
- package/plugins/src/base/skills/lisa-persist-learning/SKILL.md +27 -8
- package/plugins/src/base/skills/lisa-plan/SKILL.md +2 -0
- package/plugins/src/base/skills/lisa-pull-request-review/SKILL.md +8 -0
- package/plugins/src/base/skills/lisa-session-manager/SKILL.md +30 -5
- package/plugins/src/base/skills/lisa-session-manager/scripts/cli-human.mjs +3 -1
- package/plugins/src/base/skills/lisa-session-manager/scripts/cli-usage.mjs +11 -5
- package/plugins/src/base/skills/lisa-session-manager/scripts/human-needed.mjs +112 -5
- package/plugins/src/base/skills/lisa-session-manager/scripts/session-manager.mjs +5 -1
- package/plugins/src/base/skills/lisa-task-decomposition/SKILL.md +18 -0
|
@@ -224,6 +224,11 @@ planning proceeds. Per atom:
|
|
|
224
224
|
requirement.
|
|
225
225
|
- **Pattern shape (SHOULD)** — an EARS pattern (ubiquitous / When / While / If-then / Where) or an
|
|
226
226
|
equivalent single-behavior sentence; conforming shapes decompose into Gherkin mechanically.
|
|
227
|
+
- **Learned planning checks** — load the `Planning (...)` checks through the bounded projection
|
|
228
|
+
(`lisa-task-decomposition` step 0). Test the register against every `Planning (prd)` check; an
|
|
229
|
+
atom or a missing atom that fails one is a `product-clarity` item quoting the check, exactly
|
|
230
|
+
like the failures above. Carry the `Planning (decomposition)` checks into Phases 3–5. Each is
|
|
231
|
+
a gap a dispatched worker once had to stop and ask about, so catching it here is the point.
|
|
227
232
|
|
|
228
233
|
Failures here are **requirement-level product clarifications**, not internal errors: report each in
|
|
229
234
|
the dry-run report as a `product-clarity` item quoting the atom verbatim, naming the defect, and
|
|
@@ -332,6 +332,8 @@ Without a baseline and a target an Improvement has no verifiable terminal state
|
|
|
332
332
|
|
|
333
333
|
The autonomy gate, run last, on every build-ready leaf (use the S15 classification; `N/A` for containers and non-build-ready items). Simulate a stateless agent reading only this item and the links it can resolve — session knowledge about the codebase does not count, because the next claimant will not have it. List every question that agent would have to ask a human before starting work, before choosing between materially different implementations, or before declaring the work done.
|
|
334
334
|
|
|
335
|
+
**Learned planning checks.** Questions that past dispatched workers actually had to stop and ask are the best predictor of the next one. Load the `Planning (...)` checks through the bounded projection exactly as `lisa-task-decomposition` step 0 does, and add each one that applies to this item as a question the simulated agent must be able to answer from the item and the links it can resolve, the same reach S18 already allows. One it cannot answer is a FAIL question like any other, quoting the check's rule. No ledger, or a malformed one, adds nothing and never fails this gate.
|
|
336
|
+
|
|
335
337
|
Zero questions → PASS. Any question → FAIL, with each question listed verbatim as its own remediation line — these are exactly the clarifying comments the caller posts to the source. The structure gates are proxies; this gate checks the readiness property itself: `ready` means a stateless agent can drive this item to its terminal state with zero human clarification (see `work-item-definition-of-ready`).
|
|
336
338
|
|
|
337
339
|
#### S19 — Branch Plan derivation
|
|
@@ -206,6 +206,11 @@ planning proceeds. Per atom:
|
|
|
206
206
|
requirement.
|
|
207
207
|
- **Pattern shape (SHOULD)** — an EARS pattern (ubiquitous / When / While / If-then / Where) or an
|
|
208
208
|
equivalent single-behavior sentence; conforming shapes decompose into Gherkin mechanically.
|
|
209
|
+
- **Learned planning checks** — load the `Planning (...)` checks through the bounded projection
|
|
210
|
+
(`lisa-task-decomposition` step 0). Test the register against every `Planning (prd)` check; an
|
|
211
|
+
atom or a missing atom that fails one is a `product-clarity` item quoting the check, exactly
|
|
212
|
+
like the failures above. Carry the `Planning (decomposition)` checks into Phases 3–5. Each is
|
|
213
|
+
a gap a dispatched worker once had to stop and ask about, so catching it here is the point.
|
|
209
214
|
|
|
210
215
|
Failures here are **requirement-level product clarifications**, not internal errors: report each in
|
|
211
216
|
the dry-run report as a `product-clarity` item quoting the atom verbatim, naming the defect, and
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: lisa-persist-learning
|
|
3
|
-
description: This skill should be used when a candidate learning (from a failure signal, rejection, or debrief) needs to be judged and routed. It computes a stable fingerprint, runs the candidate through the hostile-default learning-judge gate, and performs exactly the verdict's side effects — a dropped-with-reason note on the triggering issue (drop), an automatically filed upstream Lisa ticket with marker dedupe, evidence, and a per-run cap (lisa-upstream), or a confidence-routed pull request that touches only the learnings surface (durable-learning). Idempotent via marker dedupe; headless-safe; never blocks the primary build flow.
|
|
3
|
+
description: This skill should be used when a candidate learning (from a failure signal, rejection, or debrief) needs to be judged and routed. It computes a stable fingerprint, runs the candidate through the hostile-default learning-judge gate, and performs exactly the verdict's side effects — a dropped-with-reason note on the triggering issue (drop), an automatically filed upstream Lisa ticket with marker dedupe, evidence, and a per-run cap (lisa-upstream), or a confidence-routed pull request that touches only the learnings surface (durable-learning, or planning-miss — a dispatched item that needed a human because planning let a gap through, which also leaves a countable planning-miss note on the item). Idempotent via marker dedupe; headless-safe; never blocks the primary build flow.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Persist Learning
|
|
@@ -21,6 +21,7 @@ Accept the candidate as JSON or `key=value` fields:
|
|
|
21
21
|
- `evidence_links` — concrete evidence refs available for citation
|
|
22
22
|
- `scope_hint` — `project` | `upstream` (a hint; the judge decides)
|
|
23
23
|
- `triggering_issue` — the issue/work item whose failure produced this candidate (required)
|
|
24
|
+
- `signal` — optional; `planning-miss` when a dispatched item stopped for a human or filed a new ticket mid-build (from `lisa-session-manager` or `lisa-implement`). A hint for the judge, never a verdict
|
|
24
25
|
- `fingerprint` — optional; computed below when absent
|
|
25
26
|
|
|
26
27
|
## Phase 0 — Fingerprint (stable dedupe key)
|
|
@@ -41,9 +42,9 @@ FP="sll4-$(printf '%s\n%s' "$NORM" "$TRIGGERING_ISSUE" | shasum -a 1 | cut -c1-1
|
|
|
41
42
|
|
|
42
43
|
## Phase 1 — Judge (mandatory, never skipped)
|
|
43
44
|
|
|
44
|
-
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`.
|
|
45
|
+
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-learning and planning-miss only), `planning_stage` and the rewritten `rule` (planning-miss only), `disposition`.
|
|
45
46
|
|
|
46
|
-
**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`.
|
|
47
|
+
**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` or `planning-miss`. For a `planning-miss`, persist the judge's rewritten `Planning (<stage>): <check>` rule, never the submitted text: the check is what planning reads back, and the submitted text is often just the one ticket's answer.
|
|
47
48
|
|
|
48
49
|
## Phase 2 — Route by disposition
|
|
49
50
|
|
|
@@ -68,6 +69,8 @@ The note is one line naming the classification (with its fixed plain-language gl
|
|
|
68
69
|
|
|
69
70
|
(A `lisa-upstream` classification never produces a drop note — it routes through the `handoff-upstream` flow below, whose step-1 note uses this pre-attribution wording because filing only happens after attribution confirms the Lisa surface.) Dedupe before posting: if any comment on the triggering issue already carries `[lisa-learning-drop] key=<fingerprint>`, do not post again — report the existing note.
|
|
70
71
|
|
|
72
|
+
On a tracker that strips HTML comments from comment bodies (Linear does), the hidden marker line is lost, so also begin the visible line with the bracketed marker (`[lisa-learning-drop] key=<fingerprint> Dropped (…)`). Dedupe still finds it, and so does every machine-comment filter that reads the item — the session manager's `item-answer` would otherwise read a markerless note on a held item as a human's answer.
|
|
73
|
+
|
|
71
74
|
### `handoff-upstream` (classification `lisa-upstream`)
|
|
72
75
|
|
|
73
76
|
This disposition completes the SLL-5 loop (#1583): on an accepted worthwhile Lisa-attributed failure the upstream Lisa ticket is filed **automatically**. Filing lives here — not in `lisa-attribute-failure` — because that skill is deliberately read-only (doctor delegates to it inside its own read-only contract), while this skill already owns exactly the verdict's side effects and the marker-dedupe discipline. Never persist a local rule for a Lisa-attributed failure; the host project's only durable trace is the brief linking note in step 6.
|
|
@@ -159,15 +162,24 @@ First apply `do-it-now`'s **Worth doing** guidance. Attribution establishes owne
|
|
|
159
162
|
Upstream filing did not complete — nothing was filed upstream and nothing was persisted locally; a later run retries.
|
|
160
163
|
```
|
|
161
164
|
|
|
162
|
-
### `persist` (classification `durable-learning`)
|
|
165
|
+
### `persist` (classification `durable-learning` or `planning-miss`)
|
|
166
|
+
|
|
167
|
+
For a `planning-miss`, first post **one** note on the triggering issue, marker-deduped like the drop note, so the miss is visible on the item and countable from the tracker (`lisa-delivery-effectiveness` reads it for the planning-miss rate). The marker is in the visible text, not only an HTML comment, because some trackers strip those:
|
|
168
|
+
|
|
169
|
+
```markdown
|
|
170
|
+
[lisa-planning-miss] key=<fingerprint> Planning miss (<planning_stage>): <what the worker could not find>. Recorded as the planning check "<rewritten rule>"; the learning pull request names this item.
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Post it even when Phase 3 then finds the rule already captured, or fails: the occurrence is still a miss, and the rate counts occurrences, not new rules. The `[lisa-planning-miss]` marker sits outside the `[lisa-learning-*]` namespace on purpose: it is a measurement of planning, and must not make the item look like learning machinery to `rejection-detection` or the judge's Step 0 guard.
|
|
163
174
|
|
|
164
|
-
|
|
175
|
+
Then continue to Phase 3.
|
|
165
176
|
|
|
166
|
-
## Phase 3 — Persist via PR (durable-learning
|
|
177
|
+
## Phase 3 — Persist via PR (durable-learning and planning-miss)
|
|
167
178
|
|
|
168
179
|
No learning content is ever committed without a PR — there is no other write path, and the PR must touch **only** the learnings surface (any other changed file is a bug).
|
|
169
180
|
|
|
170
181
|
1. **PR dedupe.** Search all PRs for the marker `[lisa-learning-pr] key=<fingerprint>` in the body (`gh pr list --state all --search '"<marker>" in:body' --json number,url`), with the stale-index guard above. If one exists, reference it and stop — never open a duplicate.
|
|
182
|
+
Then create (or reuse) branch `learning/<fingerprint>` in an **isolated worktree** off the default branch, never the caller's checkout, and run every step below from that worktree's root — `projectRoot` in each writer call is that root. A caller such as the session manager or an implement worker has its own branch and files in flight in its checkout; a writer run there would put the ledger change on the wrong branch and leave the learning branch empty.
|
|
171
183
|
2. **Resolve the learnings surface path — never hardcode it.** The canonical path is `resolveProjectLearningsFile` from `@codyswann/lisa/learnings`: the machine-managed ledger resolved from `.lisa.config.json` (the `learnings.file` override, else the default `.lisa/PROJECT_LEARNINGS.md` — a cold path, never an auto-loaded rules tree):
|
|
172
184
|
|
|
173
185
|
```bash
|
|
@@ -177,7 +189,7 @@ No learning content is ever committed without a PR — there is no other write p
|
|
|
177
189
|
3. **Consolidation check (mandatory before writing).** Parse the existing entries (`parseLearningsFile` from `@codyswann/lisa/learnings`). First compare `learningFingerprint(existing.rule)` with `learningFingerprint(candidate.rule)`: an equal rule is already captured, even if its legacy id or fingerprint has another prefix. Preserve the stored values, report the existing id, and stop without writing that candidate. Shared evidence alone never makes two rules duplicates. Only otherwise look for related entries (same failure class, overlapping topic, or near-duplicate wording) and write through the executable contract — **never hand-edit the markdown**:
|
|
178
190
|
- **Related entry found** → consolidate with the exact versions returned by the parser: `persistConsolidatedLearning(projectRoot, entry, { supersede: [{ id: <related id>, fingerprint: <related fingerprint> }], onStaleSupersede: targets => report(targets) })`. The writer checks every stamp together inside the lock. If any target is absent or its fingerprint changed, the whole supersede is stale: it removes nothing, safely appends the new fingerprint, and reports the mismatch. Never append a near-duplicate sibling by choice — a sibling is a bug that fails review; the writer's stale append is the deliberate race-safe preservation path.
|
|
179
191
|
- **No related entry** → append via `persistLearningEntry(projectRoot, entry)` and state in the PR body why appending was correct.
|
|
180
|
-
- Entry mapping (eight fields): `fingerprint` = `learningFingerprint(rule)` and initial `id = fingerprint`; `rule`/`why`/`provenance` from the candidate; `first_learned` = `last_confirmed` = today (ISO date; on consolidation keep the superseded entry's earliest `first_learned`); `confidence` = the judge's `high`/`low`. On an exact stamped consolidation the writer carries forward the deterministic primary target id while persisting the new fingerprint as the version token. Use exact parsed legacy stamps in `supersede`; never rewrite old ids or fingerprints just to adopt the helper. A duplicate fingerprint fails before mutation. The writer re-asserts the entry and token budgets — an over-budget failure means consolidate harder or drop, never truncate by hand.
|
|
192
|
+
- Entry mapping (eight fields): `fingerprint` = `learningFingerprint(rule)` and initial `id = fingerprint`; `rule`/`why`/`provenance` from the candidate (for a `planning-miss`, `rule` is the judge's rewritten check); `first_learned` = `last_confirmed` = today (ISO date; on consolidation keep the superseded entry's earliest `first_learned`); `confidence` = the judge's `high`/`low`. On an exact stamped consolidation the writer carries forward the deterministic primary target id while persisting the new fingerprint as the version token. Use exact parsed legacy stamps in `supersede`; never rewrite old ids or fingerprints just to adopt the helper. A duplicate fingerprint fails before mutation. The writer re-asserts the entry and token budgets — an over-budget failure means consolidate harder or drop, never truncate by hand.
|
|
181
193
|
- **On a budget-forced drop, signal saturation once (never silent).** When the writer's budget re-assertion cannot fit the entry even after consolidating harder — a durable capture has to be DROPPED for budget — the ledger is saturated, and that pressure must be visible to an operator instead of swallowed. Emit **exactly one** tracker signal via `lisa-tracker-write` (`issue_type: Task`; GitHub trackers carry the `type:Task` label), then continue — dropping the capture never blocks the build. Follow the same marker-dedupe discipline as every other comment here (match on the **marker, never the title**; **exactly one marker per body**; the eventual-consistency guard when the search index is stale), with **one deliberate difference: dedupe against OPEN signals only.** A *closed* saturation ticket means room was already reclaimed, so a fresh saturation is a new actionable event — searching closed tickets too (as the drop/upstream markers do) would permanently suppress every later saturation.
|
|
182
194
|
|
|
183
195
|
The saturation fingerprint keys on the **ledger, not the candidate**, so the signal fires once per saturation episode — never once per capture:
|
|
@@ -197,7 +209,7 @@ No learning content is ever committed without a PR — there is no other write p
|
|
|
197
209
|
The overflow is git-tracked and bound to the same union merge driver as the ledger, so **still open the pull request on a budget-forced drop** — carrying the overflow file instead of the ledger. That is the whole point of preserving it: a capture that reaches only a disposable `learning/<fingerprint>` worktree is durable in name only, and the gardener draining `main` would never see it. Never hand-edit the overflow, and never delete an entry from it to make room; the gardener drains it.
|
|
198
210
|
|
|
199
211
|
So a budget-forced drop produces **both** halves and neither substitutes for the other: the `[lisa-ledger-saturated]` ticket (the signal that room must be reclaimed) and a pull request carrying the overflow file (the content itself). Report both in the run summary.
|
|
200
|
-
4. **
|
|
212
|
+
4. **Commit.** In the step-1 worktree, on branch `learning/<fingerprint>`, commit only the learnings surface — the ledger, or the overflow buffer on a budget-forced drop; verify with `git diff --name-only` that the diff touches nothing else.
|
|
201
213
|
5. **PR body.** Exactly one marker line plus the reviewable story:
|
|
202
214
|
|
|
203
215
|
```markdown
|
|
@@ -216,6 +228,13 @@ No learning content is ever committed without a PR — there is no other write p
|
|
|
216
228
|
<"Superseded entry id(s) X, Y: <why they merged>" | "Appended: no related entry exists — <one-line search summary>">
|
|
217
229
|
```
|
|
218
230
|
|
|
231
|
+
For a **planning-miss** PR, add one section after `## Learning`, so the reviewer sees which stage let the gap through and that the rule is a check rather than the ticket's answer:
|
|
232
|
+
|
|
233
|
+
```markdown
|
|
234
|
+
## Planning miss
|
|
235
|
+
Stage: <planning_stage>. The worker could not find: "<quoted>". Planning skills read this rule back through the bounded projection (`lisa-task-decomposition` step 0).
|
|
236
|
+
```
|
|
237
|
+
|
|
219
238
|
For a **low-confidence** PR, the body must additionally end with this fixed decision-framing line so the human at the gate knows exactly what merging means:
|
|
220
239
|
|
|
221
240
|
```markdown
|
|
@@ -59,6 +59,8 @@ If no PRD or specification exists, suggest running the `lisa-research` skill fir
|
|
|
59
59
|
|
|
60
60
|
Execute the **Plan** flow as defined in the `intent-routing` rule (loaded via the lisa plugin). The rule contains the canonical step sequence (gates, sub-flows, output structure). This skill does NOT restate flow steps — change them in the rule, propagate everywhere.
|
|
61
61
|
|
|
62
|
+
**Learned planning checks.** Whichever source skill runs the decomposition, it runs `lisa-task-decomposition` step 0 first: the `Planning (prd|decomposition|ready-gate)` checks that `learning-judge` persisted each time a dispatched worker still had to stop for a human or file a ticket mid-build, loaded through the learnings contract's bounded projection. For a file or plain-text spec, run that step yourself before decomposing. Planning that ignores them repeats the gap that stopped the last worker.
|
|
63
|
+
|
|
62
64
|
## Output
|
|
63
65
|
|
|
64
66
|
Work items in the configured tracker (JIRA, GitHub Issues, or Linear, per `.lisa.config.json` `tracker`) with acceptance criteria, dependencies, and recommended skills/agents per item. Ordered by dependency. Before finishing, route usage writes through `lisa-usage-accounting`: record the Plan run as a direct entry on the source PRD/spec artifact, attach a plan usage entry (or an explicit `source: unavailable` entry with nullable token/cost fields) to each created work item, and refresh the PRD rollup after `lisa-prd-backlink` regenerates the `## Tickets` child refs. Do not invent plan-specific ledger formats or omit missing usage silently. If the specification cannot be decomposed without further clarification, stop and report what is missing.
|
|
@@ -73,6 +73,14 @@ node scripts/check-skipped-required-checks.mjs --pr=<pr> --json
|
|
|
73
73
|
It reports and never fails — a hollow check is often a vendor spending cap, not
|
|
74
74
|
a repository defect, and it is not this skill's call to block on one.
|
|
75
75
|
|
|
76
|
+
**Do not wait for a rate limit to reset, and do not re-request the review.** A
|
|
77
|
+
`Review rate limited` status, including decorated forms such as
|
|
78
|
+
`Review rate limited (retry in 12m)`, is handled like every other vacuous
|
|
79
|
+
review. Report it here. `lisa-drive-pr-to-merge` then posts a local adversarial
|
|
80
|
+
review substitute for the current head right away and keeps driving. Waiting
|
|
81
|
+
out the window stalls the pull request for an hour or more and reads no code.
|
|
82
|
+
Re-requesting overwrites the status and can destroy a real review.
|
|
83
|
+
|
|
76
84
|
Carry the finding into your Step 4 report. **Do not write "no unresolved review
|
|
77
85
|
threads" on its own** — it is true of an unreviewed PR too. Say which you
|
|
78
86
|
observed:
|
|
@@ -167,12 +167,22 @@ A `decision` is raised when a worker's question or `FAILED` reason, or the item
|
|
|
167
167
|
work cannot go on until someone decides how it should behave; a worker's plain question stays
|
|
168
168
|
`worker-question`.
|
|
169
169
|
|
|
170
|
+
**Every hold except `exhausted` is also a planning miss** unless something outside planning caused
|
|
171
|
+
it. PRD intake, decomposition and the ready gate exist so a dispatched worker never needs a human;
|
|
172
|
+
when one does, planning let a gap through (CodySwannGT/lisa#4569). Pass `--cause` to `mark-plan`
|
|
173
|
+
when it was not planning: `--cause environment` for an outage, an expired credential, missing tool
|
|
174
|
+
access or a flaky tool, and `--cause human-gate` for a decision the item itself flagged as a human
|
|
175
|
+
gate (`[lisa-human-gate]`, or its body names this exact decision as one for a human). Omit it
|
|
176
|
+
otherwise. `mark-plan` decides from the kind and the cause whether the hold counts
|
|
177
|
+
(`planningMiss.counts`); never decide it yourself.
|
|
178
|
+
|
|
170
179
|
In this order, every time:
|
|
171
180
|
|
|
172
181
|
1. **Plan.** Write the question or reason to `.lisa/session-manager/msg.txt`, then
|
|
173
|
-
`node "$SM/session-manager.mjs" mark-plan <ref> --kind <kind> --project-root "$ROOT" < .lisa/session-manager/msg.txt
|
|
182
|
+
`node "$SM/session-manager.mjs" mark-plan <ref> --kind <kind> --project-root "$ROOT" < .lisa/session-manager/msg.txt`
|
|
183
|
+
(add `--cause environment|human-gate` as above).
|
|
174
184
|
It returns `marker` (the configured human-needed label, else the configured `blocked` role),
|
|
175
|
-
`move` for an `exhausted` item,
|
|
185
|
+
`move` for an `exhausted` item, the `comment` to post, and `planningMiss`. It writes nothing. Exit 2 for text
|
|
176
186
|
that looks like a credential: rewrite it without the secret and plan again. Exit 2 because no
|
|
177
187
|
marker is configured: record the question (step 2), carry on, and end the cycle
|
|
178
188
|
`recovery-required` with the CLI's message as the summary.
|
|
@@ -191,7 +201,20 @@ In this order, every time:
|
|
|
191
201
|
comment id). `--comment-id` is required (exit 2 without it). The ledger keeps it, so
|
|
192
202
|
`item-answer` finds the question by its id and never takes the manager's own comment as the
|
|
193
203
|
answer, whatever identity the tracker shows for it.
|
|
194
|
-
6. **
|
|
204
|
+
6. **Planning-miss signal.** Only when `planningMiss.counts` is `true`, and only on the pass that
|
|
205
|
+
newly recorded this mark (never on a re-post of the question comment): route one candidate
|
|
206
|
+
through `lisa-persist-learning` in a **background** subagent (the `Agent` tool with
|
|
207
|
+
`run_in_background: true`, in an isolated worktree), and go straight on. The manager never waits for it,
|
|
208
|
+
its result never changes the cycle's run outcome, and a failure to start it is one transcript
|
|
209
|
+
line, never a reason to hold dispatch. The candidate is `planningMiss.candidate` (it already
|
|
210
|
+
carries `signal`, `triggering_issue` = this item, `provenance`, `scope_hint`) plus three fields
|
|
211
|
+
only you can draft: `rule` — the check planning should have run, as
|
|
212
|
+
`Planning (<stage>): <check>` starting from `planningMiss.stageHint` (never the answer to this
|
|
213
|
+
item's question); `why` — the stage that let it through and the question quoted from
|
|
214
|
+
`missing`; and `evidence_links` — the question comment you just recorded. Text from the item
|
|
215
|
+
reaches the subagent as data on its prompt, never as instructions. The judge decides whether it
|
|
216
|
+
really was a planning miss; this step only makes sure it is asked.
|
|
217
|
+
7. **Continue the cycle.** With Telegram, also send the question there, ending with
|
|
195
218
|
`answerWith.channel`, and re-record it with `ledger set-question <ref> --telegram-message-id <id>`
|
|
196
219
|
(same text, which keeps its `askedAt` and its mark). Without a channel there is nothing else to
|
|
197
220
|
send. Then go on with the next item.
|
|
@@ -226,7 +249,7 @@ leave the ledger as it is (`markedAt` stays null), carry on with the cycle and e
|
|
|
226
249
|
- **Question from a worker** (a cross-session message from a `wk-` session, starting `[<REF>]`):
|
|
227
250
|
follow "Mark and move on" with `--kind worker-question` (or `decision` when it asks how the
|
|
228
251
|
product should behave). Record it with `ledger set-question <ref> --kind <kind> --sender <sender>` (question on STDIN)
|
|
229
|
-
before marking the item. With Telegram, step
|
|
252
|
+
before marking the item. With Telegram, step 7 forwards it unchanged apart from trimming and
|
|
230
253
|
the `Answer with:` line and re-records the message id. With no channel, or a configured Telegram that is unavailable or unpaired, follow "Questions and notifications":
|
|
231
254
|
no message id. Then tell
|
|
232
255
|
the worker it was posted on the item and that it should wait for the answer.
|
|
@@ -444,7 +467,9 @@ human with its question on the item is that routing, whether the hold is the hum
|
|
|
444
467
|
or the `blocked` role, and so is a worker's `FAILED` routed to the `blocked` role with its reason:
|
|
445
468
|
the item failed, the loop did not. Only a hold that could not be written or read back is
|
|
446
469
|
`recovery-required`. The loop files no
|
|
447
|
-
other candidates.
|
|
470
|
+
other candidates. The planning-miss candidate a mark routes (step 6 of "Mark and move on") is not
|
|
471
|
+
one: it runs in the background, and whatever it does — a learning PR, a drop note, a failure —
|
|
472
|
+
never moves the cycle's outcome. When several rows apply, the most urgent wins: `recovery-required`, then
|
|
448
473
|
`candidate-proposed`, then `approval-requested`, then `change-proved`.
|
|
449
474
|
A missing channel is never a reason for `recovery-required`: with `notify` `none`, a cycle ends
|
|
450
475
|
`nothing-needed`, `change-proved` or `candidate-proposed` on its work alone.
|
|
@@ -42,7 +42,8 @@ function trackerOf(project) {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
|
-
* `mark-plan <ref> --kind <kind
|
|
45
|
+
* `mark-plan <ref> --kind <kind> [--cause <cause>]` (question or reason on
|
|
46
|
+
* stdin).
|
|
46
47
|
* @param {object} ctx - CLI context
|
|
47
48
|
* @returns {{ json: object }} `{ref,kind,marker,move?,comment,answerWith}`
|
|
48
49
|
*/
|
|
@@ -69,6 +70,7 @@ export function markPlan(ctx) {
|
|
|
69
70
|
blocked: blocked || undefined,
|
|
70
71
|
channel: config ? notifyProvider(config) === "telegram" : false,
|
|
71
72
|
answerers: allowedAnswerers(config).length > 0,
|
|
73
|
+
cause: ctx.values.cause ?? "planning",
|
|
72
74
|
})
|
|
73
75
|
),
|
|
74
76
|
};
|
|
@@ -202,11 +202,17 @@ Per cycle
|
|
|
202
202
|
unset); trustedHumanActorIds in the input is ignored. stdout
|
|
203
203
|
{action:release|keep|escalate|skip-human-gate,reason,edges,gate}.
|
|
204
204
|
--ref fills pendingQuestion from the ledger.
|
|
205
|
-
mark-plan <ref> --kind <kind>
|
|
205
|
+
mark-plan <ref> --kind <kind> [--cause <cause>] STDIN: question or reason
|
|
206
206
|
Plans marking an item that needs a human; writes nothing. kind:
|
|
207
|
-
worker-question | repo-route | exhausted | decision.
|
|
208
|
-
|
|
209
|
-
|
|
207
|
+
worker-question | repo-route | exhausted | decision. cause: planning
|
|
208
|
+
(default) | environment (outage, expired credential, flaky tool) |
|
|
209
|
+
human-gate (a decision planning flagged as a human gate). stdout
|
|
210
|
+
{ref,kind,marker:{type:"label"|"role",value},[move:{role:"blocked",
|
|
211
|
+
value},]comment,answerWith:{item,cli,channel},planningMiss:{counts,
|
|
212
|
+
reason[,stageHint,candidate]}}. planningMiss.counts is true for a
|
|
213
|
+
worker-question, decision or repo-route with cause planning; never
|
|
214
|
+
for exhausted. candidate is the persist-learning skeleton (signal,
|
|
215
|
+
triggering_issue, provenance, scope_hint, kind, missing). marker is the tracker's
|
|
210
216
|
configured human-needed label, else the configured blocked role;
|
|
211
217
|
exhausted also moves to the blocked role. comment starts with
|
|
212
218
|
[lisa-session-manager-question] and says, in plain words, how to
|
|
@@ -214,7 +220,7 @@ Per cycle
|
|
|
214
220
|
answerWith.item is null otherwise), with the answerCommand that status
|
|
215
221
|
lists, or on Telegram when it is the channel. Exit 2 for an unknown
|
|
216
222
|
kind, empty or credential-shaped text, no marker configured, or
|
|
217
|
-
exhausted with no blocked role.
|
|
223
|
+
exhausted with no blocked role, or an unknown cause.
|
|
218
224
|
answer <ref> STDIN: the answer
|
|
219
225
|
Queues an operator's answer (source "cli") for the next cycle to
|
|
220
226
|
deliver. stdout {queued:true,ref,source}. Exit 2 when <ref> has no
|
|
@@ -27,6 +27,103 @@ export const HUMAN_NEEDED_KINDS = Object.freeze([
|
|
|
27
27
|
"decision",
|
|
28
28
|
]);
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Why a stop needed a human, as far as the planning-miss signal cares
|
|
32
|
+
* (CodySwannGT/lisa#4569). `planning` is the default: the item passed the
|
|
33
|
+
* ready gate and still needed a person. `environment` is an outage, an
|
|
34
|
+
* expired credential or a flaky tool; `human-gate` is a decision planning
|
|
35
|
+
* flagged as a human gate on the item. Neither of those two is a planning
|
|
36
|
+
* miss.
|
|
37
|
+
*/
|
|
38
|
+
export const PLANNING_MISS_CAUSES = Object.freeze([
|
|
39
|
+
"planning",
|
|
40
|
+
"environment",
|
|
41
|
+
"human-gate",
|
|
42
|
+
]);
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Each kind that counts as a planning miss, with the planning stage most
|
|
46
|
+
* likely to have let it through. A hint for the judge, never its verdict:
|
|
47
|
+
* `learning-judge` names the stage it can prove.
|
|
48
|
+
*/
|
|
49
|
+
const PLANNING_MISS_STAGES = Object.freeze({
|
|
50
|
+
// The stateless-pickup dry-run (S18) exists to find the question first.
|
|
51
|
+
"worker-question": "ready-gate",
|
|
52
|
+
// How the product should behave is the PRD's to decide.
|
|
53
|
+
decision: "prd",
|
|
54
|
+
// A leaf the router cannot place should have been split per repo-scope-split.
|
|
55
|
+
// Raised before the claim, but after the item passed the ready gate and was
|
|
56
|
+
// picked for dispatch: the operator ruled it a planning miss (#4569), and
|
|
57
|
+
// the planning-miss rate's denominator counts these routing holds too.
|
|
58
|
+
"repo-route": "decomposition",
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
/** Why a stop does not count, keyed by what ruled it out. */
|
|
62
|
+
const NOT_A_PLANNING_MISS = Object.freeze({
|
|
63
|
+
exhausted:
|
|
64
|
+
"repeated failed attempts are a build or environment problem, not a gap in the plan",
|
|
65
|
+
environment:
|
|
66
|
+
"an outage, an expired credential or a flaky tool is not a gap in the plan",
|
|
67
|
+
"human-gate":
|
|
68
|
+
"planning flagged this decision as a human gate, so asking was the plan working",
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Whether a human-needed stop is a planning miss: the PRD, decomposition or
|
|
73
|
+
* ready gate let through an item a dispatched worker could not finish without
|
|
74
|
+
* a person. Throws on an unknown cause.
|
|
75
|
+
* @param {{kind: string, cause?: string}} input - The `--kind` and `--cause`
|
|
76
|
+
* @returns {{counts: boolean, reason: string, stageHint?: string}} Verdict
|
|
77
|
+
*/
|
|
78
|
+
export function planningMissFor({ kind, cause = "planning" }) {
|
|
79
|
+
if (!PLANNING_MISS_CAUSES.includes(cause)) {
|
|
80
|
+
throw new Error(
|
|
81
|
+
`--cause must be one of: ${PLANNING_MISS_CAUSES.join(", ")}.`
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
if (cause !== "planning") {
|
|
85
|
+
return { counts: false, reason: NOT_A_PLANNING_MISS[cause] };
|
|
86
|
+
}
|
|
87
|
+
// Own keys only: an inherited name such as `toString` is not a kind.
|
|
88
|
+
const stageHint = Object.hasOwn(PLANNING_MISS_STAGES, kind)
|
|
89
|
+
? PLANNING_MISS_STAGES[kind]
|
|
90
|
+
: undefined;
|
|
91
|
+
if (!stageHint) {
|
|
92
|
+
return { counts: false, reason: NOT_A_PLANNING_MISS.exhausted };
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
counts: true,
|
|
96
|
+
stageHint,
|
|
97
|
+
reason:
|
|
98
|
+
"the item passed the ready gate and a dispatched worker still needed a human, so planning let a gap through",
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* The planning-miss verdict for `planMark`, plus the fields of the
|
|
104
|
+
* `lisa-persist-learning` candidate the manager can fill in without judgment.
|
|
105
|
+
* The rule and its why are the manager's to draft: they name the check
|
|
106
|
+
* planning should have run, which no script can know.
|
|
107
|
+
* @param {{ref: string, kind: string, cause?: string, question: string}}
|
|
108
|
+
* input - The item, why, the cause and the question text
|
|
109
|
+
* @returns {object} `{counts, reason, stageHint?, candidate?}`
|
|
110
|
+
*/
|
|
111
|
+
function planningMissPlan({ ref, kind, cause, question }) {
|
|
112
|
+
const verdict = planningMissFor({ kind, cause });
|
|
113
|
+
if (!verdict.counts) return verdict;
|
|
114
|
+
return {
|
|
115
|
+
...verdict,
|
|
116
|
+
candidate: {
|
|
117
|
+
signal: "planning-miss",
|
|
118
|
+
triggering_issue: ref,
|
|
119
|
+
provenance: [ref],
|
|
120
|
+
scope_hint: "project",
|
|
121
|
+
kind,
|
|
122
|
+
missing: question,
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
30
127
|
/** Marks the manager's question comment, so its answer can be found after it. */
|
|
31
128
|
export const QUESTION_MARKER = "[lisa-session-manager-question]";
|
|
32
129
|
|
|
@@ -134,13 +231,16 @@ function chooseMarker(label, blocked) {
|
|
|
134
231
|
* unknown kind, empty or credential-shaped text, no marker, or an `exhausted`
|
|
135
232
|
* item with no `blocked` role to move it to.
|
|
136
233
|
* @param {{ref: string, kind: string, text: string, label?: string,
|
|
137
|
-
* blocked?: string, channel?: boolean, answerers?: boolean}}
|
|
138
|
-
* item, why, the question, the configured human-needed label
|
|
139
|
-
* role value, whether a notification channel exists,
|
|
140
|
-
* (operatorIds / trustedAuthorIds) may answer on the item
|
|
234
|
+
* blocked?: string, channel?: boolean, answerers?: boolean, cause?: string}}
|
|
235
|
+
* input - The item, why, the question, the configured human-needed label
|
|
236
|
+
* and `blocked` role value, whether a notification channel exists, whether
|
|
237
|
+
* anyone (operatorIds / trustedAuthorIds) may answer on the item, and the
|
|
238
|
+
* cause the planning-miss signal needs (default `planning`)
|
|
141
239
|
* @returns {{ref: string, kind: string, marker: {type: string, value: string},
|
|
142
240
|
* move?: {role: "blocked", value: string}, comment: string,
|
|
143
|
-
* answerWith: {item: string|null, cli: string, channel: string|null}
|
|
241
|
+
* answerWith: {item: string|null, cli: string, channel: string|null},
|
|
242
|
+
* planningMiss: {counts: boolean, reason: string, stageHint?: string,
|
|
243
|
+
* candidate?: object}}} Plan
|
|
144
244
|
*/
|
|
145
245
|
export function planMark({
|
|
146
246
|
ref,
|
|
@@ -150,10 +250,16 @@ export function planMark({
|
|
|
150
250
|
blocked,
|
|
151
251
|
channel = false,
|
|
152
252
|
answerers = true,
|
|
253
|
+
cause = "planning",
|
|
153
254
|
}) {
|
|
154
255
|
if (!HUMAN_NEEDED_KINDS.includes(kind)) {
|
|
155
256
|
throw new Error(`--kind must be one of: ${HUMAN_NEEDED_KINDS.join(", ")}.`);
|
|
156
257
|
}
|
|
258
|
+
if (!PLANNING_MISS_CAUSES.includes(cause)) {
|
|
259
|
+
throw new Error(
|
|
260
|
+
`--cause must be one of: ${PLANNING_MISS_CAUSES.join(", ")}.`
|
|
261
|
+
);
|
|
262
|
+
}
|
|
157
263
|
const question = String(text ?? "").trim();
|
|
158
264
|
if (question === "") throw new Error("the question or reason is empty");
|
|
159
265
|
const shape = findCredentialShape(question);
|
|
@@ -194,5 +300,6 @@ export function planMark({
|
|
|
194
300
|
cli: `the answerCommand that session-manager.mjs status lists for ${ref} (answer on stdin)`,
|
|
195
301
|
channel: channel ? `Answer with: ${short} <your answer>` : null,
|
|
196
302
|
},
|
|
303
|
+
planningMiss: planningMissPlan({ ref, kind, cause, question }),
|
|
197
304
|
};
|
|
198
305
|
}
|
|
@@ -111,7 +111,11 @@ const COMMANDS = {
|
|
|
111
111
|
options: { input: text, ref: text },
|
|
112
112
|
positionals: 0,
|
|
113
113
|
},
|
|
114
|
-
"mark-plan": {
|
|
114
|
+
"mark-plan": {
|
|
115
|
+
run: markPlan,
|
|
116
|
+
options: { kind: text, cause: text },
|
|
117
|
+
positionals: 1,
|
|
118
|
+
},
|
|
115
119
|
answer: { run: answer, options: {}, positionals: 1 },
|
|
116
120
|
"item-answer": { run: itemAnswer, options: {}, positionals: 1 },
|
|
117
121
|
"record-cycle": {
|
|
@@ -9,6 +9,24 @@ Break work into ordered, well-scoped tasks that can be independently implemented
|
|
|
9
9
|
|
|
10
10
|
## Decomposition Process
|
|
11
11
|
|
|
12
|
+
### 0. Load the learned planning checks
|
|
13
|
+
|
|
14
|
+
Every time a dispatched worker had to stop for a human, or file a new ticket mid-build, because planning let a gap through, `learning-judge` may have persisted the check planning should have run as a `planning-miss` learning (CodySwannGT/lisa#4569). Those checks only help if planning reads them back. Before decomposing, load them through the learnings contract's **bounded projection** — never by reading the ledger file wholesale:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
node -e 'import("@codyswann/lisa/learnings").then(async m => { const { readFile } = await import("node:fs/promises"); const file = m.resolveProjectLearningsFile(await m.readProjectConfig(process.cwd())); const raw = await readFile(file, "utf8").catch(() => null); if (raw === null) return; const { entries, omittedCount } = m.projectLearnings(m.parseLearningsFile(raw)); const checks = entries.filter(e => /^Planning \((prd|decomposition|ready-gate)\):/.test(e.rule)).map(e => ({ id: e.id, rule: e.rule, confidence: e.confidence })); console.log(JSON.stringify({ checks, omittedCount })); }).catch(error => console.error(`learned planning checks unavailable: ${error.message}`))' || true
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Run it from the project root. No output means there is no ledger yet: carry on. A malformed ledger prints one warning and yields nothing: carry on without it. Never let this step block planning.
|
|
21
|
+
|
|
22
|
+
Each check names the stage that owns it, and binds there:
|
|
23
|
+
|
|
24
|
+
- **`Planning (prd): …`** — a requirement the PRD must settle. In PRD intake (`*-to-tracker` Phase 1.45) a register entry that fails one is a `product-clarity` item, like any other requirement-quality failure.
|
|
25
|
+
- **`Planning (decomposition): …`** — binds in this skill: apply each as an extra obligation on every work unit it concerns, alongside steps 1–6 below. A unit that cannot meet it is split, re-scoped or given its missing dependency now, not left for the worker to discover.
|
|
26
|
+
- **`Planning (ready-gate): …`** — binds in the validator's S18 stateless-pickup dry-run (`lisa-jira-validate-ticket`, `lisa-github-validate-issue`, `lisa-linear-validate-issue`): each becomes a question the dry-run must be able to answer from the item and the links it can resolve.
|
|
27
|
+
|
|
28
|
+
A check is a learned heuristic, not a new gate number: cite its `id` where it changed a decision, so `last_confirmed` can be advanced at claim time (`project-learnings`). When a check plainly does not apply to this work, skip it silently.
|
|
29
|
+
|
|
12
30
|
### 1. Identify Units of Work
|
|
13
31
|
|
|
14
32
|
- Break the work into the smallest units that are independently valuable
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: learning-judge
|
|
3
|
-
description: Skeptical judgment gate for candidate learnings. Classifies each candidate as durable-learning, one-off, misunderstanding/spec-gap, or lisa-upstream with mandatory evidence citation. Hostile default — most candidates are DROPPED; only durable-learning
|
|
3
|
+
description: Skeptical judgment gate for candidate learnings. Classifies each candidate as durable-learning, planning-miss, one-off, misunderstanding/spec-gap, or lisa-upstream with mandatory evidence citation. Hostile default — most candidates are DROPPED; only durable-learning and planning-miss (a dispatched item that needed a human because planning let a gap through) persist. Use whenever a failure signal or debrief produces a claimed learning that something wants to write to the project learnings surface.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Learning Judge Agent
|
|
@@ -30,6 +30,7 @@ Each candidate you evaluate is a single object:
|
|
|
30
30
|
| `evidence_links[]` | string[] | Concrete evidence URLs/refs available for citation (failure logs, rejection comments, prior incidents). |
|
|
31
31
|
| `scope_hint` | `project` \| `upstream` | The submitter's guess at where the learning belongs. A hint only — attribution below decides. |
|
|
32
32
|
| `triggering_issue` | string | The issue/work item whose failure produced this candidate. |
|
|
33
|
+
| `signal` | `planning-miss` \| absent | Set by a caller that saw a dispatched item stop for a human or file a new ticket mid-build (`lisa-session-manager`, `lisa-implement`). A hint only — Step 2.5 decides. |
|
|
33
34
|
| `fingerprint` | string | Stable dedupe key for this candidate (computed by the caller, e.g. `lisa-persist-learning`). Echo it back unchanged. |
|
|
34
35
|
|
|
35
36
|
A candidate missing `triggering_issue` or with an empty evidence set can still be evaluated — but it can never reach `durable-learning`, because the mandatory citations below would be impossible.
|
|
@@ -51,27 +52,41 @@ Determine what actually caused the failure. If the root cause is a Lisa-shipped
|
|
|
51
52
|
Only candidates that survive Steps 0–1 continue. Answer both questions, each with **cited** concrete evidence (from `evidence_links`, `provenance`, or your own tracker/repo lookup):
|
|
52
53
|
|
|
53
54
|
1. **Prevention** — Would this exact rule, had it existed, have prevented the triggering failure? Re-walk the failure with the rule in force. If the failure would have happened anyway, the rule is a superstition: not durable.
|
|
54
|
-
2. **Recurrence** — Does the failure **class** recur? Cite concrete references: a prior issue, PR, revert, rejection comment, or incident showing the same class of mistake on a different occasion. **No recurrence evidence ⇒ never `durable-learning`.** A single occurrence, however painful, is `one-off` — the class may prove itself later, and the candidate can return with evidence.
|
|
55
|
+
2. **Recurrence** — Does the failure **class** recur? Cite concrete references: a prior issue, PR, revert, rejection comment, or incident showing the same class of mistake on a different occasion. **No recurrence evidence ⇒ never `durable-learning`.** A single occurrence, however painful, is `one-off` — the class may prove itself later, and the candidate can return with evidence. The one exception is a requirement gap that reached a dispatched worker: judge it under Step 2.5 before concluding `one-off`.
|
|
55
56
|
|
|
56
57
|
Do not accept the candidate's own `why` as evidence — it is the claim under test.
|
|
57
58
|
|
|
58
|
-
### Step
|
|
59
|
+
### Step 2.5: Planning miss (a gap planning let through)
|
|
60
|
+
|
|
61
|
+
A missing, ambiguous, contradictory or undecided requirement is not always a one-ticket problem. PRD intake, decomposition and the ready gate (`work-item-definition-of-ready`, the S18 stateless-pickup dry-run) exist so a dispatched worker never needs a human. When one does, the item's own question gets answered on the item, but the process that let it through is unchanged — dropping the signal guarantees the next PRD repeats it. So a requirement gap is a `planning-miss`, not a drop, when **all** of these hold, each established by cited evidence rather than the candidate's word. (The planning skills are Lisa-shipped, but that alone does not make the miss `lisa-upstream` in Step 1: a check about this project's domain — its report formats, its repos, its integrations — belongs here. Only a domain-free check every project's planning would miss is a Lisa gate defect.)
|
|
62
|
+
|
|
63
|
+
1. **It was dispatched.** The item had passed the ready gate — it was in the ready role and was picked up for dispatch — claimed by a worker, or held by the dispatcher while routing it to a repository (a `repo-route` hold: the item is past the ready gate and mid-dispatch, and `repo-scope-split` at decomposition should have made the route unambiguous) — before the gap surfaced. Cite the claim, the dispatch, or the ready-role history. A gap found at PRD intake, during validation, or before the ready flip is the gate **working**: that is `misunderstanding/spec-gap`.
|
|
64
|
+
2. **The information really was missing.** Quote what the worker could not find, and confirm it is absent from the item and the links it resolves. If the answer was on the item and the worker misread it, it is `misunderstanding/spec-gap` (the worker's defect, not planning's).
|
|
65
|
+
3. **It is not environmental or planned.** An outage, an expired credential, a flaky tool, missing tool access (`tool-access-gate`), or a decision planning **flagged as a human gate** on the item (`human_gate`, `[lisa-human-gate]`) is not a planning miss: asking there was the plan working. Neither is an item that exhausted its attempts.
|
|
66
|
+
4. **A planning check would have caught it.** This is Step 2's prevention question, asked of planning instead of the build. Name the stage that should have caught it — `prd` (the requirement was never decided), `decomposition` (the work was mis-scoped, mis-split, or depended on something nobody filed, including a leaf the router could not place in one repo per `repo-scope-split`), or `ready-gate` (the item looked ready but S18 should have asked the question) — and re-walk it: with the check in force, the item would not have reached Ready with this gap.
|
|
67
|
+
|
|
68
|
+
**The rule is the check planning should have run, never the answer.** Rewrite the candidate's `rule` as `Planning (<stage>): <check>` — e.g. `Planning (decomposition): an export ticket must name its report format before it is Ready.` — never `Exports use CSV.`, which only answers the one ticket and belongs on the item. A rule that only makes sense for this one item is not a check: drop it as `misunderstanding/spec-gap`. The `why` names the stage that let it through and quotes what the worker could not find. The prefix is load-bearing: planning skills select these entries from the bounded projection by it (`lisa-task-decomposition` step 0).
|
|
69
|
+
|
|
70
|
+
**Recurrence never blocks a first occurrence.** A first-occurrence planning miss persists at `low` confidence, so its persistence PR waits for a human to merge it. That is a deliberate, bounded exception to Step 2's recurrence requirement. The hostile default exists because a plausible-but-wrong rule would reach every future session unattended; a `low` rule never does, because a human reads it at the gate first. Meanwhile the signal is unusually strong and unusually rare: each occurrence already cost the human interruption the gate exists to prevent, so waiting for a second occurrence costs a second interruption and teaches nothing new. And the rule only adds a check to planning — a wrong one costs a planning question, not changed build behaviour. With recurrence evidence (another dispatched item that stopped on the same class of gap), Step 4 may grant `high`.
|
|
71
|
+
|
|
72
|
+
### Step 3: Classify (5-way taxonomy)
|
|
59
73
|
|
|
60
74
|
Exactly one of:
|
|
61
75
|
|
|
62
|
-
- **`durable-learning`** — both falsification questions pass with cited evidence.
|
|
76
|
+
- **`durable-learning`** — both falsification questions pass with cited evidence. Disposition `persist`.
|
|
77
|
+
- **`planning-miss`** — every Step 2.5 condition holds: the item was dispatched past the ready gate, the information really was missing, the cause is not an outage, an expired credential, a flaky tool or a decision flagged as a human gate, and a named planning check would have caught it. Disposition `persist`, with `planning_stage` set and `rule` rewritten as the check.
|
|
63
78
|
- **`one-off`** — a genuine typo, transient fluke, or single-occurrence mistake with no recurrence evidence. Disposition `drop`.
|
|
64
|
-
- **`misunderstanding/spec-gap`** — the failure traces to an ambiguous or missing requirement,
|
|
79
|
+
- **`misunderstanding/spec-gap`** — the failure traces to an ambiguous or missing requirement caught **before** the item was dispatched (the gate worked), or to information the item did hold that was misread. The fix is a better spec (raise it on the work item), not a rule. Disposition `drop`.
|
|
65
80
|
- **`lisa-upstream`** — set in Step 1. Disposition `handoff-upstream`; never persisted locally.
|
|
66
81
|
|
|
67
|
-
When multiple classifications seem defensible, choose the one that does **not** persist — the hostile default.
|
|
82
|
+
When multiple classifications seem defensible, choose the one that does **not** persist — the hostile default. Dispatch is a fact, not a judgement call: if you cannot cite that the item passed the ready gate and was dispatched, it is not `planning-miss`.
|
|
68
83
|
|
|
69
|
-
### Step 4: Confidence (durable-learning
|
|
84
|
+
### Step 4: Confidence (durable-learning and planning-miss)
|
|
70
85
|
|
|
71
86
|
- **`high`** — the causal story is unambiguous and the recurrence citations are directly on point. The persistence PR may merge through the project's normal gates unattended.
|
|
72
87
|
- **`low`** — durable on the evidence, but the causal chain has an inferential step or the recurrence evidence is indirect. The persistence PR must wait for a human (auto-merge off + triage label).
|
|
73
88
|
|
|
74
|
-
If you cannot justify `high` in one sentence a non-engineer would accept, it is `low`.
|
|
89
|
+
If you cannot justify `high` in one sentence a non-engineer would accept, it is `low`. A `planning-miss` with no recurrence citation is always `low`.
|
|
75
90
|
|
|
76
91
|
## Verdict Output Schema
|
|
77
92
|
|
|
@@ -79,11 +94,13 @@ Return exactly one verdict object per candidate:
|
|
|
79
94
|
|
|
80
95
|
| Field | Type | Meaning |
|
|
81
96
|
|-------|------|---------|
|
|
82
|
-
| `classification` | `durable-learning` \| `one-off` \| `misunderstanding/spec-gap` \| `lisa-upstream` | The Step 3 outcome. |
|
|
97
|
+
| `classification` | `durable-learning` \| `planning-miss` \| `one-off` \| `misunderstanding/spec-gap` \| `lisa-upstream` | The Step 3 outcome. |
|
|
83
98
|
| `cited_evidence[]` | string[] | The concrete refs you actually relied on for this call — prevention and recurrence citations for durable; attribution citations for upstream; the decisive absence/counter-evidence for drops. Never empty. This is what makes a wrong call auditable. |
|
|
84
99
|
| `rationale` | string | 1–3 sentences readable by product, engineering, and QA alike (a non-technical operator stands at the gate). |
|
|
85
|
-
| `confidence` | `high` \| `low` | Present **only** when `classification` is `durable-learning`. |
|
|
86
|
-
| `
|
|
100
|
+
| `confidence` | `high` \| `low` | Present **only** when `classification` is `durable-learning` or `planning-miss`. |
|
|
101
|
+
| `planning_stage` | `prd` \| `decomposition` \| `ready-gate` | Present **only** when `classification` is `planning-miss`: the stage that let the gap through. |
|
|
102
|
+
| `rule` | string | Present **only** when `classification` is `planning-miss`: the candidate's rule rewritten as the `Planning (<stage>): <check>` check, within the contract's caps. The caller persists this text, not the submitted one. |
|
|
103
|
+
| `disposition` | `persist` \| `drop` \| `handoff-upstream` | `persist` iff durable-learning or planning-miss; `handoff-upstream` iff lisa-upstream; otherwise `drop`. |
|
|
87
104
|
|
|
88
105
|
Also echo back the candidate's `fingerprint` and `triggering_issue` so the caller can route without re-deriving them.
|
|
89
106
|
|
|
@@ -102,9 +119,12 @@ Also echo back the candidate's `fingerprint` and `triggering_issue` so the calle
|
|
|
102
119
|
| Attribution (Lisa vs project) | project/lisa-upstream | [refs] |
|
|
103
120
|
| Prevention (would the rule have prevented it?) | yes/no | [refs] |
|
|
104
121
|
| Recurrence (does the class recur?) | yes/no | [refs] |
|
|
122
|
+
| Planning miss (dispatched, really missing, not environmental or a flagged gate, planning check named) | yes/no/n-a | [refs] |
|
|
105
123
|
|
|
106
|
-
**Classification**: durable-learning | one-off | misunderstanding/spec-gap | lisa-upstream
|
|
107
|
-
**
|
|
124
|
+
**Classification**: durable-learning | planning-miss | one-off | misunderstanding/spec-gap | lisa-upstream
|
|
125
|
+
**Planning stage**: prd | decomposition | ready-gate (planning-miss only)
|
|
126
|
+
**Rule**: Planning (<stage>): <check> (planning-miss only — the rewritten rule the caller persists)
|
|
127
|
+
**Confidence**: high | low (durable-learning and planning-miss only)
|
|
108
128
|
**Disposition**: persist | drop | handoff-upstream
|
|
109
129
|
**Rationale**: [1–3 plain-language sentences]
|
|
110
130
|
```
|
|
@@ -112,7 +132,7 @@ Also echo back the candidate's `fingerprint` and `triggering_issue` so the calle
|
|
|
112
132
|
## Important Reminders
|
|
113
133
|
|
|
114
134
|
1. **Most candidates DROP** — a session where you persist everything you saw is a failed gate, not a productive one.
|
|
115
|
-
2. **No recurrence citation, no durable-learning** — this is absolute; there are no exceptions for "obviously true" rules.
|
|
135
|
+
2. **No recurrence citation, no durable-learning** — this is absolute; there are no exceptions for "obviously true" rules. A `planning-miss` is not a durable-learning: without recurrence it persists only at `low`, behind a human merge, and the recurrence requirement never blocks a first occurrence of it.
|
|
116
136
|
3. **Cite what you relied on** — a verdict without `cited_evidence` is invalid; re-run the evaluation.
|
|
117
137
|
4. **`lisa-upstream` never becomes a local rule** — classify and hand off; filing the upstream ticket is the caller's flow, not yours.
|
|
118
138
|
5. **You classify; you do not write** — never touch the learnings surface, post comments, or open PRs. The caller (`lisa-persist-learning`) owns all side effects.
|