@codyswann/lisa 2.259.2 → 2.259.4
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/package.json +1 -1
- 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-git-submit-pr/SKILL.md +3 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-github-build-intake/SKILL.md +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-build-intake/SKILL.md +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-build-intake/SKILL.md +2 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-sync/SKILL.md +9 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-repair-intake/SKILL.md +5 -1
- package/plugins/lisa/agents/learning-judge.md +1 -1
- package/plugins/lisa/skills/lisa-git-submit-pr/SKILL.md +3 -1
- package/plugins/lisa/skills/lisa-github-build-intake/SKILL.md +1 -1
- package/plugins/lisa/skills/lisa-jira-build-intake/SKILL.md +1 -1
- package/plugins/lisa/skills/lisa-linear-build-intake/SKILL.md +2 -2
- package/plugins/lisa/skills/lisa-linear-sync/SKILL.md +9 -0
- package/plugins/lisa/skills/lisa-repair-intake/SKILL.md +5 -1
- package/plugins/lisa-agy/agents/learning-judge.md +1 -1
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/lisa-git-submit-pr/SKILL.md +3 -1
- package/plugins/lisa-agy/skills/lisa-github-build-intake/SKILL.md +1 -1
- package/plugins/lisa-agy/skills/lisa-jira-build-intake/SKILL.md +1 -1
- package/plugins/lisa-agy/skills/lisa-linear-build-intake/SKILL.md +2 -2
- package/plugins/lisa-agy/skills/lisa-linear-sync/SKILL.md +9 -0
- package/plugins/lisa-agy/skills/lisa-repair-intake/SKILL.md +5 -1
- 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-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/agents/learning-judge.agent.md +1 -1
- package/plugins/lisa-copilot/skills/lisa-git-submit-pr/SKILL.md +3 -1
- package/plugins/lisa-copilot/skills/lisa-github-build-intake/SKILL.md +1 -1
- package/plugins/lisa-copilot/skills/lisa-jira-build-intake/SKILL.md +1 -1
- package/plugins/lisa-copilot/skills/lisa-linear-build-intake/SKILL.md +2 -2
- package/plugins/lisa-copilot/skills/lisa-linear-sync/SKILL.md +9 -0
- package/plugins/lisa-copilot/skills/lisa-repair-intake/SKILL.md +5 -1
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/agents/learning-judge.md +1 -1
- package/plugins/lisa-cursor/skills/lisa-git-submit-pr/SKILL.md +3 -1
- package/plugins/lisa-cursor/skills/lisa-github-build-intake/SKILL.md +1 -1
- package/plugins/lisa-cursor/skills/lisa-jira-build-intake/SKILL.md +1 -1
- package/plugins/lisa-cursor/skills/lisa-linear-build-intake/SKILL.md +2 -2
- package/plugins/lisa-cursor/skills/lisa-linear-sync/SKILL.md +9 -0
- package/plugins/lisa-cursor/skills/lisa-repair-intake/SKILL.md +5 -1
- 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-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-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-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-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-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-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-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/src/base/agents/learning-judge.md +1 -1
- package/plugins/src/base/skills/lisa-git-submit-pr/SKILL.md +3 -1
- package/plugins/src/base/skills/lisa-github-build-intake/SKILL.md +1 -1
- package/plugins/src/base/skills/lisa-jira-build-intake/SKILL.md +1 -1
- package/plugins/src/base/skills/lisa-linear-build-intake/SKILL.md +2 -2
- package/plugins/src/base/skills/lisa-linear-sync/SKILL.md +9 -0
- package/plugins/src/base/skills/lisa-repair-intake/SKILL.md +5 -1
package/package.json
CHANGED
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
"form-data": ">=4.0.6"
|
|
103
103
|
},
|
|
104
104
|
"name": "@codyswann/lisa",
|
|
105
|
-
"version": "2.259.
|
|
105
|
+
"version": "2.259.4",
|
|
106
106
|
"description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
|
|
107
107
|
"main": "dist/index.js",
|
|
108
108
|
"exports": {
|
|
@@ -51,7 +51,9 @@ Add provider-appropriate linkage to the PR title and/or body without changing th
|
|
|
51
51
|
- For cross-repo issue refs, use the fully qualified form, for example `Closes CodySwannGT/lisa#614` or `Refs CodySwannGT/lisa#614`.
|
|
52
52
|
- **Linear**:
|
|
53
53
|
- Ensure the Linear issue identifier appears in the branch name when the branch is created upstream by `lisa-implement`.
|
|
54
|
-
- Include the identifier in the PR title or body, for example `Linear: ENG-123`, so Linear's GitHub integration can attach the PR.
|
|
54
|
+
- Include the identifier as a **non-closing** attach token in the PR title or body, for example `Linear: ENG-123` or `Refs ENG-123`, so Linear's GitHub integration can attach the PR without completing the Issue.
|
|
55
|
+
- **Do not** emit a Linear magic word (`Closes`/`Fixes`/`Resolves ENG-123`) in the PR title, body, or commit message unless the target branch is the terminal/production branch — the repository default branch or the configured production branch from `.lisa.config.json` `deploy.branches.production` (resolved via `config-resolution`). Unlike GitHub, whose `Closes` auto-close is scoped to the default branch, Linear's integration completes a linked Issue on merge to **any branch**, so a magic word on a non-terminal env merge (for example into `dev` or `staging`) auto-closes the Issue prematurely and front-runs the env-keyed `status:*` label ladder. This is the `leaf-only-lifecycle` "Terminal native closure" invariant (native closure only at the production terminal `done`) — cite it, do not restate.
|
|
56
|
+
- On a non-terminal env branch, use only the non-closing attach form and strip/neutralize any magic word copied from a ticket title or commit message. Branch-name linkage alone can still auto-complete the Issue where a Linear team enables "complete on any linked-PR merge" — behavior we cannot suppress from our side — so the post-merge reconciliation in `lisa-linear-sync` is the mandatory backstop, not an optional cleanup.
|
|
55
57
|
- **JIRA**:
|
|
56
58
|
- Ensure the JIRA issue key appears in the branch name when the branch is created upstream by `lisa-implement`.
|
|
57
59
|
- Include the key in the PR title or body, for example `JIRA: PROJ-456`, so the GitHub-JIRA integration can attach the PR.
|
|
@@ -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**:
|
|
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**:
|
|
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**:
|
|
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
|
|
@@ -283,7 +283,7 @@ If the lifecycle run returned Success:
|
|
|
283
283
|
- If `linear.labels.build.done` is an object, only the production/final environment value is terminal (default: `status:done`). Intermediate env values such as `status:on-dev` and `status:on-stg` are not terminal and must keep the native Issue open.
|
|
284
284
|
- If the project uses a different final environment name, resolve it from the configured deployment topology; if ambiguous, record an Error and do not change the native state.
|
|
285
285
|
4. Update labels via `lisa-linear-access operation: save-issue`: remove `$CLAIMED` (or `$REVIEW` if `lisa-linear-evidence` already moved it forward), add `$DONE`.
|
|
286
|
-
5. If `$DONE` is terminal, move the native Linear Issue state to the configured Done / Completed state. Resolve that state from project configuration if present; otherwise inspect the team workflow for a terminal state with `state.type = "completed"` and a name such as `Done` or `Completed`. If no terminal state can be resolved, record an Error and leave the labels as the source of truth — do not invent a state name.
|
|
286
|
+
5. If `$DONE` is terminal, move the native Linear Issue state to the configured Done / Completed state. Resolve that state from project configuration if present; otherwise inspect the team workflow for a terminal state with `state.type = "completed"` and a name such as `Done` or `Completed`. If no terminal state can be resolved, record an Error and leave the labels as the source of truth — do not invent a state name. Conversely, if `$DONE` is an intermediate env yet Linear already natively completed the Issue (a magic-word / branch-linkage front-run — Linear auto-completes on merge to **any branch**, per the asymmetry documented in `git-submit-pr`), reconcile it back to active via `lisa-linear-sync` Phase 4b so the native state mirrors the non-terminal env instead of a premature closure.
|
|
287
287
|
6. Post a `[claude-build-intake]` comment: `"Build complete. PR <URL> merged. Transitioned to $DONE."` Include whether native closure was applied, already satisfied, skipped for an intermediate env, or unavailable for setup reasons.
|
|
288
288
|
|
|
289
289
|
For any non-Success outcome, do NOT transition. The Issue sits where the lifecycle left it — humans take it from there.
|
|
@@ -92,6 +92,15 @@ Verify exactly one `status:*` label remains after the update — having two simu
|
|
|
92
92
|
|
|
93
93
|
Without `--update-label`, this skill posts the comment only and does NOT touch labels.
|
|
94
94
|
|
|
95
|
+
## Phase 4b — Reconcile Native Auto-Close (Linear-specific)
|
|
96
|
+
|
|
97
|
+
Linear's GitHub integration completes a linked Issue on merge to **any branch** — unlike GitHub's default-branch-scoped `Closes` auto-close — so a magic word (`Closes`/`Fixes`/`Resolves ENG-123`) or branch-name linkage can natively move the Issue to a Done/Completed workflow `state` at a **non-terminal** env merge, front-running the env-keyed `status:*` label ladder. `git-submit-pr` prevents the magic-word case; this phase is the required post-merge repair for the residual (branch-linkage) case we cannot suppress server-side. Run it on a `pr-merged` sync whose resolved env is **intermediate** (below the production terminal `done`):
|
|
98
|
+
|
|
99
|
+
1. Resolve the merged PR's base branch to its env via `.lisa.config.json` `deploy.branches` (`config-resolution`). If it maps to the production/terminal `done`, this phase is a **no-op** — native completion is correct there.
|
|
100
|
+
2. **Uniform / single-environment no-op.** When the project's env-keyed `done` map is uniform — every environment resolves to the same `status:done`, as in this repo (`production: main` only) and TunnlAI/frontend — dev-merge == terminal, so native completion is correct. Do nothing. Only a **non-uniform** env→`done` map (distinct `status:on-dev`/`status:on-stg`/`status:done` rungs) can desync.
|
|
101
|
+
3. Otherwise (non-uniform map, resolved env intermediate): re-read the Issue's native workflow `state`. If Linear natively moved it into a Done/Completed category while the derived `status:*` label is a lower env, **re-open** the native `state` back to the active/in-progress category (via `lisa-linear-access operation: save-issue`) so it mirrors the true env stage, and post a short `[lisa-linear-sync]` reconciliation comment. This applies the `leaf-only-lifecycle` "Terminal native closure" rule — native closure fires **only** at the production terminal `done` — as a *repair* of Linear front-running it. Cite the rule by slug; do not restate it.
|
|
102
|
+
4. **Safe default.** If the true terminal cannot be resolved (ambiguous env or unresolvable `done` map), do not change the native `state` — post a `[lisa-linear-sync]` reconciliation-suggestion comment and leave it untouched, mirroring the Phase 5 safe default.
|
|
103
|
+
|
|
95
104
|
## Phase 5 — Parent Status Rollup (`--rollup`)
|
|
96
105
|
|
|
97
106
|
When the caller passes `--rollup`, this skill **derives a parent/container's `status:*` label from the roll-up of its children** instead of acting on a leaf. A **Project** (the Epic equivalent) rolls up from its Issues; an **Issue** rolls up from its sub-Issues. This implements the Linear child-issue-status arm of the **Parent status rollup (the state machine)** section of the `leaf-only-lifecycle` rule — cite that rule, do not restate the policy.
|
|
@@ -38,7 +38,11 @@ close-out** roles and moves work *unstuck* or *fully closed*:
|
|
|
38
38
|
one missed by dependency-only re-checks: nothing else is blocking it, so re-running the same gate
|
|
39
39
|
against its current content is the only way to know it is now passable.
|
|
40
40
|
- **Terminal-open drift** — an item already carrying its true terminal lifecycle role (for
|
|
41
|
-
example GitHub `status:done`) but still open/active in the provider's native state.
|
|
41
|
+
example GitHub `status:done`) but still open/active in the provider's native state. The inverse
|
|
42
|
+
also drifts on Linear: a leaf whose native `state` was auto-completed by a magic-word / branch-linkage
|
|
43
|
+
merge into a **non-terminal** env (Linear completes on merge to any branch, unlike GitHub's
|
|
44
|
+
default-branch-scoped close) while its derived `status:*` label is still intermediate — reconcile
|
|
45
|
+
it back to active via `lisa-linear-sync` Phase 4b per `leaf-only-lifecycle`.
|
|
42
46
|
- **Rollup drift** — a parent/container item (Epic, Story, PRD, Linear Project, or equivalent)
|
|
43
47
|
whose own lifecycle state does not match the roll-up of its children's states per
|
|
44
48
|
`leaf-only-lifecycle`. This covers the *completed* case (all children terminal → close the parent
|
|
@@ -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
|
|
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
|
|
|
@@ -51,7 +51,9 @@ Add provider-appropriate linkage to the PR title and/or body without changing th
|
|
|
51
51
|
- For cross-repo issue refs, use the fully qualified form, for example `Closes CodySwannGT/lisa#614` or `Refs CodySwannGT/lisa#614`.
|
|
52
52
|
- **Linear**:
|
|
53
53
|
- Ensure the Linear issue identifier appears in the branch name when the branch is created upstream by `lisa-implement`.
|
|
54
|
-
- Include the identifier in the PR title or body, for example `Linear: ENG-123`, so Linear's GitHub integration can attach the PR.
|
|
54
|
+
- Include the identifier as a **non-closing** attach token in the PR title or body, for example `Linear: ENG-123` or `Refs ENG-123`, so Linear's GitHub integration can attach the PR without completing the Issue.
|
|
55
|
+
- **Do not** emit a Linear magic word (`Closes`/`Fixes`/`Resolves ENG-123`) in the PR title, body, or commit message unless the target branch is the terminal/production branch — the repository default branch or the configured production branch from `.lisa.config.json` `deploy.branches.production` (resolved via `config-resolution`). Unlike GitHub, whose `Closes` auto-close is scoped to the default branch, Linear's integration completes a linked Issue on merge to **any branch**, so a magic word on a non-terminal env merge (for example into `dev` or `staging`) auto-closes the Issue prematurely and front-runs the env-keyed `status:*` label ladder. This is the `leaf-only-lifecycle` "Terminal native closure" invariant (native closure only at the production terminal `done`) — cite it, do not restate.
|
|
56
|
+
- On a non-terminal env branch, use only the non-closing attach form and strip/neutralize any magic word copied from a ticket title or commit message. Branch-name linkage alone can still auto-complete the Issue where a Linear team enables "complete on any linked-PR merge" — behavior we cannot suppress from our side — so the post-merge reconciliation in `lisa-linear-sync` is the mandatory backstop, not an optional cleanup.
|
|
55
57
|
- **JIRA**:
|
|
56
58
|
- Ensure the JIRA issue key appears in the branch name when the branch is created upstream by `lisa-implement`.
|
|
57
59
|
- Include the key in the PR title or body, for example `JIRA: PROJ-456`, so the GitHub-JIRA integration can attach the PR.
|
|
@@ -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**:
|
|
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**:
|
|
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**:
|
|
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
|
|
@@ -283,7 +283,7 @@ If the lifecycle run returned Success:
|
|
|
283
283
|
- If `linear.labels.build.done` is an object, only the production/final environment value is terminal (default: `status:done`). Intermediate env values such as `status:on-dev` and `status:on-stg` are not terminal and must keep the native Issue open.
|
|
284
284
|
- If the project uses a different final environment name, resolve it from the configured deployment topology; if ambiguous, record an Error and do not change the native state.
|
|
285
285
|
4. Update labels via `lisa-linear-access operation: save-issue`: remove `$CLAIMED` (or `$REVIEW` if `lisa-linear-evidence` already moved it forward), add `$DONE`.
|
|
286
|
-
5. If `$DONE` is terminal, move the native Linear Issue state to the configured Done / Completed state. Resolve that state from project configuration if present; otherwise inspect the team workflow for a terminal state with `state.type = "completed"` and a name such as `Done` or `Completed`. If no terminal state can be resolved, record an Error and leave the labels as the source of truth — do not invent a state name.
|
|
286
|
+
5. If `$DONE` is terminal, move the native Linear Issue state to the configured Done / Completed state. Resolve that state from project configuration if present; otherwise inspect the team workflow for a terminal state with `state.type = "completed"` and a name such as `Done` or `Completed`. If no terminal state can be resolved, record an Error and leave the labels as the source of truth — do not invent a state name. Conversely, if `$DONE` is an intermediate env yet Linear already natively completed the Issue (a magic-word / branch-linkage front-run — Linear auto-completes on merge to **any branch**, per the asymmetry documented in `git-submit-pr`), reconcile it back to active via `lisa-linear-sync` Phase 4b so the native state mirrors the non-terminal env instead of a premature closure.
|
|
287
287
|
6. Post a `[claude-build-intake]` comment: `"Build complete. PR <URL> merged. Transitioned to $DONE."` Include whether native closure was applied, already satisfied, skipped for an intermediate env, or unavailable for setup reasons.
|
|
288
288
|
|
|
289
289
|
For any non-Success outcome, do NOT transition. The Issue sits where the lifecycle left it — humans take it from there.
|
|
@@ -92,6 +92,15 @@ Verify exactly one `status:*` label remains after the update — having two simu
|
|
|
92
92
|
|
|
93
93
|
Without `--update-label`, this skill posts the comment only and does NOT touch labels.
|
|
94
94
|
|
|
95
|
+
## Phase 4b — Reconcile Native Auto-Close (Linear-specific)
|
|
96
|
+
|
|
97
|
+
Linear's GitHub integration completes a linked Issue on merge to **any branch** — unlike GitHub's default-branch-scoped `Closes` auto-close — so a magic word (`Closes`/`Fixes`/`Resolves ENG-123`) or branch-name linkage can natively move the Issue to a Done/Completed workflow `state` at a **non-terminal** env merge, front-running the env-keyed `status:*` label ladder. `git-submit-pr` prevents the magic-word case; this phase is the required post-merge repair for the residual (branch-linkage) case we cannot suppress server-side. Run it on a `pr-merged` sync whose resolved env is **intermediate** (below the production terminal `done`):
|
|
98
|
+
|
|
99
|
+
1. Resolve the merged PR's base branch to its env via `.lisa.config.json` `deploy.branches` (`config-resolution`). If it maps to the production/terminal `done`, this phase is a **no-op** — native completion is correct there.
|
|
100
|
+
2. **Uniform / single-environment no-op.** When the project's env-keyed `done` map is uniform — every environment resolves to the same `status:done`, as in this repo (`production: main` only) and TunnlAI/frontend — dev-merge == terminal, so native completion is correct. Do nothing. Only a **non-uniform** env→`done` map (distinct `status:on-dev`/`status:on-stg`/`status:done` rungs) can desync.
|
|
101
|
+
3. Otherwise (non-uniform map, resolved env intermediate): re-read the Issue's native workflow `state`. If Linear natively moved it into a Done/Completed category while the derived `status:*` label is a lower env, **re-open** the native `state` back to the active/in-progress category (via `lisa-linear-access operation: save-issue`) so it mirrors the true env stage, and post a short `[lisa-linear-sync]` reconciliation comment. This applies the `leaf-only-lifecycle` "Terminal native closure" rule — native closure fires **only** at the production terminal `done` — as a *repair* of Linear front-running it. Cite the rule by slug; do not restate it.
|
|
102
|
+
4. **Safe default.** If the true terminal cannot be resolved (ambiguous env or unresolvable `done` map), do not change the native `state` — post a `[lisa-linear-sync]` reconciliation-suggestion comment and leave it untouched, mirroring the Phase 5 safe default.
|
|
103
|
+
|
|
95
104
|
## Phase 5 — Parent Status Rollup (`--rollup`)
|
|
96
105
|
|
|
97
106
|
When the caller passes `--rollup`, this skill **derives a parent/container's `status:*` label from the roll-up of its children** instead of acting on a leaf. A **Project** (the Epic equivalent) rolls up from its Issues; an **Issue** rolls up from its sub-Issues. This implements the Linear child-issue-status arm of the **Parent status rollup (the state machine)** section of the `leaf-only-lifecycle` rule — cite that rule, do not restate the policy.
|
|
@@ -38,7 +38,11 @@ close-out** roles and moves work *unstuck* or *fully closed*:
|
|
|
38
38
|
one missed by dependency-only re-checks: nothing else is blocking it, so re-running the same gate
|
|
39
39
|
against its current content is the only way to know it is now passable.
|
|
40
40
|
- **Terminal-open drift** — an item already carrying its true terminal lifecycle role (for
|
|
41
|
-
example GitHub `status:done`) but still open/active in the provider's native state.
|
|
41
|
+
example GitHub `status:done`) but still open/active in the provider's native state. The inverse
|
|
42
|
+
also drifts on Linear: a leaf whose native `state` was auto-completed by a magic-word / branch-linkage
|
|
43
|
+
merge into a **non-terminal** env (Linear completes on merge to any branch, unlike GitHub's
|
|
44
|
+
default-branch-scoped close) while its derived `status:*` label is still intermediate — reconcile
|
|
45
|
+
it back to active via `lisa-linear-sync` Phase 4b per `leaf-only-lifecycle`.
|
|
42
46
|
- **Rollup drift** — a parent/container item (Epic, Story, PRD, Linear Project, or equivalent)
|
|
43
47
|
whose own lifecycle state does not match the roll-up of its children's states per
|
|
44
48
|
`leaf-only-lifecycle`. This covers the *completed* case (all children terminal → close the parent
|
|
@@ -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
|
|
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
|
|
|
@@ -51,7 +51,9 @@ Add provider-appropriate linkage to the PR title and/or body without changing th
|
|
|
51
51
|
- For cross-repo issue refs, use the fully qualified form, for example `Closes CodySwannGT/lisa#614` or `Refs CodySwannGT/lisa#614`.
|
|
52
52
|
- **Linear**:
|
|
53
53
|
- Ensure the Linear issue identifier appears in the branch name when the branch is created upstream by `lisa-implement`.
|
|
54
|
-
- Include the identifier in the PR title or body, for example `Linear: ENG-123`, so Linear's GitHub integration can attach the PR.
|
|
54
|
+
- Include the identifier as a **non-closing** attach token in the PR title or body, for example `Linear: ENG-123` or `Refs ENG-123`, so Linear's GitHub integration can attach the PR without completing the Issue.
|
|
55
|
+
- **Do not** emit a Linear magic word (`Closes`/`Fixes`/`Resolves ENG-123`) in the PR title, body, or commit message unless the target branch is the terminal/production branch — the repository default branch or the configured production branch from `.lisa.config.json` `deploy.branches.production` (resolved via `config-resolution`). Unlike GitHub, whose `Closes` auto-close is scoped to the default branch, Linear's integration completes a linked Issue on merge to **any branch**, so a magic word on a non-terminal env merge (for example into `dev` or `staging`) auto-closes the Issue prematurely and front-runs the env-keyed `status:*` label ladder. This is the `leaf-only-lifecycle` "Terminal native closure" invariant (native closure only at the production terminal `done`) — cite it, do not restate.
|
|
56
|
+
- On a non-terminal env branch, use only the non-closing attach form and strip/neutralize any magic word copied from a ticket title or commit message. Branch-name linkage alone can still auto-complete the Issue where a Linear team enables "complete on any linked-PR merge" — behavior we cannot suppress from our side — so the post-merge reconciliation in `lisa-linear-sync` is the mandatory backstop, not an optional cleanup.
|
|
55
57
|
- **JIRA**:
|
|
56
58
|
- Ensure the JIRA issue key appears in the branch name when the branch is created upstream by `lisa-implement`.
|
|
57
59
|
- Include the key in the PR title or body, for example `JIRA: PROJ-456`, so the GitHub-JIRA integration can attach the PR.
|
|
@@ -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**:
|
|
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**:
|
|
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**:
|
|
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
|
|
@@ -283,7 +283,7 @@ If the lifecycle run returned Success:
|
|
|
283
283
|
- If `linear.labels.build.done` is an object, only the production/final environment value is terminal (default: `status:done`). Intermediate env values such as `status:on-dev` and `status:on-stg` are not terminal and must keep the native Issue open.
|
|
284
284
|
- If the project uses a different final environment name, resolve it from the configured deployment topology; if ambiguous, record an Error and do not change the native state.
|
|
285
285
|
4. Update labels via `lisa-linear-access operation: save-issue`: remove `$CLAIMED` (or `$REVIEW` if `lisa-linear-evidence` already moved it forward), add `$DONE`.
|
|
286
|
-
5. If `$DONE` is terminal, move the native Linear Issue state to the configured Done / Completed state. Resolve that state from project configuration if present; otherwise inspect the team workflow for a terminal state with `state.type = "completed"` and a name such as `Done` or `Completed`. If no terminal state can be resolved, record an Error and leave the labels as the source of truth — do not invent a state name.
|
|
286
|
+
5. If `$DONE` is terminal, move the native Linear Issue state to the configured Done / Completed state. Resolve that state from project configuration if present; otherwise inspect the team workflow for a terminal state with `state.type = "completed"` and a name such as `Done` or `Completed`. If no terminal state can be resolved, record an Error and leave the labels as the source of truth — do not invent a state name. Conversely, if `$DONE` is an intermediate env yet Linear already natively completed the Issue (a magic-word / branch-linkage front-run — Linear auto-completes on merge to **any branch**, per the asymmetry documented in `git-submit-pr`), reconcile it back to active via `lisa-linear-sync` Phase 4b so the native state mirrors the non-terminal env instead of a premature closure.
|
|
287
287
|
6. Post a `[claude-build-intake]` comment: `"Build complete. PR <URL> merged. Transitioned to $DONE."` Include whether native closure was applied, already satisfied, skipped for an intermediate env, or unavailable for setup reasons.
|
|
288
288
|
|
|
289
289
|
For any non-Success outcome, do NOT transition. The Issue sits where the lifecycle left it — humans take it from there.
|
|
@@ -92,6 +92,15 @@ Verify exactly one `status:*` label remains after the update — having two simu
|
|
|
92
92
|
|
|
93
93
|
Without `--update-label`, this skill posts the comment only and does NOT touch labels.
|
|
94
94
|
|
|
95
|
+
## Phase 4b — Reconcile Native Auto-Close (Linear-specific)
|
|
96
|
+
|
|
97
|
+
Linear's GitHub integration completes a linked Issue on merge to **any branch** — unlike GitHub's default-branch-scoped `Closes` auto-close — so a magic word (`Closes`/`Fixes`/`Resolves ENG-123`) or branch-name linkage can natively move the Issue to a Done/Completed workflow `state` at a **non-terminal** env merge, front-running the env-keyed `status:*` label ladder. `git-submit-pr` prevents the magic-word case; this phase is the required post-merge repair for the residual (branch-linkage) case we cannot suppress server-side. Run it on a `pr-merged` sync whose resolved env is **intermediate** (below the production terminal `done`):
|
|
98
|
+
|
|
99
|
+
1. Resolve the merged PR's base branch to its env via `.lisa.config.json` `deploy.branches` (`config-resolution`). If it maps to the production/terminal `done`, this phase is a **no-op** — native completion is correct there.
|
|
100
|
+
2. **Uniform / single-environment no-op.** When the project's env-keyed `done` map is uniform — every environment resolves to the same `status:done`, as in this repo (`production: main` only) and TunnlAI/frontend — dev-merge == terminal, so native completion is correct. Do nothing. Only a **non-uniform** env→`done` map (distinct `status:on-dev`/`status:on-stg`/`status:done` rungs) can desync.
|
|
101
|
+
3. Otherwise (non-uniform map, resolved env intermediate): re-read the Issue's native workflow `state`. If Linear natively moved it into a Done/Completed category while the derived `status:*` label is a lower env, **re-open** the native `state` back to the active/in-progress category (via `lisa-linear-access operation: save-issue`) so it mirrors the true env stage, and post a short `[lisa-linear-sync]` reconciliation comment. This applies the `leaf-only-lifecycle` "Terminal native closure" rule — native closure fires **only** at the production terminal `done` — as a *repair* of Linear front-running it. Cite the rule by slug; do not restate it.
|
|
102
|
+
4. **Safe default.** If the true terminal cannot be resolved (ambiguous env or unresolvable `done` map), do not change the native `state` — post a `[lisa-linear-sync]` reconciliation-suggestion comment and leave it untouched, mirroring the Phase 5 safe default.
|
|
103
|
+
|
|
95
104
|
## Phase 5 — Parent Status Rollup (`--rollup`)
|
|
96
105
|
|
|
97
106
|
When the caller passes `--rollup`, this skill **derives a parent/container's `status:*` label from the roll-up of its children** instead of acting on a leaf. A **Project** (the Epic equivalent) rolls up from its Issues; an **Issue** rolls up from its sub-Issues. This implements the Linear child-issue-status arm of the **Parent status rollup (the state machine)** section of the `leaf-only-lifecycle` rule — cite that rule, do not restate the policy.
|
|
@@ -38,7 +38,11 @@ close-out** roles and moves work *unstuck* or *fully closed*:
|
|
|
38
38
|
one missed by dependency-only re-checks: nothing else is blocking it, so re-running the same gate
|
|
39
39
|
against its current content is the only way to know it is now passable.
|
|
40
40
|
- **Terminal-open drift** — an item already carrying its true terminal lifecycle role (for
|
|
41
|
-
example GitHub `status:done`) but still open/active in the provider's native state.
|
|
41
|
+
example GitHub `status:done`) but still open/active in the provider's native state. The inverse
|
|
42
|
+
also drifts on Linear: a leaf whose native `state` was auto-completed by a magic-word / branch-linkage
|
|
43
|
+
merge into a **non-terminal** env (Linear completes on merge to any branch, unlike GitHub's
|
|
44
|
+
default-branch-scoped close) while its derived `status:*` label is still intermediate — reconcile
|
|
45
|
+
it back to active via `lisa-linear-sync` Phase 4b per `leaf-only-lifecycle`.
|
|
42
46
|
- **Rollup drift** — a parent/container item (Epic, Story, PRD, Linear Project, or equivalent)
|
|
43
47
|
whose own lifecycle state does not match the roll-up of its children's states per
|
|
44
48
|
`leaf-only-lifecycle`. This covers the *completed* case (all children terminal → close the parent
|
|
@@ -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
|
|
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
|
|
|
@@ -51,7 +51,9 @@ Add provider-appropriate linkage to the PR title and/or body without changing th
|
|
|
51
51
|
- For cross-repo issue refs, use the fully qualified form, for example `Closes CodySwannGT/lisa#614` or `Refs CodySwannGT/lisa#614`.
|
|
52
52
|
- **Linear**:
|
|
53
53
|
- Ensure the Linear issue identifier appears in the branch name when the branch is created upstream by `lisa-implement`.
|
|
54
|
-
- Include the identifier in the PR title or body, for example `Linear: ENG-123`, so Linear's GitHub integration can attach the PR.
|
|
54
|
+
- Include the identifier as a **non-closing** attach token in the PR title or body, for example `Linear: ENG-123` or `Refs ENG-123`, so Linear's GitHub integration can attach the PR without completing the Issue.
|
|
55
|
+
- **Do not** emit a Linear magic word (`Closes`/`Fixes`/`Resolves ENG-123`) in the PR title, body, or commit message unless the target branch is the terminal/production branch — the repository default branch or the configured production branch from `.lisa.config.json` `deploy.branches.production` (resolved via `config-resolution`). Unlike GitHub, whose `Closes` auto-close is scoped to the default branch, Linear's integration completes a linked Issue on merge to **any branch**, so a magic word on a non-terminal env merge (for example into `dev` or `staging`) auto-closes the Issue prematurely and front-runs the env-keyed `status:*` label ladder. This is the `leaf-only-lifecycle` "Terminal native closure" invariant (native closure only at the production terminal `done`) — cite it, do not restate.
|
|
56
|
+
- On a non-terminal env branch, use only the non-closing attach form and strip/neutralize any magic word copied from a ticket title or commit message. Branch-name linkage alone can still auto-complete the Issue where a Linear team enables "complete on any linked-PR merge" — behavior we cannot suppress from our side — so the post-merge reconciliation in `lisa-linear-sync` is the mandatory backstop, not an optional cleanup.
|
|
55
57
|
- **JIRA**:
|
|
56
58
|
- Ensure the JIRA issue key appears in the branch name when the branch is created upstream by `lisa-implement`.
|
|
57
59
|
- Include the key in the PR title or body, for example `JIRA: PROJ-456`, so the GitHub-JIRA integration can attach the PR.
|
|
@@ -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**:
|
|
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**:
|
|
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**:
|
|
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
|
|
@@ -283,7 +283,7 @@ If the lifecycle run returned Success:
|
|
|
283
283
|
- If `linear.labels.build.done` is an object, only the production/final environment value is terminal (default: `status:done`). Intermediate env values such as `status:on-dev` and `status:on-stg` are not terminal and must keep the native Issue open.
|
|
284
284
|
- If the project uses a different final environment name, resolve it from the configured deployment topology; if ambiguous, record an Error and do not change the native state.
|
|
285
285
|
4. Update labels via `lisa-linear-access operation: save-issue`: remove `$CLAIMED` (or `$REVIEW` if `lisa-linear-evidence` already moved it forward), add `$DONE`.
|
|
286
|
-
5. If `$DONE` is terminal, move the native Linear Issue state to the configured Done / Completed state. Resolve that state from project configuration if present; otherwise inspect the team workflow for a terminal state with `state.type = "completed"` and a name such as `Done` or `Completed`. If no terminal state can be resolved, record an Error and leave the labels as the source of truth — do not invent a state name.
|
|
286
|
+
5. If `$DONE` is terminal, move the native Linear Issue state to the configured Done / Completed state. Resolve that state from project configuration if present; otherwise inspect the team workflow for a terminal state with `state.type = "completed"` and a name such as `Done` or `Completed`. If no terminal state can be resolved, record an Error and leave the labels as the source of truth — do not invent a state name. Conversely, if `$DONE` is an intermediate env yet Linear already natively completed the Issue (a magic-word / branch-linkage front-run — Linear auto-completes on merge to **any branch**, per the asymmetry documented in `git-submit-pr`), reconcile it back to active via `lisa-linear-sync` Phase 4b so the native state mirrors the non-terminal env instead of a premature closure.
|
|
287
287
|
6. Post a `[claude-build-intake]` comment: `"Build complete. PR <URL> merged. Transitioned to $DONE."` Include whether native closure was applied, already satisfied, skipped for an intermediate env, or unavailable for setup reasons.
|
|
288
288
|
|
|
289
289
|
For any non-Success outcome, do NOT transition. The Issue sits where the lifecycle left it — humans take it from there.
|
|
@@ -92,6 +92,15 @@ Verify exactly one `status:*` label remains after the update — having two simu
|
|
|
92
92
|
|
|
93
93
|
Without `--update-label`, this skill posts the comment only and does NOT touch labels.
|
|
94
94
|
|
|
95
|
+
## Phase 4b — Reconcile Native Auto-Close (Linear-specific)
|
|
96
|
+
|
|
97
|
+
Linear's GitHub integration completes a linked Issue on merge to **any branch** — unlike GitHub's default-branch-scoped `Closes` auto-close — so a magic word (`Closes`/`Fixes`/`Resolves ENG-123`) or branch-name linkage can natively move the Issue to a Done/Completed workflow `state` at a **non-terminal** env merge, front-running the env-keyed `status:*` label ladder. `git-submit-pr` prevents the magic-word case; this phase is the required post-merge repair for the residual (branch-linkage) case we cannot suppress server-side. Run it on a `pr-merged` sync whose resolved env is **intermediate** (below the production terminal `done`):
|
|
98
|
+
|
|
99
|
+
1. Resolve the merged PR's base branch to its env via `.lisa.config.json` `deploy.branches` (`config-resolution`). If it maps to the production/terminal `done`, this phase is a **no-op** — native completion is correct there.
|
|
100
|
+
2. **Uniform / single-environment no-op.** When the project's env-keyed `done` map is uniform — every environment resolves to the same `status:done`, as in this repo (`production: main` only) and TunnlAI/frontend — dev-merge == terminal, so native completion is correct. Do nothing. Only a **non-uniform** env→`done` map (distinct `status:on-dev`/`status:on-stg`/`status:done` rungs) can desync.
|
|
101
|
+
3. Otherwise (non-uniform map, resolved env intermediate): re-read the Issue's native workflow `state`. If Linear natively moved it into a Done/Completed category while the derived `status:*` label is a lower env, **re-open** the native `state` back to the active/in-progress category (via `lisa-linear-access operation: save-issue`) so it mirrors the true env stage, and post a short `[lisa-linear-sync]` reconciliation comment. This applies the `leaf-only-lifecycle` "Terminal native closure" rule — native closure fires **only** at the production terminal `done` — as a *repair* of Linear front-running it. Cite the rule by slug; do not restate it.
|
|
102
|
+
4. **Safe default.** If the true terminal cannot be resolved (ambiguous env or unresolvable `done` map), do not change the native `state` — post a `[lisa-linear-sync]` reconciliation-suggestion comment and leave it untouched, mirroring the Phase 5 safe default.
|
|
103
|
+
|
|
95
104
|
## Phase 5 — Parent Status Rollup (`--rollup`)
|
|
96
105
|
|
|
97
106
|
When the caller passes `--rollup`, this skill **derives a parent/container's `status:*` label from the roll-up of its children** instead of acting on a leaf. A **Project** (the Epic equivalent) rolls up from its Issues; an **Issue** rolls up from its sub-Issues. This implements the Linear child-issue-status arm of the **Parent status rollup (the state machine)** section of the `leaf-only-lifecycle` rule — cite that rule, do not restate the policy.
|
|
@@ -38,7 +38,11 @@ close-out** roles and moves work *unstuck* or *fully closed*:
|
|
|
38
38
|
one missed by dependency-only re-checks: nothing else is blocking it, so re-running the same gate
|
|
39
39
|
against its current content is the only way to know it is now passable.
|
|
40
40
|
- **Terminal-open drift** — an item already carrying its true terminal lifecycle role (for
|
|
41
|
-
example GitHub `status:done`) but still open/active in the provider's native state.
|
|
41
|
+
example GitHub `status:done`) but still open/active in the provider's native state. The inverse
|
|
42
|
+
also drifts on Linear: a leaf whose native `state` was auto-completed by a magic-word / branch-linkage
|
|
43
|
+
merge into a **non-terminal** env (Linear completes on merge to any branch, unlike GitHub's
|
|
44
|
+
default-branch-scoped close) while its derived `status:*` label is still intermediate — reconcile
|
|
45
|
+
it back to active via `lisa-linear-sync` Phase 4b per `leaf-only-lifecycle`.
|
|
42
46
|
- **Rollup drift** — a parent/container item (Epic, Story, PRD, Linear Project, or equivalent)
|
|
43
47
|
whose own lifecycle state does not match the roll-up of its children's states per
|
|
44
48
|
`leaf-only-lifecycle`. This covers the *completed* case (all children terminal → close the parent
|
|
@@ -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
|
|
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
|
|
|
@@ -51,7 +51,9 @@ Add provider-appropriate linkage to the PR title and/or body without changing th
|
|
|
51
51
|
- For cross-repo issue refs, use the fully qualified form, for example `Closes CodySwannGT/lisa#614` or `Refs CodySwannGT/lisa#614`.
|
|
52
52
|
- **Linear**:
|
|
53
53
|
- Ensure the Linear issue identifier appears in the branch name when the branch is created upstream by `lisa-implement`.
|
|
54
|
-
- Include the identifier in the PR title or body, for example `Linear: ENG-123`, so Linear's GitHub integration can attach the PR.
|
|
54
|
+
- Include the identifier as a **non-closing** attach token in the PR title or body, for example `Linear: ENG-123` or `Refs ENG-123`, so Linear's GitHub integration can attach the PR without completing the Issue.
|
|
55
|
+
- **Do not** emit a Linear magic word (`Closes`/`Fixes`/`Resolves ENG-123`) in the PR title, body, or commit message unless the target branch is the terminal/production branch — the repository default branch or the configured production branch from `.lisa.config.json` `deploy.branches.production` (resolved via `config-resolution`). Unlike GitHub, whose `Closes` auto-close is scoped to the default branch, Linear's integration completes a linked Issue on merge to **any branch**, so a magic word on a non-terminal env merge (for example into `dev` or `staging`) auto-closes the Issue prematurely and front-runs the env-keyed `status:*` label ladder. This is the `leaf-only-lifecycle` "Terminal native closure" invariant (native closure only at the production terminal `done`) — cite it, do not restate.
|
|
56
|
+
- On a non-terminal env branch, use only the non-closing attach form and strip/neutralize any magic word copied from a ticket title or commit message. Branch-name linkage alone can still auto-complete the Issue where a Linear team enables "complete on any linked-PR merge" — behavior we cannot suppress from our side — so the post-merge reconciliation in `lisa-linear-sync` is the mandatory backstop, not an optional cleanup.
|
|
55
57
|
- **JIRA**:
|
|
56
58
|
- Ensure the JIRA issue key appears in the branch name when the branch is created upstream by `lisa-implement`.
|
|
57
59
|
- Include the key in the PR title or body, for example `JIRA: PROJ-456`, so the GitHub-JIRA integration can attach the PR.
|
|
@@ -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**:
|
|
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
|