@codyswann/lisa 2.259.1 → 2.259.2

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 (57) 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/.codex-plugin/skills/lisa-drive-pr-to-merge/SKILL.md +76 -4
  5. package/plugins/lisa/skills/lisa-drive-pr-to-merge/SKILL.md +77 -5
  6. package/plugins/lisa-agy/plugin.json +1 -1
  7. package/plugins/lisa-agy/skills/lisa-drive-pr-to-merge/SKILL.md +77 -5
  8. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  9. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  10. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  11. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  12. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  13. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  14. package/plugins/lisa-copilot/skills/lisa-drive-pr-to-merge/SKILL.md +77 -5
  15. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  16. package/plugins/lisa-cursor/skills/lisa-drive-pr-to-merge/SKILL.md +77 -5
  17. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  18. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  19. package/plugins/lisa-expo-agy/plugin.json +1 -1
  20. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  21. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  22. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  23. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  24. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  25. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  26. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  27. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  28. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  29. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  30. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  31. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  32. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  33. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  34. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  35. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  36. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  37. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  38. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  39. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  40. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  41. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  42. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  43. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  44. package/plugins/lisa-rails-agy/plugin.json +1 -1
  45. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  46. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  47. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  48. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  49. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  50. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  51. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  52. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  53. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  54. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  55. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  56. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  57. package/plugins/src/base/skills/lisa-drive-pr-to-merge/SKILL.md +77 -5
package/package.json CHANGED
@@ -102,7 +102,7 @@
102
102
  "form-data": ">=4.0.6"
103
103
  },
104
104
  "name": "@codyswann/lisa",
105
- "version": "2.259.1",
105
+ "version": "2.259.2",
106
106
  "description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
107
107
  "main": "dist/index.js",
108
108
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.259.1",
3
+ "version": "2.259.2",
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": "2.259.1",
3
+ "version": "2.259.2",
4
4
  "description": "Universal governance: agents, skills, commands, hooks, and rules for all projects.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -246,11 +246,16 @@ head's checks to start, then re-enable auto-merge (section 1). In
246
246
  `on_blocker=report` mode this whole step is off-limits (diagnose-only): do not
247
247
  merge, close, or delete anything — return `blocked:pending-auto-fix`.
248
248
 
249
- ## 3. Merge and verify it actually shipped (ancestry check)
249
+ ## 3. Merge and verify it actually shipped (ancestry + deploy run)
250
250
 
251
251
  Enabling auto-merge + green checks + resolved threads is **not** proof the merge
252
- included your fix. Auto-merge can land the PRIOR head the instant gates go green,
253
- before a late fix commit becomes the head. After the PR reports `MERGED`:
252
+ included your fix, and a passing merge **not** proof anything deployed. Both must
253
+ be verified after the PR reports `MERGED`.
254
+
255
+ ### a. Ancestry check — is my code in the merged branch
256
+
257
+ Auto-merge can land the PRIOR head the instant gates go green, before a late fix
258
+ commit becomes the head:
254
259
 
255
260
  ```bash
256
261
  git fetch origin
@@ -263,11 +268,78 @@ ship — fix forward with a new commit/PR and re-drive. Re-confirm after any com
263
268
  that lands while auto-merge is enabled; a successful merge of an older head is a
264
269
  failed drive-to-merge outcome, not a successful closeout.
265
270
 
271
+ ### b. Deploy-run check — did a deploy/release workflow run actually fire
272
+
273
+ Ancestry proves your code is *in* the merged branch; it does **not** prove
274
+ anything deployed. GitHub can **suppress the `on: push` event for a merge commit
275
+ created by auto-merge or a bot token** (`GITHUB_TOKEN`), so the deploy workflow
276
+ fires **zero** runs — no run, not even a `startup_failure` — while the ancestry
277
+ check above stays green. Incident of record: TunnlAI/frontend **TUN-186** (PR #67)
278
+ merged to `dev` via auto-merge; the merge commit `1b3f836` produced **no**
279
+ `deploy.yml` run, and only the next human push `d1fe18c` (which carries `1b3f836`
280
+ as an ancestor) actually shipped it. **Never report shipped on ancestry alone.**
281
+
282
+ After ancestry passes, capture the merge SHA and poll for a **deploy/release
283
+ workflow run** whose head SHA **is the merge SHA or an including descendant** (a
284
+ run whose head has the merge SHA as an ancestor also shipped the merge, mirroring
285
+ `d1fe18c` shipping `1b3f836`), keyed to the merged-into branch. The observing
286
+ workflow name is **not fixed** — do **not** hardcode `deploy.yml`:
287
+
288
+ - **Downstream projects:** the deploy/release workflow run keyed to the base
289
+ branch resolved via `.lisa.config.json` `deploy.branches` (the merged-into env
290
+ branch) — the same "deploy run keyed to the merged-into branch via
291
+ `deploy.branches`" observation `lisa-linear-build-intake` performs before
292
+ relabeling.
293
+ - **lisa / other repos:** the repo's release or publish workflow for
294
+ `<baseRefName>`.
295
+
296
+ Discover the run with the same `gh run list --json …headSha…` pattern
297
+ `lisa-verify-workflow-change` uses:
298
+
299
+ ```bash
300
+ merge_sha=$(gh pr view <pr> --json mergeCommit -q .mergeCommit.oid)
301
+ gh run list --branch <baseRefName> --commit "$merge_sha" \
302
+ --json databaseId,workflowName,status,conclusion,headSha,headBranch,createdAt --limit 20
303
+ ```
304
+
305
+ **Bounded wait:** a just-created run can take a few seconds to register — poll
306
+ briefly (a small number of short intervals / a short ceiling, mirroring the "wait
307
+ for that head's checks to start" bound used above) before concluding the run is
308
+ absent, so a not-yet-registered run is not mis-read as zero. When no run matches
309
+ the merge SHA directly, also accept a descendant run whose head has `$merge_sha`
310
+ as an ancestor (`git merge-base --is-ancestor "$merge_sha" <run_head_sha>`).
311
+
312
+ **Zero runs after the bounded wait — do NOT report shipped.** Recover in order:
313
+
314
+ 1. **Dispatch the deploy, then re-verify.** Trigger the env's `workflow_dispatch`
315
+ for the merged-into branch and re-poll for a run that now covers the merge SHA
316
+ (or an including descendant):
317
+ ```bash
318
+ gh workflow run <deploy-or-release-workflow> --ref <baseRefName>
319
+ ```
320
+ Once such a run appears, the merge is confirmed shipped.
321
+ 2. **Still zero, or dispatch not permitted → surface a blocker.** Emit a hard
322
+ block (`blocked:deploy`) reporting exactly what was observed — the merge SHA,
323
+ the base branch, and zero deploy runs. A failed/blocked path, **never** a
324
+ silent "done".
325
+
326
+ In **`on_blocker=report`** mode this deploy-run step is diagnose-only: dispatching
327
+ a workflow is an action, so do **not** run `gh workflow run` / `workflow_dispatch`
328
+ — classify the absence as `blocked:deploy` (or `blocked:no-deploy-run`) and return
329
+ it for the caller to act on, consistent with the report-mode contract (steps b–f
330
+ of section 2 are diagnose-only).
331
+
266
332
  ## 4. Terminal states
267
333
 
268
334
  Loop until one of:
269
335
 
270
- - **`MERGED`** and the ancestry check passes success.
336
+ - **`MERGED`** and the ancestry check passes **and** a deploy/release run for the
337
+ merge SHA (or an including descendant) is confirmed — observed directly or after
338
+ a `workflow_dispatch` recovery → success. Ancestry alone is **not** success.
339
+ - **`blocked:deploy`** — merged with ancestry green, but after the bounded wait no
340
+ deploy/release run fired for the merge SHA and dispatch recovery could not
341
+ confirm one (or was not permitted, e.g. `on_blocker=report`). Stop and report
342
+ the merge SHA, base branch, and zero observed runs — never a silent "done".
271
343
  - **`awaiting-human`** (`auto_merge=false` only) → success. The PR is `OPEN`,
272
344
  required checks are green, the review gate is clear, and
273
345
  `mergeable == MERGEABLE`, with auto-merge deliberately not enabled
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: lisa-drive-pr-to-merge
3
- description: This skill should be used to drive a pull request all the way to MERGED, handling ANYTHING that blocks the merge. It enables auto-merge when the repo supports it (direct-merge fallback otherwise), keeps the branch rebased/synced and resolves merge conflicts, fixes failing CI/deploy checks, addresses and resolves every human and bot review comment (CodeRabbit, etc.) — implementing valid feedback and replying-then-resolving invalid feedback — dismisses stale CHANGES_REQUESTED gates, and verifies the fix actually shipped (auto-merge race ancestry check). Composable and inline — invoked by other skills (e.g. git-submit-pr, implement, sync-down) via the Skill tool, never as a standalone user command.
3
+ description: This skill should be used to drive a pull request all the way to MERGED, handling ANYTHING that blocks the merge. It enables auto-merge when the repo supports it (direct-merge fallback otherwise), keeps the branch rebased/synced and resolves merge conflicts, fixes failing CI/deploy checks, addresses and resolves every human and bot review comment (CodeRabbit, etc.) — implementing valid feedback and replying-then-resolving invalid feedback — dismisses stale CHANGES_REQUESTED gates, and verifies the fix actually shipped — both merge ancestry and that a deploy/release run fired for the merge SHA (auto-merge race + zero-deploy-run check). Composable and inline — invoked by other skills (e.g. git-submit-pr, implement, sync-down) via the Skill tool, never as a standalone user command.
4
4
  allowed-tools: ["Bash", "Read", "Edit", "Write", "Grep", "Glob", "Skill"]
5
5
  ---
6
6
 
@@ -246,11 +246,16 @@ head's checks to start, then re-enable auto-merge (section 1). In
246
246
  `on_blocker=report` mode this whole step is off-limits (diagnose-only): do not
247
247
  merge, close, or delete anything — return `blocked:pending-auto-fix`.
248
248
 
249
- ## 3. Merge and verify it actually shipped (ancestry check)
249
+ ## 3. Merge and verify it actually shipped (ancestry + deploy run)
250
250
 
251
251
  Enabling auto-merge + green checks + resolved threads is **not** proof the merge
252
- included your fix. Auto-merge can land the PRIOR head the instant gates go green,
253
- before a late fix commit becomes the head. After the PR reports `MERGED`:
252
+ included your fix, and a passing merge **not** proof anything deployed. Both must
253
+ be verified after the PR reports `MERGED`.
254
+
255
+ ### a. Ancestry check — is my code in the merged branch
256
+
257
+ Auto-merge can land the PRIOR head the instant gates go green, before a late fix
258
+ commit becomes the head:
254
259
 
255
260
  ```bash
256
261
  git fetch origin
@@ -263,11 +268,78 @@ ship — fix forward with a new commit/PR and re-drive. Re-confirm after any com
263
268
  that lands while auto-merge is enabled; a successful merge of an older head is a
264
269
  failed drive-to-merge outcome, not a successful closeout.
265
270
 
271
+ ### b. Deploy-run check — did a deploy/release workflow run actually fire
272
+
273
+ Ancestry proves your code is *in* the merged branch; it does **not** prove
274
+ anything deployed. GitHub can **suppress the `on: push` event for a merge commit
275
+ created by auto-merge or a bot token** (`GITHUB_TOKEN`), so the deploy workflow
276
+ fires **zero** runs — no run, not even a `startup_failure` — while the ancestry
277
+ check above stays green. Incident of record: TunnlAI/frontend **TUN-186** (PR #67)
278
+ merged to `dev` via auto-merge; the merge commit `1b3f836` produced **no**
279
+ `deploy.yml` run, and only the next human push `d1fe18c` (which carries `1b3f836`
280
+ as an ancestor) actually shipped it. **Never report shipped on ancestry alone.**
281
+
282
+ After ancestry passes, capture the merge SHA and poll for a **deploy/release
283
+ workflow run** whose head SHA **is the merge SHA or an including descendant** (a
284
+ run whose head has the merge SHA as an ancestor also shipped the merge, mirroring
285
+ `d1fe18c` shipping `1b3f836`), keyed to the merged-into branch. The observing
286
+ workflow name is **not fixed** — do **not** hardcode `deploy.yml`:
287
+
288
+ - **Downstream projects:** the deploy/release workflow run keyed to the base
289
+ branch resolved via `.lisa.config.json` `deploy.branches` (the merged-into env
290
+ branch) — the same "deploy run keyed to the merged-into branch via
291
+ `deploy.branches`" observation `lisa-linear-build-intake` performs before
292
+ relabeling.
293
+ - **lisa / other repos:** the repo's release or publish workflow for
294
+ `<baseRefName>`.
295
+
296
+ Discover the run with the same `gh run list --json …headSha…` pattern
297
+ `lisa-verify-workflow-change` uses:
298
+
299
+ ```bash
300
+ merge_sha=$(gh pr view <pr> --json mergeCommit -q .mergeCommit.oid)
301
+ gh run list --branch <baseRefName> --commit "$merge_sha" \
302
+ --json databaseId,workflowName,status,conclusion,headSha,headBranch,createdAt --limit 20
303
+ ```
304
+
305
+ **Bounded wait:** a just-created run can take a few seconds to register — poll
306
+ briefly (a small number of short intervals / a short ceiling, mirroring the "wait
307
+ for that head's checks to start" bound used above) before concluding the run is
308
+ absent, so a not-yet-registered run is not mis-read as zero. When no run matches
309
+ the merge SHA directly, also accept a descendant run whose head has `$merge_sha`
310
+ as an ancestor (`git merge-base --is-ancestor "$merge_sha" <run_head_sha>`).
311
+
312
+ **Zero runs after the bounded wait — do NOT report shipped.** Recover in order:
313
+
314
+ 1. **Dispatch the deploy, then re-verify.** Trigger the env's `workflow_dispatch`
315
+ for the merged-into branch and re-poll for a run that now covers the merge SHA
316
+ (or an including descendant):
317
+ ```bash
318
+ gh workflow run <deploy-or-release-workflow> --ref <baseRefName>
319
+ ```
320
+ Once such a run appears, the merge is confirmed shipped.
321
+ 2. **Still zero, or dispatch not permitted → surface a blocker.** Emit a hard
322
+ block (`blocked:deploy`) reporting exactly what was observed — the merge SHA,
323
+ the base branch, and zero deploy runs. A failed/blocked path, **never** a
324
+ silent "done".
325
+
326
+ In **`on_blocker=report`** mode this deploy-run step is diagnose-only: dispatching
327
+ a workflow is an action, so do **not** run `gh workflow run` / `workflow_dispatch`
328
+ — classify the absence as `blocked:deploy` (or `blocked:no-deploy-run`) and return
329
+ it for the caller to act on, consistent with the report-mode contract (steps b–f
330
+ of section 2 are diagnose-only).
331
+
266
332
  ## 4. Terminal states
267
333
 
268
334
  Loop until one of:
269
335
 
270
- - **`MERGED`** and the ancestry check passes success.
336
+ - **`MERGED`** and the ancestry check passes **and** a deploy/release run for the
337
+ merge SHA (or an including descendant) is confirmed — observed directly or after
338
+ a `workflow_dispatch` recovery → success. Ancestry alone is **not** success.
339
+ - **`blocked:deploy`** — merged with ancestry green, but after the bounded wait no
340
+ deploy/release run fired for the merge SHA and dispatch recovery could not
341
+ confirm one (or was not permitted, e.g. `on_blocker=report`). Stop and report
342
+ the merge SHA, base branch, and zero observed runs — never a silent "done".
271
343
  - **`awaiting-human`** (`auto_merge=false` only) → success. The PR is `OPEN`,
272
344
  required checks are green, the review gate is clear, and
273
345
  `mergeable == MERGEABLE`, with auto-merge deliberately not enabled
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.259.1",
3
+ "version": "2.259.2",
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-drive-pr-to-merge
3
- description: This skill should be used to drive a pull request all the way to MERGED, handling ANYTHING that blocks the merge. It enables auto-merge when the repo supports it (direct-merge fallback otherwise), keeps the branch rebased/synced and resolves merge conflicts, fixes failing CI/deploy checks, addresses and resolves every human and bot review comment (CodeRabbit, etc.) — implementing valid feedback and replying-then-resolving invalid feedback — dismisses stale CHANGES_REQUESTED gates, and verifies the fix actually shipped (auto-merge race ancestry check). Composable and inline — invoked by other skills (e.g. git-submit-pr, implement, sync-down) via the Skill tool, never as a standalone user command.
3
+ description: This skill should be used to drive a pull request all the way to MERGED, handling ANYTHING that blocks the merge. It enables auto-merge when the repo supports it (direct-merge fallback otherwise), keeps the branch rebased/synced and resolves merge conflicts, fixes failing CI/deploy checks, addresses and resolves every human and bot review comment (CodeRabbit, etc.) — implementing valid feedback and replying-then-resolving invalid feedback — dismisses stale CHANGES_REQUESTED gates, and verifies the fix actually shipped — both merge ancestry and that a deploy/release run fired for the merge SHA (auto-merge race + zero-deploy-run check). Composable and inline — invoked by other skills (e.g. git-submit-pr, implement, sync-down) via the Skill tool, never as a standalone user command.
4
4
  allowed-tools: ["Bash", "Read", "Edit", "Write", "Grep", "Glob", "Skill"]
5
5
  ---
6
6
 
@@ -246,11 +246,16 @@ head's checks to start, then re-enable auto-merge (section 1). In
246
246
  `on_blocker=report` mode this whole step is off-limits (diagnose-only): do not
247
247
  merge, close, or delete anything — return `blocked:pending-auto-fix`.
248
248
 
249
- ## 3. Merge and verify it actually shipped (ancestry check)
249
+ ## 3. Merge and verify it actually shipped (ancestry + deploy run)
250
250
 
251
251
  Enabling auto-merge + green checks + resolved threads is **not** proof the merge
252
- included your fix. Auto-merge can land the PRIOR head the instant gates go green,
253
- before a late fix commit becomes the head. After the PR reports `MERGED`:
252
+ included your fix, and a passing merge **not** proof anything deployed. Both must
253
+ be verified after the PR reports `MERGED`.
254
+
255
+ ### a. Ancestry check — is my code in the merged branch
256
+
257
+ Auto-merge can land the PRIOR head the instant gates go green, before a late fix
258
+ commit becomes the head:
254
259
 
255
260
  ```bash
256
261
  git fetch origin
@@ -263,11 +268,78 @@ ship — fix forward with a new commit/PR and re-drive. Re-confirm after any com
263
268
  that lands while auto-merge is enabled; a successful merge of an older head is a
264
269
  failed drive-to-merge outcome, not a successful closeout.
265
270
 
271
+ ### b. Deploy-run check — did a deploy/release workflow run actually fire
272
+
273
+ Ancestry proves your code is *in* the merged branch; it does **not** prove
274
+ anything deployed. GitHub can **suppress the `on: push` event for a merge commit
275
+ created by auto-merge or a bot token** (`GITHUB_TOKEN`), so the deploy workflow
276
+ fires **zero** runs — no run, not even a `startup_failure` — while the ancestry
277
+ check above stays green. Incident of record: TunnlAI/frontend **TUN-186** (PR #67)
278
+ merged to `dev` via auto-merge; the merge commit `1b3f836` produced **no**
279
+ `deploy.yml` run, and only the next human push `d1fe18c` (which carries `1b3f836`
280
+ as an ancestor) actually shipped it. **Never report shipped on ancestry alone.**
281
+
282
+ After ancestry passes, capture the merge SHA and poll for a **deploy/release
283
+ workflow run** whose head SHA **is the merge SHA or an including descendant** (a
284
+ run whose head has the merge SHA as an ancestor also shipped the merge, mirroring
285
+ `d1fe18c` shipping `1b3f836`), keyed to the merged-into branch. The observing
286
+ workflow name is **not fixed** — do **not** hardcode `deploy.yml`:
287
+
288
+ - **Downstream projects:** the deploy/release workflow run keyed to the base
289
+ branch resolved via `.lisa.config.json` `deploy.branches` (the merged-into env
290
+ branch) — the same "deploy run keyed to the merged-into branch via
291
+ `deploy.branches`" observation `lisa-linear-build-intake` performs before
292
+ relabeling.
293
+ - **lisa / other repos:** the repo's release or publish workflow for
294
+ `<baseRefName>`.
295
+
296
+ Discover the run with the same `gh run list --json …headSha…` pattern
297
+ `lisa-verify-workflow-change` uses:
298
+
299
+ ```bash
300
+ merge_sha=$(gh pr view <pr> --json mergeCommit -q .mergeCommit.oid)
301
+ gh run list --branch <baseRefName> --commit "$merge_sha" \
302
+ --json databaseId,workflowName,status,conclusion,headSha,headBranch,createdAt --limit 20
303
+ ```
304
+
305
+ **Bounded wait:** a just-created run can take a few seconds to register — poll
306
+ briefly (a small number of short intervals / a short ceiling, mirroring the "wait
307
+ for that head's checks to start" bound used above) before concluding the run is
308
+ absent, so a not-yet-registered run is not mis-read as zero. When no run matches
309
+ the merge SHA directly, also accept a descendant run whose head has `$merge_sha`
310
+ as an ancestor (`git merge-base --is-ancestor "$merge_sha" <run_head_sha>`).
311
+
312
+ **Zero runs after the bounded wait — do NOT report shipped.** Recover in order:
313
+
314
+ 1. **Dispatch the deploy, then re-verify.** Trigger the env's `workflow_dispatch`
315
+ for the merged-into branch and re-poll for a run that now covers the merge SHA
316
+ (or an including descendant):
317
+ ```bash
318
+ gh workflow run <deploy-or-release-workflow> --ref <baseRefName>
319
+ ```
320
+ Once such a run appears, the merge is confirmed shipped.
321
+ 2. **Still zero, or dispatch not permitted → surface a blocker.** Emit a hard
322
+ block (`blocked:deploy`) reporting exactly what was observed — the merge SHA,
323
+ the base branch, and zero deploy runs. A failed/blocked path, **never** a
324
+ silent "done".
325
+
326
+ In **`on_blocker=report`** mode this deploy-run step is diagnose-only: dispatching
327
+ a workflow is an action, so do **not** run `gh workflow run` / `workflow_dispatch`
328
+ — classify the absence as `blocked:deploy` (or `blocked:no-deploy-run`) and return
329
+ it for the caller to act on, consistent with the report-mode contract (steps b–f
330
+ of section 2 are diagnose-only).
331
+
266
332
  ## 4. Terminal states
267
333
 
268
334
  Loop until one of:
269
335
 
270
- - **`MERGED`** and the ancestry check passes success.
336
+ - **`MERGED`** and the ancestry check passes **and** a deploy/release run for the
337
+ merge SHA (or an including descendant) is confirmed — observed directly or after
338
+ a `workflow_dispatch` recovery → success. Ancestry alone is **not** success.
339
+ - **`blocked:deploy`** — merged with ancestry green, but after the bounded wait no
340
+ deploy/release run fired for the merge SHA and dispatch recovery could not
341
+ confirm one (or was not permitted, e.g. `on_blocker=report`). Stop and report
342
+ the merge SHA, base branch, and zero observed runs — never a silent "done".
271
343
  - **`awaiting-human`** (`auto_merge=false` only) → success. The PR is `OPEN`,
272
344
  required checks are green, the review gate is clear, and
273
345
  `mergeable == MERGEABLE`, with auto-merge deliberately not enabled
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "2.259.1",
3
+ "version": "2.259.2",
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": "2.259.1",
3
+ "version": "2.259.2",
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": "2.259.1",
3
+ "version": "2.259.2",
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": "2.259.1",
3
+ "version": "2.259.2",
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": "2.259.1",
3
+ "version": "2.259.2",
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": "2.259.1",
3
+ "version": "2.259.2",
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-drive-pr-to-merge
3
- description: This skill should be used to drive a pull request all the way to MERGED, handling ANYTHING that blocks the merge. It enables auto-merge when the repo supports it (direct-merge fallback otherwise), keeps the branch rebased/synced and resolves merge conflicts, fixes failing CI/deploy checks, addresses and resolves every human and bot review comment (CodeRabbit, etc.) — implementing valid feedback and replying-then-resolving invalid feedback — dismisses stale CHANGES_REQUESTED gates, and verifies the fix actually shipped (auto-merge race ancestry check). Composable and inline — invoked by other skills (e.g. git-submit-pr, implement, sync-down) via the Skill tool, never as a standalone user command.
3
+ description: This skill should be used to drive a pull request all the way to MERGED, handling ANYTHING that blocks the merge. It enables auto-merge when the repo supports it (direct-merge fallback otherwise), keeps the branch rebased/synced and resolves merge conflicts, fixes failing CI/deploy checks, addresses and resolves every human and bot review comment (CodeRabbit, etc.) — implementing valid feedback and replying-then-resolving invalid feedback — dismisses stale CHANGES_REQUESTED gates, and verifies the fix actually shipped — both merge ancestry and that a deploy/release run fired for the merge SHA (auto-merge race + zero-deploy-run check). Composable and inline — invoked by other skills (e.g. git-submit-pr, implement, sync-down) via the Skill tool, never as a standalone user command.
4
4
  allowed-tools: ["Bash", "Read", "Edit", "Write", "Grep", "Glob", "Skill"]
5
5
  ---
6
6
 
@@ -246,11 +246,16 @@ head's checks to start, then re-enable auto-merge (section 1). In
246
246
  `on_blocker=report` mode this whole step is off-limits (diagnose-only): do not
247
247
  merge, close, or delete anything — return `blocked:pending-auto-fix`.
248
248
 
249
- ## 3. Merge and verify it actually shipped (ancestry check)
249
+ ## 3. Merge and verify it actually shipped (ancestry + deploy run)
250
250
 
251
251
  Enabling auto-merge + green checks + resolved threads is **not** proof the merge
252
- included your fix. Auto-merge can land the PRIOR head the instant gates go green,
253
- before a late fix commit becomes the head. After the PR reports `MERGED`:
252
+ included your fix, and a passing merge **not** proof anything deployed. Both must
253
+ be verified after the PR reports `MERGED`.
254
+
255
+ ### a. Ancestry check — is my code in the merged branch
256
+
257
+ Auto-merge can land the PRIOR head the instant gates go green, before a late fix
258
+ commit becomes the head:
254
259
 
255
260
  ```bash
256
261
  git fetch origin
@@ -263,11 +268,78 @@ ship — fix forward with a new commit/PR and re-drive. Re-confirm after any com
263
268
  that lands while auto-merge is enabled; a successful merge of an older head is a
264
269
  failed drive-to-merge outcome, not a successful closeout.
265
270
 
271
+ ### b. Deploy-run check — did a deploy/release workflow run actually fire
272
+
273
+ Ancestry proves your code is *in* the merged branch; it does **not** prove
274
+ anything deployed. GitHub can **suppress the `on: push` event for a merge commit
275
+ created by auto-merge or a bot token** (`GITHUB_TOKEN`), so the deploy workflow
276
+ fires **zero** runs — no run, not even a `startup_failure` — while the ancestry
277
+ check above stays green. Incident of record: TunnlAI/frontend **TUN-186** (PR #67)
278
+ merged to `dev` via auto-merge; the merge commit `1b3f836` produced **no**
279
+ `deploy.yml` run, and only the next human push `d1fe18c` (which carries `1b3f836`
280
+ as an ancestor) actually shipped it. **Never report shipped on ancestry alone.**
281
+
282
+ After ancestry passes, capture the merge SHA and poll for a **deploy/release
283
+ workflow run** whose head SHA **is the merge SHA or an including descendant** (a
284
+ run whose head has the merge SHA as an ancestor also shipped the merge, mirroring
285
+ `d1fe18c` shipping `1b3f836`), keyed to the merged-into branch. The observing
286
+ workflow name is **not fixed** — do **not** hardcode `deploy.yml`:
287
+
288
+ - **Downstream projects:** the deploy/release workflow run keyed to the base
289
+ branch resolved via `.lisa.config.json` `deploy.branches` (the merged-into env
290
+ branch) — the same "deploy run keyed to the merged-into branch via
291
+ `deploy.branches`" observation `lisa-linear-build-intake` performs before
292
+ relabeling.
293
+ - **lisa / other repos:** the repo's release or publish workflow for
294
+ `<baseRefName>`.
295
+
296
+ Discover the run with the same `gh run list --json …headSha…` pattern
297
+ `lisa-verify-workflow-change` uses:
298
+
299
+ ```bash
300
+ merge_sha=$(gh pr view <pr> --json mergeCommit -q .mergeCommit.oid)
301
+ gh run list --branch <baseRefName> --commit "$merge_sha" \
302
+ --json databaseId,workflowName,status,conclusion,headSha,headBranch,createdAt --limit 20
303
+ ```
304
+
305
+ **Bounded wait:** a just-created run can take a few seconds to register — poll
306
+ briefly (a small number of short intervals / a short ceiling, mirroring the "wait
307
+ for that head's checks to start" bound used above) before concluding the run is
308
+ absent, so a not-yet-registered run is not mis-read as zero. When no run matches
309
+ the merge SHA directly, also accept a descendant run whose head has `$merge_sha`
310
+ as an ancestor (`git merge-base --is-ancestor "$merge_sha" <run_head_sha>`).
311
+
312
+ **Zero runs after the bounded wait — do NOT report shipped.** Recover in order:
313
+
314
+ 1. **Dispatch the deploy, then re-verify.** Trigger the env's `workflow_dispatch`
315
+ for the merged-into branch and re-poll for a run that now covers the merge SHA
316
+ (or an including descendant):
317
+ ```bash
318
+ gh workflow run <deploy-or-release-workflow> --ref <baseRefName>
319
+ ```
320
+ Once such a run appears, the merge is confirmed shipped.
321
+ 2. **Still zero, or dispatch not permitted → surface a blocker.** Emit a hard
322
+ block (`blocked:deploy`) reporting exactly what was observed — the merge SHA,
323
+ the base branch, and zero deploy runs. A failed/blocked path, **never** a
324
+ silent "done".
325
+
326
+ In **`on_blocker=report`** mode this deploy-run step is diagnose-only: dispatching
327
+ a workflow is an action, so do **not** run `gh workflow run` / `workflow_dispatch`
328
+ — classify the absence as `blocked:deploy` (or `blocked:no-deploy-run`) and return
329
+ it for the caller to act on, consistent with the report-mode contract (steps b–f
330
+ of section 2 are diagnose-only).
331
+
266
332
  ## 4. Terminal states
267
333
 
268
334
  Loop until one of:
269
335
 
270
- - **`MERGED`** and the ancestry check passes success.
336
+ - **`MERGED`** and the ancestry check passes **and** a deploy/release run for the
337
+ merge SHA (or an including descendant) is confirmed — observed directly or after
338
+ a `workflow_dispatch` recovery → success. Ancestry alone is **not** success.
339
+ - **`blocked:deploy`** — merged with ancestry green, but after the bounded wait no
340
+ deploy/release run fired for the merge SHA and dispatch recovery could not
341
+ confirm one (or was not permitted, e.g. `on_blocker=report`). Stop and report
342
+ the merge SHA, base branch, and zero observed runs — never a silent "done".
271
343
  - **`awaiting-human`** (`auto_merge=false` only) → success. The PR is `OPEN`,
272
344
  required checks are green, the review gate is clear, and
273
345
  `mergeable == MERGEABLE`, with auto-merge deliberately not enabled
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.259.1",
3
+ "version": "2.259.2",
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-drive-pr-to-merge
3
- description: This skill should be used to drive a pull request all the way to MERGED, handling ANYTHING that blocks the merge. It enables auto-merge when the repo supports it (direct-merge fallback otherwise), keeps the branch rebased/synced and resolves merge conflicts, fixes failing CI/deploy checks, addresses and resolves every human and bot review comment (CodeRabbit, etc.) — implementing valid feedback and replying-then-resolving invalid feedback — dismisses stale CHANGES_REQUESTED gates, and verifies the fix actually shipped (auto-merge race ancestry check). Composable and inline — invoked by other skills (e.g. git-submit-pr, implement, sync-down) via the Skill tool, never as a standalone user command.
3
+ description: This skill should be used to drive a pull request all the way to MERGED, handling ANYTHING that blocks the merge. It enables auto-merge when the repo supports it (direct-merge fallback otherwise), keeps the branch rebased/synced and resolves merge conflicts, fixes failing CI/deploy checks, addresses and resolves every human and bot review comment (CodeRabbit, etc.) — implementing valid feedback and replying-then-resolving invalid feedback — dismisses stale CHANGES_REQUESTED gates, and verifies the fix actually shipped — both merge ancestry and that a deploy/release run fired for the merge SHA (auto-merge race + zero-deploy-run check). Composable and inline — invoked by other skills (e.g. git-submit-pr, implement, sync-down) via the Skill tool, never as a standalone user command.
4
4
  allowed-tools: ["Bash", "Read", "Edit", "Write", "Grep", "Glob", "Skill"]
5
5
  ---
6
6
 
@@ -246,11 +246,16 @@ head's checks to start, then re-enable auto-merge (section 1). In
246
246
  `on_blocker=report` mode this whole step is off-limits (diagnose-only): do not
247
247
  merge, close, or delete anything — return `blocked:pending-auto-fix`.
248
248
 
249
- ## 3. Merge and verify it actually shipped (ancestry check)
249
+ ## 3. Merge and verify it actually shipped (ancestry + deploy run)
250
250
 
251
251
  Enabling auto-merge + green checks + resolved threads is **not** proof the merge
252
- included your fix. Auto-merge can land the PRIOR head the instant gates go green,
253
- before a late fix commit becomes the head. After the PR reports `MERGED`:
252
+ included your fix, and a passing merge **not** proof anything deployed. Both must
253
+ be verified after the PR reports `MERGED`.
254
+
255
+ ### a. Ancestry check — is my code in the merged branch
256
+
257
+ Auto-merge can land the PRIOR head the instant gates go green, before a late fix
258
+ commit becomes the head:
254
259
 
255
260
  ```bash
256
261
  git fetch origin
@@ -263,11 +268,78 @@ ship — fix forward with a new commit/PR and re-drive. Re-confirm after any com
263
268
  that lands while auto-merge is enabled; a successful merge of an older head is a
264
269
  failed drive-to-merge outcome, not a successful closeout.
265
270
 
271
+ ### b. Deploy-run check — did a deploy/release workflow run actually fire
272
+
273
+ Ancestry proves your code is *in* the merged branch; it does **not** prove
274
+ anything deployed. GitHub can **suppress the `on: push` event for a merge commit
275
+ created by auto-merge or a bot token** (`GITHUB_TOKEN`), so the deploy workflow
276
+ fires **zero** runs — no run, not even a `startup_failure` — while the ancestry
277
+ check above stays green. Incident of record: TunnlAI/frontend **TUN-186** (PR #67)
278
+ merged to `dev` via auto-merge; the merge commit `1b3f836` produced **no**
279
+ `deploy.yml` run, and only the next human push `d1fe18c` (which carries `1b3f836`
280
+ as an ancestor) actually shipped it. **Never report shipped on ancestry alone.**
281
+
282
+ After ancestry passes, capture the merge SHA and poll for a **deploy/release
283
+ workflow run** whose head SHA **is the merge SHA or an including descendant** (a
284
+ run whose head has the merge SHA as an ancestor also shipped the merge, mirroring
285
+ `d1fe18c` shipping `1b3f836`), keyed to the merged-into branch. The observing
286
+ workflow name is **not fixed** — do **not** hardcode `deploy.yml`:
287
+
288
+ - **Downstream projects:** the deploy/release workflow run keyed to the base
289
+ branch resolved via `.lisa.config.json` `deploy.branches` (the merged-into env
290
+ branch) — the same "deploy run keyed to the merged-into branch via
291
+ `deploy.branches`" observation `lisa-linear-build-intake` performs before
292
+ relabeling.
293
+ - **lisa / other repos:** the repo's release or publish workflow for
294
+ `<baseRefName>`.
295
+
296
+ Discover the run with the same `gh run list --json …headSha…` pattern
297
+ `lisa-verify-workflow-change` uses:
298
+
299
+ ```bash
300
+ merge_sha=$(gh pr view <pr> --json mergeCommit -q .mergeCommit.oid)
301
+ gh run list --branch <baseRefName> --commit "$merge_sha" \
302
+ --json databaseId,workflowName,status,conclusion,headSha,headBranch,createdAt --limit 20
303
+ ```
304
+
305
+ **Bounded wait:** a just-created run can take a few seconds to register — poll
306
+ briefly (a small number of short intervals / a short ceiling, mirroring the "wait
307
+ for that head's checks to start" bound used above) before concluding the run is
308
+ absent, so a not-yet-registered run is not mis-read as zero. When no run matches
309
+ the merge SHA directly, also accept a descendant run whose head has `$merge_sha`
310
+ as an ancestor (`git merge-base --is-ancestor "$merge_sha" <run_head_sha>`).
311
+
312
+ **Zero runs after the bounded wait — do NOT report shipped.** Recover in order:
313
+
314
+ 1. **Dispatch the deploy, then re-verify.** Trigger the env's `workflow_dispatch`
315
+ for the merged-into branch and re-poll for a run that now covers the merge SHA
316
+ (or an including descendant):
317
+ ```bash
318
+ gh workflow run <deploy-or-release-workflow> --ref <baseRefName>
319
+ ```
320
+ Once such a run appears, the merge is confirmed shipped.
321
+ 2. **Still zero, or dispatch not permitted → surface a blocker.** Emit a hard
322
+ block (`blocked:deploy`) reporting exactly what was observed — the merge SHA,
323
+ the base branch, and zero deploy runs. A failed/blocked path, **never** a
324
+ silent "done".
325
+
326
+ In **`on_blocker=report`** mode this deploy-run step is diagnose-only: dispatching
327
+ a workflow is an action, so do **not** run `gh workflow run` / `workflow_dispatch`
328
+ — classify the absence as `blocked:deploy` (or `blocked:no-deploy-run`) and return
329
+ it for the caller to act on, consistent with the report-mode contract (steps b–f
330
+ of section 2 are diagnose-only).
331
+
266
332
  ## 4. Terminal states
267
333
 
268
334
  Loop until one of:
269
335
 
270
- - **`MERGED`** and the ancestry check passes success.
336
+ - **`MERGED`** and the ancestry check passes **and** a deploy/release run for the
337
+ merge SHA (or an including descendant) is confirmed — observed directly or after
338
+ a `workflow_dispatch` recovery → success. Ancestry alone is **not** success.
339
+ - **`blocked:deploy`** — merged with ancestry green, but after the bounded wait no
340
+ deploy/release run fired for the merge SHA and dispatch recovery could not
341
+ confirm one (or was not permitted, e.g. `on_blocker=report`). Stop and report
342
+ the merge SHA, base branch, and zero observed runs — never a silent "done".
271
343
  - **`awaiting-human`** (`auto_merge=false` only) → success. The PR is `OPEN`,
272
344
  required checks are green, the review gate is clear, and
273
345
  `mergeable == MERGEABLE`, with auto-merge deliberately not enabled
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.259.1",
3
+ "version": "2.259.2",
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.259.1",
3
+ "version": "2.259.2",
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.259.1",
3
+ "version": "2.259.2",
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.259.1",
3
+ "version": "2.259.2",
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.259.1",
3
+ "version": "2.259.2",
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.259.1",
3
+ "version": "2.259.2",
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.259.1",
3
+ "version": "2.259.2",
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.259.1",
3
+ "version": "2.259.2",
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.259.1",
3
+ "version": "2.259.2",
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.259.1",
3
+ "version": "2.259.2",
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.259.1",
3
+ "version": "2.259.2",
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.259.1",
3
+ "version": "2.259.2",
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.259.1",
3
+ "version": "2.259.2",
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.259.1",
3
+ "version": "2.259.2",
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.259.1",
3
+ "version": "2.259.2",
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.259.1",
3
+ "version": "2.259.2",
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.259.1",
3
+ "version": "2.259.2",
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.259.1",
3
+ "version": "2.259.2",
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.259.1",
3
+ "version": "2.259.2",
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.259.1",
3
+ "version": "2.259.2",
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": "2.259.1",
3
+ "version": "2.259.2",
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": "2.259.1",
3
+ "version": "2.259.2",
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": "2.259.1",
3
+ "version": "2.259.2",
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": "2.259.1",
3
+ "version": "2.259.2",
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": "2.259.1",
3
+ "version": "2.259.2",
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": "2.259.1",
3
+ "version": "2.259.2",
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.259.1",
3
+ "version": "2.259.2",
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.259.1",
3
+ "version": "2.259.2",
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.259.1",
3
+ "version": "2.259.2",
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.259.1",
3
+ "version": "2.259.2",
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": "2.259.1",
3
+ "version": "2.259.2",
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": "2.259.1",
3
+ "version": "2.259.2",
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": "2.259.1",
3
+ "version": "2.259.2",
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": "2.259.1",
3
+ "version": "2.259.2",
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": "2.259.1",
3
+ "version": "2.259.2",
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": "2.259.1",
3
+ "version": "2.259.2",
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": "2.259.1",
3
+ "version": "2.259.2",
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": "2.259.1",
3
+ "version": "2.259.2",
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": "2.259.1",
3
+ "version": "2.259.2",
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": "2.259.1",
3
+ "version": "2.259.2",
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-drive-pr-to-merge
3
- description: This skill should be used to drive a pull request all the way to MERGED, handling ANYTHING that blocks the merge. It enables auto-merge when the repo supports it (direct-merge fallback otherwise), keeps the branch rebased/synced and resolves merge conflicts, fixes failing CI/deploy checks, addresses and resolves every human and bot review comment (CodeRabbit, etc.) — implementing valid feedback and replying-then-resolving invalid feedback — dismisses stale CHANGES_REQUESTED gates, and verifies the fix actually shipped (auto-merge race ancestry check). Composable and inline — invoked by other skills (e.g. git-submit-pr, implement, sync-down) via the Skill tool, never as a standalone user command.
3
+ description: This skill should be used to drive a pull request all the way to MERGED, handling ANYTHING that blocks the merge. It enables auto-merge when the repo supports it (direct-merge fallback otherwise), keeps the branch rebased/synced and resolves merge conflicts, fixes failing CI/deploy checks, addresses and resolves every human and bot review comment (CodeRabbit, etc.) — implementing valid feedback and replying-then-resolving invalid feedback — dismisses stale CHANGES_REQUESTED gates, and verifies the fix actually shipped — both merge ancestry and that a deploy/release run fired for the merge SHA (auto-merge race + zero-deploy-run check). Composable and inline — invoked by other skills (e.g. git-submit-pr, implement, sync-down) via the Skill tool, never as a standalone user command.
4
4
  allowed-tools: ["Bash", "Read", "Edit", "Write", "Grep", "Glob", "Skill"]
5
5
  ---
6
6
 
@@ -246,11 +246,16 @@ head's checks to start, then re-enable auto-merge (section 1). In
246
246
  `on_blocker=report` mode this whole step is off-limits (diagnose-only): do not
247
247
  merge, close, or delete anything — return `blocked:pending-auto-fix`.
248
248
 
249
- ## 3. Merge and verify it actually shipped (ancestry check)
249
+ ## 3. Merge and verify it actually shipped (ancestry + deploy run)
250
250
 
251
251
  Enabling auto-merge + green checks + resolved threads is **not** proof the merge
252
- included your fix. Auto-merge can land the PRIOR head the instant gates go green,
253
- before a late fix commit becomes the head. After the PR reports `MERGED`:
252
+ included your fix, and a passing merge **not** proof anything deployed. Both must
253
+ be verified after the PR reports `MERGED`.
254
+
255
+ ### a. Ancestry check — is my code in the merged branch
256
+
257
+ Auto-merge can land the PRIOR head the instant gates go green, before a late fix
258
+ commit becomes the head:
254
259
 
255
260
  ```bash
256
261
  git fetch origin
@@ -263,11 +268,78 @@ ship — fix forward with a new commit/PR and re-drive. Re-confirm after any com
263
268
  that lands while auto-merge is enabled; a successful merge of an older head is a
264
269
  failed drive-to-merge outcome, not a successful closeout.
265
270
 
271
+ ### b. Deploy-run check — did a deploy/release workflow run actually fire
272
+
273
+ Ancestry proves your code is *in* the merged branch; it does **not** prove
274
+ anything deployed. GitHub can **suppress the `on: push` event for a merge commit
275
+ created by auto-merge or a bot token** (`GITHUB_TOKEN`), so the deploy workflow
276
+ fires **zero** runs — no run, not even a `startup_failure` — while the ancestry
277
+ check above stays green. Incident of record: TunnlAI/frontend **TUN-186** (PR #67)
278
+ merged to `dev` via auto-merge; the merge commit `1b3f836` produced **no**
279
+ `deploy.yml` run, and only the next human push `d1fe18c` (which carries `1b3f836`
280
+ as an ancestor) actually shipped it. **Never report shipped on ancestry alone.**
281
+
282
+ After ancestry passes, capture the merge SHA and poll for a **deploy/release
283
+ workflow run** whose head SHA **is the merge SHA or an including descendant** (a
284
+ run whose head has the merge SHA as an ancestor also shipped the merge, mirroring
285
+ `d1fe18c` shipping `1b3f836`), keyed to the merged-into branch. The observing
286
+ workflow name is **not fixed** — do **not** hardcode `deploy.yml`:
287
+
288
+ - **Downstream projects:** the deploy/release workflow run keyed to the base
289
+ branch resolved via `.lisa.config.json` `deploy.branches` (the merged-into env
290
+ branch) — the same "deploy run keyed to the merged-into branch via
291
+ `deploy.branches`" observation `lisa-linear-build-intake` performs before
292
+ relabeling.
293
+ - **lisa / other repos:** the repo's release or publish workflow for
294
+ `<baseRefName>`.
295
+
296
+ Discover the run with the same `gh run list --json …headSha…` pattern
297
+ `lisa-verify-workflow-change` uses:
298
+
299
+ ```bash
300
+ merge_sha=$(gh pr view <pr> --json mergeCommit -q .mergeCommit.oid)
301
+ gh run list --branch <baseRefName> --commit "$merge_sha" \
302
+ --json databaseId,workflowName,status,conclusion,headSha,headBranch,createdAt --limit 20
303
+ ```
304
+
305
+ **Bounded wait:** a just-created run can take a few seconds to register — poll
306
+ briefly (a small number of short intervals / a short ceiling, mirroring the "wait
307
+ for that head's checks to start" bound used above) before concluding the run is
308
+ absent, so a not-yet-registered run is not mis-read as zero. When no run matches
309
+ the merge SHA directly, also accept a descendant run whose head has `$merge_sha`
310
+ as an ancestor (`git merge-base --is-ancestor "$merge_sha" <run_head_sha>`).
311
+
312
+ **Zero runs after the bounded wait — do NOT report shipped.** Recover in order:
313
+
314
+ 1. **Dispatch the deploy, then re-verify.** Trigger the env's `workflow_dispatch`
315
+ for the merged-into branch and re-poll for a run that now covers the merge SHA
316
+ (or an including descendant):
317
+ ```bash
318
+ gh workflow run <deploy-or-release-workflow> --ref <baseRefName>
319
+ ```
320
+ Once such a run appears, the merge is confirmed shipped.
321
+ 2. **Still zero, or dispatch not permitted → surface a blocker.** Emit a hard
322
+ block (`blocked:deploy`) reporting exactly what was observed — the merge SHA,
323
+ the base branch, and zero deploy runs. A failed/blocked path, **never** a
324
+ silent "done".
325
+
326
+ In **`on_blocker=report`** mode this deploy-run step is diagnose-only: dispatching
327
+ a workflow is an action, so do **not** run `gh workflow run` / `workflow_dispatch`
328
+ — classify the absence as `blocked:deploy` (or `blocked:no-deploy-run`) and return
329
+ it for the caller to act on, consistent with the report-mode contract (steps b–f
330
+ of section 2 are diagnose-only).
331
+
266
332
  ## 4. Terminal states
267
333
 
268
334
  Loop until one of:
269
335
 
270
- - **`MERGED`** and the ancestry check passes success.
336
+ - **`MERGED`** and the ancestry check passes **and** a deploy/release run for the
337
+ merge SHA (or an including descendant) is confirmed — observed directly or after
338
+ a `workflow_dispatch` recovery → success. Ancestry alone is **not** success.
339
+ - **`blocked:deploy`** — merged with ancestry green, but after the bounded wait no
340
+ deploy/release run fired for the merge SHA and dispatch recovery could not
341
+ confirm one (or was not permitted, e.g. `on_blocker=report`). Stop and report
342
+ the merge SHA, base branch, and zero observed runs — never a silent "done".
271
343
  - **`awaiting-human`** (`auto_merge=false` only) → success. The PR is `OPEN`,
272
344
  required checks are green, the review gate is clear, and
273
345
  `mergeable == MERGEABLE`, with auto-merge deliberately not enabled