@rune-kit/rune 2.29.1 → 2.30.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 (58) hide show
  1. package/.codex-plugin/plugin.json +1 -1
  2. package/README.md +11 -3
  3. package/agents/audit.md +1 -1
  4. package/agents/cook.md +1 -1
  5. package/agents/journal.md +1 -1
  6. package/agents/reviewer.md +23 -1
  7. package/agents/session-bridge.md +1 -1
  8. package/agents/skill-forge.md +1 -1
  9. package/agents/skill-router.md +1 -1
  10. package/agents/trend-scout.md +1 -1
  11. package/agents/worktree.md +1 -1
  12. package/compiler/__tests__/skill-attribution.test.js +109 -0
  13. package/compiler/emitter.js +1 -1
  14. package/hooks/context-watch/index.cjs +5 -8
  15. package/hooks/hooks.json +1 -1
  16. package/hooks/intent-router/index.cjs +9 -6
  17. package/hooks/lib/hook-output.cjs +7 -1
  18. package/hooks/lib/hook-stdin.cjs +52 -0
  19. package/hooks/metrics-collector/index.cjs +5 -8
  20. package/hooks/pre-tool-guard/index.cjs +6 -6
  21. package/hooks/quarantine/index.cjs +12 -21
  22. package/package.json +4 -3
  23. package/skill-index.json +2187 -0
  24. package/skills/audit/SKILL.md +3 -3
  25. package/skills/completion-gate/SKILL.md +1 -1
  26. package/skills/constraint-check/SKILL.md +1 -1
  27. package/skills/context-engine/SKILL.md +2 -2
  28. package/skills/cook/SKILL.md +2 -2
  29. package/skills/cook/references/loop-detection.md +1 -1
  30. package/skills/cook/references/mid-run-signals.md +1 -1
  31. package/skills/debug/SKILL.md +2 -2
  32. package/skills/dependency-doctor/SKILL.md +1 -1
  33. package/skills/design/SKILL.md +1 -1
  34. package/skills/docs/SKILL.md +1 -1
  35. package/skills/docs-seeker/SKILL.md +3 -0
  36. package/skills/hallucination-guard/SKILL.md +2 -2
  37. package/skills/incident/SKILL.md +1 -1
  38. package/skills/integrity-check/SKILL.md +1 -1
  39. package/skills/launch/SKILL.md +1 -1
  40. package/skills/preflight/SKILL.md +35 -9
  41. package/skills/rescue/SKILL.md +1 -1
  42. package/skills/research/SKILL.md +1 -1
  43. package/skills/review/SKILL.md +135 -84
  44. package/skills/review/references/rules/config.md +63 -0
  45. package/skills/review/references/rules/default.md +57 -0
  46. package/skills/review/references/rules/go.md +65 -0
  47. package/skills/review/references/rules/index.md +43 -0
  48. package/skills/review/references/rules/python.md +64 -0
  49. package/skills/review/references/rules/rust.md +65 -0
  50. package/skills/review/references/rules/sql.md +65 -0
  51. package/skills/review/references/rules/ts-js.md +80 -0
  52. package/skills/sast/SKILL.md +1 -1
  53. package/skills/scout/SKILL.md +3 -0
  54. package/skills/sentinel/SKILL.md +29 -6
  55. package/skills/skill-router/SKILL.md +1 -1
  56. package/skills/team/SKILL.md +2 -2
  57. package/skills/verification/SKILL.md +3 -4
  58. 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.
@@ -5,7 +5,7 @@ metadata:
5
5
  author: runedev
6
6
  version: "1.0.0"
7
7
  layer: L3
8
- model: haiku
8
+ model: sonnet
9
9
  group: validation
10
10
  tools: "Read, Bash, Glob, Grep"
11
11
  ---
@@ -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"
@@ -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 (file:line, regex match, tool output)? | Discard — no evidence = hallucination |
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
- - `path/to/file.ts:42` — Hardcoded API key detected (pattern: sk-...)
326
- - `path/to/api.ts:15` — SQL injection: string concatenation in query
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
@@ -6,7 +6,7 @@ metadata:
6
6
  author: runedev
7
7
  version: "1.4.0"
8
8
  layer: L0
9
- model: haiku
9
+ model: sonnet
10
10
  group: orchestrator
11
11
  tools: "Read, Glob, Grep"
12
12
  ---
@@ -197,7 +197,7 @@ Contract format in NEXUS Handoff:
197
197
 
198
198
  **1d. Question Gate (non-trivial tasks only).**
199
199
 
200
- > From superpowers (obra/superpowers, 84k★): "Subagents that start work without asking questions produce the wrong thing 40% of the time."
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
- > From agency-agents (msitarzewski/agency-agents, 50.8k★): "Structured handoff docs prevent the #1 multi-agent failure: context loss between agents."
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: haiku
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
- > Inspired by CLI-Anything (HKUDS/CLI-Anything, 14.5k★): "Never trust exit 0."
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
- > From taste-skill (Leonxlnx/taste-skill, 3.4k★): Truncated code is worse than no code — it passes reviews but breaks at runtime.
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
 
@@ -5,7 +5,7 @@ metadata:
5
5
  author: runedev
6
6
  version: "0.2.0"
7
7
  layer: L3
8
- model: sonnet
8
+ model: haiku
9
9
  group: monitoring
10
10
  tools: "Read, Bash, Glob, Grep"
11
11
  emit: incident.detected