@codyswann/lisa 2.159.1 → 2.159.3

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 (69) hide show
  1. package/package.json +1 -1
  2. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  3. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  4. package/plugins/lisa/rules/eager/verification.md +2 -0
  5. package/plugins/lisa/rules/reference/verification.md +14 -0
  6. package/plugins/lisa/skills/atlassian-access/SKILL.md +32 -10
  7. package/plugins/lisa/skills/verification-lifecycle/SKILL.md +16 -0
  8. package/plugins/lisa/skills/verify/SKILL.md +3 -0
  9. package/plugins/lisa-agy/plugin.json +1 -1
  10. package/plugins/lisa-agy/skills/atlassian-access/SKILL.md +32 -10
  11. package/plugins/lisa-agy/skills/verification-lifecycle/SKILL.md +16 -0
  12. package/plugins/lisa-agy/skills/verify/SKILL.md +3 -0
  13. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  14. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  15. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  16. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  17. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  18. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  19. package/plugins/lisa-copilot/rules/eager/verification.md +2 -0
  20. package/plugins/lisa-copilot/rules/reference/verification.md +14 -0
  21. package/plugins/lisa-copilot/skills/atlassian-access/SKILL.md +32 -10
  22. package/plugins/lisa-copilot/skills/verification-lifecycle/SKILL.md +16 -0
  23. package/plugins/lisa-copilot/skills/verify/SKILL.md +3 -0
  24. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  25. package/plugins/lisa-cursor/rules/verification-reference.mdc +14 -0
  26. package/plugins/lisa-cursor/rules/verification.mdc +2 -0
  27. package/plugins/lisa-cursor/skills/atlassian-access/SKILL.md +32 -10
  28. package/plugins/lisa-cursor/skills/verification-lifecycle/SKILL.md +16 -0
  29. package/plugins/lisa-cursor/skills/verify/SKILL.md +3 -0
  30. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  31. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  32. package/plugins/lisa-expo-agy/plugin.json +1 -1
  33. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  34. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  35. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  36. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  37. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  38. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  39. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  40. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  41. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  42. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  43. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  44. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  45. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  46. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  47. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  48. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  49. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  50. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  51. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  52. package/plugins/lisa-rails-agy/plugin.json +1 -1
  53. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  54. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  55. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  56. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  57. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  58. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  59. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  60. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  61. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  62. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  63. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  64. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  65. package/plugins/src/base/rules/eager/verification.md +2 -0
  66. package/plugins/src/base/rules/reference/verification.md +14 -0
  67. package/plugins/src/base/skills/atlassian-access/SKILL.md +32 -10
  68. package/plugins/src/base/skills/verification-lifecycle/SKILL.md +16 -0
  69. package/plugins/src/base/skills/verify/SKILL.md +3 -0
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: atlassian-access
3
- description: "Vendor-neutral access layer for Atlassian (JIRA + Confluence). Every jira-* and confluence-* skill MUST delegate through this skill rather than calling Atlassian directly. Resolves a substrate per operation in this order: (1) acli if installed and switchable to a profile matching the configured site, (2) Atlassian MCP if authenticated and the configured cloudId is in its accessible resources, (3) curl + API-token Basic auth. Verifies the active connection matches `.lisa.config.json` before every operation substrates authenticated as a different Atlassian account are switched to the configured profile when one exists, and skipped only after switch plus re-verification fails."
3
+ description: "Vendor-neutral access layer for Atlassian (JIRA + Confluence). Every jira-* and confluence-* skill MUST delegate through this skill rather than calling Atlassian directly. Resolves a substrate per operation, binding JIRA writes to the configured cloudId via Atlassian REST whenever token auth is available and using acli only for reads or as a guarded fallback. For non-write acli operations, acli is used when installed and switchable to a profile matching the configured site; mismatched active profiles are skipped only after switch plus re-verification fails."
4
4
  allowed-tools: ["Bash", "Read", "Skill"]
5
5
  ---
6
6
 
@@ -40,8 +40,13 @@ Probe each tier in order; the first that's ready AND identity-matches is the sub
40
40
  ```bash
41
41
  substrate=""
42
42
 
43
- # Tier 1: acli
44
- if command -v acli >/dev/null 2>&1 && acli auth status >/dev/null 2>&1; then
43
+ # Tier 1: acli for reads and non-write operations only.
44
+ #
45
+ # Do not choose acli for JIRA writes when curl/token auth is available. acli stores
46
+ # one machine-global active account and workitem writes cannot pin a cloudId per
47
+ # invocation, so switch-then-write is a TOCTOU risk in multi-account or concurrent
48
+ # sessions. Write operations prefer the cloudId-scoped REST URL below.
49
+ if [ "$OP_KIND" != "jira-write" ] && command -v acli >/dev/null 2>&1 && acli auth status >/dev/null 2>&1; then
45
50
  current_site=$(acli auth status 2>/dev/null | awk '/^ Site:/{print $2}')
46
51
  if [ "$current_site" != "$SITE" ]; then
47
52
  # acli installed but pointing at a different site. Try switching profiles.
@@ -114,7 +119,13 @@ public static class LisaCred {
114
119
  esac
115
120
  }
116
121
  TOKEN=$(read_atlassian_token "$EMAIL")
117
- [ -n "$TOKEN" ] && curl_available=true && : ${substrate:=curl}
122
+ [ -n "$TOKEN" ] && curl_available=true && {
123
+ if [ "$OP_KIND" = "jira-write" ]; then
124
+ substrate="curl"
125
+ else
126
+ : ${substrate:=curl}
127
+ fi
128
+ }
118
129
 
119
130
  # Fail loudly with actionable remediation if nothing works.
120
131
  if [ -z "$substrate" ]; then
@@ -271,18 +282,18 @@ Substrate column meanings:
271
282
  - Multiple cells filled means tier ordering applies — try acli, then MCP, then curl, taking the first that has an adapter for the op AND is identity-matched.
272
283
  - One cell means only that substrate can perform the op.
273
284
 
274
- `<SITE>` = `.atlassian.site` (e.g. `propswap.atlassian.net`). `<CLOUDID>` = `.atlassian.cloudId`. `<AUTH>` = `Basic $(printf '%s:%s' "$email" "$ATLASSIAN_API_TOKEN" | base64)`. JIRA paths use `/rest/api/3/...`; Confluence uses `/wiki/rest/api/...` (v1) or `/api/v2/...` (v2).
285
+ `<SITE>` = `.atlassian.site` (e.g. `propswap.atlassian.net`). `<CLOUDID>` = `.atlassian.cloudId`. `<AUTH>` = `Basic $(printf '%s:%s' "$email" "$ATLASSIAN_API_TOKEN" | base64)`. JIRA curl writes use the cloudId-bound Atlassian gateway `https://api.atlassian.com/ex/jira/<CLOUDID>/rest/api/3/...`; JIRA curl reads may use either that gateway or `https://<SITE>/rest/api/3/...` after the token account check. Confluence uses `/wiki/rest/api/...` (v1) or `/api/v2/...` (v2).
275
286
 
276
287
  | Operation | acli adapter | MCP adapter | curl adapter |
277
288
  |---|---|---|---|
278
289
  | **JIRA ops** | | | |
279
290
  | `read-ticket key:<K>` | `acli jira workitem view <K> --fields '*all' --json` | `mcp__plugin_atlassian_atlassian__getJiraIssue` | `GET https://<SITE>/rest/api/3/issue/<K>?fields=*all` |
280
- | `write-ticket payload:<P>` (create) | `acli jira workitem create --from-json <P>` | `mcp__plugin_atlassian_atlassian__createJiraIssue` | `POST https://<SITE>/rest/api/3/issue` body=`<P>` |
281
- | `write-ticket payload:<P>` (edit) | `acli jira workitem edit <K> --from-json <P>` | `mcp__plugin_atlassian_atlassian__editJiraIssue` | `PUT https://<SITE>/rest/api/3/issue/<K>` body=`<P>` |
282
- | `transition key:<K> to:<S>` | `acli jira workitem transition --key <K> --status "<S>" --yes` | `mcp__plugin_atlassian_atlassian__transitionJiraIssue` | resolve transition id then `POST .../issue/<K>/transitions` |
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
+ | `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
+ | `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` |
283
294
  | `transitions key:<K>` | (not exposed) | `mcp__plugin_atlassian_atlassian__getTransitionsForJiraIssue` | `GET https://<SITE>/rest/api/3/issue/<K>/transitions` |
284
- | `comment key:<K> body:<B>` | `acli jira workitem comment add --key <K> --body "<B>"` | `mcp__plugin_atlassian_atlassian__addCommentToJiraIssue` | `POST https://<SITE>/rest/api/3/issue/<K>/comment` |
285
- | `link from:<K> to:<K2> type:<T>` | `acli jira workitem link create --in <K> --out <K2> --type "<T>" --yes` (see direction note) | `mcp__plugin_atlassian_atlassian__createJiraIssueLink` | `POST https://<SITE>/rest/api/3/issueLink` |
295
+ | `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
+ | `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` |
286
297
  | `remote-links key:<K>` | (not exposed) | `mcp__plugin_atlassian_atlassian__getJiraIssueRemoteIssueLinks` | `GET https://<SITE>/rest/api/3/issue/<K>/remotelink` |
287
298
  | `search-issues jql:<J>` | `acli jira workitem search --jql "<J>" --json` | `mcp__plugin_atlassian_atlassian__searchJiraIssuesUsingJql` | `POST https://<SITE>/rest/api/3/search/jql` |
288
299
  | `list-projects` | `acli jira project list --paginate --json` | `mcp__plugin_atlassian_atlassian__getVisibleJiraProjects` | `GET https://<SITE>/rest/api/3/project/search` |
@@ -305,6 +316,16 @@ Substrate column meanings:
305
316
 
306
317
  **acli flag note:** acli's `--output` flag does not exist; the correct flag is `--json`. List commands require `--paginate` or `--limit` (no implicit fetch-all). `acli jira workitem view` defaults to a restricted field set (`key,issuetype,summary,status,assignee,description`), so `read-ticket` MUST pass `--fields '*all'` or an explicit equivalent that includes every downstream dependency: parent, subtasks, issue links, components, labels, priority, status, issue type, summary, description, fix versions, affected versions, attachments, comments, estimates, sprint/story-point fields, and project-required custom fields. Never rely on the default view fields; they hide parent/components/labels and corrupt leaf-only, relationship-search, build-ready, and required-custom-field gates. Several documented adapters are nominal — verify against `acli <subcmd> --help` before relying on them. When acli's adapter is broken or missing for a specific op, fall through to MCP (if identity-matched) then curl per the tier ordering.
307
318
 
319
+ **JIRA write tenant-safety rule:** create, edit, transition, comment, and link are write operations. They MUST prefer the curl adapter whenever token auth is available because the URL includes `<CLOUDID>` and cannot be redirected by the user-global acli active account. If the flow must fall back to acli for a write, it is a guarded fallback, not the normal path:
320
+
321
+ 1. Switch and assert the active `acli auth status` site/email matches config immediately before the write.
322
+ 2. Execute the write.
323
+ 3. Read the affected issue(s) immediately after the write.
324
+ 4. Assert each response belongs to the configured tenant by checking one of: response `self` URL host equals `<SITE>`, response `self` URL path includes `/ex/jira/<CLOUDID>/`, or response metadata reports `<CLOUDID>`.
325
+ 5. If the assertion fails, stop, report a cross-tenant write hazard, and best-effort roll back the write when there is a safe reversal: delete a newly created issue, remove a newly created comment/link, or revert a reversible field edit. Never continue as if the write succeeded.
326
+
327
+ Do not treat a successful `acli auth switch` or pre-write `auth status` as sufficient for tenant safety. Another process can mutate the global acli active account between the check and the write.
328
+
308
329
  **acli link-create direction is invertible — flags and verification:** acli has no `--inward`/`--outward` flags; the real flags are `--in` and `--out` (confirm with `acli jira workitem link create --help`). For a `Blocks` link, **`--in` is the blocker and `--out` is the blocked** issue, i.e. `--in <X> --out <Y> --type Blocks` resolves to "X blocks Y" (Y `is blocked by` X). The lisa op `link from:<K> to:<K2> type:<T>` means "K ⟨T⟩ K2", so the blocker `from` maps to `--in` and the blocked `to` maps to `--out` (as in the adapter above). The acli success banner only echoes the `--in`/`--out` values you passed — it does NOT confirm the resolved semantic direction, so a reversed link reports success and looks fine. **After every `link` write, re-read the affected issues via `read-ticket` (which already requests `--fields '*all'`) and confirm `issuelinks[].type` + `inwardIssue`/`outwardIssue` resolve to the intended `blocks` / `is blocked by` direction.** Skipping this can silently reverse an entire epic's dependency graph — e.g. cutover tickets recorded as *blocking* the prerequisites that should block them.
309
330
 
310
331
  **JIRA terminal-resolution note:** when a caller marks a transition as terminal per `leaf-only-lifecycle`, the substrate must not treat a Done-named status as sufficient by name alone. After `transition key:<K> to:<S>`, re-read the issue and verify `statusCategory = Done`; if the workflow requires a resolution, verify `resolution` is set. If the transition screen requires a resolution value, pass the configured default resolution when available; otherwise return a setup error so the build-intake skill can report the workflow gap instead of silently leaving an unresolved ticket in a Done-looking status.
@@ -332,6 +353,7 @@ Do not paraphrase substrate output beyond JSON normalization.
332
353
  - Substrate is decided once per skill invocation and never switches mid-operation.
333
354
  - Connection match is mandatory. Operations that bypass it (because "the user obviously meant the configured site") are forbidden.
334
355
  - Profile mutations (`acli auth switch`) are allowed when acli is the active substrate. The curl substrate never mutates the token — if `ATLASSIAN_API_TOKEN` doesn't match the configured account, fail loud rather than silently substituting.
356
+ - JIRA writes are cloudId-bound by default. `acli` write adapters are fallback-only and must perform post-write tenant assertions plus safe rollback on mismatch.
335
357
  - `.lisa.config.local.json` overrides `.lisa.config.json` per-key — the same precedence rule as every other consumer of project config.
336
358
 
337
359
  ## Headless behavior
@@ -35,10 +35,20 @@ For each required verification type, discover what tools are available in the pr
35
35
 
36
36
  Report what is available for each required type. If a required type has no available tool, proceed to step 4.
37
37
 
38
+ If a required verification type needs sign-in or other credentials, exhaust credential sources before declaring the verification blocked. Check credential sources in this order:
39
+
40
+ 1. Project e2e / Playwright config and fixtures, including files such as `e2e/constants.ts`, `e2e/fixtures/api-login.ts`, seeded test users, and OTP-bypass patterns such as `555555`.
41
+ 2. `.lisa.config.local.json` and environment variables.
42
+ 3. Documented ticket credentials, including a `Sign-in Required` or equivalent section in the issue, ticket, PRD, or linked implementation notes.
43
+
44
+ Report which sources were checked. Do not say credentials are unavailable until all three source classes have been checked or proven absent.
45
+
38
46
  ### 4. Fail Fast
39
47
 
40
48
  If a required verification type has no available tool and no reasonable alternative, escalate immediately using the Escalation Protocol. Do not begin implementation without a verification plan for every required type.
41
49
 
50
+ If credentials are genuinely unavailable after the credential lookup order above is exhausted, treat the work item as blocked rather than done. Post a clear tracker comment stating exactly what runtime behavior could not be verified and which credential sources were checked, transition the item to the configured blocked state, and apply the configured `needs-human` / `human-review` label, creating that label if the tracker supports label creation and it is missing.
51
+
42
52
  ### 5. Plan
43
53
 
44
54
  For each verification type, state:
@@ -52,6 +62,8 @@ A verification plan that only lists `bun run test`, `bun run typecheck`, or `bun
52
62
 
53
63
  After implementation, run the verification plan. Execute each verification type in order.
54
64
 
65
+ Evidence output must explicitly label each verification result as either `verified empirically` or `artifact-only / verification deferred`. Artifact-only evidence can support a blocked escalation packet, but it cannot mark a required runtime verification complete.
66
+
55
67
  ### 7. Codify
56
68
 
57
69
  After each empirical verification produces PASS evidence, invoke the `codify-verification` skill to encode the verification as an automated regression test. The manual proof becomes a repeatable check that catches future regressions.
@@ -229,6 +241,7 @@ Agents must follow this sequence unless explicitly instructed otherwise:
229
241
  4. **If verification blocked** (missing tools, services, etc.): Mark as blocked, not complete
230
242
  5. **Must not be dependent on CI/CD** if necessary, you may use local deploy methods found in the project manifest, but the verification methods must be listed in the pull request and therefore cannot be dependent on CI/CD completing
231
243
  6. **Evidence manifest satisfied (leaf work units)**: For a leaf work unit (Bug / Task / Sub-task / Improvement) whose ticket carries a Validation Journey, do not mark the ticket complete or transition it out of in-progress until every `[EVIDENCE: name]` marker declared on the ticket has a corresponding captured, non-empty artifact attached to the ticket. A missing or empty artifact for any declared marker blocks completion exactly like a failed verification — fix and re-capture, or escalate; never close with an unsatisfied manifest. Epics / Stories / Spikes are exempt (coordination containers, not work units).
244
+ 7. **No artifact-only completion for required runtime verification**: If empirical verification is required and cannot run because credentials are missing, do not mark the item done on artifact-only evidence. Exhaust the credential lookup order first; if still blocked, post the blocker comment, move the item to the configured blocked state, and apply the configured `needs-human` / `human-review` label.
232
245
 
233
246
  ---
234
247
 
@@ -245,6 +258,7 @@ Common blockers:
245
258
  - Missing documentation on how to access required tooling
246
259
  - Production-only access gates
247
260
  - Compliance restrictions
261
+ - Missing runtime credentials after checking project e2e / Playwright config and fixtures, `.lisa.config.local.json` / environment, and documented ticket credentials
248
262
 
249
263
  When blocked, agents must do the following:
250
264
 
@@ -255,6 +269,8 @@ When blocked, agents must do the following:
255
269
  5. Produce a Human Action Packet.
256
270
  6. Pause until explicit human confirmation or tooling is provided.
257
271
 
272
+ For tracker-backed work items, also post the packet to the tracker, transition to the configured blocked state, and apply the configured `needs-human` / `human-review` label. If the label is missing and the tracker supports label creation, create it before applying it.
273
+
258
274
  Agents must never proceed past an unverified boundary without surfacing it to the human overseer.
259
275
 
260
276
  ### Human Action Packet Format
@@ -39,6 +39,9 @@ Execute the **Verify** flow as defined in the `intent-routing` rule (loaded via
39
39
  4. **Review loop** — handle CodeRabbit / human review comments via `lisa:pull-request-review`
40
40
  5. **Merge** when CI is green
41
41
  6. **Remote verification** — invoke the `lisa:monitor` skill against the target environment to confirm the deploy actually works (health endpoints, recent logs/errors, Validation Journey replay if defined). If remote verification surfaces a behavioral gap that the existing codified tests do not guard, invoke `codify-verification` to add coverage and open a follow-up PR.
42
+ - When remote verification needs credentials, follow the shared `verification-lifecycle` credential lookup order before declaring them missing: project e2e / Playwright config and fixtures first, then `.lisa.config.local.json` / environment variables, then documented ticket credentials such as a `Sign-in Required` section.
43
+ - Should credentials remain genuinely unavailable after those sources are exhausted, do not complete the item on artifact-only evidence. Post a tracker comment stating what could not be verified and why, transition the work item to the configured blocked state, and apply the configured `needs-human` / `human-review` label, creating it if the tracker supports label creation and it is missing.
44
+ - Evidence must explicitly distinguish `verified empirically` from `artifact-only / verification deferred`.
42
45
  7. **Evidence usage** — before posting, route the generated evidence artifact through `lisa:usage-accounting` so the comment body / PR evidence section / markdown proof carries a direct `verify` usage entry in the canonical `## Lisa Usage` section. If the originating work item or PRD parentage is known, prefer `record_and_rollup` so ancestor totals refresh in the same pass. If runtime usage is unavailable, still write `source: unavailable` with nullable token/cost fields instead of skipping the row.
43
46
  8. **Evidence** — post results to the originating ticket via `lisa:tracker-evidence` (vendor-neutral; dispatches to `lisa:jira-evidence`, `lisa:github-evidence`, or `lisa:linear-evidence` per `.lisa.config.json` `tracker`), including the list of codified tests added on this branch. **If the work is UI-visible** (any verification step ran in a browser, or the change touches a user-facing surface), author `evidence/comment.md` per the **UI Evidence Checklist** in `lisa:tracker-evidence` — numbered live-session steps, one Playwright-MCP screenshot per step uploaded to the GitHub `pr-assets` release as plain URLs, and an explicit invitation to be corrected.
44
47
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.159.1",
3
+ "version": "2.159.3",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -126,4 +126,18 @@ Both levels use the same verification types table above. The difference is the e
126
126
 
127
127
  ---
128
128
 
129
+ ## Credential-Gated Verification
130
+
131
+ Some runtime verification requires signing in to a deployed or local app. Agents must exhaust credential sources before declaring verification blocked:
132
+
133
+ 1. Project e2e / Playwright config and fixtures, including files such as `e2e/constants.ts`, `e2e/fixtures/api-login.ts`, seeded test users, and OTP-bypass patterns such as `555555`.
134
+ 2. `.lisa.config.local.json` and environment variables.
135
+ 3. Documented ticket credentials, including a `Sign-in Required` or equivalent section in the issue, ticket, PRD, or linked implementation notes.
136
+
137
+ If credentials are genuinely unavailable after all three source classes are checked, the item is blocked, not done. The agent must post a tracker comment explaining what could not be verified and which sources were checked, transition the item to the configured blocked state, and apply the configured `needs-human` / `human-review` label, creating the label if the tracker supports label creation and it is missing.
138
+
139
+ Evidence and summaries must explicitly distinguish `verified empirically` from `artifact-only / verification deferred`. Artifact-only evidence can explain what was checked before escalation, but it cannot complete a work item that requires runtime verification.
140
+
141
+ ---
142
+
129
143
  For the full verification lifecycle (classify, check tooling, plan, execute, loop), surfaces, escalation protocol, and proof artifact requirements, see the `verification-lifecycle` skill loaded by the `verification-specialist` agent.
@@ -16,6 +16,8 @@ alwaysApply: true
16
16
  - **Before starting implementation, state your verification plan** — how you will USE the resulting software to prove it works. A plan that only lists `test`/`typecheck`/`lint` commands is not a plan. Do not begin until confirmed.
17
17
  - **After verifying empirically, codify it as a regression test** via the `codify-verification` skill — Playwright for UI, integration test for API/DB/auth, benchmark for performance. Codification is mandatory for every verification type except PR/Documentation/Deploy and Investigate-Only spikes.
18
18
  - **Every PR must include reviewer replay steps** — the exact human steps to use the software and confirm the change works. Not test commands. If a reviewer can't reproduce from the PR description alone, the PR is incomplete.
19
+ - **Exhaust credential sources before deferring runtime verification** — check project e2e / Playwright config and fixtures first, then `.lisa.config.local.json` / environment variables, then documented ticket credentials such as `Sign-in Required`.
20
+ - **Never mark required runtime verification done on artifact-only evidence** — if credentials are genuinely unavailable after all sources are checked, post the blocker, transition the item to the configured blocked state, apply the configured `needs-human` / `human-review` label, and label the evidence as `artifact-only / verification deferred`.
19
21
 
20
22
  ## Roles
21
23
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: atlassian-access
3
- description: "Vendor-neutral access layer for Atlassian (JIRA + Confluence). Every jira-* and confluence-* skill MUST delegate through this skill rather than calling Atlassian directly. Resolves a substrate per operation in this order: (1) acli if installed and switchable to a profile matching the configured site, (2) Atlassian MCP if authenticated and the configured cloudId is in its accessible resources, (3) curl + API-token Basic auth. Verifies the active connection matches `.lisa.config.json` before every operation substrates authenticated as a different Atlassian account are switched to the configured profile when one exists, and skipped only after switch plus re-verification fails."
3
+ description: "Vendor-neutral access layer for Atlassian (JIRA + Confluence). Every jira-* and confluence-* skill MUST delegate through this skill rather than calling Atlassian directly. Resolves a substrate per operation, binding JIRA writes to the configured cloudId via Atlassian REST whenever token auth is available and using acli only for reads or as a guarded fallback. For non-write acli operations, acli is used when installed and switchable to a profile matching the configured site; mismatched active profiles are skipped only after switch plus re-verification fails."
4
4
  allowed-tools: ["Bash", "Read", "Skill"]
5
5
  ---
6
6
 
@@ -40,8 +40,13 @@ Probe each tier in order; the first that's ready AND identity-matches is the sub
40
40
  ```bash
41
41
  substrate=""
42
42
 
43
- # Tier 1: acli
44
- if command -v acli >/dev/null 2>&1 && acli auth status >/dev/null 2>&1; then
43
+ # Tier 1: acli for reads and non-write operations only.
44
+ #
45
+ # Do not choose acli for JIRA writes when curl/token auth is available. acli stores
46
+ # one machine-global active account and workitem writes cannot pin a cloudId per
47
+ # invocation, so switch-then-write is a TOCTOU risk in multi-account or concurrent
48
+ # sessions. Write operations prefer the cloudId-scoped REST URL below.
49
+ if [ "$OP_KIND" != "jira-write" ] && command -v acli >/dev/null 2>&1 && acli auth status >/dev/null 2>&1; then
45
50
  current_site=$(acli auth status 2>/dev/null | awk '/^ Site:/{print $2}')
46
51
  if [ "$current_site" != "$SITE" ]; then
47
52
  # acli installed but pointing at a different site. Try switching profiles.
@@ -114,7 +119,13 @@ public static class LisaCred {
114
119
  esac
115
120
  }
116
121
  TOKEN=$(read_atlassian_token "$EMAIL")
117
- [ -n "$TOKEN" ] && curl_available=true && : ${substrate:=curl}
122
+ [ -n "$TOKEN" ] && curl_available=true && {
123
+ if [ "$OP_KIND" = "jira-write" ]; then
124
+ substrate="curl"
125
+ else
126
+ : ${substrate:=curl}
127
+ fi
128
+ }
118
129
 
119
130
  # Fail loudly with actionable remediation if nothing works.
120
131
  if [ -z "$substrate" ]; then
@@ -271,18 +282,18 @@ Substrate column meanings:
271
282
  - Multiple cells filled means tier ordering applies — try acli, then MCP, then curl, taking the first that has an adapter for the op AND is identity-matched.
272
283
  - One cell means only that substrate can perform the op.
273
284
 
274
- `<SITE>` = `.atlassian.site` (e.g. `propswap.atlassian.net`). `<CLOUDID>` = `.atlassian.cloudId`. `<AUTH>` = `Basic $(printf '%s:%s' "$email" "$ATLASSIAN_API_TOKEN" | base64)`. JIRA paths use `/rest/api/3/...`; Confluence uses `/wiki/rest/api/...` (v1) or `/api/v2/...` (v2).
285
+ `<SITE>` = `.atlassian.site` (e.g. `propswap.atlassian.net`). `<CLOUDID>` = `.atlassian.cloudId`. `<AUTH>` = `Basic $(printf '%s:%s' "$email" "$ATLASSIAN_API_TOKEN" | base64)`. JIRA curl writes use the cloudId-bound Atlassian gateway `https://api.atlassian.com/ex/jira/<CLOUDID>/rest/api/3/...`; JIRA curl reads may use either that gateway or `https://<SITE>/rest/api/3/...` after the token account check. Confluence uses `/wiki/rest/api/...` (v1) or `/api/v2/...` (v2).
275
286
 
276
287
  | Operation | acli adapter | MCP adapter | curl adapter |
277
288
  |---|---|---|---|
278
289
  | **JIRA ops** | | | |
279
290
  | `read-ticket key:<K>` | `acli jira workitem view <K> --fields '*all' --json` | `mcp__plugin_atlassian_atlassian__getJiraIssue` | `GET https://<SITE>/rest/api/3/issue/<K>?fields=*all` |
280
- | `write-ticket payload:<P>` (create) | `acli jira workitem create --from-json <P>` | `mcp__plugin_atlassian_atlassian__createJiraIssue` | `POST https://<SITE>/rest/api/3/issue` body=`<P>` |
281
- | `write-ticket payload:<P>` (edit) | `acli jira workitem edit <K> --from-json <P>` | `mcp__plugin_atlassian_atlassian__editJiraIssue` | `PUT https://<SITE>/rest/api/3/issue/<K>` body=`<P>` |
282
- | `transition key:<K> to:<S>` | `acli jira workitem transition --key <K> --status "<S>" --yes` | `mcp__plugin_atlassian_atlassian__transitionJiraIssue` | resolve transition id then `POST .../issue/<K>/transitions` |
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
+ | `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
+ | `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` |
283
294
  | `transitions key:<K>` | (not exposed) | `mcp__plugin_atlassian_atlassian__getTransitionsForJiraIssue` | `GET https://<SITE>/rest/api/3/issue/<K>/transitions` |
284
- | `comment key:<K> body:<B>` | `acli jira workitem comment add --key <K> --body "<B>"` | `mcp__plugin_atlassian_atlassian__addCommentToJiraIssue` | `POST https://<SITE>/rest/api/3/issue/<K>/comment` |
285
- | `link from:<K> to:<K2> type:<T>` | `acli jira workitem link create --in <K> --out <K2> --type "<T>" --yes` (see direction note) | `mcp__plugin_atlassian_atlassian__createJiraIssueLink` | `POST https://<SITE>/rest/api/3/issueLink` |
295
+ | `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
+ | `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` |
286
297
  | `remote-links key:<K>` | (not exposed) | `mcp__plugin_atlassian_atlassian__getJiraIssueRemoteIssueLinks` | `GET https://<SITE>/rest/api/3/issue/<K>/remotelink` |
287
298
  | `search-issues jql:<J>` | `acli jira workitem search --jql "<J>" --json` | `mcp__plugin_atlassian_atlassian__searchJiraIssuesUsingJql` | `POST https://<SITE>/rest/api/3/search/jql` |
288
299
  | `list-projects` | `acli jira project list --paginate --json` | `mcp__plugin_atlassian_atlassian__getVisibleJiraProjects` | `GET https://<SITE>/rest/api/3/project/search` |
@@ -305,6 +316,16 @@ Substrate column meanings:
305
316
 
306
317
  **acli flag note:** acli's `--output` flag does not exist; the correct flag is `--json`. List commands require `--paginate` or `--limit` (no implicit fetch-all). `acli jira workitem view` defaults to a restricted field set (`key,issuetype,summary,status,assignee,description`), so `read-ticket` MUST pass `--fields '*all'` or an explicit equivalent that includes every downstream dependency: parent, subtasks, issue links, components, labels, priority, status, issue type, summary, description, fix versions, affected versions, attachments, comments, estimates, sprint/story-point fields, and project-required custom fields. Never rely on the default view fields; they hide parent/components/labels and corrupt leaf-only, relationship-search, build-ready, and required-custom-field gates. Several documented adapters are nominal — verify against `acli <subcmd> --help` before relying on them. When acli's adapter is broken or missing for a specific op, fall through to MCP (if identity-matched) then curl per the tier ordering.
307
318
 
319
+ **JIRA write tenant-safety rule:** create, edit, transition, comment, and link are write operations. They MUST prefer the curl adapter whenever token auth is available because the URL includes `<CLOUDID>` and cannot be redirected by the user-global acli active account. If the flow must fall back to acli for a write, it is a guarded fallback, not the normal path:
320
+
321
+ 1. Switch and assert the active `acli auth status` site/email matches config immediately before the write.
322
+ 2. Execute the write.
323
+ 3. Read the affected issue(s) immediately after the write.
324
+ 4. Assert each response belongs to the configured tenant by checking one of: response `self` URL host equals `<SITE>`, response `self` URL path includes `/ex/jira/<CLOUDID>/`, or response metadata reports `<CLOUDID>`.
325
+ 5. If the assertion fails, stop, report a cross-tenant write hazard, and best-effort roll back the write when there is a safe reversal: delete a newly created issue, remove a newly created comment/link, or revert a reversible field edit. Never continue as if the write succeeded.
326
+
327
+ Do not treat a successful `acli auth switch` or pre-write `auth status` as sufficient for tenant safety. Another process can mutate the global acli active account between the check and the write.
328
+
308
329
  **acli link-create direction is invertible — flags and verification:** acli has no `--inward`/`--outward` flags; the real flags are `--in` and `--out` (confirm with `acli jira workitem link create --help`). For a `Blocks` link, **`--in` is the blocker and `--out` is the blocked** issue, i.e. `--in <X> --out <Y> --type Blocks` resolves to "X blocks Y" (Y `is blocked by` X). The lisa op `link from:<K> to:<K2> type:<T>` means "K ⟨T⟩ K2", so the blocker `from` maps to `--in` and the blocked `to` maps to `--out` (as in the adapter above). The acli success banner only echoes the `--in`/`--out` values you passed — it does NOT confirm the resolved semantic direction, so a reversed link reports success and looks fine. **After every `link` write, re-read the affected issues via `read-ticket` (which already requests `--fields '*all'`) and confirm `issuelinks[].type` + `inwardIssue`/`outwardIssue` resolve to the intended `blocks` / `is blocked by` direction.** Skipping this can silently reverse an entire epic's dependency graph — e.g. cutover tickets recorded as *blocking* the prerequisites that should block them.
309
330
 
310
331
  **JIRA terminal-resolution note:** when a caller marks a transition as terminal per `leaf-only-lifecycle`, the substrate must not treat a Done-named status as sufficient by name alone. After `transition key:<K> to:<S>`, re-read the issue and verify `statusCategory = Done`; if the workflow requires a resolution, verify `resolution` is set. If the transition screen requires a resolution value, pass the configured default resolution when available; otherwise return a setup error so the build-intake skill can report the workflow gap instead of silently leaving an unresolved ticket in a Done-looking status.
@@ -332,6 +353,7 @@ Do not paraphrase substrate output beyond JSON normalization.
332
353
  - Substrate is decided once per skill invocation and never switches mid-operation.
333
354
  - Connection match is mandatory. Operations that bypass it (because "the user obviously meant the configured site") are forbidden.
334
355
  - Profile mutations (`acli auth switch`) are allowed when acli is the active substrate. The curl substrate never mutates the token — if `ATLASSIAN_API_TOKEN` doesn't match the configured account, fail loud rather than silently substituting.
356
+ - JIRA writes are cloudId-bound by default. `acli` write adapters are fallback-only and must perform post-write tenant assertions plus safe rollback on mismatch.
335
357
  - `.lisa.config.local.json` overrides `.lisa.config.json` per-key — the same precedence rule as every other consumer of project config.
336
358
 
337
359
  ## Headless behavior
@@ -35,10 +35,20 @@ For each required verification type, discover what tools are available in the pr
35
35
 
36
36
  Report what is available for each required type. If a required type has no available tool, proceed to step 4.
37
37
 
38
+ If a required verification type needs sign-in or other credentials, exhaust credential sources before declaring the verification blocked. Check credential sources in this order:
39
+
40
+ 1. Project e2e / Playwright config and fixtures, including files such as `e2e/constants.ts`, `e2e/fixtures/api-login.ts`, seeded test users, and OTP-bypass patterns such as `555555`.
41
+ 2. `.lisa.config.local.json` and environment variables.
42
+ 3. Documented ticket credentials, including a `Sign-in Required` or equivalent section in the issue, ticket, PRD, or linked implementation notes.
43
+
44
+ Report which sources were checked. Do not say credentials are unavailable until all three source classes have been checked or proven absent.
45
+
38
46
  ### 4. Fail Fast
39
47
 
40
48
  If a required verification type has no available tool and no reasonable alternative, escalate immediately using the Escalation Protocol. Do not begin implementation without a verification plan for every required type.
41
49
 
50
+ If credentials are genuinely unavailable after the credential lookup order above is exhausted, treat the work item as blocked rather than done. Post a clear tracker comment stating exactly what runtime behavior could not be verified and which credential sources were checked, transition the item to the configured blocked state, and apply the configured `needs-human` / `human-review` label, creating that label if the tracker supports label creation and it is missing.
51
+
42
52
  ### 5. Plan
43
53
 
44
54
  For each verification type, state:
@@ -52,6 +62,8 @@ A verification plan that only lists `bun run test`, `bun run typecheck`, or `bun
52
62
 
53
63
  After implementation, run the verification plan. Execute each verification type in order.
54
64
 
65
+ Evidence output must explicitly label each verification result as either `verified empirically` or `artifact-only / verification deferred`. Artifact-only evidence can support a blocked escalation packet, but it cannot mark a required runtime verification complete.
66
+
55
67
  ### 7. Codify
56
68
 
57
69
  After each empirical verification produces PASS evidence, invoke the `codify-verification` skill to encode the verification as an automated regression test. The manual proof becomes a repeatable check that catches future regressions.
@@ -229,6 +241,7 @@ Agents must follow this sequence unless explicitly instructed otherwise:
229
241
  4. **If verification blocked** (missing tools, services, etc.): Mark as blocked, not complete
230
242
  5. **Must not be dependent on CI/CD** if necessary, you may use local deploy methods found in the project manifest, but the verification methods must be listed in the pull request and therefore cannot be dependent on CI/CD completing
231
243
  6. **Evidence manifest satisfied (leaf work units)**: For a leaf work unit (Bug / Task / Sub-task / Improvement) whose ticket carries a Validation Journey, do not mark the ticket complete or transition it out of in-progress until every `[EVIDENCE: name]` marker declared on the ticket has a corresponding captured, non-empty artifact attached to the ticket. A missing or empty artifact for any declared marker blocks completion exactly like a failed verification — fix and re-capture, or escalate; never close with an unsatisfied manifest. Epics / Stories / Spikes are exempt (coordination containers, not work units).
244
+ 7. **No artifact-only completion for required runtime verification**: If empirical verification is required and cannot run because credentials are missing, do not mark the item done on artifact-only evidence. Exhaust the credential lookup order first; if still blocked, post the blocker comment, move the item to the configured blocked state, and apply the configured `needs-human` / `human-review` label.
232
245
 
233
246
  ---
234
247
 
@@ -245,6 +258,7 @@ Common blockers:
245
258
  - Missing documentation on how to access required tooling
246
259
  - Production-only access gates
247
260
  - Compliance restrictions
261
+ - Missing runtime credentials after checking project e2e / Playwright config and fixtures, `.lisa.config.local.json` / environment, and documented ticket credentials
248
262
 
249
263
  When blocked, agents must do the following:
250
264
 
@@ -255,6 +269,8 @@ When blocked, agents must do the following:
255
269
  5. Produce a Human Action Packet.
256
270
  6. Pause until explicit human confirmation or tooling is provided.
257
271
 
272
+ For tracker-backed work items, also post the packet to the tracker, transition to the configured blocked state, and apply the configured `needs-human` / `human-review` label. If the label is missing and the tracker supports label creation, create it before applying it.
273
+
258
274
  Agents must never proceed past an unverified boundary without surfacing it to the human overseer.
259
275
 
260
276
  ### Human Action Packet Format
@@ -39,6 +39,9 @@ Execute the **Verify** flow as defined in the `intent-routing` rule (loaded via
39
39
  4. **Review loop** — handle CodeRabbit / human review comments via `lisa:pull-request-review`
40
40
  5. **Merge** when CI is green
41
41
  6. **Remote verification** — invoke the `lisa:monitor` skill against the target environment to confirm the deploy actually works (health endpoints, recent logs/errors, Validation Journey replay if defined). If remote verification surfaces a behavioral gap that the existing codified tests do not guard, invoke `codify-verification` to add coverage and open a follow-up PR.
42
+ - When remote verification needs credentials, follow the shared `verification-lifecycle` credential lookup order before declaring them missing: project e2e / Playwright config and fixtures first, then `.lisa.config.local.json` / environment variables, then documented ticket credentials such as a `Sign-in Required` section.
43
+ - Should credentials remain genuinely unavailable after those sources are exhausted, do not complete the item on artifact-only evidence. Post a tracker comment stating what could not be verified and why, transition the work item to the configured blocked state, and apply the configured `needs-human` / `human-review` label, creating it if the tracker supports label creation and it is missing.
44
+ - Evidence must explicitly distinguish `verified empirically` from `artifact-only / verification deferred`.
42
45
  7. **Evidence usage** — before posting, route the generated evidence artifact through `lisa:usage-accounting` so the comment body / PR evidence section / markdown proof carries a direct `verify` usage entry in the canonical `## Lisa Usage` section. If the originating work item or PRD parentage is known, prefer `record_and_rollup` so ancestor totals refresh in the same pass. If runtime usage is unavailable, still write `source: unavailable` with nullable token/cost fields instead of skipping the row.
43
46
  8. **Evidence** — post results to the originating ticket via `lisa:tracker-evidence` (vendor-neutral; dispatches to `lisa:jira-evidence`, `lisa:github-evidence`, or `lisa:linear-evidence` per `.lisa.config.json` `tracker`), including the list of codified tests added on this branch. **If the work is UI-visible** (any verification step ran in a browser, or the change touches a user-facing surface), author `evidence/comment.md` per the **UI Evidence Checklist** in `lisa:tracker-evidence` — numbered live-session steps, one Playwright-MCP screenshot per step uploaded to the GitHub `pr-assets` release as plain URLs, and an explicit invitation to be corrected.
44
47
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.159.1",
3
+ "version": "2.159.3",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.159.1",
3
+ "version": "2.159.3",
4
4
  "description": "Expo and React Native-specific skills, agents, rules, and MCP servers.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.159.1",
3
+ "version": "2.159.3",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.159.1",
3
+ "version": "2.159.3",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.159.1",
3
+ "version": "2.159.3",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.159.1",
3
+ "version": "2.159.3",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.159.1",
3
+ "version": "2.159.3",
4
4
  "description": "Harper/Fabric-specific Lisa rules for TypeScript component apps.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.159.1",
3
+ "version": "2.159.3",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.159.1",
3
+ "version": "2.159.3",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.159.1",
3
+ "version": "2.159.3",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.159.1",
3
+ "version": "2.159.3",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.159.1",
3
+ "version": "2.159.3",
4
4
  "description": "NestJS-specific skills and migration write-protection hooks.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.159.1",
3
+ "version": "2.159.3",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.159.1",
3
+ "version": "2.159.3",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.159.1",
3
+ "version": "2.159.3",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.159.1",
3
+ "version": "2.159.3",
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.159.1",
3
+ "version": "2.159.3",
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.159.1",
3
+ "version": "2.159.3",
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.159.1",
3
+ "version": "2.159.3",
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.159.1",
3
+ "version": "2.159.3",
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-rails",
3
- "version": "2.159.1",
3
+ "version": "2.159.3",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.159.1",
3
+ "version": "2.159.3",
4
4
  "description": "Ruby on Rails-specific skills and hooks for RuboCop and ast-grep scanning on edit.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.159.1",
3
+ "version": "2.159.3",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.159.1",
3
+ "version": "2.159.3",
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"