@codyswann/lisa 4.55.24 → 4.55.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
  2. package/dist/core/upstream-evidence-manifest.js +3 -3
  3. package/package.json +4 -4
  4. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  5. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  6. package/plugins/lisa/.codex-plugin/skills/lisa-github-build-intake/SKILL.md +18 -8
  7. package/plugins/lisa/.codex-plugin/skills/lisa-jira-build-intake/SKILL.md +10 -1
  8. package/plugins/lisa/.codex-plugin/skills/lisa-linear-build-intake/SKILL.md +9 -2
  9. package/plugins/lisa/skills/lisa-github-build-intake/SKILL.md +18 -8
  10. package/plugins/lisa/skills/lisa-jira-build-intake/SKILL.md +10 -1
  11. package/plugins/lisa/skills/lisa-linear-build-intake/SKILL.md +9 -2
  12. package/plugins/lisa-agy/plugin.json +1 -1
  13. package/plugins/lisa-agy/skills/lisa-github-build-intake/SKILL.md +18 -8
  14. package/plugins/lisa-agy/skills/lisa-jira-build-intake/SKILL.md +10 -1
  15. package/plugins/lisa-agy/skills/lisa-linear-build-intake/SKILL.md +9 -2
  16. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  17. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  18. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  19. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  20. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  21. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  22. package/plugins/lisa-copilot/skills/lisa-github-build-intake/SKILL.md +18 -8
  23. package/plugins/lisa-copilot/skills/lisa-jira-build-intake/SKILL.md +10 -1
  24. package/plugins/lisa-copilot/skills/lisa-linear-build-intake/SKILL.md +9 -2
  25. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  26. package/plugins/lisa-cursor/skills/lisa-github-build-intake/SKILL.md +18 -8
  27. package/plugins/lisa-cursor/skills/lisa-jira-build-intake/SKILL.md +10 -1
  28. package/plugins/lisa-cursor/skills/lisa-linear-build-intake/SKILL.md +9 -2
  29. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  30. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  31. package/plugins/lisa-expo-agy/plugin.json +1 -1
  32. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  33. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  34. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  35. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  36. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  37. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  38. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  39. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  40. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  41. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  42. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  43. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  44. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  45. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  46. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  47. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  48. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  49. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  50. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  51. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  52. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  53. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  54. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  55. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  56. package/plugins/lisa-rails-agy/plugin.json +1 -1
  57. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  58. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  59. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  60. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  61. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  62. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  63. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  64. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  65. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  66. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  67. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  68. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  69. package/plugins/src/base/skills/lisa-github-build-intake/SKILL.md +18 -8
  70. package/plugins/src/base/skills/lisa-jira-build-intake/SKILL.md +10 -1
  71. package/plugins/src/base/skills/lisa-linear-build-intake/SKILL.md +9 -2
@@ -41,9 +41,9 @@ export const NIGHTLY_E2E_GUARD_BEHAVIOR_CERTIFICATES = Object.freeze({
41
41
  }),
42
42
  cd02b94b4db5134984c7b69f905af71c96bb5aac09a18fb3c6aef5ab0c22cf17: Object.freeze({
43
43
  contractVersion: "1.9.0",
44
- packageVersions: Object.freeze(["4.55.24"]),
44
+ packageVersions: Object.freeze(["4.55.26"]),
45
45
  provenances: Object.freeze([
46
- "workspace package @codyswann/lisa@4.55.24 (typescript/copy-overwrite/scripts/check-nightly-e2e-health.mjs)",
46
+ "workspace package @codyswann/lisa@4.55.26 (typescript/copy-overwrite/scripts/check-nightly-e2e-health.mjs)",
47
47
  ]),
48
48
  }),
49
49
  dfd2fef680de5ef03e63075e8a61c62ca4d95cdfdff6201939b79c748d3397f6: Object.freeze({
@@ -567,7 +567,7 @@ export const UPSTREAM_EVIDENCE_MANIFEST = Object.freeze({
567
567
  "plugins/src/base/skills/lisa-git-prune/SKILL.md": "11fad06d109538f1a8ee4ef8043bb0e083672e3c9a7cb7ae8a7233c5411d6dd2",
568
568
  "plugins/src/base/skills/lisa-git-submit-pr/SKILL.md": "395c08ad3e620e27a1c636d784f8051853136cdb409b2a52661f79711ad5edc7",
569
569
  "plugins/src/base/skills/lisa-github-add-journey/SKILL.md": "4ceda3474a9b32abae835c2676e8cb2b7e888c6ba04b95843dbe7254293bbf32",
570
- "plugins/src/base/skills/lisa-github-build-intake/SKILL.md": "64bdbf75ef115752b91a357b6ce04e3a6118bb4899610bc9d9e8d8013638945e",
570
+ "plugins/src/base/skills/lisa-github-build-intake/SKILL.md": "aa84417983f20fc9193518df2698b4781fc561cc2ed1d78831cb659379e624bc",
571
571
  "plugins/src/base/skills/lisa-github-claim/SKILL.md": "71301c6d45d7eb5523e74aa7f070bb2becf57ca68fb8bde9e02ee937b78815f7",
572
572
  "plugins/src/base/skills/lisa-github-create/SKILL.md": "2128a5069c2663a6a33cef7d0465e672682429b176183e101d3ea65f276a1b93",
573
573
  "plugins/src/base/skills/lisa-github-evidence/SKILL.md": "73142ef660766f4b4e4947ad25d00614b8fb9ad4dfa7e4f45b19379ae981d84d",
@@ -594,7 +594,7 @@ export const UPSTREAM_EVIDENCE_MANIFEST = Object.freeze({
594
594
  "plugins/src/base/skills/lisa-intake/SKILL.md": "6ad62fd1a8148729b6ff0cdffdf853529f72ee73ba08f7bb1b27237c19f47d4d",
595
595
  "plugins/src/base/skills/lisa-jam-access/SKILL.md": "8c9007e4ef4b79ba6de30be0baf75972d1a68451204d7a29f5cc504d7095279e",
596
596
  "plugins/src/base/skills/lisa-jira-add-journey/SKILL.md": "a00606cc7927f034e847f34d7e44e72fa7f3a14ddf6a469deb7eae1e06531fd7",
597
- "plugins/src/base/skills/lisa-jira-build-intake/SKILL.md": "c59ee7fb3eb285b698241ad3c705bb41bcd68ee11393a3588fc8708ab4378ce2",
597
+ "plugins/src/base/skills/lisa-jira-build-intake/SKILL.md": "ef4e1f071a8ee63f8cb2a4d875153391753cd537740be4116a4f8ff145377357",
598
598
  "plugins/src/base/skills/lisa-jira-claim/SKILL.md": "9c4935441a4e6b55df0949178f96e927184c4909bffff8929b39a304bc5ac00a",
599
599
  "plugins/src/base/skills/lisa-jira-create/SKILL.md": "77078002d2a16e0b2a65725f4e86b13caa1c43ba193eb37beb5b7da20feed3f1",
600
600
  "plugins/src/base/skills/lisa-jira-evidence/SKILL.md": "091149fefcfc51e3cec789082a0a8e21167239da1cf2b684e86224db733d974d",
@@ -613,7 +613,7 @@ export const UPSTREAM_EVIDENCE_MANIFEST = Object.freeze({
613
613
  "plugins/src/base/skills/lisa-learnings-audit/SKILL.md": "ca79cd7fed7e9ca0965c2fcfa8266f2ebfb4ff9cc5fc53dc59343849e5373540",
614
614
  "plugins/src/base/skills/lisa-linear-access/SKILL.md": "cdd4fa5e60c70d0e054d9d85239d20536f24800946ae0bb64e296db8da0bb1eb",
615
615
  "plugins/src/base/skills/lisa-linear-add-journey/SKILL.md": "e63ae35df1a928dac7b42535ce11e77e8c617e60838ba319f22081400e87886e",
616
- "plugins/src/base/skills/lisa-linear-build-intake/SKILL.md": "950616d4fdd364be4be4ced054dc5d1c049105c9c205866417399bcac5bcd504",
616
+ "plugins/src/base/skills/lisa-linear-build-intake/SKILL.md": "f65cbb4a54e5b2d7e2767c002c8e02d282d8835479dac3cf6d5e1df3d1646cb6",
617
617
  "plugins/src/base/skills/lisa-linear-claim/SKILL.md": "efde30b5eac8b2cc56499ce391bd3d43ebb017c4ce948b5d547b52acb66715bb",
618
618
  "plugins/src/base/skills/lisa-linear-create/SKILL.md": "b9b0b89903fc980e7b591109cffcf377f7397cc6c7b6110975d0b21bafb6de2e",
619
619
  "plugins/src/base/skills/lisa-linear-evidence/SKILL.md": "e25f8ab93f5204ac55c99c6cba5fe53cc4ad792c0140553eef7d3478ffb69694",
package/package.json CHANGED
@@ -187,7 +187,7 @@
187
187
  "zod-validation-error": "^4.0.0"
188
188
  },
189
189
  "name": "@codyswann/lisa",
190
- "version": "4.55.24",
190
+ "version": "4.55.26",
191
191
  "description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
192
192
  "main": "dist/index.js",
193
193
  "exports": {
@@ -336,7 +336,7 @@
336
336
  "test": "tests"
337
337
  },
338
338
  "types": "./dist/index.d.ts",
339
- "lisaReleaseCommit": "81aff1bda41c66dfec814c7b1caa109a6c5c94c6",
340
- "gitHead": "81aff1bda41c66dfec814c7b1caa109a6c5c94c6",
341
- "lisaReleaseTag": "v4.55.24"
339
+ "lisaReleaseCommit": "930911c159f0167461a637e71c170d6d718d47ed",
340
+ "gitHead": "930911c159f0167461a637e71c170d6d718d47ed",
341
+ "lisaReleaseTag": "v4.55.26"
342
342
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "Universal governance: agents, skills, commands, hooks, and rules for all projects.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -174,15 +174,25 @@ A "transition" means: remove the old role label and add the new one, in two `gh
174
174
  ### Phase 2 — Find ready issues
175
175
 
176
176
  ```bash
177
- if [ -n "$ASSIGNEE" ]; then
178
- gh issue list --repo <org>/<repo> --label "$READY" --assignee "$ASSIGNEE" --state open \
179
- --json number,title,labels,assignees,milestone,createdAt --limit 100
180
- else
181
- gh issue list --repo <org>/<repo> --label "$READY" --state open \
182
- --json number,title,labels,assignees,milestone,createdAt --limit 100
177
+ # QUEUE_REPO is the resolved <org>/<repo> from Phase 1.
178
+ if [ "${ASSIGNEE:-}" = "@me" ]; then
179
+ ASSIGNEE=$(gh api user --jq .login) || exit 1
183
180
  fi
181
+ ISSUE_PAGES=$(gh api --method GET "repos/$QUEUE_REPO/issues" \
182
+ -f state=open -f per_page=100 --paginate --slurp) || exit 1
183
+ # The repository issues endpoint also returns pull requests; exclude them.
184
+ ISSUES_JSON=$(printf '%s' "$ISSUE_PAGES" | jq '[.[][] | select(has("pull_request") | not)]') || exit 1
185
+ printf '%s' "$ISSUES_JSON" | jq --arg ready "$READY" --arg assignee "${ASSIGNEE:-}" '
186
+ [.[] | select(any(.labels[]; .name == $ready))
187
+ | select($assignee == "" or any(.assignees[]; .login == $assignee))]'
184
188
  ```
185
189
 
190
+ Wait for every page before choosing work or reporting an empty queue. A failed
191
+ page is an incomplete read: report it and end this cycle without dispatching.
192
+ The REST fields use `created_at` and label/assignee objects. Reuse this complete
193
+ issue snapshot for the lane counts below; apply the assignee filter to candidates
194
+ only, so the repository totals still describe the whole queue.
195
+
186
196
  If empty, run a secondary check to distinguish a genuinely empty queue from an unconfigured repo:
187
197
 
188
198
  ```bash
@@ -206,8 +216,8 @@ GitHub's data model, not a preference (see "Why labels" above). That makes the o
206
216
  - open issues carrying **no** build role label — which this scanner must see anyway in order to
207
217
  determine and stamp their repo.
208
218
 
209
- Count each lane and the repo's **total open** count (`gh issue list --state open --limit 1000 --json
210
- number | jq length`), then build the denominator with the shared helper — GitHub callers pass the
219
+ Count each lane and the repo's **total open** count from `ISSUES_JSON`, then build
220
+ the denominator with the shared helper — GitHub callers pass the
211
221
  lane type explicitly, since there is none to read:
212
222
 
213
223
  ```text
@@ -177,7 +177,16 @@ the Linear side produced 31 consecutive false "dry lane" cycles (#2657).
177
177
  2. Then sweep the rest of pre-work with the same base JQL, swapping the status clause for
178
178
  `statusCategory = "To Do"`, and read the **total open** count (`statusCategory != Done`). The
179
179
  open total is what makes an omitted lane arithmetically visible.
180
- 3. Page to exhaustion — a single unpaged `search-issues` call is not a count.
180
+ 3. Page each query to exhaustion using the configured access tool's pagination
181
+ fields. For token-based search, pass the returned `nextPageToken` until the
182
+ response marks the last page. For offset-based search, advance `startAt` by
183
+ the number of returned issues until the reported total is reached. Keep the
184
+ same JQL and ordering throughout, and deduplicate issue keys across pages.
185
+ A failed page, repeated cursor, or missing continuation while more results
186
+ are reported makes the read incomplete. Report that condition and end the
187
+ cycle without dispatching; never report a partial read as an empty queue.
188
+ If the access tool hides pagination, use its documented complete-list mode
189
+ or another configured read path that exposes continuation metadata.
181
190
 
182
191
  Capture each ticket's: key, summary, issue type, priority, assignee, parent (epic), status (with
183
192
  its category), labels, components.
@@ -164,8 +164,15 @@ This skill ONLY transitions `$READY → $CLAIMED` on claim, and `$CLAIMED → $D
164
164
 
165
165
  1. List the team's workflow states via `lisa-linear-access operation: list-workflow-states`.
166
166
  2. Keep every state whose `type` is `backlog` or `unstarted` — that is the pre-work set. `$READY` is one member of it, not the whole of it.
167
- 3. Query each pre-work state: `lisa-linear-access operation: list-issues({team: <teamId>, state: "<state>"})`, paging to `hasNextPage=false`. Linear's GraphQL complexity ceiling silently truncates at `first: 250`, so a single unpaged call is not a count.
168
- 4. Also read the **total open** count for the team (every state whose `type` is not `completed` / `canceled`). This number is what makes an omitted lane arithmetically visible.
167
+ 3. Query each pre-work state: `lisa-linear-access operation: list-issues({team: <teamId>, state: "<state>"})`, following `endCursor` until `hasNextPage=false`. Deduplicate issue IDs. A failed page or non-advancing cursor makes the read incomplete; report it and end the cycle without dispatching. Do not infer completeness from a single page's size.
168
+ 4. Also read the **total open** count for the team using the same terminal set as the child check below: exclude `completed`, `canceled`, and `duplicate`. Intermediate deployment states remain open.
169
+
170
+ Report the query scope, pages read and distinct issue count. If a previous read
171
+ or a known issue contradicts the result, re-read that evidence before declaring
172
+ the queue empty. Identifier ranges and gaps are diagnostics, not proof of
173
+ completeness: filters, deleted issues and unseen omissions can all affect them.
174
+ The historical 249-row report did not establish a root-connection defect, so it
175
+ does not justify changing connections or adding a separate range-validation gate.
169
176
 
170
177
  Capture each Issue's: identifier, title, type label, priority, assignee, project, state (with its `type`), labels, description summary.
171
178
 
@@ -174,15 +174,25 @@ A "transition" means: remove the old role label and add the new one, in two `gh
174
174
  ### Phase 2 — Find ready issues
175
175
 
176
176
  ```bash
177
- if [ -n "$ASSIGNEE" ]; then
178
- gh issue list --repo <org>/<repo> --label "$READY" --assignee "$ASSIGNEE" --state open \
179
- --json number,title,labels,assignees,milestone,createdAt --limit 100
180
- else
181
- gh issue list --repo <org>/<repo> --label "$READY" --state open \
182
- --json number,title,labels,assignees,milestone,createdAt --limit 100
177
+ # QUEUE_REPO is the resolved <org>/<repo> from Phase 1.
178
+ if [ "${ASSIGNEE:-}" = "@me" ]; then
179
+ ASSIGNEE=$(gh api user --jq .login) || exit 1
183
180
  fi
181
+ ISSUE_PAGES=$(gh api --method GET "repos/$QUEUE_REPO/issues" \
182
+ -f state=open -f per_page=100 --paginate --slurp) || exit 1
183
+ # The repository issues endpoint also returns pull requests; exclude them.
184
+ ISSUES_JSON=$(printf '%s' "$ISSUE_PAGES" | jq '[.[][] | select(has("pull_request") | not)]') || exit 1
185
+ printf '%s' "$ISSUES_JSON" | jq --arg ready "$READY" --arg assignee "${ASSIGNEE:-}" '
186
+ [.[] | select(any(.labels[]; .name == $ready))
187
+ | select($assignee == "" or any(.assignees[]; .login == $assignee))]'
184
188
  ```
185
189
 
190
+ Wait for every page before choosing work or reporting an empty queue. A failed
191
+ page is an incomplete read: report it and end this cycle without dispatching.
192
+ The REST fields use `created_at` and label/assignee objects. Reuse this complete
193
+ issue snapshot for the lane counts below; apply the assignee filter to candidates
194
+ only, so the repository totals still describe the whole queue.
195
+
186
196
  If empty, run a secondary check to distinguish a genuinely empty queue from an unconfigured repo:
187
197
 
188
198
  ```bash
@@ -206,8 +216,8 @@ GitHub's data model, not a preference (see "Why labels" above). That makes the o
206
216
  - open issues carrying **no** build role label — which this scanner must see anyway in order to
207
217
  determine and stamp their repo.
208
218
 
209
- Count each lane and the repo's **total open** count (`gh issue list --state open --limit 1000 --json
210
- number | jq length`), then build the denominator with the shared helper — GitHub callers pass the
219
+ Count each lane and the repo's **total open** count from `ISSUES_JSON`, then build
220
+ the denominator with the shared helper — GitHub callers pass the
211
221
  lane type explicitly, since there is none to read:
212
222
 
213
223
  ```text
@@ -177,7 +177,16 @@ the Linear side produced 31 consecutive false "dry lane" cycles (#2657).
177
177
  2. Then sweep the rest of pre-work with the same base JQL, swapping the status clause for
178
178
  `statusCategory = "To Do"`, and read the **total open** count (`statusCategory != Done`). The
179
179
  open total is what makes an omitted lane arithmetically visible.
180
- 3. Page to exhaustion — a single unpaged `search-issues` call is not a count.
180
+ 3. Page each query to exhaustion using the configured access tool's pagination
181
+ fields. For token-based search, pass the returned `nextPageToken` until the
182
+ response marks the last page. For offset-based search, advance `startAt` by
183
+ the number of returned issues until the reported total is reached. Keep the
184
+ same JQL and ordering throughout, and deduplicate issue keys across pages.
185
+ A failed page, repeated cursor, or missing continuation while more results
186
+ are reported makes the read incomplete. Report that condition and end the
187
+ cycle without dispatching; never report a partial read as an empty queue.
188
+ If the access tool hides pagination, use its documented complete-list mode
189
+ or another configured read path that exposes continuation metadata.
181
190
 
182
191
  Capture each ticket's: key, summary, issue type, priority, assignee, parent (epic), status (with
183
192
  its category), labels, components.
@@ -164,8 +164,15 @@ This skill ONLY transitions `$READY → $CLAIMED` on claim, and `$CLAIMED → $D
164
164
 
165
165
  1. List the team's workflow states via `lisa-linear-access operation: list-workflow-states`.
166
166
  2. Keep every state whose `type` is `backlog` or `unstarted` — that is the pre-work set. `$READY` is one member of it, not the whole of it.
167
- 3. Query each pre-work state: `lisa-linear-access operation: list-issues({team: <teamId>, state: "<state>"})`, paging to `hasNextPage=false`. Linear's GraphQL complexity ceiling silently truncates at `first: 250`, so a single unpaged call is not a count.
168
- 4. Also read the **total open** count for the team (every state whose `type` is not `completed` / `canceled`). This number is what makes an omitted lane arithmetically visible.
167
+ 3. Query each pre-work state: `lisa-linear-access operation: list-issues({team: <teamId>, state: "<state>"})`, following `endCursor` until `hasNextPage=false`. Deduplicate issue IDs. A failed page or non-advancing cursor makes the read incomplete; report it and end the cycle without dispatching. Do not infer completeness from a single page's size.
168
+ 4. Also read the **total open** count for the team using the same terminal set as the child check below: exclude `completed`, `canceled`, and `duplicate`. Intermediate deployment states remain open.
169
+
170
+ Report the query scope, pages read and distinct issue count. If a previous read
171
+ or a known issue contradicts the result, re-read that evidence before declaring
172
+ the queue empty. Identifier ranges and gaps are diagnostics, not proof of
173
+ completeness: filters, deleted issues and unseen omissions can all affect them.
174
+ The historical 249-row report did not establish a root-connection defect, so it
175
+ does not justify changing connections or adding a separate range-validation gate.
169
176
 
170
177
  Capture each Issue's: identifier, title, type label, priority, assignee, project, state (with its `type`), labels, description summary.
171
178
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -174,15 +174,25 @@ A "transition" means: remove the old role label and add the new one, in two `gh
174
174
  ### Phase 2 — Find ready issues
175
175
 
176
176
  ```bash
177
- if [ -n "$ASSIGNEE" ]; then
178
- gh issue list --repo <org>/<repo> --label "$READY" --assignee "$ASSIGNEE" --state open \
179
- --json number,title,labels,assignees,milestone,createdAt --limit 100
180
- else
181
- gh issue list --repo <org>/<repo> --label "$READY" --state open \
182
- --json number,title,labels,assignees,milestone,createdAt --limit 100
177
+ # QUEUE_REPO is the resolved <org>/<repo> from Phase 1.
178
+ if [ "${ASSIGNEE:-}" = "@me" ]; then
179
+ ASSIGNEE=$(gh api user --jq .login) || exit 1
183
180
  fi
181
+ ISSUE_PAGES=$(gh api --method GET "repos/$QUEUE_REPO/issues" \
182
+ -f state=open -f per_page=100 --paginate --slurp) || exit 1
183
+ # The repository issues endpoint also returns pull requests; exclude them.
184
+ ISSUES_JSON=$(printf '%s' "$ISSUE_PAGES" | jq '[.[][] | select(has("pull_request") | not)]') || exit 1
185
+ printf '%s' "$ISSUES_JSON" | jq --arg ready "$READY" --arg assignee "${ASSIGNEE:-}" '
186
+ [.[] | select(any(.labels[]; .name == $ready))
187
+ | select($assignee == "" or any(.assignees[]; .login == $assignee))]'
184
188
  ```
185
189
 
190
+ Wait for every page before choosing work or reporting an empty queue. A failed
191
+ page is an incomplete read: report it and end this cycle without dispatching.
192
+ The REST fields use `created_at` and label/assignee objects. Reuse this complete
193
+ issue snapshot for the lane counts below; apply the assignee filter to candidates
194
+ only, so the repository totals still describe the whole queue.
195
+
186
196
  If empty, run a secondary check to distinguish a genuinely empty queue from an unconfigured repo:
187
197
 
188
198
  ```bash
@@ -206,8 +216,8 @@ GitHub's data model, not a preference (see "Why labels" above). That makes the o
206
216
  - open issues carrying **no** build role label — which this scanner must see anyway in order to
207
217
  determine and stamp their repo.
208
218
 
209
- Count each lane and the repo's **total open** count (`gh issue list --state open --limit 1000 --json
210
- number | jq length`), then build the denominator with the shared helper — GitHub callers pass the
219
+ Count each lane and the repo's **total open** count from `ISSUES_JSON`, then build
220
+ the denominator with the shared helper — GitHub callers pass the
211
221
  lane type explicitly, since there is none to read:
212
222
 
213
223
  ```text
@@ -177,7 +177,16 @@ the Linear side produced 31 consecutive false "dry lane" cycles (#2657).
177
177
  2. Then sweep the rest of pre-work with the same base JQL, swapping the status clause for
178
178
  `statusCategory = "To Do"`, and read the **total open** count (`statusCategory != Done`). The
179
179
  open total is what makes an omitted lane arithmetically visible.
180
- 3. Page to exhaustion — a single unpaged `search-issues` call is not a count.
180
+ 3. Page each query to exhaustion using the configured access tool's pagination
181
+ fields. For token-based search, pass the returned `nextPageToken` until the
182
+ response marks the last page. For offset-based search, advance `startAt` by
183
+ the number of returned issues until the reported total is reached. Keep the
184
+ same JQL and ordering throughout, and deduplicate issue keys across pages.
185
+ A failed page, repeated cursor, or missing continuation while more results
186
+ are reported makes the read incomplete. Report that condition and end the
187
+ cycle without dispatching; never report a partial read as an empty queue.
188
+ If the access tool hides pagination, use its documented complete-list mode
189
+ or another configured read path that exposes continuation metadata.
181
190
 
182
191
  Capture each ticket's: key, summary, issue type, priority, assignee, parent (epic), status (with
183
192
  its category), labels, components.
@@ -164,8 +164,15 @@ This skill ONLY transitions `$READY → $CLAIMED` on claim, and `$CLAIMED → $D
164
164
 
165
165
  1. List the team's workflow states via `lisa-linear-access operation: list-workflow-states`.
166
166
  2. Keep every state whose `type` is `backlog` or `unstarted` — that is the pre-work set. `$READY` is one member of it, not the whole of it.
167
- 3. Query each pre-work state: `lisa-linear-access operation: list-issues({team: <teamId>, state: "<state>"})`, paging to `hasNextPage=false`. Linear's GraphQL complexity ceiling silently truncates at `first: 250`, so a single unpaged call is not a count.
168
- 4. Also read the **total open** count for the team (every state whose `type` is not `completed` / `canceled`). This number is what makes an omitted lane arithmetically visible.
167
+ 3. Query each pre-work state: `lisa-linear-access operation: list-issues({team: <teamId>, state: "<state>"})`, following `endCursor` until `hasNextPage=false`. Deduplicate issue IDs. A failed page or non-advancing cursor makes the read incomplete; report it and end the cycle without dispatching. Do not infer completeness from a single page's size.
168
+ 4. Also read the **total open** count for the team using the same terminal set as the child check below: exclude `completed`, `canceled`, and `duplicate`. Intermediate deployment states remain open.
169
+
170
+ Report the query scope, pages read and distinct issue count. If a previous read
171
+ or a known issue contradicts the result, re-read that evidence before declaring
172
+ the queue empty. Identifier ranges and gaps are diagnostics, not proof of
173
+ completeness: filters, deleted issues and unseen omissions can all affect them.
174
+ The historical 249-row report did not establish a root-connection defect, so it
175
+ does not justify changing connections or adding a separate range-validation gate.
169
176
 
170
177
  Capture each Issue's: identifier, title, type label, priority, assignee, project, state (with its `type`), labels, description summary.
171
178
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "AWS CDK-specific Lisa plugin.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -174,15 +174,25 @@ A "transition" means: remove the old role label and add the new one, in two `gh
174
174
  ### Phase 2 — Find ready issues
175
175
 
176
176
  ```bash
177
- if [ -n "$ASSIGNEE" ]; then
178
- gh issue list --repo <org>/<repo> --label "$READY" --assignee "$ASSIGNEE" --state open \
179
- --json number,title,labels,assignees,milestone,createdAt --limit 100
180
- else
181
- gh issue list --repo <org>/<repo> --label "$READY" --state open \
182
- --json number,title,labels,assignees,milestone,createdAt --limit 100
177
+ # QUEUE_REPO is the resolved <org>/<repo> from Phase 1.
178
+ if [ "${ASSIGNEE:-}" = "@me" ]; then
179
+ ASSIGNEE=$(gh api user --jq .login) || exit 1
183
180
  fi
181
+ ISSUE_PAGES=$(gh api --method GET "repos/$QUEUE_REPO/issues" \
182
+ -f state=open -f per_page=100 --paginate --slurp) || exit 1
183
+ # The repository issues endpoint also returns pull requests; exclude them.
184
+ ISSUES_JSON=$(printf '%s' "$ISSUE_PAGES" | jq '[.[][] | select(has("pull_request") | not)]') || exit 1
185
+ printf '%s' "$ISSUES_JSON" | jq --arg ready "$READY" --arg assignee "${ASSIGNEE:-}" '
186
+ [.[] | select(any(.labels[]; .name == $ready))
187
+ | select($assignee == "" or any(.assignees[]; .login == $assignee))]'
184
188
  ```
185
189
 
190
+ Wait for every page before choosing work or reporting an empty queue. A failed
191
+ page is an incomplete read: report it and end this cycle without dispatching.
192
+ The REST fields use `created_at` and label/assignee objects. Reuse this complete
193
+ issue snapshot for the lane counts below; apply the assignee filter to candidates
194
+ only, so the repository totals still describe the whole queue.
195
+
186
196
  If empty, run a secondary check to distinguish a genuinely empty queue from an unconfigured repo:
187
197
 
188
198
  ```bash
@@ -206,8 +216,8 @@ GitHub's data model, not a preference (see "Why labels" above). That makes the o
206
216
  - open issues carrying **no** build role label — which this scanner must see anyway in order to
207
217
  determine and stamp their repo.
208
218
 
209
- Count each lane and the repo's **total open** count (`gh issue list --state open --limit 1000 --json
210
- number | jq length`), then build the denominator with the shared helper — GitHub callers pass the
219
+ Count each lane and the repo's **total open** count from `ISSUES_JSON`, then build
220
+ the denominator with the shared helper — GitHub callers pass the
211
221
  lane type explicitly, since there is none to read:
212
222
 
213
223
  ```text
@@ -177,7 +177,16 @@ the Linear side produced 31 consecutive false "dry lane" cycles (#2657).
177
177
  2. Then sweep the rest of pre-work with the same base JQL, swapping the status clause for
178
178
  `statusCategory = "To Do"`, and read the **total open** count (`statusCategory != Done`). The
179
179
  open total is what makes an omitted lane arithmetically visible.
180
- 3. Page to exhaustion — a single unpaged `search-issues` call is not a count.
180
+ 3. Page each query to exhaustion using the configured access tool's pagination
181
+ fields. For token-based search, pass the returned `nextPageToken` until the
182
+ response marks the last page. For offset-based search, advance `startAt` by
183
+ the number of returned issues until the reported total is reached. Keep the
184
+ same JQL and ordering throughout, and deduplicate issue keys across pages.
185
+ A failed page, repeated cursor, or missing continuation while more results
186
+ are reported makes the read incomplete. Report that condition and end the
187
+ cycle without dispatching; never report a partial read as an empty queue.
188
+ If the access tool hides pagination, use its documented complete-list mode
189
+ or another configured read path that exposes continuation metadata.
181
190
 
182
191
  Capture each ticket's: key, summary, issue type, priority, assignee, parent (epic), status (with
183
192
  its category), labels, components.
@@ -164,8 +164,15 @@ This skill ONLY transitions `$READY → $CLAIMED` on claim, and `$CLAIMED → $D
164
164
 
165
165
  1. List the team's workflow states via `lisa-linear-access operation: list-workflow-states`.
166
166
  2. Keep every state whose `type` is `backlog` or `unstarted` — that is the pre-work set. `$READY` is one member of it, not the whole of it.
167
- 3. Query each pre-work state: `lisa-linear-access operation: list-issues({team: <teamId>, state: "<state>"})`, paging to `hasNextPage=false`. Linear's GraphQL complexity ceiling silently truncates at `first: 250`, so a single unpaged call is not a count.
168
- 4. Also read the **total open** count for the team (every state whose `type` is not `completed` / `canceled`). This number is what makes an omitted lane arithmetically visible.
167
+ 3. Query each pre-work state: `lisa-linear-access operation: list-issues({team: <teamId>, state: "<state>"})`, following `endCursor` until `hasNextPage=false`. Deduplicate issue IDs. A failed page or non-advancing cursor makes the read incomplete; report it and end the cycle without dispatching. Do not infer completeness from a single page's size.
168
+ 4. Also read the **total open** count for the team using the same terminal set as the child check below: exclude `completed`, `canceled`, and `duplicate`. Intermediate deployment states remain open.
169
+
170
+ Report the query scope, pages read and distinct issue count. If a previous read
171
+ or a known issue contradicts the result, re-read that evidence before declaring
172
+ the queue empty. Identifier ranges and gaps are diagnostics, not proof of
173
+ completeness: filters, deleted issues and unseen omissions can all affect them.
174
+ The historical 249-row report did not establish a root-connection defect, so it
175
+ does not justify changing connections or adding a separate range-validation gate.
169
176
 
170
177
  Capture each Issue's: identifier, title, type label, priority, assignee, project, state (with its `type`), labels, description summary.
171
178
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -174,15 +174,25 @@ A "transition" means: remove the old role label and add the new one, in two `gh
174
174
  ### Phase 2 — Find ready issues
175
175
 
176
176
  ```bash
177
- if [ -n "$ASSIGNEE" ]; then
178
- gh issue list --repo <org>/<repo> --label "$READY" --assignee "$ASSIGNEE" --state open \
179
- --json number,title,labels,assignees,milestone,createdAt --limit 100
180
- else
181
- gh issue list --repo <org>/<repo> --label "$READY" --state open \
182
- --json number,title,labels,assignees,milestone,createdAt --limit 100
177
+ # QUEUE_REPO is the resolved <org>/<repo> from Phase 1.
178
+ if [ "${ASSIGNEE:-}" = "@me" ]; then
179
+ ASSIGNEE=$(gh api user --jq .login) || exit 1
183
180
  fi
181
+ ISSUE_PAGES=$(gh api --method GET "repos/$QUEUE_REPO/issues" \
182
+ -f state=open -f per_page=100 --paginate --slurp) || exit 1
183
+ # The repository issues endpoint also returns pull requests; exclude them.
184
+ ISSUES_JSON=$(printf '%s' "$ISSUE_PAGES" | jq '[.[][] | select(has("pull_request") | not)]') || exit 1
185
+ printf '%s' "$ISSUES_JSON" | jq --arg ready "$READY" --arg assignee "${ASSIGNEE:-}" '
186
+ [.[] | select(any(.labels[]; .name == $ready))
187
+ | select($assignee == "" or any(.assignees[]; .login == $assignee))]'
184
188
  ```
185
189
 
190
+ Wait for every page before choosing work or reporting an empty queue. A failed
191
+ page is an incomplete read: report it and end this cycle without dispatching.
192
+ The REST fields use `created_at` and label/assignee objects. Reuse this complete
193
+ issue snapshot for the lane counts below; apply the assignee filter to candidates
194
+ only, so the repository totals still describe the whole queue.
195
+
186
196
  If empty, run a secondary check to distinguish a genuinely empty queue from an unconfigured repo:
187
197
 
188
198
  ```bash
@@ -206,8 +216,8 @@ GitHub's data model, not a preference (see "Why labels" above). That makes the o
206
216
  - open issues carrying **no** build role label — which this scanner must see anyway in order to
207
217
  determine and stamp their repo.
208
218
 
209
- Count each lane and the repo's **total open** count (`gh issue list --state open --limit 1000 --json
210
- number | jq length`), then build the denominator with the shared helper — GitHub callers pass the
219
+ Count each lane and the repo's **total open** count from `ISSUES_JSON`, then build
220
+ the denominator with the shared helper — GitHub callers pass the
211
221
  lane type explicitly, since there is none to read:
212
222
 
213
223
  ```text
@@ -177,7 +177,16 @@ the Linear side produced 31 consecutive false "dry lane" cycles (#2657).
177
177
  2. Then sweep the rest of pre-work with the same base JQL, swapping the status clause for
178
178
  `statusCategory = "To Do"`, and read the **total open** count (`statusCategory != Done`). The
179
179
  open total is what makes an omitted lane arithmetically visible.
180
- 3. Page to exhaustion — a single unpaged `search-issues` call is not a count.
180
+ 3. Page each query to exhaustion using the configured access tool's pagination
181
+ fields. For token-based search, pass the returned `nextPageToken` until the
182
+ response marks the last page. For offset-based search, advance `startAt` by
183
+ the number of returned issues until the reported total is reached. Keep the
184
+ same JQL and ordering throughout, and deduplicate issue keys across pages.
185
+ A failed page, repeated cursor, or missing continuation while more results
186
+ are reported makes the read incomplete. Report that condition and end the
187
+ cycle without dispatching; never report a partial read as an empty queue.
188
+ If the access tool hides pagination, use its documented complete-list mode
189
+ or another configured read path that exposes continuation metadata.
181
190
 
182
191
  Capture each ticket's: key, summary, issue type, priority, assignee, parent (epic), status (with
183
192
  its category), labels, components.
@@ -164,8 +164,15 @@ This skill ONLY transitions `$READY → $CLAIMED` on claim, and `$CLAIMED → $D
164
164
 
165
165
  1. List the team's workflow states via `lisa-linear-access operation: list-workflow-states`.
166
166
  2. Keep every state whose `type` is `backlog` or `unstarted` — that is the pre-work set. `$READY` is one member of it, not the whole of it.
167
- 3. Query each pre-work state: `lisa-linear-access operation: list-issues({team: <teamId>, state: "<state>"})`, paging to `hasNextPage=false`. Linear's GraphQL complexity ceiling silently truncates at `first: 250`, so a single unpaged call is not a count.
168
- 4. Also read the **total open** count for the team (every state whose `type` is not `completed` / `canceled`). This number is what makes an omitted lane arithmetically visible.
167
+ 3. Query each pre-work state: `lisa-linear-access operation: list-issues({team: <teamId>, state: "<state>"})`, following `endCursor` until `hasNextPage=false`. Deduplicate issue IDs. A failed page or non-advancing cursor makes the read incomplete; report it and end the cycle without dispatching. Do not infer completeness from a single page's size.
168
+ 4. Also read the **total open** count for the team using the same terminal set as the child check below: exclude `completed`, `canceled`, and `duplicate`. Intermediate deployment states remain open.
169
+
170
+ Report the query scope, pages read and distinct issue count. If a previous read
171
+ or a known issue contradicts the result, re-read that evidence before declaring
172
+ the queue empty. Identifier ranges and gaps are diagnostics, not proof of
173
+ completeness: filters, deleted issues and unseen omissions can all affect them.
174
+ The historical 249-row report did not establish a root-connection defect, so it
175
+ does not justify changing connections or adding a separate range-validation gate.
169
176
 
170
177
  Capture each Issue's: identifier, title, type label, priority, assignee, project, state (with its `type`), labels, description summary.
171
178
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "Expo and React Native-specific skills, agents, rules, and MCP servers.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "Harper/Fabric-specific Lisa rules for TypeScript component apps.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "NestJS-specific skills and migration write-protection hooks.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
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": "4.55.24",
3
+ "version": "4.55.26",
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": "4.55.24",
3
+ "version": "4.55.26",
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": "4.55.24",
3
+ "version": "4.55.26",
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": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "Ruby on Rails-specific skills and hooks for RuboCop and ast-grep scanning on edit.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "TypeScript-specific hooks for formatting, linting, and ast-grep scanning on edit.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "Distributable LLM Wiki kernel — ingest, query, lint, and maintain a git-native markdown knowledge base across Claude and Codex.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "4.55.24",
3
+ "version": "4.55.26",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -174,15 +174,25 @@ A "transition" means: remove the old role label and add the new one, in two `gh
174
174
  ### Phase 2 — Find ready issues
175
175
 
176
176
  ```bash
177
- if [ -n "$ASSIGNEE" ]; then
178
- gh issue list --repo <org>/<repo> --label "$READY" --assignee "$ASSIGNEE" --state open \
179
- --json number,title,labels,assignees,milestone,createdAt --limit 100
180
- else
181
- gh issue list --repo <org>/<repo> --label "$READY" --state open \
182
- --json number,title,labels,assignees,milestone,createdAt --limit 100
177
+ # QUEUE_REPO is the resolved <org>/<repo> from Phase 1.
178
+ if [ "${ASSIGNEE:-}" = "@me" ]; then
179
+ ASSIGNEE=$(gh api user --jq .login) || exit 1
183
180
  fi
181
+ ISSUE_PAGES=$(gh api --method GET "repos/$QUEUE_REPO/issues" \
182
+ -f state=open -f per_page=100 --paginate --slurp) || exit 1
183
+ # The repository issues endpoint also returns pull requests; exclude them.
184
+ ISSUES_JSON=$(printf '%s' "$ISSUE_PAGES" | jq '[.[][] | select(has("pull_request") | not)]') || exit 1
185
+ printf '%s' "$ISSUES_JSON" | jq --arg ready "$READY" --arg assignee "${ASSIGNEE:-}" '
186
+ [.[] | select(any(.labels[]; .name == $ready))
187
+ | select($assignee == "" or any(.assignees[]; .login == $assignee))]'
184
188
  ```
185
189
 
190
+ Wait for every page before choosing work or reporting an empty queue. A failed
191
+ page is an incomplete read: report it and end this cycle without dispatching.
192
+ The REST fields use `created_at` and label/assignee objects. Reuse this complete
193
+ issue snapshot for the lane counts below; apply the assignee filter to candidates
194
+ only, so the repository totals still describe the whole queue.
195
+
186
196
  If empty, run a secondary check to distinguish a genuinely empty queue from an unconfigured repo:
187
197
 
188
198
  ```bash
@@ -206,8 +216,8 @@ GitHub's data model, not a preference (see "Why labels" above). That makes the o
206
216
  - open issues carrying **no** build role label — which this scanner must see anyway in order to
207
217
  determine and stamp their repo.
208
218
 
209
- Count each lane and the repo's **total open** count (`gh issue list --state open --limit 1000 --json
210
- number | jq length`), then build the denominator with the shared helper — GitHub callers pass the
219
+ Count each lane and the repo's **total open** count from `ISSUES_JSON`, then build
220
+ the denominator with the shared helper — GitHub callers pass the
211
221
  lane type explicitly, since there is none to read:
212
222
 
213
223
  ```text
@@ -177,7 +177,16 @@ the Linear side produced 31 consecutive false "dry lane" cycles (#2657).
177
177
  2. Then sweep the rest of pre-work with the same base JQL, swapping the status clause for
178
178
  `statusCategory = "To Do"`, and read the **total open** count (`statusCategory != Done`). The
179
179
  open total is what makes an omitted lane arithmetically visible.
180
- 3. Page to exhaustion — a single unpaged `search-issues` call is not a count.
180
+ 3. Page each query to exhaustion using the configured access tool's pagination
181
+ fields. For token-based search, pass the returned `nextPageToken` until the
182
+ response marks the last page. For offset-based search, advance `startAt` by
183
+ the number of returned issues until the reported total is reached. Keep the
184
+ same JQL and ordering throughout, and deduplicate issue keys across pages.
185
+ A failed page, repeated cursor, or missing continuation while more results
186
+ are reported makes the read incomplete. Report that condition and end the
187
+ cycle without dispatching; never report a partial read as an empty queue.
188
+ If the access tool hides pagination, use its documented complete-list mode
189
+ or another configured read path that exposes continuation metadata.
181
190
 
182
191
  Capture each ticket's: key, summary, issue type, priority, assignee, parent (epic), status (with
183
192
  its category), labels, components.
@@ -164,8 +164,15 @@ This skill ONLY transitions `$READY → $CLAIMED` on claim, and `$CLAIMED → $D
164
164
 
165
165
  1. List the team's workflow states via `lisa-linear-access operation: list-workflow-states`.
166
166
  2. Keep every state whose `type` is `backlog` or `unstarted` — that is the pre-work set. `$READY` is one member of it, not the whole of it.
167
- 3. Query each pre-work state: `lisa-linear-access operation: list-issues({team: <teamId>, state: "<state>"})`, paging to `hasNextPage=false`. Linear's GraphQL complexity ceiling silently truncates at `first: 250`, so a single unpaged call is not a count.
168
- 4. Also read the **total open** count for the team (every state whose `type` is not `completed` / `canceled`). This number is what makes an omitted lane arithmetically visible.
167
+ 3. Query each pre-work state: `lisa-linear-access operation: list-issues({team: <teamId>, state: "<state>"})`, following `endCursor` until `hasNextPage=false`. Deduplicate issue IDs. A failed page or non-advancing cursor makes the read incomplete; report it and end the cycle without dispatching. Do not infer completeness from a single page's size.
168
+ 4. Also read the **total open** count for the team using the same terminal set as the child check below: exclude `completed`, `canceled`, and `duplicate`. Intermediate deployment states remain open.
169
+
170
+ Report the query scope, pages read and distinct issue count. If a previous read
171
+ or a known issue contradicts the result, re-read that evidence before declaring
172
+ the queue empty. Identifier ranges and gaps are diagnostics, not proof of
173
+ completeness: filters, deleted issues and unseen omissions can all affect them.
174
+ The historical 249-row report did not establish a root-connection defect, so it
175
+ does not justify changing connections or adding a separate range-validation gate.
169
176
 
170
177
  Capture each Issue's: identifier, title, type label, priority, assignee, project, state (with its `type`), labels, description summary.
171
178