@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.
- package/README.md +52 -3
- package/all/create-only/.github/workflows/continuous-gates.yml +2 -2
- package/all/create-only/.github/workflows/workflow-load-failure-sweep.yml +1 -1
- package/cdk/create-only/.github/workflows/ci.yml +2 -2
- package/cdk/create-only/.github/workflows/deploy.yml +3 -3
- package/cdk/package-lisa/package.lisa.json +1 -1
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +60 -0
- package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
- package/dist/core/lisa-owned-templates.d.ts +9 -2
- package/dist/core/lisa-owned-templates.d.ts.map +1 -1
- package/dist/core/lisa-owned-templates.js +13 -3
- package/dist/core/lisa-owned-templates.js.map +1 -1
- package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +87 -33
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/expo/copy-overwrite/jest.setup.pre.js +15 -1
- package/expo/copy-overwrite/scripts/bdd/ci-summary.mjs +37 -0
- package/expo/copy-overwrite/scripts/bdd/projection-model.mjs +157 -0
- package/expo/copy-overwrite/scripts/bdd/projection-ownership.mjs +300 -0
- package/expo/copy-overwrite/scripts/bdd/projection-paths.mjs +152 -0
- package/expo/copy-overwrite/scripts/bdd/projection-render.mjs +303 -0
- package/expo/copy-overwrite/scripts/bdd/projection-write.mjs +84 -0
- package/expo/copy-overwrite/scripts/bdd/projection.mjs +30 -0
- package/expo/copy-overwrite/scripts/bdd-matrix.mjs +54 -18
- package/expo/copy-overwrite/scripts/check-bdd-coverage.mjs +36 -27
- package/expo/create-only/.github/workflows/ci.yml +3 -3
- package/expo/create-only/.github/workflows/deploy.yml +4 -4
- package/expo/create-only/.github/workflows/nightly-e2e-bypass-reaper.yml +1 -1
- package/expo/create-only/.github/workflows/playwright-e2e.yml +1 -1
- package/expo/create-only/eas.json +1 -1
- package/harper-fabric/copy-overwrite/.github/workflows/ci.yml +1 -1
- package/harper-fabric/create-only/.github/workflows/deploy.yml +3 -3
- package/harper-fabric/create-only/.github/workflows/zap-baseline.yml +1 -1
- package/harper-fabric/package-lisa/package.lisa.json +2 -2
- package/nestjs/create-only/.github/workflows/ci.yml +2 -2
- package/nestjs/create-only/.github/workflows/deploy.yml +5 -5
- package/package.json +6 -6
- package/phaser/copy-overwrite/.github/workflows/ci.yml +1 -1
- package/phaser/package-lisa/package.lisa.json +2 -2
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-parity-sentry-sdk-setup/SKILL.md +104 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-workstation/scripts/workstation.mjs +3 -1
- package/plugins/lisa/rules/reference/bdd-e2e-coverage.md +9 -7
- package/plugins/lisa/skills/lisa-parity-sentry-sdk-setup/SKILL.md +104 -0
- package/plugins/lisa/skills/lisa-setup-workstation/scripts/workstation.mjs +3 -1
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/lisa-parity-sentry-sdk-setup/SKILL.md +104 -0
- package/plugins/lisa-agy/skills/lisa-setup-workstation/scripts/workstation.mjs +3 -1
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/rules/reference/bdd-e2e-coverage.md +9 -7
- package/plugins/lisa-copilot/skills/lisa-parity-sentry-sdk-setup/SKILL.md +104 -0
- package/plugins/lisa-copilot/skills/lisa-setup-workstation/scripts/workstation.mjs +3 -1
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/rules/bdd-e2e-coverage-reference.mdc +9 -7
- package/plugins/lisa-cursor/skills/lisa-parity-sentry-sdk-setup/SKILL.md +104 -0
- package/plugins/lisa-cursor/skills/lisa-setup-workstation/scripts/workstation.mjs +3 -1
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/rules/reference/bdd-e2e-coverage.md +9 -7
- package/plugins/src/base/skills/lisa-parity-sentry-sdk-setup/SKILL.md +104 -0
- package/plugins/src/base/skills/lisa-setup-workstation/scripts/workstation.mjs +3 -1
- package/scripts/check-shell-guard-refusal-coverage.mjs +65 -7
- package/scripts/generate-lisa-owned-hash-ledger.mjs +3 -0
- package/scripts/lib/shell-guard-shard-runner.mjs +381 -0
- package/scripts/lib/shell-guard-shards.mjs +383 -0
- package/scripts/lib/shell-guard-terminal-reporter.mjs +89 -0
- package/scripts/two-channel-couplings.json +2 -2
- package/scripts/update-node-version.ts +52 -6
- package/typescript/copy-overwrite/.nvmrc +1 -1
- package/typescript/create-only/.github/workflows/ci.yml +1 -1
- package/typescript/create-only/.github/workflows/review-evidence.yml +1 -1
- package/typescript/create-only/.github/workflows/third-party-review-evidence.yml +1 -1
- package/typescript/package-lisa/package.lisa.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.74.1",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.74.1",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, across Claude and Codex.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.74.1",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.74.1",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.74.1",
|
|
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"
|
|
@@ -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
|
|
26
|
-
| Burndown | `docs/e2e-bdd-coverage
|
|
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
|
|
184
|
-
|
|
185
|
-
|
|
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
|
|
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
|
|
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("
|
|
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
|
|
@@ -35,9 +35,17 @@
|
|
|
35
35
|
* --trace-out FILE
|
|
36
36
|
* also write the judged trace to FILE, so a later step in the
|
|
37
37
|
* same job can read what this run observed. Never commit it.
|
|
38
|
+
* --collect-only --shard I/3 --trace-out NEW_DIRECTORY/trace.jsonl
|
|
39
|
+
* collect one complete native Actions shard without judging
|
|
40
|
+
* its individual trace. All canonical candidates are supplied.
|
|
41
|
+
* --merge-traces DIRECTORY --trace-out FILE
|
|
42
|
+
* validate all three current run/attempt shard receipts, then
|
|
43
|
+
* apply the original judge once to their combined trace.
|
|
44
|
+
* A new Actions attempt must reproduce all three shards.
|
|
38
45
|
*
|
|
39
46
|
* Exit codes (mirroring the sibling check-* scripts):
|
|
40
|
-
* 0 —
|
|
47
|
+
* 0 — the judgment passed, or --collect-only retained a complete eligible
|
|
48
|
+
* shard without judging its individual trace.
|
|
41
49
|
* 1 — >=1 finding.
|
|
42
50
|
* 2 — operational error: unknown flag, vitest could not run, or ZERO guards
|
|
43
51
|
* observed.
|
|
@@ -59,9 +67,15 @@ import {
|
|
|
59
67
|
parseTrace,
|
|
60
68
|
tracerIndex,
|
|
61
69
|
} from "./lib/shell-guard-refusal-coverage.mjs";
|
|
70
|
+
import {
|
|
71
|
+
collectShard,
|
|
72
|
+
mergeCollected,
|
|
73
|
+
} from "./lib/shell-guard-shard-runner.mjs";
|
|
62
74
|
|
|
63
75
|
/** The flag naming a file the produced trace should also be written to. */
|
|
64
76
|
const TRACE_OUT_FLAG = "--trace-out";
|
|
77
|
+
/** Collection receipts to combine before the original judgment. */
|
|
78
|
+
const MERGE_TRACES_FLAG = "--merge-traces";
|
|
65
79
|
|
|
66
80
|
/** Wall-clock ceiling for the traced vitest run. */
|
|
67
81
|
const RUN_TIMEOUT_MS = 45 * 60_000;
|
|
@@ -233,8 +247,20 @@ function keepTrace(root, args, trace) {
|
|
|
233
247
|
*/
|
|
234
248
|
export function main() {
|
|
235
249
|
const args = process.argv.slice(2);
|
|
236
|
-
const known = new Set([
|
|
237
|
-
|
|
250
|
+
const known = new Set([
|
|
251
|
+
"--json",
|
|
252
|
+
"--trace",
|
|
253
|
+
TRACE_OUT_FLAG,
|
|
254
|
+
"--collect-only",
|
|
255
|
+
"--shard",
|
|
256
|
+
MERGE_TRACES_FLAG,
|
|
257
|
+
]);
|
|
258
|
+
const valueFlags = new Set([
|
|
259
|
+
"--trace",
|
|
260
|
+
TRACE_OUT_FLAG,
|
|
261
|
+
"--shard",
|
|
262
|
+
MERGE_TRACES_FLAG,
|
|
263
|
+
]);
|
|
238
264
|
const unknown = args.find(
|
|
239
265
|
(arg, at) =>
|
|
240
266
|
arg.startsWith("--") &&
|
|
@@ -249,13 +275,45 @@ export function main() {
|
|
|
249
275
|
return;
|
|
250
276
|
}
|
|
251
277
|
const root = process.cwd();
|
|
278
|
+
if (args.includes("--collect-only")) {
|
|
279
|
+
try {
|
|
280
|
+
collectShard(root, candidateSuites, args);
|
|
281
|
+
} catch (error) {
|
|
282
|
+
console.error(`check:shell-guard-refusal-coverage: ${String(error)}`);
|
|
283
|
+
process.exitCode = 2;
|
|
284
|
+
}
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
if (args.includes("--shard")) {
|
|
288
|
+
console.error(
|
|
289
|
+
"check:shell-guard-refusal-coverage: --shard requires --collect-only"
|
|
290
|
+
);
|
|
291
|
+
process.exitCode = 2;
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
252
294
|
const population = guardPopulation(root);
|
|
253
295
|
const at = args.indexOf("--trace");
|
|
254
296
|
const supplied = at === -1 ? undefined : args[at + 1];
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
297
|
+
let produced;
|
|
298
|
+
if (args.includes(MERGE_TRACES_FLAG)) {
|
|
299
|
+
try {
|
|
300
|
+
produced = mergeCollected(root, candidateSuites, args);
|
|
301
|
+
} catch (error) {
|
|
302
|
+
console.error(`check:shell-guard-refusal-coverage: ${String(error)}`);
|
|
303
|
+
process.exitCode = 2;
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
} else {
|
|
307
|
+
produced =
|
|
308
|
+
supplied === undefined
|
|
309
|
+
? produceTrace(root, population)
|
|
310
|
+
: {
|
|
311
|
+
trace: readOrEmpty(root, supplied),
|
|
312
|
+
suites: 0,
|
|
313
|
+
ok: true,
|
|
314
|
+
detail: "",
|
|
315
|
+
};
|
|
316
|
+
}
|
|
259
317
|
if (!produced.ok) {
|
|
260
318
|
console.error(`check:shell-guard-refusal-coverage: ${produced.detail}`);
|
|
261
319
|
process.exitCode = 2;
|
|
@@ -160,6 +160,9 @@ function git(root, args) {
|
|
|
160
160
|
*/
|
|
161
161
|
export function isLisaOwned(destination) {
|
|
162
162
|
return (
|
|
163
|
+
// Exact runtime-policy destination only, mirrored by the runtime predicate.
|
|
164
|
+
// Enrol historical hashes too so custom/newer host content stays protected.
|
|
165
|
+
destination === ".nvmrc" ||
|
|
163
166
|
destination.startsWith(ENFORCEMENT_TREE) ||
|
|
164
167
|
destination
|
|
165
168
|
.split("/")
|