@codyswann/lisa 4.73.9 → 4.74.1

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 (119) hide show
  1. package/README.md +52 -3
  2. package/all/create-only/.github/workflows/continuous-gates.yml +2 -2
  3. package/all/create-only/.github/workflows/workflow-load-failure-sweep.yml +1 -1
  4. package/cdk/create-only/.github/workflows/ci.yml +2 -2
  5. package/cdk/create-only/.github/workflows/deploy.yml +3 -3
  6. package/cdk/package-lisa/package.lisa.json +1 -1
  7. package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
  8. package/dist/core/lisa-owned-hash-ledger.js +60 -0
  9. package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
  10. package/dist/core/lisa-owned-templates.d.ts +9 -2
  11. package/dist/core/lisa-owned-templates.d.ts.map +1 -1
  12. package/dist/core/lisa-owned-templates.js +13 -3
  13. package/dist/core/lisa-owned-templates.js.map +1 -1
  14. package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
  15. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  16. package/dist/core/upstream-evidence-manifest.js +87 -33
  17. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  18. package/expo/copy-overwrite/jest.setup.pre.js +15 -1
  19. package/expo/copy-overwrite/scripts/bdd/ci-summary.mjs +37 -0
  20. package/expo/copy-overwrite/scripts/bdd/projection-model.mjs +157 -0
  21. package/expo/copy-overwrite/scripts/bdd/projection-ownership.mjs +300 -0
  22. package/expo/copy-overwrite/scripts/bdd/projection-paths.mjs +152 -0
  23. package/expo/copy-overwrite/scripts/bdd/projection-render.mjs +303 -0
  24. package/expo/copy-overwrite/scripts/bdd/projection-write.mjs +84 -0
  25. package/expo/copy-overwrite/scripts/bdd/projection.mjs +30 -0
  26. package/expo/copy-overwrite/scripts/bdd-matrix.mjs +54 -18
  27. package/expo/copy-overwrite/scripts/check-bdd-coverage.mjs +36 -27
  28. package/expo/create-only/.github/workflows/ci.yml +3 -3
  29. package/expo/create-only/.github/workflows/deploy.yml +4 -4
  30. package/expo/create-only/.github/workflows/nightly-e2e-bypass-reaper.yml +1 -1
  31. package/expo/create-only/.github/workflows/playwright-e2e.yml +1 -1
  32. package/expo/create-only/eas.json +1 -1
  33. package/harper-fabric/copy-overwrite/.github/workflows/ci.yml +1 -1
  34. package/harper-fabric/create-only/.github/workflows/deploy.yml +3 -3
  35. package/harper-fabric/create-only/.github/workflows/zap-baseline.yml +1 -1
  36. package/harper-fabric/package-lisa/package.lisa.json +2 -2
  37. package/nestjs/create-only/.github/workflows/ci.yml +2 -2
  38. package/nestjs/create-only/.github/workflows/deploy.yml +5 -5
  39. package/package.json +6 -6
  40. package/phaser/copy-overwrite/.github/workflows/ci.yml +1 -1
  41. package/phaser/package-lisa/package.lisa.json +2 -2
  42. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  43. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  44. package/plugins/lisa/.codex-plugin/skills/lisa-parity-sentry-sdk-setup/SKILL.md +104 -0
  45. package/plugins/lisa/.codex-plugin/skills/lisa-setup-workstation/scripts/workstation.mjs +3 -1
  46. package/plugins/lisa/rules/reference/bdd-e2e-coverage.md +9 -7
  47. package/plugins/lisa/skills/lisa-parity-sentry-sdk-setup/SKILL.md +104 -0
  48. package/plugins/lisa/skills/lisa-setup-workstation/scripts/workstation.mjs +3 -1
  49. package/plugins/lisa-agy/plugin.json +1 -1
  50. package/plugins/lisa-agy/skills/lisa-parity-sentry-sdk-setup/SKILL.md +104 -0
  51. package/plugins/lisa-agy/skills/lisa-setup-workstation/scripts/workstation.mjs +3 -1
  52. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  53. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  54. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  55. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  56. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  57. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  58. package/plugins/lisa-copilot/rules/reference/bdd-e2e-coverage.md +9 -7
  59. package/plugins/lisa-copilot/skills/lisa-parity-sentry-sdk-setup/SKILL.md +104 -0
  60. package/plugins/lisa-copilot/skills/lisa-setup-workstation/scripts/workstation.mjs +3 -1
  61. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  62. package/plugins/lisa-cursor/rules/bdd-e2e-coverage-reference.mdc +9 -7
  63. package/plugins/lisa-cursor/skills/lisa-parity-sentry-sdk-setup/SKILL.md +104 -0
  64. package/plugins/lisa-cursor/skills/lisa-setup-workstation/scripts/workstation.mjs +3 -1
  65. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  66. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  67. package/plugins/lisa-expo-agy/plugin.json +1 -1
  68. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  69. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  70. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  71. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  72. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  73. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  74. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  75. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  76. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  77. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  78. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  79. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  80. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  81. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  82. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  83. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  84. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  85. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  86. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  87. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  88. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  89. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  90. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  91. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  92. package/plugins/lisa-rails-agy/plugin.json +1 -1
  93. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  94. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  95. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  96. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  97. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  98. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  99. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  100. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  101. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  102. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  103. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  104. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  105. package/plugins/src/base/rules/reference/bdd-e2e-coverage.md +9 -7
  106. package/plugins/src/base/skills/lisa-parity-sentry-sdk-setup/SKILL.md +104 -0
  107. package/plugins/src/base/skills/lisa-setup-workstation/scripts/workstation.mjs +3 -1
  108. package/scripts/check-shell-guard-refusal-coverage.mjs +65 -7
  109. package/scripts/generate-lisa-owned-hash-ledger.mjs +3 -0
  110. package/scripts/lib/shell-guard-shard-runner.mjs +381 -0
  111. package/scripts/lib/shell-guard-shards.mjs +383 -0
  112. package/scripts/lib/shell-guard-terminal-reporter.mjs +89 -0
  113. package/scripts/two-channel-couplings.json +2 -2
  114. package/scripts/update-node-version.ts +52 -6
  115. package/typescript/copy-overwrite/.nvmrc +1 -1
  116. package/typescript/create-only/.github/workflows/ci.yml +1 -1
  117. package/typescript/create-only/.github/workflows/review-evidence.yml +1 -1
  118. package/typescript/create-only/.github/workflows/third-party-review-evidence.yml +1 -1
  119. package/typescript/package-lisa/package.lisa.json +1 -1
@@ -114,7 +114,7 @@ jobs:
114
114
  # (CodySwannGT/lisa#3698).
115
115
  expected_workflow_contract_major: '1'
116
116
  moment: pre-deploy:${{ needs.determine_environment.outputs.environment }}
117
- node_version: '22.23.3'
117
+ node_version: '24.21.0'
118
118
  package_manager: 'bun'
119
119
  # No `secrets:` key: gates.yml declares none in its `workflow_call`, so
120
120
  # passing any grants everything to a callee that reads nothing (#3065).
@@ -142,7 +142,7 @@ jobs:
142
142
  approval_environment: ${{ needs.determine_environment.outputs.approval_environment }}
143
143
  require_signatures: false
144
144
  generate_sbom: true
145
- node_version: '22.23.3'
145
+ node_version: '24.21.0'
146
146
  package_manager: 'bun'
147
147
  override_blackout: true
148
148
  emergency_release: false
@@ -330,7 +330,7 @@ jobs:
330
330
  uses: actions/setup-node@v6
331
331
  with:
332
332
  package-manager-cache: false
333
- node-version: '22.23.3'
333
+ node-version: '24.21.0'
334
334
  - name: 🍞 Setup Bun
335
335
  uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
336
336
  with:
@@ -424,7 +424,7 @@ jobs:
424
424
  # (CodySwannGT/lisa#3698).
425
425
  expected_workflow_contract_major: '1'
426
426
  moment: post-deploy:${{ needs.determine_environment.outputs.environment }}
427
- node_version: '22.23.3'
427
+ node_version: '24.21.0'
428
428
  package_manager: 'bun'
429
429
  # No `secrets:` key: gates.yml declares none in its `workflow_call`, so
430
430
  # passing any grants everything to a callee that reads nothing (#3065).
@@ -93,7 +93,7 @@ jobs:
93
93
  uses: actions/setup-node@v6
94
94
  with:
95
95
  package-manager-cache: false
96
- node-version: '22.23.3'
96
+ node-version: '24.21.0'
97
97
 
98
98
  - name: 🔎 Locate the guard
99
99
  id: guard
@@ -137,7 +137,7 @@ jobs:
137
137
  # declared a break, and says NOT DETERMINED if this line goes missing
138
138
  # (CodySwannGT/lisa#3698).
139
139
  expected_workflow_contract_major: '1'
140
- node_version: '22.23.3'
140
+ node_version: '24.21.0'
141
141
  package_manager: 'bun'
142
142
  # The moment this workflow's cadence corresponds to. It is what makes the
143
143
  # `.lisa.config.json` declaration above readable from here — a gate
@@ -5,7 +5,7 @@
5
5
  },
6
6
  "build": {
7
7
  "base": {
8
- "node": "22.23.3",
8
+ "node": "24.21.0",
9
9
  "resourceClass": "large",
10
10
  "env": {
11
11
  "NODE_OPTIONS": "--max-old-space-size=4096",
@@ -26,7 +26,7 @@ jobs:
26
26
  # declared a break, and says NOT DETERMINED if this line goes missing
27
27
  # (CodySwannGT/lisa#3698).
28
28
  expected_workflow_contract_major: '1'
29
- node_version: '22.23.3'
29
+ node_version: '24.21.0'
30
30
  package_manager: 'bun'
31
31
  skip_jobs: ''
32
32
  secrets:
@@ -41,7 +41,7 @@ jobs:
41
41
  # (CodySwannGT/lisa#3698).
42
42
  expected_workflow_contract_major: '1'
43
43
  moment: pre-deploy:${{ github.ref_name }}
44
- node_version: '22.23.3'
44
+ node_version: '24.21.0'
45
45
  package_manager: 'bun'
46
46
  # No `secrets:` key: gates.yml declares none in its `workflow_call`, so
47
47
  # passing any grants everything to a callee that reads nothing (#3065).
@@ -64,7 +64,7 @@ jobs:
64
64
  - name: Setup Node.js
65
65
  uses: actions/setup-node@v6
66
66
  with:
67
- node-version: '22.23.3'
67
+ node-version: '24.21.0'
68
68
  package-manager-cache: false
69
69
 
70
70
  - name: Setup Bun
@@ -132,7 +132,7 @@ jobs:
132
132
  # (CodySwannGT/lisa#3698).
133
133
  expected_workflow_contract_major: '1'
134
134
  moment: post-deploy:${{ github.ref_name }}
135
- node_version: '22.23.3'
135
+ node_version: '24.21.0'
136
136
  package_manager: 'bun'
137
137
  # No `secrets:` key: gates.yml declares none in its `workflow_call`, so
138
138
  # passing any grants everything to a callee that reads nothing (#3065).
@@ -33,7 +33,7 @@ jobs:
33
33
  - name: Setup Node.js
34
34
  uses: actions/setup-node@v6
35
35
  with:
36
- node-version: '22.23.3'
36
+ node-version: '24.21.0'
37
37
  package-manager-cache: false
38
38
 
39
39
  - name: Setup Bun
@@ -37,7 +37,7 @@
37
37
  "@eslint-community/eslint-plugin-eslint-comments": "^4.5.0",
38
38
  "@eslint/eslintrc": "^3.3.7",
39
39
  "@eslint/js": "^9.39.5",
40
- "@types/node": "^22.0.0",
40
+ "@types/node": "^24.0.0",
41
41
  "@vitest/coverage-v8": "^4.1.11",
42
42
  "eslint": "^9.39.5",
43
43
  "eslint-config-prettier": "^10.0.0",
@@ -65,7 +65,7 @@
65
65
  "yarn": "please-use-bun",
66
66
  "pnpm": "please-use-bun",
67
67
  "bun": ">= 1.3.11",
68
- "node": ">= 22.23.3"
68
+ "node": ">= 24.21.0"
69
69
  },
70
70
  "packageManager": "bun@1.3.11",
71
71
  "private": true
@@ -28,7 +28,7 @@ jobs:
28
28
  # declared a break, and says NOT DETERMINED if this line goes missing
29
29
  # (CodySwannGT/lisa#3698).
30
30
  expected_workflow_contract_major: '1'
31
- node_version: '22.23.3'
31
+ node_version: '24.21.0'
32
32
  package_manager: 'bun'
33
33
  skip_jobs: 'test:e2e,playwright_e2e'
34
34
  secrets:
@@ -56,5 +56,5 @@ jobs:
56
56
  # declared a break, and says NOT DETERMINED if this line goes missing
57
57
  # (CodySwannGT/lisa#3698).
58
58
  expected_workflow_contract_major: '1'
59
- node_version: '22.23.3'
59
+ node_version: '24.21.0'
60
60
  package_manager: 'bun'
@@ -110,7 +110,7 @@ jobs:
110
110
  # (CodySwannGT/lisa#3698).
111
111
  expected_workflow_contract_major: '1'
112
112
  moment: pre-deploy:${{ needs.determine_environment.outputs.environment }}
113
- node_version: '22.23.3'
113
+ node_version: '24.21.0'
114
114
  package_manager: 'bun'
115
115
  # No `secrets:` key: gates.yml declares none in its `workflow_call`, so
116
116
  # passing any grants everything to a callee that reads nothing (#3065).
@@ -139,7 +139,7 @@ jobs:
139
139
  require_approval: ${{ needs.determine_environment.outputs.require_approval == 'true' }}
140
140
  approval_environment: ${{ needs.determine_environment.outputs.approval_environment }}
141
141
  require_signatures: false
142
- node_version: '22.23.3'
142
+ node_version: '24.21.0'
143
143
  package_manager: 'bun'
144
144
  secrets:
145
145
  DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
@@ -306,10 +306,10 @@ jobs:
306
306
  contents: read
307
307
  steps:
308
308
  - uses: actions/checkout@v6
309
- - name: Use Node.js 22.23.3
309
+ - name: Use Node.js 24.21.0
310
310
  uses: actions/setup-node@v6
311
311
  with:
312
- node-version: 22.23.3
312
+ node-version: 24.21.0
313
313
  package-manager-cache: false
314
314
  - uses: noliran/branch-based-secrets@ef9182f16f118c7c3d05c36973546ebc990b8c69 # v1 (2020-10-09, no semver tag)
315
315
  with:
@@ -462,7 +462,7 @@ jobs:
462
462
  # (CodySwannGT/lisa#3698).
463
463
  expected_workflow_contract_major: '1'
464
464
  moment: post-deploy:${{ needs.determine_environment.outputs.environment }}
465
- node_version: '22.23.3'
465
+ node_version: '24.21.0'
466
466
  package_manager: 'bun'
467
467
  # No `secrets:` key: gates.yml declares none in its `workflow_call`, so
468
468
  # passing any grants everything to a callee that reads nothing (#3065).
package/package.json CHANGED
@@ -109,7 +109,7 @@
109
109
  "yarn": "please-use-bun",
110
110
  "pnpm": "please-use-bun",
111
111
  "bun": "1.3.8",
112
- "node": "22.23.3"
112
+ "node": "24.21.0"
113
113
  },
114
114
  "workspaces": [
115
115
  "eslint-plugin-code-organization",
@@ -189,7 +189,7 @@
189
189
  "qs": "^6.16.0"
190
190
  },
191
191
  "name": "@codyswann/lisa",
192
- "version": "4.73.9",
192
+ "version": "4.74.1",
193
193
  "description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
194
194
  "main": "dist/index.js",
195
195
  "exports": {
@@ -272,7 +272,7 @@
272
272
  "@types/fs-extra": "^11.0.0",
273
273
  "@types/jest": "^30.0.0",
274
274
  "@types/lodash.merge": "^4.6.0",
275
- "@types/node": "^22.0.0",
275
+ "@types/node": "^24.0.0",
276
276
  "@vitest/coverage-v8": "^4.1.11",
277
277
  "commander": "^12.0.0",
278
278
  "esbuild-register": "^3.6.0",
@@ -345,7 +345,7 @@
345
345
  "test": "tests"
346
346
  },
347
347
  "types": "./dist/index.d.ts",
348
- "lisaReleaseCommit": "1db4b5f0e5e55ddc3ed5229e15ed337f1236081c",
349
- "gitHead": "1db4b5f0e5e55ddc3ed5229e15ed337f1236081c",
350
- "lisaReleaseTag": "v4.73.9"
348
+ "lisaReleaseCommit": "cc1eae7783ceef7fb72a4883139a4df03d37e732",
349
+ "gitHead": "cc1eae7783ceef7fb72a4883139a4df03d37e732",
350
+ "lisaReleaseTag": "v4.74.1"
351
351
  }
@@ -29,7 +29,7 @@ jobs:
29
29
  # declared a break, and says NOT DETERMINED if this line goes missing
30
30
  # (CodySwannGT/lisa#3698).
31
31
  expected_workflow_contract_major: '1'
32
- node_version: '22.23.3'
32
+ node_version: '24.21.0'
33
33
  package_manager: 'bun'
34
34
  skip_jobs: ''
35
35
  # Verification IS UAT: a feat/fix must ship a tests/e2e verification spec
@@ -30,7 +30,7 @@
30
30
  "@eslint-community/eslint-plugin-eslint-comments": "^4.5.0",
31
31
  "@eslint/eslintrc": "^3.3.7",
32
32
  "@eslint/js": "^9.39.5",
33
- "@types/node": "^22.0.0",
33
+ "@types/node": "^24.0.0",
34
34
  "@vitest/coverage-v8": "^4.1.11",
35
35
  "eslint": "^9.39.5",
36
36
  "eslint-config-prettier": "^10.0.0",
@@ -57,7 +57,7 @@
57
57
  "yarn": "please-use-bun",
58
58
  "pnpm": "please-use-bun",
59
59
  "bun": ">= 1.3.11",
60
- "node": ">= 22.23.3"
60
+ "node": ">= 24.21.0"
61
61
  },
62
62
  "packageManager": "bun@1.3.11",
63
63
  "private": true,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "4.73.9",
3
+ "version": "4.74.1",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "4.73.9",
3
+ "version": "4.74.1",
4
4
  "description": "Universal governance: agents, skills, commands, hooks, and rules for all projects.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -86,6 +86,8 @@ Inspect the project before choosing an SDK. Read `package.json`
86
86
  - `pyproject.toml` / `requirements.txt`; `django`/`flask`/`fastapi` →
87
87
  **Python** (and which web framework)
88
88
  - A plain Node library/CLI → **Node**
89
+ - AWS Lambda handlers or a Serverless/SAM/CDK function runtime → inspect the
90
+ function's actual runtime and wrapper before choosing **Node/Lambda**.
89
91
 
90
92
  If the runtime is genuinely ambiguous, ask which app to instrument rather than
91
93
  guessing. Respect the project's package manager (bun/npm/pnpm/yarn — match the
@@ -100,6 +102,7 @@ Use the project's package manager. Examples (swap `bun add` for your manager):
100
102
  | React (browser) | `@sentry/react` |
101
103
  | Next.js | `@sentry/nextjs` |
102
104
  | Node / Express / Fastify | `@sentry/node` (+ `@sentry/profiling-node` for profiling) |
105
+ | AWS Lambda | `@sentry/aws-serverless` for a compatible Lambda wrapper, or `@sentry/node` for an unwrapped async handler |
103
106
  | NestJS | `@sentry/nestjs` (+ `@sentry/node`) |
104
107
  | React Native / Expo | `@sentry/react-native` |
105
108
  | Vue | `@sentry/vue` |
@@ -150,6 +153,107 @@ Sentry.init({
150
153
 
151
154
  Then, after routes are defined: `Sentry.setupExpressErrorHandler(app);`
152
155
 
156
+ ### Node24 Lambda completion
157
+
158
+ Review the actual function runtime and installed SDK before migrating. Node24
159
+ LTS is Lisa's default for new TypeScript hosts; an existing host's explicit
160
+ engine and create-only workflows remain host-owned. On AWS Lambda `nodejs24.x`,
161
+ callback-style handlers and legacy context completion APIs, including
162
+ `callbackWaitsForEmptyEventLoop`, are removed. Do not assign those properties,
163
+ including to frozen/non-extensible context objects. Supported async handlers,
164
+ synchronous returns and response streaming are distinct forms; follow the
165
+ [AWS handler contract](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-handler.html).
166
+
167
+ Earlier non-streaming async handlers already returned without waiting for
168
+ unresolved background promises. Node24 aligns streaming completion with that
169
+ behavior; await work that must finish before returning or ending the stream.
170
+ Do not claim all Node20/22 async handlers drained arbitrary background work.
171
+ For streaming, flush at the appropriate point before `responseStream.end()` or
172
+ inside the awaited streaming pipeline, rather than after the stream is ended.
173
+ [AWS's Node24 migration explanation](https://aws.amazon.com/blogs/compute/node-js-24-runtime-now-available-in-aws-lambda/)
174
+ is the runtime authority; ordinary local Node process behavior is not deployed
175
+ Lambda evidence.
176
+
177
+ For an **unwrapped async** scheduled, queue or Cognito handler, initialize Sentry
178
+ once at module startup with the DSN from the environment. Await a finite positive
179
+ flush budget on both success and original-error paths. A false flush result or
180
+ rejection must not turn successful queue work into a retry or replace its real
181
+ error. Keep diagnostics local and non-throwing, and preserve the client for warm
182
+ invocations: `close()` disables it. The following helper wraps the host's existing
183
+ business operation; it neither mutates context nor adds a Lambda callback.
184
+
185
+ <!-- lisa-node24-unwrapped-example:start -->
186
+ ```ts
187
+ import * as Sentry from "@sentry/node";
188
+
189
+ // Initialize early, once outside the handler, with DSN from the environment.
190
+ function reportFlushProblem(message: string): void {
191
+ try {
192
+ console.warn(message);
193
+ } catch {
194
+ // Telemetry diagnostics must preserve the business outcome too.
195
+ }
196
+ }
197
+
198
+ export async function withSentryFlush<T>(
199
+ work: () => Promise<T>,
200
+ timeoutMs = 2000
201
+ ): Promise<T> {
202
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
203
+ throw new RangeError("Choose a finite positive Sentry flush budget");
204
+ }
205
+ try {
206
+ return await work();
207
+ } catch (originalError) {
208
+ try {
209
+ Sentry.captureException(originalError);
210
+ } catch {
211
+ // Preserve the original handler error even if capture fails.
212
+ }
213
+ throw originalError;
214
+ } finally {
215
+ try {
216
+ if (!(await Sentry.flush(timeoutMs))) {
217
+ reportFlushProblem("Sentry flush did not finish in time");
218
+ }
219
+ } catch {
220
+ reportFlushProblem("Sentry flush rejected");
221
+ }
222
+ }
223
+ }
224
+ ```
225
+ <!-- lisa-node24-unwrapped-example:end -->
226
+
227
+ In the existing async handler, return
228
+ `withSentryFlush(() => performBusinessWork(event, context))`; use the host's
229
+ actual business operation and preserve its return/error contract. Select a
230
+ positive budget that fits remaining invocation time with a safety margin.
231
+ Do not omit the timeout or use zero as a finite cap. The SDK's timeout argument
232
+ does not cancel every custom transport or guarantee completion before Lambda's
233
+ hard timeout, and a drained local queue does not prove tenant ingestion.
234
+ [Sentry API semantics](https://docs.sentry.io/platforms/javascript/guides/aws-lambda/configuration/apis.md)
235
+ describe `flush()` and `close()`.
236
+
237
+ For a **compatible `Sentry.wrapHandler`**, its documented default flush is up
238
+ to2000ms, configurable through `flushTimeout`; avoid a redundant manual flush
239
+ when that wrapper already handles completion. Check the installed version's
240
+ context behavior, too: `@sentry/aws-serverless`11.6.0 unconditionally assigns
241
+ `context.callbackWaitsForEmptyEventLoop` before invoking the business handler.
242
+ It throws on a non-extensible context lacking that removed property. Changing
243
+ the option does not remove the assignment. Use the unwrapped form when this
244
+ incompatibility applies; do not clone/unfreeze context or pre-add an obsolete
245
+ property to claim compatibility. See the [wrapper documentation](https://docs.sentry.io/platforms/javascript/guides/aws-lambda/configuration/lambda-wrapper.md)
246
+ and [versioned implementation](https://github.com/getsentry/sentry-javascript/blob/11.6.0/packages/aws-serverless/src/sdk.ts).
247
+
248
+ Treat Node types and optional native profiling as migration checks. Examples
249
+ using `Array.at` need an ES2022-or-later TypeScript `lib`; keep a host's business
250
+ compiler target deliberate. Confirm optional profiling prebuilds against the
251
+ actual Node ABI (Node24 uses137) only when profiling is in use; do not install an
252
+ unused profiling package. Verify the helper with the real installed SDK and
253
+ local transport, including success/error, timeout/false, rejected flush and a
254
+ second warm invocation. Label local observations honestly; actual Lambda
255
+ deployment and Sentry event ingestion require their own provider proof.
256
+
153
257
  **NestJS** — import `./instrument` first in `main.ts`, then add Sentry's module:
154
258
 
155
259
  ```ts
@@ -63,7 +63,9 @@ import {
63
63
  export function locate(name, exec = boundedChildOutput) {
64
64
  try {
65
65
  return String(
66
- exec("command", ["-v", name], { encoding: "utf8", shell: true })
66
+ exec("sh", ["-c", 'command -v -- "$1"', "lisa-locate", name], {
67
+ encoding: "utf8",
68
+ })
67
69
  ).trim();
68
70
  } catch {
69
71
  // probe-direction: fail-closed — null means "not proven present", and the
@@ -22,8 +22,9 @@ Default locations (a project that already has an equivalent contract keeps its o
22
22
  |---|---|---|
23
23
  | Scenarios | `bdd/features/*.feature` | Gherkin, the product-level behavior contract |
24
24
  | Coverage map | `bdd/coverage-map.json` | scenario → runner/platform/file/evidence mappings, plus waivers, per-runner test-discovery roots, and exclusions |
25
- | Generated matrix | `docs/bdd-scenario-matrix.md` | regenerated, never hand-edited |
26
- | Burndown | `docs/e2e-bdd-coverage.md` | current coverage per platform |
25
+ | Generated matrix | `docs/bdd-scenario-matrix/` | per-source-file leaves, regenerated, never hand-edited; static navigation at `docs/bdd-scenario-matrix.md` |
26
+ | Burndown | `docs/e2e-bdd-coverage/` | per-source-file mapping gaps and waivers; static navigation at `docs/e2e-bdd-coverage.md` |
27
+ | Feature JSON | `bdd/reports/v1/features/` | versioned local declarations/evidence; full aggregate remains in runtime `--report` and CI |
27
28
 
28
29
  ## Scenario shape
29
30
 
@@ -180,9 +181,10 @@ exclusion whose file is gone, whose title was renamed, or that no discovery root
180
181
 
181
182
  Two commands, wired into the project's script surface and into CI:
182
183
 
183
- 1. **Regenerate** — recompute coverage from features + map, rewrite the generated matrix
184
- (`docs/bdd-scenario-matrix.md`) and the burndown (`docs/e2e-bdd-coverage.md`), and refresh the
185
- machine-readable report. Low coverage is reported honestly and does **not** fail this command.
184
+ 1. **Regenerate** — recompute coverage from features + map and write the feature-local matrix,
185
+ burndown and JSON under `docs/bdd-scenario-matrix/`, `docs/e2e-bdd-coverage/` and
186
+ `bdd/reports/v1/features/`. Shared entry points contain static guidance. Reportable coverage
187
+ defects still produce paperwork; the coverage CLI keeps its original failing exit.
186
188
  2. **Check** — the CI gate. It fails on contract defects, not on ambition:
187
189
  - a duplicate or malformed scenario ID;
188
190
  - a scenario declaring a platform with no configured runner;
@@ -197,7 +199,7 @@ Two commands, wired into the project's script surface and into CI:
197
199
  - coverage given back: an obligation mapped at the base revision that nothing maps here;
198
200
  - new behavior nobody mapped or waived.
199
201
 
200
- Regeneration is never blocked by the check: `--write` rewrites the report and burndown whenever a
202
+ Regeneration is never blocked by a reportable coverage defect: `--write` rewrites feature reports whenever a
201
203
  report can be built at all, so a stale evidence string can never hold hostage the paperwork that
202
204
  documents it.
203
205
 
@@ -277,7 +279,7 @@ A repo with no contract yet, taking its first frontend work item:
277
279
  Pre-existing tests that align to no product behavior are recorded as `exclusions` with reasons
278
280
  during this step, never left undisclosed.
279
281
  3. **Write only this item's scenarios.** The first item is not a backfill project. Pre-existing
280
- uncovered behavior becomes burndown in `docs/e2e-bdd-coverage.md`, and the floor starts where the
282
+ uncovered behavior becomes feature-local burndown under `docs/e2e-bdd-coverage/`, and the floor starts where the
281
283
  repo actually is. That is a one-time act, not a recurring one: from here on the floor stays put
282
284
  and what protects each new obligation is the per-obligation check, not the number.
283
285
  4. **Seal this item's obligations** and commit the regenerated matrix and burndown with the change.
@@ -84,6 +84,8 @@ Inspect the project before choosing an SDK. Read `package.json`
84
84
  - `pyproject.toml` / `requirements.txt`; `django`/`flask`/`fastapi` →
85
85
  **Python** (and which web framework)
86
86
  - A plain Node library/CLI → **Node**
87
+ - AWS Lambda handlers or a Serverless/SAM/CDK function runtime → inspect the
88
+ function's actual runtime and wrapper before choosing **Node/Lambda**.
87
89
 
88
90
  If the runtime is genuinely ambiguous, ask which app to instrument rather than
89
91
  guessing. Respect the project's package manager (bun/npm/pnpm/yarn — match the
@@ -98,6 +100,7 @@ Use the project's package manager. Examples (swap `bun add` for your manager):
98
100
  | React (browser) | `@sentry/react` |
99
101
  | Next.js | `@sentry/nextjs` |
100
102
  | Node / Express / Fastify | `@sentry/node` (+ `@sentry/profiling-node` for profiling) |
103
+ | AWS Lambda | `@sentry/aws-serverless` for a compatible Lambda wrapper, or `@sentry/node` for an unwrapped async handler |
101
104
  | NestJS | `@sentry/nestjs` (+ `@sentry/node`) |
102
105
  | React Native / Expo | `@sentry/react-native` |
103
106
  | Vue | `@sentry/vue` |
@@ -148,6 +151,107 @@ Sentry.init({
148
151
 
149
152
  Then, after routes are defined: `Sentry.setupExpressErrorHandler(app);`
150
153
 
154
+ ### Node24 Lambda completion
155
+
156
+ Review the actual function runtime and installed SDK before migrating. Node24
157
+ LTS is Lisa's default for new TypeScript hosts; an existing host's explicit
158
+ engine and create-only workflows remain host-owned. On AWS Lambda `nodejs24.x`,
159
+ callback-style handlers and legacy context completion APIs, including
160
+ `callbackWaitsForEmptyEventLoop`, are removed. Do not assign those properties,
161
+ including to frozen/non-extensible context objects. Supported async handlers,
162
+ synchronous returns and response streaming are distinct forms; follow the
163
+ [AWS handler contract](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-handler.html).
164
+
165
+ Earlier non-streaming async handlers already returned without waiting for
166
+ unresolved background promises. Node24 aligns streaming completion with that
167
+ behavior; await work that must finish before returning or ending the stream.
168
+ Do not claim all Node20/22 async handlers drained arbitrary background work.
169
+ For streaming, flush at the appropriate point before `responseStream.end()` or
170
+ inside the awaited streaming pipeline, rather than after the stream is ended.
171
+ [AWS's Node24 migration explanation](https://aws.amazon.com/blogs/compute/node-js-24-runtime-now-available-in-aws-lambda/)
172
+ is the runtime authority; ordinary local Node process behavior is not deployed
173
+ Lambda evidence.
174
+
175
+ For an **unwrapped async** scheduled, queue or Cognito handler, initialize Sentry
176
+ once at module startup with the DSN from the environment. Await a finite positive
177
+ flush budget on both success and original-error paths. A false flush result or
178
+ rejection must not turn successful queue work into a retry or replace its real
179
+ error. Keep diagnostics local and non-throwing, and preserve the client for warm
180
+ invocations: `close()` disables it. The following helper wraps the host's existing
181
+ business operation; it neither mutates context nor adds a Lambda callback.
182
+
183
+ <!-- lisa-node24-unwrapped-example:start -->
184
+ ```ts
185
+ import * as Sentry from "@sentry/node";
186
+
187
+ // Initialize early, once outside the handler, with DSN from the environment.
188
+ function reportFlushProblem(message: string): void {
189
+ try {
190
+ console.warn(message);
191
+ } catch {
192
+ // Telemetry diagnostics must preserve the business outcome too.
193
+ }
194
+ }
195
+
196
+ export async function withSentryFlush<T>(
197
+ work: () => Promise<T>,
198
+ timeoutMs = 2000
199
+ ): Promise<T> {
200
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
201
+ throw new RangeError("Choose a finite positive Sentry flush budget");
202
+ }
203
+ try {
204
+ return await work();
205
+ } catch (originalError) {
206
+ try {
207
+ Sentry.captureException(originalError);
208
+ } catch {
209
+ // Preserve the original handler error even if capture fails.
210
+ }
211
+ throw originalError;
212
+ } finally {
213
+ try {
214
+ if (!(await Sentry.flush(timeoutMs))) {
215
+ reportFlushProblem("Sentry flush did not finish in time");
216
+ }
217
+ } catch {
218
+ reportFlushProblem("Sentry flush rejected");
219
+ }
220
+ }
221
+ }
222
+ ```
223
+ <!-- lisa-node24-unwrapped-example:end -->
224
+
225
+ In the existing async handler, return
226
+ `withSentryFlush(() => performBusinessWork(event, context))`; use the host's
227
+ actual business operation and preserve its return/error contract. Select a
228
+ positive budget that fits remaining invocation time with a safety margin.
229
+ Do not omit the timeout or use zero as a finite cap. The SDK's timeout argument
230
+ does not cancel every custom transport or guarantee completion before Lambda's
231
+ hard timeout, and a drained local queue does not prove tenant ingestion.
232
+ [Sentry API semantics](https://docs.sentry.io/platforms/javascript/guides/aws-lambda/configuration/apis.md)
233
+ describe `flush()` and `close()`.
234
+
235
+ For a **compatible `Sentry.wrapHandler`**, its documented default flush is up
236
+ to2000ms, configurable through `flushTimeout`; avoid a redundant manual flush
237
+ when that wrapper already handles completion. Check the installed version's
238
+ context behavior, too: `@sentry/aws-serverless`11.6.0 unconditionally assigns
239
+ `context.callbackWaitsForEmptyEventLoop` before invoking the business handler.
240
+ It throws on a non-extensible context lacking that removed property. Changing
241
+ the option does not remove the assignment. Use the unwrapped form when this
242
+ incompatibility applies; do not clone/unfreeze context or pre-add an obsolete
243
+ property to claim compatibility. See the [wrapper documentation](https://docs.sentry.io/platforms/javascript/guides/aws-lambda/configuration/lambda-wrapper.md)
244
+ and [versioned implementation](https://github.com/getsentry/sentry-javascript/blob/11.6.0/packages/aws-serverless/src/sdk.ts).
245
+
246
+ Treat Node types and optional native profiling as migration checks. Examples
247
+ using `Array.at` need an ES2022-or-later TypeScript `lib`; keep a host's business
248
+ compiler target deliberate. Confirm optional profiling prebuilds against the
249
+ actual Node ABI (Node24 uses137) only when profiling is in use; do not install an
250
+ unused profiling package. Verify the helper with the real installed SDK and
251
+ local transport, including success/error, timeout/false, rejected flush and a
252
+ second warm invocation. Label local observations honestly; actual Lambda
253
+ deployment and Sentry event ingestion require their own provider proof.
254
+
151
255
  **NestJS** — import `./instrument` first in `main.ts`, then add Sentry's module:
152
256
 
153
257
  ```ts
@@ -63,7 +63,9 @@ import {
63
63
  export function locate(name, exec = boundedChildOutput) {
64
64
  try {
65
65
  return String(
66
- exec("command", ["-v", name], { encoding: "utf8", shell: true })
66
+ exec("sh", ["-c", 'command -v -- "$1"', "lisa-locate", name], {
67
+ encoding: "utf8",
68
+ })
67
69
  ).trim();
68
70
  } catch {
69
71
  // probe-direction: fail-closed — null means "not proven present", and the
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "4.73.9",
3
+ "version": "4.74.1",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"