@codyswann/lisa 2.238.0 → 2.239.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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-atlassian-access/SKILL.md +12 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-github-build-intake/SKILL.md +5 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-implement/SKILL.md +2 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-build-intake/SKILL.md +5 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-access/SKILL.md +54 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-build-intake/SKILL.md +5 -1
- package/plugins/lisa/rules/eager/rejection-detection.md +40 -0
- package/plugins/lisa/rules/reference/rejection-detection.md +103 -0
- package/plugins/lisa/skills/lisa-atlassian-access/SKILL.md +12 -1
- package/plugins/lisa/skills/lisa-github-build-intake/SKILL.md +5 -1
- package/plugins/lisa/skills/lisa-implement/SKILL.md +2 -0
- package/plugins/lisa/skills/lisa-jira-build-intake/SKILL.md +5 -1
- package/plugins/lisa/skills/lisa-linear-access/SKILL.md +54 -0
- package/plugins/lisa/skills/lisa-linear-build-intake/SKILL.md +5 -1
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/lisa-atlassian-access/SKILL.md +12 -1
- package/plugins/lisa-agy/skills/lisa-github-build-intake/SKILL.md +5 -1
- package/plugins/lisa-agy/skills/lisa-implement/SKILL.md +2 -0
- package/plugins/lisa-agy/skills/lisa-jira-build-intake/SKILL.md +5 -1
- package/plugins/lisa-agy/skills/lisa-linear-access/SKILL.md +54 -0
- package/plugins/lisa-agy/skills/lisa-linear-build-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/rules/eager/rejection-detection.md +40 -0
- package/plugins/lisa-copilot/rules/reference/rejection-detection.md +103 -0
- package/plugins/lisa-copilot/skills/lisa-atlassian-access/SKILL.md +12 -1
- package/plugins/lisa-copilot/skills/lisa-github-build-intake/SKILL.md +5 -1
- package/plugins/lisa-copilot/skills/lisa-implement/SKILL.md +2 -0
- package/plugins/lisa-copilot/skills/lisa-jira-build-intake/SKILL.md +5 -1
- package/plugins/lisa-copilot/skills/lisa-linear-access/SKILL.md +54 -0
- package/plugins/lisa-copilot/skills/lisa-linear-build-intake/SKILL.md +5 -1
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/rules/rejection-detection-reference.mdc +108 -0
- package/plugins/lisa-cursor/rules/rejection-detection.mdc +45 -0
- package/plugins/lisa-cursor/skills/lisa-atlassian-access/SKILL.md +12 -1
- package/plugins/lisa-cursor/skills/lisa-github-build-intake/SKILL.md +5 -1
- package/plugins/lisa-cursor/skills/lisa-implement/SKILL.md +2 -0
- package/plugins/lisa-cursor/skills/lisa-jira-build-intake/SKILL.md +5 -1
- package/plugins/lisa-cursor/skills/lisa-linear-access/SKILL.md +54 -0
- package/plugins/lisa-cursor/skills/lisa-linear-build-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/rules/eager/rejection-detection.md +40 -0
- package/plugins/src/base/rules/reference/rejection-detection.md +103 -0
- package/plugins/src/base/skills/lisa-atlassian-access/SKILL.md +12 -1
- package/plugins/src/base/skills/lisa-github-build-intake/SKILL.md +5 -1
- package/plugins/src/base/skills/lisa-implement/SKILL.md +2 -0
- package/plugins/src/base/skills/lisa-jira-build-intake/SKILL.md +5 -1
- package/plugins/src/base/skills/lisa-linear-access/SKILL.md +54 -0
- package/plugins/src/base/skills/lisa-linear-build-intake/SKILL.md +5 -1
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Rejection Detection at Claim Time"
|
|
3
|
+
alwaysApply: false
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Rejection Detection at Claim Time
|
|
7
|
+
|
|
8
|
+
When QA rejects an item, it moves the item **backward** — from a `review`/`done`-ward lane back to the build-ready lane — usually with a comment naming the defect. Today the re-claiming agent treats that bounced item as fresh work and repeats the rejected approach. This rule turns the backward move into a detectable, teachable signal.
|
|
9
|
+
|
|
10
|
+
It is a **single vendor-neutral contract** consumed by all three build-intake skills (`lisa-jira-build-intake`, `lisa-github-build-intake`, `lisa-linear-build-intake`). Each vendor arm cites this slug at its claim step rather than re-implementing detection, exactly as the vendor arms cite `leaf-only-lifecycle` and `repo-scope-split`. That is what keeps a rejection detected on JIRA from being missed on Linear.
|
|
11
|
+
|
|
12
|
+
## Seam — where detection runs
|
|
13
|
+
|
|
14
|
+
The three build-intake skills share a uniform claim phase: `3a.0` repo-scope gate → `3a` leaf-only claim gate → `3b` Claim → `3c` run lifecycle (culminating in `lisa-implement`) → `3d` transition to done.
|
|
15
|
+
|
|
16
|
+
Detection runs at the **top of `3b`, BEFORE the relabel** `$READY → $CLAIMED`. The relabel is what makes the claim idempotent, but it also overwrites the current lane — after it, "the item is currently in `$READY`" is no longer observable, and part of the rejection signal (reached-a-later-lane AND now-back-in-ready) depends on reading the current lane against history. So detection reads history first, classifies, and only then does `3b` perform the relabel.
|
|
17
|
+
|
|
18
|
+
**`lisa-implement` is NOT the seam** — it never sees the claim. Detection belongs to the build-intake claim phase.
|
|
19
|
+
|
|
20
|
+
## Classification
|
|
21
|
+
|
|
22
|
+
Detection is a pure read of the item's transition history (via the vendor access layers). It returns exactly one classification:
|
|
23
|
+
|
|
24
|
+
| Classification | Condition |
|
|
25
|
+
|---|---|
|
|
26
|
+
| `rejection-reclaim` | History shows the item reached a `review`/`done`-ward lane, then returned to the ready lane; it is now in the ready lane being claimed. |
|
|
27
|
+
| `forward-only` | History shows only forward lane moves — the item never returned to the ready lane from a later lane. |
|
|
28
|
+
| `never-left-ready` | History shows the item never left the ready lane. |
|
|
29
|
+
| `unknown` | The vendor history query failed, was inconclusive, or returned nothing usable. |
|
|
30
|
+
|
|
31
|
+
Running detection twice on the same item yields the same classification and produces no side effects (idempotent, headless-safe — safe under intake crons with no interactive prompts).
|
|
32
|
+
|
|
33
|
+
## Vendor history bindings
|
|
34
|
+
|
|
35
|
+
History is always obtained through the vendor access layer — never a direct vendor API call from a build-intake skill (`integration-access-layer`).
|
|
36
|
+
|
|
37
|
+
- **GitHub** — read the issue via `lisa-github-read-issue`, whose Label-Event History surface returns chronological `LabeledEvent` / `UnlabeledEvent` entries. A backward move is: the configured **ready** label was removed (item advanced) and later re-added (item bounced back). Non-status label churn is ignored for classification.
|
|
38
|
+
- **JIRA** — call `lisa-atlassian-access operation: changelog key:<K>`. A backward move is a status changelog entry whose `to` is the configured ready status, following an earlier entry that reached a `review`/`done`-ward status.
|
|
39
|
+
- **Linear** — call `lisa-linear-access operation: history id:<ID>`, keyed on `status:*` **label** history (Linear build lanes are label-driven — `lisa-linear-build-intake` keys the queue on `status:*` labels). Resolve `addedLabelIds` / `removedLabelIds` against `list-issue-labels`; a backward move is the configured ready label re-added after a later-lane label was applied. Linear workflow-state moves (`fromState`/`toState`) are a secondary corroborating signal where the project maps lanes to states.
|
|
40
|
+
|
|
41
|
+
### Lane names are configuration, never literals
|
|
42
|
+
|
|
43
|
+
The ready / claimed / done lane names ALWAYS come from `.lisa.config.json` lanes:
|
|
44
|
+
|
|
45
|
+
- `github.labels.build.{ready,claimed,done}` (GitHub),
|
|
46
|
+
- the JIRA status equivalents, and
|
|
47
|
+
- the Linear label equivalents,
|
|
48
|
+
|
|
49
|
+
resolved per the `config-resolution` rule with the `src/sync/registry.ts` `BUILD_LABEL_DEFAULTS` (`ready: status:ready`, `claimed: status:in-progress`, `done: {dev: status:on-dev, staging: status:on-stg, production: status:done}`) as the fallback. **Never hardcode** a lane string in the detection logic — a project that renames its ready lane must still detect rejections.
|
|
50
|
+
|
|
51
|
+
## Never block the build
|
|
52
|
+
|
|
53
|
+
`unknown` is a **first-class result**, not an error. If the history query fails (network, revoked credentials, missing substrate), is inconclusive, or the vendor returns nothing usable, detection returns `unknown` and the build **proceeds** to implement the item normally. Reflection is a bonus signal layered on top of the claim; it never gates it. A history failure, an unreadable history, or an absent history all degrade gracefully to "implement the item anyway".
|
|
54
|
+
|
|
55
|
+
## Learning-loop exclusion (no learning about learning)
|
|
56
|
+
|
|
57
|
+
This flow persists learnings via PRs and files upstream issues, so its own artifacts are themselves rejectable. If a learning PR or an auto-filed upstream issue is ever moved backward, a naive detector would fire `rejection-reclaim` on it and reflect on the flow's own output — a learning about learning, recursively.
|
|
58
|
+
|
|
59
|
+
The trigger is therefore **suppressed at the source**. Before an item is classified `rejection-reclaim`, exclude it if it carries any of the learning producer markers — `[lisa-learning-drop]`, `[lisa-learning-pr]`, `[lisa-learning-upstream-handoff]` (embedded in the artifact body/PR the same way other Lisa markers are) — or the `learning:needs-triage` label. An excluded item is treated as `forward-only` (normal work); the rejection-reflection path never fires on it, no matter how the artifact moved. (These markers ship with the learning-persistence flow; reference them by name — do not assume their files are present in this branch.)
|
|
60
|
+
|
|
61
|
+
This is the **trigger-side** half of the no-learning-loops guard. The claim-time archaeology path carries the symmetric **scan-side** exclusion ("a learning PR is never treated as an ancestor").
|
|
62
|
+
|
|
63
|
+
## Reflection at re-claim (`rejection-reclaim` only)
|
|
64
|
+
|
|
65
|
+
When detection returns `rejection-reclaim`, the build-intake claim phase reflects on the rejection **before re-implementing** — the QA comment describing the defect, the review threads, and any linked failure output are the teaching material. This runs in the `3b`/`3c` claim seam, not in `lisa-implement` (which never sees the claim). On any other classification (`forward-only`, `never-left-ready`, `unknown`) there is nothing to reflect on — proceed to the normal claim.
|
|
66
|
+
|
|
67
|
+
1. **Read the rejection evidence — through the access layers only** (`integration-access-layer`): the issue/ticket comments posted **after** the backward transition (the QA rejection comment), the review threads on the rejected PR, and any linked failure output. Read via `lisa-github-read-issue` / `lisa-atlassian-access` / `lisa-linear-access` as the vendor dictates — never a direct vendor API call.
|
|
68
|
+
2. **Assemble ONE candidate learning** from that evidence:
|
|
69
|
+
|
|
70
|
+
| Field | Content |
|
|
71
|
+
|---|---|
|
|
72
|
+
| `rule` | The candidate rule/lesson the rejection teaches. |
|
|
73
|
+
| `why` | Why it matters — the defect the rejection named. |
|
|
74
|
+
| `provenance` | The rejection linked as provenance: the issue, the backward transition, the QA comment link, the rejected PR. |
|
|
75
|
+
| `evidence_links` | The comment / review-thread / failure-output URLs. |
|
|
76
|
+
| `scope_hint` | Where the learning applies (repo / stack / global). |
|
|
77
|
+
| `triggering_issue` | The re-claimed item's ref. |
|
|
78
|
+
| `fingerprint` | `sll4-` + `sha1(<normalized-rule> + "\n" + <triggering_issue>)` truncated to 12 chars (the learning-persistence flow's formula). |
|
|
79
|
+
|
|
80
|
+
3. **Route the candidate into the judgment gate** via the `lisa-persist-learning` skill (the learning-persistence flow — cite it by name; it ships with that flow, so do not assume its file is present in this branch). Pass the candidate with the rejection as provenance.
|
|
81
|
+
|
|
82
|
+
### Graceful degrade — `lisa-persist-learning` unavailable
|
|
83
|
+
|
|
84
|
+
If `lisa-persist-learning` is not installed when reflection runs (e.g. the learning-persistence flow has not merged yet), do **not** fail. Record the candidate as a marked comment on the item and proceed. The comment MUST carry a **visible prose line** as well as the marker — a bare HTML marker renders as an empty comment bubble on GitHub/Linear, defeating the "visible paper trail" this reflection exists to create:
|
|
85
|
+
|
|
86
|
+
```text
|
|
87
|
+
Recorded a candidate learning from this rejection (queued for the judgment gate): <one-line candidate rule>.
|
|
88
|
+
<!-- [lisa-rejection-candidate] key=<issue>-<transition-ts> -->
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
so a human sees the paper trail, a later run (once the skill exists) can pick it up, and the build still proceeds to implement the item. The marker line is verbatim — the dedupe contract keys on it, not on the prose.
|
|
92
|
+
|
|
93
|
+
### Idempotency — marker dedupe
|
|
94
|
+
|
|
95
|
+
The candidate marker key is `<issue>-<backward-transition-timestamp>` (the ISO timestamp of the backward transition that produced the rejection). Reuse the marker-dedupe discipline from `lisa-github-write-prd` Phase 2 — search for an existing candidate carrying this exact key before producing one; **match on the marker, never the title**. Re-claiming the same rejected item twice must **not** produce a duplicate candidate: the second run finds the existing marker and short-circuits. The backward-transition timestamp (not "now") makes the key stable across re-claims of the same rejection.
|
|
96
|
+
|
|
97
|
+
### Never block the build
|
|
98
|
+
|
|
99
|
+
Unreadable or absent rejection evidence (no comment, deleted PR) ends with **no candidate produced and the item still implemented** — degraded, not stopped. Reflection is layered on top of the claim; it never gates it.
|
|
100
|
+
|
|
101
|
+
## Evidence handoff into implementation (`rejection-reclaim` only)
|
|
102
|
+
|
|
103
|
+
Mining a learning is not enough — if the agent then rebuilds the same rejected thing, the item is re-bounced. So the same rejection evidence read in reflection is **also** handed into the implementation, so the re-implementation consumes it instead of repeating the rejected approach.
|
|
104
|
+
|
|
105
|
+
- **The handoff is at claim time.** `lisa-implement` never sees the claim and cannot fetch this itself; the build-intake `3c` lifecycle dispatch passes the rejection evidence summary into `lisa-implement` as part of the context bundle. Reuse the evidence already read in the reflection step — do not fetch it twice.
|
|
106
|
+
- **The evidence summary** names: what was rejected, why (the defect the QA comment named), and the specific approach the rejection named as wrong.
|
|
107
|
+
- **The plan must reckon with it.** On a `rejection-reclaim`, the re-implementation plan MUST explicitly address the rejection evidence and MUST NOT re-propose the specific approach the rejection named as wrong.
|
|
108
|
+
- **Absence never blocks.** If the rejection evidence is unreadable or absent, the agent still implements the item — degraded, not stopped.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Rejection Detection at Claim Time (load-bearing)"
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Rejection Detection at Claim Time (load-bearing)
|
|
7
|
+
|
|
8
|
+
A QA rejection — an item that reached a `review`/`done`-ward state and is now back in the build-ready lane — is a **teaching signal**, not fresh work. Detect it at claim time so the re-claim can reflect on the rejection instead of repeating it.
|
|
9
|
+
|
|
10
|
+
**One vendor-neutral contract, cited by every build-intake arm** (the `leaf-only-lifecycle` / `repo-scope-split` precedent: one shared slug, never three divergent implementations).
|
|
11
|
+
|
|
12
|
+
## When it runs
|
|
13
|
+
|
|
14
|
+
At the **top of build-intake step 3b (Claim), BEFORE the relabel** `$READY → $CLAIMED`. After the relabel the current-lane signal is gone, so detection must read history first. Detection is a pure read — idempotent, headless-safe, no side effects.
|
|
15
|
+
|
|
16
|
+
## Classify the claimed item
|
|
17
|
+
|
|
18
|
+
Return exactly one of:
|
|
19
|
+
|
|
20
|
+
- **`rejection-reclaim`** — history shows the item reached a `review`/`done`-ward lane and is now back in `$READY`.
|
|
21
|
+
- **`forward-only`** — history shows only forward moves (never returned to `$READY` from a later lane).
|
|
22
|
+
- **`never-left-ready`** — history shows the item never left `$READY`.
|
|
23
|
+
- **`unknown`** — the vendor history query failed, was inconclusive, or is absent.
|
|
24
|
+
|
|
25
|
+
## Vendor history sources (through the access layers only — `integration-access-layer`)
|
|
26
|
+
|
|
27
|
+
- **GitHub** — `LABELED` / `UNLABELED` timeline events on the configured **ready** label (the Label-Event History surface from `lisa-github-read-issue`).
|
|
28
|
+
- **JIRA** — the `changelog` operation on `lisa-atlassian-access` (`?expand=changelog`, status items).
|
|
29
|
+
- **Linear** — the `history` operation on `lisa-linear-access`, keyed on `status:*` label history (`addedLabelIds`/`removedLabelIds` resolved against `list-issue-labels`).
|
|
30
|
+
|
|
31
|
+
**Lane names ALWAYS come from `.lisa.config.json` lanes** (`github.labels.build.{ready,claimed,done}` and the JIRA/Linear equivalents; `src/sync/registry.ts` `BUILD_LABEL_DEFAULTS`). **Never hardcode** `status:ready`, `Ready`, etc.
|
|
32
|
+
|
|
33
|
+
## Never block the build
|
|
34
|
+
|
|
35
|
+
`unknown` is a first-class result, not an error. A failing/absent history yields `unknown` and **the build proceeds** to implement the item. Detection never stops a claim.
|
|
36
|
+
|
|
37
|
+
## Learning-loop exclusion (no learning about learning)
|
|
38
|
+
|
|
39
|
+
An artifact this flow produced is **never** a rejection-reflection trigger, no matter how it moves. Before classifying as `rejection-reclaim`, exclude items carrying any learning marker — `[lisa-learning-drop]`, `[lisa-learning-pr]`, `[lisa-learning-upstream-handoff]` — or the `learning:needs-triage` label. Such items short-circuit to `forward-only` (treated as normal work) so the detector never fires on the flow's own learning PRs/issues.
|
|
40
|
+
|
|
41
|
+
## Reflect on a `rejection-reclaim`
|
|
42
|
+
|
|
43
|
+
On `rejection-reclaim` only, before re-implementing: read the rejection evidence (comments after the backward transition, review threads on the rejected PR) through the access layers, assemble **one** candidate learning with the rejection linked as provenance, and route it to the `lisa-persist-learning` skill. If that skill is absent, record the candidate as a comment that carries a **visible prose line** plus the marker (a bare marker renders as an empty comment bubble) — `Recorded a candidate learning from this rejection (queued for the judgment gate): <one-line candidate rule>.` followed by `<!-- [lisa-rejection-candidate] key=<issue>-<transition-ts> -->` — and proceed. **Marker-dedupe** on `<issue>-<backward-transition-timestamp>`: re-claiming twice produces no duplicate. Unreadable/absent evidence → proceed without a candidate, never block.
|
|
44
|
+
|
|
45
|
+
Full contract (classification table, per-vendor bindings, reflection & evidence handoff): [reference/rejection-detection.md](rejection-detection-reference.mdc).
|
|
@@ -291,7 +291,8 @@ Substrate column meanings:
|
|
|
291
291
|
| `write-ticket payload:<P>` (create) | guarded fallback only: `acli jira workitem create --from-json <P>` + response tenant assertion | `mcp__plugin_atlassian_atlassian__createJiraIssue` | `POST https://api.atlassian.com/ex/jira/<CLOUDID>/rest/api/3/issue` body=`<P>` |
|
|
292
292
|
| `write-ticket payload:<P>` (edit) | guarded fallback only: `acli jira workitem edit <K> --from-json <P>` + response tenant assertion | `mcp__plugin_atlassian_atlassian__editJiraIssue` | `PUT https://api.atlassian.com/ex/jira/<CLOUDID>/rest/api/3/issue/<K>` body=`<P>` |
|
|
293
293
|
| `transition key:<K> to:<S>` | guarded fallback only: `acli jira workitem transition --key <K> --status "<S>" --yes` + post-read tenant assertion | `mcp__plugin_atlassian_atlassian__transitionJiraIssue` | resolve transition id then `POST https://api.atlassian.com/ex/jira/<CLOUDID>/rest/api/3/issue/<K>/transitions` |
|
|
294
|
-
| `transitions key:<K>` | (not exposed) | `mcp__plugin_atlassian_atlassian__getTransitionsForJiraIssue` | `GET https://<SITE>/rest/api/3/issue/<K>/transitions` |
|
|
294
|
+
| `transitions key:<K>` — **false friend:** available transitions from current status, **NOT** past history; for history use `changelog` | (not exposed) | `mcp__plugin_atlassian_atlassian__getTransitionsForJiraIssue` | `GET https://<SITE>/rest/api/3/issue/<K>/transitions` |
|
|
295
|
+
| `changelog key:<K>` (read; ordered past status transitions) | (not exposed) | (not exposed) | `GET https://<SITE>/rest/api/3/issue/<K>?expand=changelog` |
|
|
295
296
|
| `comment key:<K> body:<B>` | guarded fallback only: `acli jira workitem comment add --key <K> --body "<B>"` + post-read tenant assertion | `mcp__plugin_atlassian_atlassian__addCommentToJiraIssue` | `POST https://api.atlassian.com/ex/jira/<CLOUDID>/rest/api/3/issue/<K>/comment` |
|
|
296
297
|
| `link from:<K> to:<K2> type:<T>` | guarded fallback only: `acli jira workitem link create --in <K> --out <K2> --type "<T>" --yes` + direction and tenant assertion (see direction note) | `mcp__plugin_atlassian_atlassian__createJiraIssueLink` | `POST https://api.atlassian.com/ex/jira/<CLOUDID>/rest/api/3/issueLink` |
|
|
297
298
|
| `remote-links key:<K>` | (not exposed) | `mcp__plugin_atlassian_atlassian__getJiraIssueRemoteIssueLinks` | `GET https://<SITE>/rest/api/3/issue/<K>/remotelink` |
|
|
@@ -338,6 +339,16 @@ Operations not in this table are unsupported — add an adapter row before using
|
|
|
338
339
|
- `write-page` payload: supports a label-only mutation form — `{ "id": "<I>", "labels": { "add": [...], "remove": [...] } }` — so callers transitioning PRD lifecycle labels do not need to resend the page body. Full create/update payloads also accepted.
|
|
339
340
|
- `comment-page` `kind: inline` requires `anchor` (the highlighted text the comment attaches to). `kind: footer` ignores `anchor`.
|
|
340
341
|
|
|
342
|
+
### `changelog` — transition history (read-only)
|
|
343
|
+
|
|
344
|
+
`changelog key:<K>` returns the ordered past status transitions of a JIRA issue — the raw material for rejection detection (an issue that reached `review`/`done`-ward and is now back in `ready`). It is distinct from `transitions`, which is a false friend: `transitions` lists the *available* next transitions from the current status, never past ones. `read-ticket` uses `fields=*all`, which does **not** include the changelog — the expansion must be requested explicitly with `?expand=changelog`.
|
|
345
|
+
|
|
346
|
+
- **Substrate.** The only substrate that exposes the changelog is JIRA REST via the `?expand=changelog` query parameter (a read, so the `<SITE>` gateway is allowed after the token account check). Neither `acli jira workitem view` (a field-projection tool; the changelog is an `expand`, not a field) nor the Atlassian MCP surfaces a changelog expansion, so both are marked `(not exposed)` — do not invent a separate transport, and do not try to reconstruct history from `transitions`.
|
|
347
|
+
- **Shape.** Walk `changelog.histories[].items[]` and keep entries where `field == "status"`; for each emit `{ from, to, when, author }` — `items[].fromString` → `items[].toString`, `histories[].created` (ISO timestamp), `histories[].author.displayName`/`accountId`. Preserve JIRA's oldest→newest ordering.
|
|
348
|
+
- **Empty is valid.** An issue that never transitioned returns an **empty** history — an empty history is a valid result, not an error. Callers treat empty as "never left its initial status".
|
|
349
|
+
- **Pagination / truncation.** The issue-resource changelog (`?expand=changelog`) truncates busy issues (`changelog.maxResults`/`total`/`startAt`). When `total` exceeds what the issue resource returned, page the dedicated endpoint `GET https://<SITE>/rest/api/3/issue/<K>/changelog?startAt=<n>` until `startAt + maxResults >= total`, preserving order across pages. A silently truncated history is a correctness bug for detection.
|
|
350
|
+
- **Graceful degrade — never block the build.** A failed changelog fetch (network, auth, missing substrate) returns the substrate contract's `Error:` result. Callers MUST treat that as **unknown** history and proceed — a history read failure never blocks the build.
|
|
351
|
+
|
|
341
352
|
### Step 4 — Return result
|
|
342
353
|
|
|
343
354
|
Emit either:
|
|
@@ -252,6 +252,10 @@ A blocker is active if it is open and has no cleared status label. Treat `status
|
|
|
252
252
|
|
|
253
253
|
#### 3b. Claim
|
|
254
254
|
|
|
255
|
+
**Rejection detection runs first — before the relabel below.** Per the vendor-neutral `rejection-detection` rule (cite the slug; do not restate its classification table), classify this item at the **top of 3b, BEFORE** the `$READY → $CLAIMED` relabel — after the relabel the current-lane signal is gone. Read the item's Label-Event History from `lisa-github-read-issue` (chronological `LabeledEvent` / `UnlabeledEvent` on the configured `$READY` label) and classify it `rejection-reclaim | forward-only | never-left-ready | unknown`. Lane names come from `.lisa.config.json` (`github.labels.build.*`), never hardcoded. A failing/absent history yields `unknown` and the claim proceeds — detection never blocks the build. Items carrying a learning marker (`[lisa-learning-drop]` / `[lisa-learning-pr]` / `[lisa-learning-upstream-handoff]`) or the `learning:needs-triage` label are never rejection triggers (no learning-about-learning). Carry the classification into the relabel and lifecycle below.
|
|
256
|
+
|
|
257
|
+
**On `rejection-reclaim`, reflect before re-implementing** (per `rejection-detection`): read the rejection evidence through the access layer — the issue comments posted after the backward transition (the QA rejection comment) and the review threads on the rejected PR via `lisa-github-read-issue` — assemble ONE candidate learning (rule, why, provenance linking the rejection comment + rejected PR, evidence links, scope hint, triggering issue, fingerprint `sll4-sha1(rule\ntriggering_issue)[:12]`), and route it to the `lisa-persist-learning` skill. If that skill is absent, record the candidate as a comment carrying a **visible prose line plus** the marker (a bare marker renders as an empty bubble) — `Recorded a candidate learning from this rejection (queued for the judgment gate): <one-line candidate rule>.` then `<!-- [lisa-rejection-candidate] key=<issue>-<transition-ts> -->` — and proceed. Dedupe on `<issue>-<backward-transition-timestamp>` — a second re-claim produces no duplicate. Unreadable/absent evidence → no candidate, still implement.
|
|
258
|
+
|
|
255
259
|
```bash
|
|
256
260
|
gh issue edit <number> --repo <org>/<repo> --remove-label "$READY" --add-label "$CLAIMED"
|
|
257
261
|
# Assign to the authenticated user ONLY when the issue is currently unassigned (attributable claim;
|
|
@@ -274,7 +278,7 @@ After the claim succeeds, run the per-issue lifecycle defined by the `github-age
|
|
|
274
278
|
- `lisa-github-verify` — pre-flight quality gate, including the draft-then-block procedure on FAIL
|
|
275
279
|
- `lisa-ticket-triage` — analytical triage gate (a `BLOCKED` verdict stops the cycle with findings posted)
|
|
276
280
|
- Intent determination from the `type:` label
|
|
277
|
-
2. **Dispatch the flow in-session:** when the gates pass, invoke the lifecycle skill via the Skill tool — `lisa-implement <org>/<repo>#<number>` for Build / Fix / Improve / Investigate-Only (or `lisa-plan` for an Epic) — passing the full context bundle from the read step. `lisa-implement`'s own orchestration preamble then creates the per-item agent team (input-resolver, Roster Decision, specialist fanout) exactly as a direct invocation would.
|
|
281
|
+
2. **Dispatch the flow in-session:** when the gates pass, invoke the lifecycle skill via the Skill tool — `lisa-implement <org>/<repo>#<number>` for Build / Fix / Improve / Investigate-Only (or `lisa-plan` for an Epic) — passing the full context bundle from the read step. **When 3b classified this item `rejection-reclaim`, the context bundle passed to `lisa-implement` MUST include the rejection evidence summary** (what was rejected, the defect the QA comment named, the approach named as wrong) — reuse the evidence already read in 3b, do not fetch it twice — so the plan can address it per `rejection-detection`; absence of evidence never blocks. `lisa-implement`'s own orchestration preamble then creates the per-item agent team (input-resolver, Roster Decision, specialist fanout) exactly as a direct invocation would.
|
|
278
282
|
3. **Milestone sync and evidence** (`lisa-github-sync`, `lisa-github-evidence`) happen at the milestones the `github-agent` workflow defines, within the dispatched flow.
|
|
279
283
|
|
|
280
284
|
If you are somehow running this skill as a spawned teammate inside an existing team (nested misrouting — Intake keeps this chain in the lead session), do NOT run the lifecycle inline and do NOT spawn named peers. Return this payload to the lead so the lead session can run this Phase 3c in-session:
|
|
@@ -49,6 +49,8 @@ The team lead does NOT read the input directly. The first task on the team's pla
|
|
|
49
49
|
|
|
50
50
|
The input resolver is the only teammate that may be spawned before the Roster Decision exists. After it returns the resolved input, do not spawn any lifecycle, research, implementation, review, verification, or learning teammate until the Roster Decision has been recorded.
|
|
51
51
|
|
|
52
|
+
**Rejection evidence in the claim handoff.** When this flow was dispatched from a build-intake claim that classified the item as a `rejection-reclaim` (per the `rejection-detection` rule), the context bundle carries a **rejection evidence summary** (what was rejected, the defect the QA comment named, the approach named as wrong). The plan MUST explicitly address that rejection evidence and MUST NOT re-propose the specific approach the rejection named as wrong — a bounced item must come back fixed, not re-bounced. `lisa-implement` cannot fetch this itself (it never sees the claim); it consumes what the handoff carries. Absence of rejection evidence never blocks — plan and implement normally.
|
|
53
|
+
|
|
52
54
|
## Select the agent roster
|
|
53
55
|
|
|
54
56
|
Before spawning any teammate beyond the bounded input resolver, record a **Roster Decision** artifact. It must enumerate every agent or specialist type exposed by the current runtime's delegation tool and record one line per type:
|
|
@@ -196,6 +196,10 @@ This gate never blocks a legitimate flat Task/Bug: those have no open children a
|
|
|
196
196
|
|
|
197
197
|
#### 3b. Claim
|
|
198
198
|
|
|
199
|
+
**Rejection detection runs first — before the transition below.** Per the vendor-neutral `rejection-detection` rule (cite the slug; do not restate its classification table), classify this ticket at the **top of 3b, BEFORE** the `$READY → $CLAIMED` transition — after the transition the current-status signal is gone. Read the ticket's status changelog via `lisa-atlassian-access operation: changelog key: <TICKET>` and classify it `rejection-reclaim | forward-only | never-left-ready | unknown` (a `rejection-reclaim` is a changelog entry whose `to` is the configured `$READY` status following an earlier `review`/`done`-ward status). Status names come from `.lisa.config.json`, never hardcoded. A failing/absent changelog yields `unknown` and the claim proceeds — detection never blocks the build. Tickets carrying a learning marker (`[lisa-learning-drop]` / `[lisa-learning-pr]` / `[lisa-learning-upstream-handoff]`) or the `learning:needs-triage` label are never rejection triggers (no learning-about-learning). Carry the classification into the transition and lifecycle below.
|
|
200
|
+
|
|
201
|
+
**On `rejection-reclaim`, reflect before re-implementing** (per `rejection-detection`): read the rejection evidence through the access layer — the ticket comments posted after the backward transition (the QA rejection comment) via `lisa-atlassian-access operation: read-ticket` / `comment` reads and the review threads on the rejected PR — assemble ONE candidate learning (rule, why, provenance linking the rejection comment + rejected PR, evidence links, scope hint, triggering issue, fingerprint `sll4-sha1(rule\ntriggering_issue)[:12]`), and route it to the `lisa-persist-learning` skill. If that skill is absent, record the candidate via `lisa-atlassian-access operation: comment` as a comment carrying a **visible prose line plus** the marker (a bare marker renders as an empty bubble) — `Recorded a candidate learning from this rejection (queued for the judgment gate): <one-line candidate rule>.` then `<!-- [lisa-rejection-candidate] key=<issue>-<transition-ts> -->` — and proceed. Dedupe on `<issue>-<backward-transition-timestamp>` — a second re-claim produces no duplicate. Unreadable/absent evidence → no candidate, still implement.
|
|
202
|
+
|
|
199
203
|
Transition the ticket from `$READY` to `$CLAIMED` by invoking `lisa-atlassian-access` `operation: transition key: <TICKET> to: "$CLAIMED"`.
|
|
200
204
|
- **Assign to the authenticated user when the ticket is unassigned.** A claim must be attributable. If the ticket has no assignee, assign it to the authenticated account — prefer acli `--assignee @me` (resolves server-side to the authenticated user, which avoids the federated-`accountId` mis-assignment), or `write-ticket` with the `accountId` from the `/rest/api/3/myself` identity probe the access skill already documents. Leave an already-assigned ticket's assignee untouched — never reassign work that already has an owner.
|
|
201
205
|
- Post a `[claude-build-intake]` comment via `lisa-atlassian-access` `operation: comment key: <TICKET> body: "Claimed by Claude. Starting build."`
|
|
@@ -212,7 +216,7 @@ After the claim succeeds, run the per-ticket lifecycle defined by the `jira-agen
|
|
|
212
216
|
- `lisa-jira-verify` — pre-flight quality gate, including the draft-then-block procedure on FAIL
|
|
213
217
|
- `lisa-ticket-triage` — analytical triage gate (a `BLOCKED` verdict stops the cycle with findings posted)
|
|
214
218
|
- Intent determination from the issue type
|
|
215
|
-
2. **Dispatch the flow in-session:** when the gates pass, invoke the lifecycle skill via the Skill tool — `lisa-implement <TICKET>` for Build / Fix / Improve / Investigate-Only (or `lisa-plan` for an Epic) — passing the full context bundle from the read step. `lisa-implement`'s own orchestration preamble then creates the per-item agent team (input-resolver, Roster Decision, specialist fanout) exactly as a direct invocation would.
|
|
219
|
+
2. **Dispatch the flow in-session:** when the gates pass, invoke the lifecycle skill via the Skill tool — `lisa-implement <TICKET>` for Build / Fix / Improve / Investigate-Only (or `lisa-plan` for an Epic) — passing the full context bundle from the read step. **When 3b classified this ticket `rejection-reclaim`, the context bundle passed to `lisa-implement` MUST include the rejection evidence summary** (what was rejected, the defect the QA comment named, the approach named as wrong) — reuse the evidence already read in 3b, do not fetch it twice — so the plan can address it per `rejection-detection`; absence of evidence never blocks. `lisa-implement`'s own orchestration preamble then creates the per-item agent team (input-resolver, Roster Decision, specialist fanout) exactly as a direct invocation would.
|
|
216
220
|
3. **Milestone sync and evidence** (`lisa-jira-sync`, `lisa-jira-evidence`) happen at the milestones the `jira-agent` workflow defines, within the dispatched flow.
|
|
217
221
|
|
|
218
222
|
If you are somehow running this skill as a spawned teammate inside an existing team (nested misrouting — Intake keeps this chain in the lead session), do NOT run the lifecycle inline and do NOT spawn named peers. Return this payload to the lead so the lead session can run this Phase 3c in-session:
|
|
@@ -23,6 +23,7 @@ operation: get-issue id:<ID>
|
|
|
23
23
|
operation: save-issue payload:{...}
|
|
24
24
|
operation: list-comments issue_id:<ID>
|
|
25
25
|
operation: save-comment issue_id:<ID> body:"..."
|
|
26
|
+
operation: history id:<ID>
|
|
26
27
|
operation: list-issue-labels [team:<ID>]
|
|
27
28
|
operation: create-issue-label payload:{...}
|
|
28
29
|
operation: list-project-labels
|
|
@@ -81,6 +82,59 @@ linear_graphql() {
|
|
|
81
82
|
Map operation names to Linear GraphQL queries/mutations in this access skill.
|
|
82
83
|
Consumers pass business-shaped arguments only; they do not embed GraphQL.
|
|
83
84
|
|
|
85
|
+
## `history` — transition history (read-only)
|
|
86
|
+
|
|
87
|
+
`history id:<ID>` returns an Issue's ordered past state changes — the raw
|
|
88
|
+
material for rejection detection (an Issue that reached a `review`/`done`-ward
|
|
89
|
+
state and is now back in `ready`). `IssueHistory` is reachable today through the
|
|
90
|
+
existing `linear_graphql` adapter but was **not** in the documented contract; an
|
|
91
|
+
undocumented-but-reachable capability is not exposed, so it now appears in the
|
|
92
|
+
Invocation Contract above. Reuse the existing adapter — this is a
|
|
93
|
+
contract/surface change, not a new transport (the `integration-access-layer`
|
|
94
|
+
rule forbids consumers from reaching around the layer).
|
|
95
|
+
|
|
96
|
+
Query through `linear_graphql` (oldest→newest; page `history(first:…, after:…)`
|
|
97
|
+
via `pageInfo` for busy Issues so history never silently truncates):
|
|
98
|
+
|
|
99
|
+
```graphql
|
|
100
|
+
query($id:String!){
|
|
101
|
+
issue(id:$id){
|
|
102
|
+
history(first:100){
|
|
103
|
+
pageInfo{hasNextPage endCursor}
|
|
104
|
+
nodes{
|
|
105
|
+
createdAt
|
|
106
|
+
fromState{name type}
|
|
107
|
+
toState{name type}
|
|
108
|
+
actor{name}
|
|
109
|
+
addedLabelIds
|
|
110
|
+
removedLabelIds
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
- **Shape.** For each node emit `{ from, to, when, who }` — `fromState.name` →
|
|
118
|
+
`toState.name`, `createdAt` (ISO timestamp), `actor.name`. Nodes with no
|
|
119
|
+
`fromState`/`toState` are non-state edits (label-only, assignee, etc.); keep
|
|
120
|
+
them for the label stream, skip them for workflow-state ordering.
|
|
121
|
+
- **Label history (honest caveat).** Linear's build lanes are **label-driven**
|
|
122
|
+
(`lisa-linear-build-intake` keys the queue on `status:*` labels), so label
|
|
123
|
+
moves matter as much as workflow-state moves. `IssueHistory` carries label
|
|
124
|
+
changes as `addedLabelIds` / `removedLabelIds` — arrays of label **IDs**, not
|
|
125
|
+
names. It does **not** inline label names, and it does not carry the label's
|
|
126
|
+
full prior/next set — only the per-event deltas. Resolve IDs → names by
|
|
127
|
+
cross-referencing `list-issue-labels`. Do not overclaim: a caller that needs
|
|
128
|
+
`status:*` label transitions reconstructs them from the ID deltas plus the
|
|
129
|
+
label catalog, not from an inline name on the history node.
|
|
130
|
+
- **Empty is valid.** An Issue that never changed state returns an **empty**
|
|
131
|
+
history — an empty history is a valid result, not an error.
|
|
132
|
+
- **Graceful degrade — never block the build.** A failed history fetch returns
|
|
133
|
+
the layer's `Error:` result. Callers MUST treat that as **unknown** history
|
|
134
|
+
and proceed — a history read failure never blocks the build. MCP cannot reach
|
|
135
|
+
`IssueHistory`, so the `history` operation resolves only through the
|
|
136
|
+
`LINEAR_API_KEY` GraphQL substrate; without it, the result is unknown.
|
|
137
|
+
|
|
84
138
|
## Invariants
|
|
85
139
|
|
|
86
140
|
- MCP is preferred when it is present and already authenticated.
|
|
@@ -186,6 +186,10 @@ This gate never blocks a legitimate flat Task/Bug: those have no open children a
|
|
|
186
186
|
|
|
187
187
|
#### 3b. Claim
|
|
188
188
|
|
|
189
|
+
**Rejection detection runs first — before the relabel below.** Per the vendor-neutral `rejection-detection` rule (cite the slug; do not restate its classification table), classify this Issue at the **top of 3b, BEFORE** the `$READY → $CLAIMED` relabel — after the relabel the current-lane signal is gone. Read the Issue's history via `lisa-linear-access operation: history id: <ISSUE-ID>`, keyed on `status:*` **label** history (Linear build lanes are label-driven; resolve `addedLabelIds`/`removedLabelIds` against `list-issue-labels`), and classify it `rejection-reclaim | forward-only | never-left-ready | unknown` (a `rejection-reclaim` is the configured `$READY` label re-added after a later-lane label). Label names come from `.lisa.config.json`, never hardcoded. A failing/absent history yields `unknown` and the claim proceeds — detection never blocks the build. Issues carrying a learning marker (`[lisa-learning-drop]` / `[lisa-learning-pr]` / `[lisa-learning-upstream-handoff]`) or the `learning:needs-triage` label are never rejection triggers (no learning-about-learning). Carry the classification into the relabel and lifecycle below.
|
|
190
|
+
|
|
191
|
+
**On `rejection-reclaim`, reflect before re-implementing** (per `rejection-detection`): read the rejection evidence through the access layer — the Issue comments posted after the backward transition (the QA rejection comment) via `lisa-linear-access operation: list-comments` and the review threads on the rejected PR — assemble ONE candidate learning (rule, why, provenance linking the rejection comment + rejected PR, evidence links, scope hint, triggering issue, fingerprint `sll4-sha1(rule\ntriggering_issue)[:12]`), and route it to the `lisa-persist-learning` skill. If that skill is absent, record the candidate via `lisa-linear-access operation: save-comment` as a comment carrying a **visible prose line plus** the marker (a bare marker renders as an empty bubble) — `Recorded a candidate learning from this rejection (queued for the judgment gate): <one-line candidate rule>.` then `<!-- [lisa-rejection-candidate] key=<issue>-<transition-ts> -->` — and proceed. Dedupe on `<issue>-<backward-transition-timestamp>` — a second re-claim produces no duplicate. Unreadable/absent evidence → no candidate, still implement.
|
|
192
|
+
|
|
189
193
|
Update labels via `lisa-linear-access operation: save-issue`: remove `$READY`, add `$CLAIMED`. Resolve label IDs via `list_issue_labels` (create `$CLAIMED` if missing).
|
|
190
194
|
|
|
191
195
|
**Assign to the authenticated user when the Issue is unassigned.** A claim must be attributable. If the Issue has no assignee, set its `assigneeId` to the authenticated viewer (resolve the viewer's id via the Linear MCP identity — e.g. `get_user` for the current actor) through `lisa-linear-access operation: save-issue`. Leave an already-assigned Issue's assignee untouched — never reassign work that already has an owner.
|
|
@@ -205,7 +209,7 @@ After the claim succeeds, run the per-Issue lifecycle defined by the `linear-age
|
|
|
205
209
|
- `lisa-linear-verify` — pre-flight quality gate, including the draft-then-block procedure on FAIL
|
|
206
210
|
- `lisa-ticket-triage` — analytical triage gate (a `BLOCKED` verdict stops the cycle with findings posted)
|
|
207
211
|
- Intent determination from the type label
|
|
208
|
-
2. **Dispatch the flow in-session:** when the gates pass, invoke the lifecycle skill via the Skill tool — `lisa-implement <ISSUE-ID>` for Build / Fix / Improve / Investigate-Only (or `lisa-plan` for an Epic-equivalent) — passing the full context bundle from the read step. `lisa-implement`'s own orchestration preamble then creates the per-item agent team (input-resolver, Roster Decision, specialist fanout) exactly as a direct invocation would.
|
|
212
|
+
2. **Dispatch the flow in-session:** when the gates pass, invoke the lifecycle skill via the Skill tool — `lisa-implement <ISSUE-ID>` for Build / Fix / Improve / Investigate-Only (or `lisa-plan` for an Epic-equivalent) — passing the full context bundle from the read step. **When 3b classified this Issue `rejection-reclaim`, the context bundle passed to `lisa-implement` MUST include the rejection evidence summary** (what was rejected, the defect the QA comment named, the approach named as wrong) — reuse the evidence already read in 3b, do not fetch it twice — so the plan can address it per `rejection-detection`; absence of evidence never blocks. `lisa-implement`'s own orchestration preamble then creates the per-item agent team (input-resolver, Roster Decision, specialist fanout) exactly as a direct invocation would.
|
|
209
213
|
3. **Milestone sync and evidence** (`lisa-linear-sync`, `lisa-linear-evidence`) happen at the milestones the `linear-agent` workflow defines, within the dispatched flow.
|
|
210
214
|
|
|
211
215
|
If you are somehow running this skill as a spawned teammate inside an existing team (nested misrouting — Intake keeps this chain in the lead session), do NOT run the lifecycle inline and do NOT spawn named peers. Return this payload to the lead so the lead session can run this Phase 3c in-session:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.239.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.239.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, across Claude and Codex.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.239.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.239.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.239.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|