@rune-kit/rune 2.29.1 → 2.30.0
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/.codex-plugin/plugin.json +1 -1
- package/README.md +7 -3
- package/agents/audit.md +1 -1
- package/agents/cook.md +1 -1
- package/agents/journal.md +1 -1
- package/agents/reviewer.md +23 -1
- package/agents/session-bridge.md +1 -1
- package/agents/skill-forge.md +1 -1
- package/agents/skill-router.md +1 -1
- package/agents/trend-scout.md +1 -1
- package/agents/worktree.md +1 -1
- package/compiler/__tests__/skill-attribution.test.js +109 -0
- package/package.json +1 -1
- package/skills/audit/SKILL.md +3 -3
- package/skills/completion-gate/SKILL.md +1 -1
- package/skills/constraint-check/SKILL.md +1 -1
- package/skills/context-engine/SKILL.md +2 -2
- package/skills/cook/SKILL.md +2 -2
- package/skills/cook/references/loop-detection.md +1 -1
- package/skills/cook/references/mid-run-signals.md +1 -1
- package/skills/debug/SKILL.md +2 -2
- package/skills/dependency-doctor/SKILL.md +1 -1
- package/skills/design/SKILL.md +1 -1
- package/skills/docs/SKILL.md +1 -1
- package/skills/docs-seeker/SKILL.md +3 -0
- package/skills/hallucination-guard/SKILL.md +2 -2
- package/skills/incident/SKILL.md +1 -1
- package/skills/integrity-check/SKILL.md +1 -1
- package/skills/launch/SKILL.md +1 -1
- package/skills/preflight/SKILL.md +35 -9
- package/skills/rescue/SKILL.md +1 -1
- package/skills/research/SKILL.md +1 -1
- package/skills/review/SKILL.md +135 -84
- package/skills/review/references/rules/config.md +63 -0
- package/skills/review/references/rules/default.md +57 -0
- package/skills/review/references/rules/go.md +65 -0
- package/skills/review/references/rules/index.md +43 -0
- package/skills/review/references/rules/python.md +64 -0
- package/skills/review/references/rules/rust.md +65 -0
- package/skills/review/references/rules/sql.md +65 -0
- package/skills/review/references/rules/ts-js.md +80 -0
- package/skills/sast/SKILL.md +1 -1
- package/skills/scout/SKILL.md +3 -0
- package/skills/sentinel/SKILL.md +29 -6
- package/skills/skill-router/SKILL.md +1 -1
- package/skills/team/SKILL.md +2 -2
- package/skills/verification/SKILL.md +3 -4
- package/skills/watchdog/SKILL.md +1 -1
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Rust
|
|
2
|
+
|
|
3
|
+
Blocking here: panics on reachable paths, blocking calls inside async, and `unsafe` without a stated
|
|
4
|
+
invariant. The compiler and Clippy already enforce most of what a reviewer might otherwise flag —
|
|
5
|
+
so an idiom finding has to earn its place, and usually does not.
|
|
6
|
+
|
|
7
|
+
## Panicking paths
|
|
8
|
+
|
|
9
|
+
- `unwrap` / `expect` on a `Result` or `Option` in library code or a request path
|
|
10
|
+
- Slice or array indexing where the index derives from input or a length not just checked
|
|
11
|
+
- Integer arithmetic that can overflow on a value from outside — release builds wrap silently
|
|
12
|
+
- Division or modulo by a value that can be zero
|
|
13
|
+
- `RefCell::borrow_mut` where another borrow can still be live — a runtime panic, not a compile error
|
|
14
|
+
|
|
15
|
+
Do not report `unwrap` in tests, in `build.rs`, or immediately after a check that proves the variant
|
|
16
|
+
— `if x.is_some()` then `x.unwrap()` is ugly, not a defect, and is at most LOW.
|
|
17
|
+
|
|
18
|
+
## Error handling
|
|
19
|
+
|
|
20
|
+
- `let _ = fallible();` — the error is discarded without a comment saying why
|
|
21
|
+
- `.ok()` used to drop an error the caller needed to see
|
|
22
|
+
- An error type erased to `String` or `Box<dyn Error>` where the caller must branch on the cause
|
|
23
|
+
- A `?` in a function whose error type loses context with no `map_err` or source chain
|
|
24
|
+
|
|
25
|
+
Do not report an erased error type in a binary's top-level `main` or a CLI handler, where the error
|
|
26
|
+
is about to be printed and the process is about to exit.
|
|
27
|
+
|
|
28
|
+
## Async correctness
|
|
29
|
+
|
|
30
|
+
- A blocking call inside `async fn`: `std::thread::sleep`, `std::fs`, a sync HTTP client, or a
|
|
31
|
+
CPU-bound loop — it stalls the executor thread, not just this task
|
|
32
|
+
- A `std::sync::Mutex` guard held across an `.await`
|
|
33
|
+
- A future created and never awaited — it does nothing at all
|
|
34
|
+
- `block_on` called from inside an async context
|
|
35
|
+
|
|
36
|
+
Do not report a blocking call wrapped in `spawn_blocking` or an equivalent offload, and do not
|
|
37
|
+
report `std::sync::Mutex` when no guard crosses an await point.
|
|
38
|
+
|
|
39
|
+
## Ownership and lifetimes
|
|
40
|
+
|
|
41
|
+
- `Arc<Mutex<...>>` locked in inconsistent order across paths — a deadlock waiting on scheduling
|
|
42
|
+
- A lock guard held far longer than the data access requires, across I/O or a long computation
|
|
43
|
+
- `clone()` on a large structure inside a hot loop where a borrow would do
|
|
44
|
+
|
|
45
|
+
Do not report a `clone` that exists to satisfy the borrow checker at an ownership boundary, or one
|
|
46
|
+
on a cheap handle type such as `Arc` or `Rc` — that is the intended use.
|
|
47
|
+
|
|
48
|
+
## Unsafe
|
|
49
|
+
|
|
50
|
+
- An `unsafe` block with no comment stating the invariant that makes it sound
|
|
51
|
+
- `transmute` where a checked conversion exists
|
|
52
|
+
- A raw pointer dereferenced without a null and alignment argument in the same scope
|
|
53
|
+
- An `unsafe fn` made public without documenting the caller's obligations
|
|
54
|
+
|
|
55
|
+
Do not report `unsafe` in generated bindings or an FFI shim whose invariants are documented at the
|
|
56
|
+
module level — read the module doc before reporting.
|
|
57
|
+
|
|
58
|
+
## Resource and correctness
|
|
59
|
+
|
|
60
|
+
- A `Drop` implementation that can panic — panicking during unwind aborts the process
|
|
61
|
+
- A `Vec` grown in a loop with a known final size and no `with_capacity`
|
|
62
|
+
- Float equality on values that arrive from arithmetic rather than a literal
|
|
63
|
+
|
|
64
|
+
Do not report the missing `with_capacity` unless the loop is on a measured hot path — otherwise it
|
|
65
|
+
is a LOW-severity suggestion at best.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# SQL and migrations
|
|
2
|
+
|
|
3
|
+
Blocking here: anything irreversible, anything that takes a long lock on a live table, and anything
|
|
4
|
+
that concatenates input into a statement. A migration is reviewed as an operation on production
|
|
5
|
+
data, not as a file — the question is always "what happens when this runs against the real table".
|
|
6
|
+
|
|
7
|
+
## Reversibility
|
|
8
|
+
|
|
9
|
+
- A migration with no down path, or a down path that does not restore what the up path removed
|
|
10
|
+
- A destructive step and a data backfill in the same migration — a rollback loses the data
|
|
11
|
+
- A down path that recreates a column but not its constraints, defaults, or index
|
|
12
|
+
|
|
13
|
+
Do not report a missing down migration in a project whose visible convention is forward-only
|
|
14
|
+
migrations — check the neighbouring files first; if they are all forward-only, this is the pattern,
|
|
15
|
+
not the defect.
|
|
16
|
+
|
|
17
|
+
## Locking and online safety
|
|
18
|
+
|
|
19
|
+
- `ALTER TABLE` that rewrites a large table: changing a column type, adding a `NOT NULL` column with
|
|
20
|
+
a volatile default
|
|
21
|
+
- `CREATE INDEX` without a concurrent variant on an engine that supports one
|
|
22
|
+
- Adding a foreign key without a `NOT VALID` / validate split where the engine offers it
|
|
23
|
+
- A migration that holds a transaction open across a long backfill
|
|
24
|
+
|
|
25
|
+
Do not report lock risk on a table that is demonstrably small or new — a table created earlier in
|
|
26
|
+
the same migration takes no meaningful lock.
|
|
27
|
+
|
|
28
|
+
## Destructive operations
|
|
29
|
+
|
|
30
|
+
- `DROP TABLE`, `DROP COLUMN`, or `TRUNCATE` with no evidence the data is already migrated
|
|
31
|
+
- `UPDATE` or `DELETE` with no `WHERE`, or a `WHERE` on a column that is not selective
|
|
32
|
+
- A column dropped in the same release that deploys the code which stops reading it — old instances
|
|
33
|
+
are still running during the rollout
|
|
34
|
+
|
|
35
|
+
Do not report a drop that is explicitly the second half of an expand-migrate-contract sequence when
|
|
36
|
+
the earlier migration in the same directory did the expand.
|
|
37
|
+
|
|
38
|
+
## Query correctness
|
|
39
|
+
|
|
40
|
+
- `NOT IN` against a subquery whose column is nullable — a single NULL makes the result empty
|
|
41
|
+
- An outer join whose `WHERE` clause filters the outer side, silently making it an inner join
|
|
42
|
+
- `LIMIT` with no `ORDER BY` — the rows returned are whatever the plan produced
|
|
43
|
+
- Aggregates mixed with ungrouped columns
|
|
44
|
+
- Implicit cross joins from a missing join condition
|
|
45
|
+
|
|
46
|
+
Do not report a missing `ORDER BY` on a query whose result is fed to an aggregate or an existence
|
|
47
|
+
check, where row order cannot affect the outcome.
|
|
48
|
+
|
|
49
|
+
## Indexing and performance
|
|
50
|
+
|
|
51
|
+
- A `WHERE` clause wrapping an indexed column in a function or a cast — the index goes unused
|
|
52
|
+
- `LIKE` with a leading wildcard on a large table
|
|
53
|
+
- A foreign key with no index on the referencing side, where the parent gets deleted
|
|
54
|
+
- `SELECT *` in application code that will break when a column is added
|
|
55
|
+
|
|
56
|
+
Do not report a missing index on a table that is small, append-only, or read once per deployment.
|
|
57
|
+
|
|
58
|
+
## Injection and privileges
|
|
59
|
+
|
|
60
|
+
- A statement assembled by string concatenation or interpolation instead of bind parameters
|
|
61
|
+
- Dynamic SQL built from input inside a stored procedure or a function
|
|
62
|
+
- A `GRANT` broader than the operation needs, or a migration that runs as a superuser role
|
|
63
|
+
|
|
64
|
+
Do not report interpolation of an identifier drawn from a fixed allowlist in the same file — many
|
|
65
|
+
drivers cannot parameterize identifiers, and the allowlist is the correct mitigation.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# TypeScript / JavaScript
|
|
2
|
+
|
|
3
|
+
Blocking here: async sequencing bugs, unvalidated input reaching a sink, and type escapes on values
|
|
4
|
+
that cross a boundary. Formatting and idiom are non-blocking — a linter already owns them, and
|
|
5
|
+
repeating it spends the report's credibility on findings the author has already seen.
|
|
6
|
+
|
|
7
|
+
## Async sequencing
|
|
8
|
+
|
|
9
|
+
- A promise-returning call whose result decides correctness, invoked without `await` or `.then`
|
|
10
|
+
- `await` inside a loop over independent iterations — serial latency for no reason
|
|
11
|
+
- `Promise.all` over operations that must not partially apply: one rejects, the rest still land
|
|
12
|
+
- An `async` function passed where a sync callback is expected (`forEach`, most event emitters) —
|
|
13
|
+
the caller cannot await it, so a rejection is unobserved
|
|
14
|
+
- `.catch` on a promise that is never returned, so the caller is told it succeeded
|
|
15
|
+
|
|
16
|
+
Do not report when the call is deliberately fire-and-forget **and** carries its own rejection
|
|
17
|
+
handler, or when the return value is genuinely unused and failure is non-fatal — name which of the
|
|
18
|
+
two you read.
|
|
19
|
+
|
|
20
|
+
## Type escapes
|
|
21
|
+
|
|
22
|
+
- `any` on a value crossing a module, API, or storage boundary
|
|
23
|
+
- Non-null assertion `!` on something the path does not prove is present
|
|
24
|
+
- `as` casts that widen or re-label a shape rather than narrow a checked union
|
|
25
|
+
- `@ts-ignore` / `@ts-expect-error` with no comment naming what it suppresses
|
|
26
|
+
|
|
27
|
+
Do not report when the escape stays inside one function whose inputs are all typed, or when the
|
|
28
|
+
project's own config already permits it (`strict: false`, the rule disabled in its lint config) —
|
|
29
|
+
that is a project decision, not a defect introduced by this diff.
|
|
30
|
+
|
|
31
|
+
## Null and equality semantics
|
|
32
|
+
|
|
33
|
+
- `==` / `!=` where a side can be `null`, `undefined`, `0`, or `''` and the coercion changes the outcome
|
|
34
|
+
- `||` for defaulting where `0`, `''`, or `false` are legitimate values (`??` is the intent)
|
|
35
|
+
- Optional chaining that stops short — `a?.b.c` still throws when `b` is nullish
|
|
36
|
+
- `JSON.parse` on untrusted or possibly-empty input with no `try`
|
|
37
|
+
|
|
38
|
+
Do not report when the value is narrowed earlier in the same path, or when the loose comparison is
|
|
39
|
+
against a literal that makes the coercion unambiguous.
|
|
40
|
+
|
|
41
|
+
## Mutation and shared state
|
|
42
|
+
|
|
43
|
+
- Mutating a parameter, prop, or module-level object the caller still holds
|
|
44
|
+
- `sort`, `reverse`, `splice` on an array received from outside the function
|
|
45
|
+
- A closure capturing a variable reassigned before the closure runs
|
|
46
|
+
|
|
47
|
+
Do not report when the object is constructed inside the same function, or when in-place mutation
|
|
48
|
+
with an explicit ownership comment is the visible convention in neighbouring files.
|
|
49
|
+
|
|
50
|
+
## React rendering
|
|
51
|
+
|
|
52
|
+
- `useEffect` missing a dependency its body reads — a stale closure, not a lint nit
|
|
53
|
+
- An effect that sets state it also depends on, unguarded — render loop
|
|
54
|
+
- Array index as `key` on a list that reorders, filters, or inserts
|
|
55
|
+
- `useState` / `useEffect` / event handlers in a Server Component (Next.js App Router)
|
|
56
|
+
- State written during render rather than in an effect or a handler
|
|
57
|
+
|
|
58
|
+
Do not report when the dependency is stable (a `useRef`, a `useState` setter, a module constant),
|
|
59
|
+
when the list is append-only and static, or when the file declares `'use client'`.
|
|
60
|
+
|
|
61
|
+
## Server-side request handling
|
|
62
|
+
|
|
63
|
+
- `req.body`, params, or query reaching a query, file path, template, or shell unvalidated
|
|
64
|
+
- A new route with no auth check where its siblings in the same router have one
|
|
65
|
+
- A public endpoint that authenticates, sends mail, or costs money per call, with no rate limit
|
|
66
|
+
- Synchronous filesystem, crypto, or large-payload serialization inside a request handler
|
|
67
|
+
- User-controlled input concatenated into a redirect target or an HTML string
|
|
68
|
+
|
|
69
|
+
Do not report when a validation schema, auth middleware, or rate limiter runs earlier in the chain,
|
|
70
|
+
or when rate limiting is applied at a gateway or reverse proxy the repo also owns — open the router
|
|
71
|
+
or that config and confirm, or file it `ASSUMED` naming the file you did not read.
|
|
72
|
+
|
|
73
|
+
## Errors and resources
|
|
74
|
+
|
|
75
|
+
- `catch` that swallows: an empty block, or one that logs and continues as though it succeeded
|
|
76
|
+
- Errors re-thrown without preserving `cause` or the original stack
|
|
77
|
+
- `setInterval`, listeners, subscriptions, or streams opened with no matching teardown
|
|
78
|
+
|
|
79
|
+
Do not report a swallowed error when the catch is a fallback path whose recovery behaviour is
|
|
80
|
+
visible in the same block.
|
package/skills/sast/SKILL.md
CHANGED
package/skills/scout/SKILL.md
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: scout
|
|
3
3
|
description: "Fast codebase scanner. Use when any skill needs codebase context. Finds files, patterns, dependencies, project structure. Pure read-only — never modifies files."
|
|
4
|
+
context: fork
|
|
5
|
+
agent: general-purpose
|
|
6
|
+
model: haiku
|
|
4
7
|
metadata:
|
|
5
8
|
author: runedev
|
|
6
9
|
version: "0.4.0"
|
package/skills/sentinel/SKILL.md
CHANGED
|
@@ -270,7 +270,7 @@ Before reporting ANY finding as BLOCK or WARN, it MUST pass through these 6 gate
|
|
|
270
270
|
|
|
271
271
|
| Gate | Question | If Fails |
|
|
272
272
|
|------|----------|----------|
|
|
273
|
-
| 1. **Process** | Is there concrete evidence
|
|
273
|
+
| 1. **Process** | Is there concrete evidence — a **verbatim snippet copied from the file**, a regex match, or tool output? | Discard — no evidence = hallucination |
|
|
274
274
|
| 2. **Reachability** | Can an attacker actually reach this code path? | Downgrade to INFO |
|
|
275
275
|
| 3. **Real Impact** | Would exploitation cause actual harm (data loss, RCE, privilege escalation)? | Downgrade to INFO |
|
|
276
276
|
| 4. **PoC Plausibility** | Can you describe a concrete attack scenario in ≤3 steps? | Downgrade to INFO — theoretical ≠ real |
|
|
@@ -285,6 +285,12 @@ Before reporting ANY finding as BLOCK or WARN, it MUST pass through these 6 gate
|
|
|
285
285
|
|
|
286
286
|
### Step 5 — Report
|
|
287
287
|
|
|
288
|
+
**Anchor Pass first.** Gate 1 above required a verbatim snippet, not a remembered line number. Resolve each surviving finding's line now via the Anchor Ladder defined in `../review/SKILL.md` → Step 6: `Grep` the exact snippet, retry once whitespace-normalised with the outer lines dropped, and on a second miss mark it `UNANCHORED`.
|
|
289
|
+
|
|
290
|
+
`UNANCHORED` behaves as it does everywhere else — downgrade one level (BLOCK → WARN → INFO), report as `path (unanchored)` with the snippet inline, never drop. **An unanchored finding cannot BLOCK on its own**: a vulnerability nobody can locate halts the pipeline without telling anyone where to look. It still gets reported, because a failed `Grep` is a bookkeeping failure, not a security clearance.
|
|
291
|
+
|
|
292
|
+
Secrets are the exception worth naming: **never paste the matched secret into the evidence block.** Anchor on the leading substring of the line up to the first few characters of the value (`const apiKey = "sk-` — still a real substring, so `Grep` resolves it), then render the block with the remainder masked: `const apiKey = "sk-…"`. Reporting a leaked key by reprinting it in full copies it into one more log.
|
|
293
|
+
|
|
288
294
|
Aggregate all findings across all steps. Verdict rules:
|
|
289
295
|
- Any **BLOCK** → overall status = **BLOCK**. List all BLOCK items first.
|
|
290
296
|
- No BLOCK but any **WARN** → overall status = **WARN**. Developer must acknowledge each WARN.
|
|
@@ -315,25 +321,41 @@ Generate domain-specific pre-commit hook scripts when requested. Load reference
|
|
|
315
321
|
|
|
316
322
|
## Output Format
|
|
317
323
|
|
|
318
|
-
|
|
324
|
+
````
|
|
319
325
|
## Sentinel Report
|
|
320
326
|
- **Status**: PASS | WARN | BLOCK
|
|
321
327
|
- **Files Scanned**: [count]
|
|
322
328
|
- **Findings**: [count by severity]
|
|
329
|
+
- **Unanchored**: [count — findings whose evidence did not resolve to a line]
|
|
323
330
|
|
|
324
331
|
### BLOCK (must fix before commit)
|
|
325
|
-
- `
|
|
326
|
-
|
|
332
|
+
- `config/client.ts:42` — Hardcoded API key committed to the repo
|
|
333
|
+
```ts
|
|
334
|
+
const apiKey = "sk-…"
|
|
335
|
+
```
|
|
336
|
+
- `api/search.ts:15` — SQL injection: user input concatenated into the query string
|
|
337
|
+
```ts
|
|
338
|
+
db.query(`SELECT * FROM items WHERE name = '${req.query.q}'`);
|
|
339
|
+
```
|
|
327
340
|
|
|
328
341
|
### WARN (must acknowledge)
|
|
329
342
|
- `package.json` — lodash@4.17.20 has known prototype pollution (CVE-2021-23337, CVSS 7.4)
|
|
343
|
+
- `api/upload.ts (unanchored)` — path traversal: request filename joined onto the upload dir without normalisation
|
|
344
|
+
```ts
|
|
345
|
+
fs.writeFileSync(path.join(UPLOAD_DIR, req.body.filename), buf);
|
|
346
|
+
```
|
|
330
347
|
|
|
331
348
|
### INFO
|
|
332
|
-
- `auth.ts:30` — Consider adding rate limiting to login endpoint
|
|
349
|
+
- `auth/login.ts:30` — Consider adding rate limiting to the login endpoint
|
|
350
|
+
```ts
|
|
351
|
+
router.post("/login", handleLogin);
|
|
352
|
+
```
|
|
333
353
|
|
|
334
354
|
### Verdict
|
|
335
355
|
BLOCKED — 2 critical findings must be resolved before commit.
|
|
336
|
-
|
|
356
|
+
````
|
|
357
|
+
|
|
358
|
+
Secret values are masked in the evidence block, never reprinted. Dependency findings (`package.json` above) are file-level and carry no snippet. The unanchored WARN shows the shape of a real finding whose snippet would not resolve — downgraded from BLOCK, reported in full, its evidence left visible for the reader to locate by hand.
|
|
337
359
|
|
|
338
360
|
## Constraints
|
|
339
361
|
|
|
@@ -378,6 +400,7 @@ BLOCKED — 2 critical findings must be resolved before commit.
|
|
|
378
400
|
- OWASP checks applied (SQL injection, XSS, CSRF, input validation)
|
|
379
401
|
- Dependency audit ran (or "tool not found" reported as INFO)
|
|
380
402
|
- Framework-specific checks applied for every detected framework
|
|
403
|
+
- Every line-level finding anchored to a verbatim snippet (or reported `(unanchored)` and downgraded), with secret values masked
|
|
381
404
|
- Structured report emitted with PASS / WARN / BLOCK verdict and all files scanned listed
|
|
382
405
|
|
|
383
406
|
## Cost Profile
|
package/skills/team/SKILL.md
CHANGED
|
@@ -197,7 +197,7 @@ Contract format in NEXUS Handoff:
|
|
|
197
197
|
|
|
198
198
|
**1d. Question Gate (non-trivial tasks only).**
|
|
199
199
|
|
|
200
|
-
|
|
200
|
+
Subagents that start work without asking questions frequently produce the wrong thing.
|
|
201
201
|
|
|
202
202
|
Before dispatching streams, include in each NEXUS Handoff: "Before starting, ask up to 3 clarifying questions if anything is unclear about scope, conventions, or expected output."
|
|
203
203
|
|
|
@@ -217,7 +217,7 @@ Mark todo[1] `in_progress`.
|
|
|
217
217
|
|
|
218
218
|
Launch independent streams (depends_on: []) in parallel using Task tool with worktree isolation.
|
|
219
219
|
|
|
220
|
-
|
|
220
|
+
Structured handoff docs prevent the most common multi-agent failure: context loss between agents.
|
|
221
221
|
|
|
222
222
|
Each stream receives a **NEXUS Handoff Template** — not a bare prompt:
|
|
223
223
|
|
|
@@ -5,7 +5,7 @@ metadata:
|
|
|
5
5
|
author: runedev
|
|
6
6
|
version: "0.8.0"
|
|
7
7
|
layer: L3
|
|
8
|
-
model:
|
|
8
|
+
model: sonnet
|
|
9
9
|
group: validation
|
|
10
10
|
tools: "Read, Bash, Glob, Grep"
|
|
11
11
|
listen: code.changed
|
|
@@ -171,8 +171,7 @@ Report which level failed for each file in the Verification Report.
|
|
|
171
171
|
|
|
172
172
|
### Artifact Output Verification
|
|
173
173
|
|
|
174
|
-
|
|
175
|
-
> Many tools exit 0 even when they fail silently. Always verify ACTUAL output.
|
|
174
|
+
**Never trust exit 0.** Many tools exit 0 even when they fail silently. Always verify ACTUAL output.
|
|
176
175
|
|
|
177
176
|
After each phase command, verify that the expected artifact or indicator is present:
|
|
178
177
|
|
|
@@ -311,7 +310,7 @@ Overall: [PASS/FAIL]
|
|
|
311
310
|
|
|
312
311
|
## Output Completion Enforcement
|
|
313
312
|
|
|
314
|
-
|
|
313
|
+
Truncated code is worse than no code — it passes reviews but breaks at runtime.
|
|
315
314
|
|
|
316
315
|
When verifying code files (Level 2 SUBSTANTIVE check), also scan for **truncation patterns** — signs that the agent generated partial output and stopped:
|
|
317
316
|
|