nubos-pilot 1.2.2 → 1.2.3

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 (63) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/agents/np-architect.md +2 -0
  3. package/agents/np-executor.md +1 -1
  4. package/agents/np-learnings-extractor.md +54 -0
  5. package/agents/np-planner.md +1 -1
  6. package/agents/np-security-reviewer.md +9 -0
  7. package/bin/np-tools/_commands.cjs +4 -0
  8. package/bin/np-tools/derive-tier.cjs +86 -0
  9. package/bin/np-tools/derive-tier.test.cjs +83 -0
  10. package/bin/np-tools/learnings.cjs +105 -0
  11. package/bin/np-tools/learnings.test.cjs +66 -0
  12. package/bin/np-tools/loop-run-round.cjs +7 -1
  13. package/bin/np-tools/skill-audit.cjs +79 -0
  14. package/bin/np-tools/skill-audit.test.cjs +86 -0
  15. package/bin/np-tools/verify-reliability.cjs +65 -0
  16. package/bin/np-tools/verify-reliability.test.cjs +69 -0
  17. package/lib/agents.test.cjs +1 -0
  18. package/lib/config-defaults.cjs +13 -0
  19. package/lib/config-schema.cjs +11 -0
  20. package/lib/eval-reliability.cjs +63 -0
  21. package/lib/eval-reliability.test.cjs +56 -0
  22. package/lib/install/claude-hooks-learnings.test.cjs +82 -0
  23. package/lib/install/claude-hooks.cjs +65 -4
  24. package/lib/install/claude-hooks.test.cjs +5 -2
  25. package/lib/learnings/capture-ledger.cjs +80 -0
  26. package/lib/learnings/capture-ledger.test.cjs +54 -0
  27. package/lib/learnings/extract.cjs +191 -0
  28. package/lib/learnings/extract.test.cjs +115 -0
  29. package/lib/nubosloop-audit.cjs +104 -0
  30. package/lib/nubosloop-skill-audit.test.cjs +98 -0
  31. package/lib/nubosloop.cjs +9 -0
  32. package/lib/tier-classify.cjs +67 -0
  33. package/lib/tier-classify.test.cjs +67 -0
  34. package/np-tools.cjs +4 -0
  35. package/package.json +1 -1
  36. package/skills/np-access-control/SKILL.md +42 -0
  37. package/skills/np-accessibility-audit/SKILL.md +41 -0
  38. package/skills/np-adr/SKILL.md +37 -0
  39. package/skills/np-api-design/SKILL.md +34 -0
  40. package/skills/np-caching-strategy/SKILL.md +38 -0
  41. package/skills/np-data-modeling/SKILL.md +37 -0
  42. package/skills/np-data-privacy/SKILL.md +39 -0
  43. package/skills/np-dependency-audit/SKILL.md +47 -0
  44. package/skills/np-encryption/SKILL.md +47 -0
  45. package/skills/np-error-handling/SKILL.md +37 -0
  46. package/skills/np-incident-response/SKILL.md +38 -0
  47. package/skills/np-llm-app-architecture/SKILL.md +50 -0
  48. package/skills/np-observability/SKILL.md +39 -0
  49. package/skills/np-performance/SKILL.md +38 -0
  50. package/skills/np-queue-design/SKILL.md +32 -0
  51. package/skills/np-rag-design/SKILL.md +43 -0
  52. package/skills/np-refactoring/SKILL.md +35 -0
  53. package/skills/np-resilience-patterns/SKILL.md +39 -0
  54. package/skills/np-secure-code-review/SKILL.md +46 -0
  55. package/skills/np-secure-design/SKILL.md +44 -0
  56. package/skills/np-service-boundary/SKILL.md +35 -0
  57. package/skills/np-system-design/SKILL.md +40 -0
  58. package/skills/np-test-strategy/SKILL.md +46 -0
  59. package/skills/np-threat-model/SKILL.md +42 -0
  60. package/templates/claude/payload/hooks/np-learnings-hook.cjs +55 -0
  61. package/workflows/architect-phase.md +21 -1
  62. package/workflows/execute-phase.md +66 -4
  63. package/workflows/verify-work.md +17 -4
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const fs = require('node:fs');
5
+ const path = require('node:path');
6
+ const cp = require('node:child_process');
7
+
8
+ // ADR-0010 / ECC continuous-learning: thin Stop-hook shim. On session Stop it
9
+ // asks np-tools to (rate-limited) auto-capture reusable learnings from the
10
+ // turn's diff; on UserPromptSubmit it resets the consecutive-stop streak. All
11
+ // heavy logic lives in lib/learnings/. A learning hook must NEVER break the
12
+ // session — every failure path exits 0 silently.
13
+
14
+ const ALLOWED_VERBS = new Set(['capture', 'reset']);
15
+
16
+ function resolveNpTools() {
17
+ const candidates = [
18
+ path.join(process.cwd(), '.nubos-pilot', 'bin', 'np-tools.cjs'),
19
+ path.join(__dirname, '..', '..', '..', '.nubos-pilot', 'bin', 'np-tools.cjs'),
20
+ ];
21
+ for (const c of candidates) {
22
+ try { if (fs.statSync(c).isFile()) return c; } catch {}
23
+ }
24
+ return null;
25
+ }
26
+
27
+ function readStdin() {
28
+ return new Promise((resolve) => {
29
+ if (process.stdin.isTTY) return resolve('');
30
+ let buf = '';
31
+ process.stdin.setEncoding('utf-8');
32
+ const timer = setTimeout(() => { try { process.stdin.removeAllListeners(); } catch {} resolve(buf); }, 800);
33
+ process.stdin.on('data', (c) => { buf += c; });
34
+ process.stdin.on('end', () => { clearTimeout(timer); resolve(buf); });
35
+ process.stdin.on('error', () => { clearTimeout(timer); resolve(buf); });
36
+ });
37
+ }
38
+
39
+ (async () => {
40
+ const verb = process.argv[2];
41
+ if (!ALLOWED_VERBS.has(verb)) { process.exit(0); return; }
42
+ const npTools = resolveNpTools();
43
+ if (!npTools) { process.exit(0); return; }
44
+ const input = await readStdin();
45
+ try {
46
+ cp.spawnSync(process.execPath, [npTools, 'learnings', verb, '--stdin'], {
47
+ input,
48
+ encoding: 'utf-8',
49
+ timeout: 15000,
50
+ maxBuffer: 4 * 1024 * 1024,
51
+ cwd: process.cwd(),
52
+ });
53
+ } catch { /* never let a learning hook break the session */ }
54
+ process.exit(0);
55
+ })().catch(() => { process.exit(0); });
@@ -74,9 +74,24 @@ The architect then consumes the consensus-merged `RESEARCH.md` instead of a sing
74
74
 
75
75
  After the architect emits `M<NNN>-ARCHITECTURE.md`, the orchestrator spawns ONE `np-critic` instance with the architecture file + `M<NNN>-CONTEXT.md` as inputs. The critic verifies that every locked decision in CONTEXT has a corresponding architecture entry and that no `Deferred` items leaked into the architecture. Findings of category `unmet-criterion`, `locked-decision-violation`, or `information-missing` route per `lib/nubosloop.cjs::routeFindings`. A single Build-Fixer-style round on the architect closes the loop. Beyond one round the workflow exits with `stuck` and the user resolves manually — architecture decisions don't merit unbounded looping.
76
76
 
77
+ ## Skills (Nubos library)
78
+
79
+ Nubos ships a design-time skill library under `.claude/skills/np-*/` (present only on Claude Code). These are the **quality bar for the architecture decisions you are about to commit** — each skill's "Verification bar" is the standard each ADR-style decision is held to. Before spawning `np-architect`, classify the milestone (read `M<NNN>-CONTEXT.md` + `M<NNN>-RESEARCH.md`) and inject the matching skill triggers into the architect's spawn prompt. Skills **stack** — include every row the milestone matches (cap at the most relevant ~4 if more match; always keep the security row when it applies).
80
+
81
+ | Milestone signal | Skills to trigger |
82
+ |---|---|
83
+ | Designs a new system, module, or significant feature | `np-system-design` (with `np-adr` for an architecturally significant, hard-to-reverse choice) |
84
+ | Introduces or moves a module/service boundary, splits a service, or chooses sync vs async | `np-service-boundary` |
85
+ | Any structural decision that is costly to reverse — datastore, sync/async, new dependency, auth model, public contract | `np-adr` |
86
+ | New external surface, new trust boundary, new privilege model, or handling of sensitive assets | `np-secure-design` (with `np-threat-model`) |
87
+ | Authorization model — roles, permissions, policies, resource ownership | `np-access-control` |
88
+ | Design depends on an unreliable dependency, async/queue processing, or a cache | `np-resilience-patterns`, `np-queue-design`, `np-caching-strategy` (each as it applies) |
89
+ | Persisted data shape, or personal/sensitive data | `np-data-modeling`, `np-data-privacy` (as they apply) |
90
+ | Purely additive milestone with no structural/security decision | None — skip the skill block (and reconsider whether the architect pass is needed at all) |
91
+
77
92
  ## Spawn np-architect
78
93
 
79
- Spawn `agents/np-architect.md` mit dem folgenden Files-to-Read-Block:
94
+ Spawn `agents/np-architect.md` mit dem folgenden Files-to-Read-Block und (sofern Skills matchen) der angehängten Skill-Direktive:
80
95
 
81
96
  ```
82
97
  <files_to_read>
@@ -88,8 +103,13 @@ Spawn `agents/np-architect.md` mit dem folgenden Files-to-Read-Block:
88
103
 
89
104
  Milestone: M<NNN>
90
105
  Task: Emit M<NNN>-ARCHITECTURE.md per the agent's Output Contract.
106
+
107
+ Use the following Nubos skills as the quality bar for your decisions: <skill-1>, <skill-2>, ...
108
+ Each is installed at .claude/skills/<skill>/SKILL.md; every architecture decision must satisfy the matching skill's "Verification bar".
91
109
  ```
92
110
 
111
+ If zero skills match, omit the skill-directive line — do not invent skills.
112
+
93
113
  Der Agent ist read-only auf Source — er schreibt EINE Datei:
94
114
  `.nubos-pilot/milestones/M<NNN>/M<NNN>-ARCHITECTURE.md`.
95
115
 
@@ -33,6 +33,8 @@ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
33
33
  AGENT_SKILLS_EXECUTOR=$(node .nubos-pilot/bin/np-tools.cjs agent-skills executor 2>/dev/null)
34
34
  RUNTIME=$(node .nubos-pilot/bin/np-tools.cjs detect-runtime)
35
35
  WORKTREE_ISOLATION=$(node .nubos-pilot/bin/np-tools.cjs config-get workflow.worktree_isolation 2>/dev/null || echo "false")
36
+ TIER_ROUTING=$(node .nubos-pilot/bin/np-tools.cjs config-get workflow.tier_routing 2>/dev/null || echo "false")
37
+ VERIFY_RUNS=$(node .nubos-pilot/bin/np-tools.cjs config-get loop.verify_runs 2>/dev/null || echo "1")
36
38
  ```
37
39
 
38
40
  When `--verify-work` is passed, the init payload's `auto_verify: true` flag tells this workflow to chain into `/np:verify-work $PHASE` after every slice committed and `finalize-milestone` ran. Without the flag the workflow stops after finalize as before — verify-work then remains a separate manual step.
@@ -57,18 +59,44 @@ Parse JSON for: `milestone`, `milestone_id`, `milestone_dir`, `waves[]` (each wi
57
59
 
58
60
  Nubos ships a skill library under `.claude/skills/np-*/` (auto-installed by `npx nubos-pilot`, present only on Claude Code). For each task in a wave, before spawning `np-executor`, classify the task by reading its `T<NNNN>-PLAN.md` and inject the matching skill triggers into the executor's spawn prompt as a "Use these skills" directive. The executor then loads each skill's `SKILL.md` via the runtime's skill mechanism and follows its rules during implementation.
59
61
 
60
- Mapping (match the dominant signal in `files_modified` + task description):
62
+ Match the task against **both** tables below — a task can match rows in each (e.g. a new authenticated endpoint backed by a migration is UI-free but matches `np-api-design` + `np-secure-code-review` + `np-data-modeling`). Skills **stack**: trigger every row whose signal the task matches. The only exception is the UI style anchor (pick exactly one). If more than ~4 rows match, keep the most task-critical and always retain any security row (`np-secure-code-review` / `np-threat-model`) and `np-test-strategy` for behaviour changes.
63
+
64
+ **UI / frontend** (match the dominant signal in `files_modified` + task description):
61
65
 
62
66
  | Task signal | Skills to trigger |
63
67
  |---|---|
64
- | Any UI/component edit (`.tsx`, `.jsx`, `.vue`, `.svelte`, `views/**`, `components/**`, `pages/**`, `app/**`) | `np-impeccable` (polish/audit), `np-frontend-design` (build), `np-design` (review), `np-web-design-guidelines` (a11y/UX) |
68
+ | Any UI/component edit (`.tsx`, `.jsx`, `.vue`, `.svelte`, `views/**`, `components/**`, `pages/**`, `app/**`) | `np-impeccable` (polish/audit), `np-frontend-design` (build), `np-design` (review), `np-web-design-guidelines` (a11y/UX), `np-accessibility-audit` (WCAG AA bar) |
65
69
  | `components.json` present in repo OR shadcn/ui imports in modified files | `np-shadcn` (in addition to UI skills above) |
66
70
  | React/Next.js component or hook edit | `np-react-best-practices`, `np-composition-patterns` |
67
71
  | Page/route transitions, `<ViewTransition>`, `startViewTransition` | `np-react-view-transitions` |
68
72
  | React Native / Expo source (`*.tsx` under `app/`, `screens/`, `mobile/**`) | `np-react-native-skills` |
69
73
  | Restyling an existing surface (no greenfield) | `np-redesign-existing-projects` |
70
74
  | New surface needing visual direction | Pick exactly **one** style anchor: `np-high-end-visual-design` (default agency premium), `np-minimalist-ui`, `np-industrial-brutalist-ui`, or `np-stitch-design-taste` |
71
- | Non-UI task (backend, infra, tooling, docs) | None — skip the skill block entirely |
75
+
76
+ **Engineering / non-UI** (these stack — include each row the task matches):
77
+
78
+ | Task signal | Skills to trigger |
79
+ |---|---|
80
+ | Adds/changes a consumed contract — HTTP route, RPC/GraphQL handler, controller, resolver, public SDK/library function, CLI flag | `np-api-design` |
81
+ | Touches auth, authz, session, secrets, crypto, SQL/query construction, file upload, deserialization, or any untrusted input reaching a sink | `np-secure-code-review` |
82
+ | Introduces or alters a trust boundary — new ingress, webhook/callback, queue consumer, third-party integration, or a new store for credentials/PII | `np-threat-model` (with `np-secure-code-review`) |
83
+ | DB schema, migration, ORM model/entity, or any backfill/transform of persisted data | `np-data-modeling` |
84
+ | Backend/service/integration/IO path that can fail — external calls, retries, timeouts, batch work | `np-error-handling` |
85
+ | Calls an external/unreliable dependency (other service, third-party API, DB under load) | `np-resilience-patterns` (with `np-error-handling`) |
86
+ | New service/handler/job/integration path, or a new failure path that must be diagnosable | `np-observability` |
87
+ | Data access, queries, loops over collections, hot paths — anything that scales with input size | `np-performance` |
88
+ | Adds or changes a cache / memoization layer (in-memory, distributed, HTTP/CDN) | `np-caching-strategy` |
89
+ | Message queue, background job, worker, async consumer, or event handler | `np-queue-design` |
90
+ | Introduces or changes a module/service boundary, splits a service, or makes a cross-module change | `np-service-boundary` |
91
+ | Roles, permissions, policies, resource ownership, or access-rule changes (RBAC/ABAC, authz checks) | `np-access-control` (with `np-secure-code-review`) |
92
+ | Encryption, hashing, password storage, TLS, tokens, signing/HMAC, or key/secret management | `np-encryption` |
93
+ | Adds or upgrades a third-party dependency, or edits a manifest/lockfile | `np-dependency-audit` |
94
+ | Collects, stores, processes, exports, or logs personal/sensitive data (PII) | `np-data-privacy` |
95
+ | Refactor / cleanup / restructure where behaviour must be preserved | `np-refactoring` |
96
+ | Risky / hard-to-reverse / high-blast-radius change — feature flags, migration coupled to code, change to an external integration | `np-incident-response` |
97
+ | LLM / agent / prompt / tool-use / structured-output / AI feature | `np-llm-app-architecture` (add `np-rag-design` if it retrieves from a corpus) |
98
+ | Any change to logic or behaviour (almost all non-trivial tasks) | `np-test-strategy` |
99
+ | Pure docs/config with no behaviour change | None — skip the skill block |
72
100
 
73
101
  **Spawn-prompt injection format.** Append to the executor prompt verbatim (one line per matched skill):
74
102
 
@@ -78,6 +106,14 @@ Each skill is installed at .claude/skills/<skill>/SKILL.md and encodes a
78
106
  quality bar you must satisfy before invoking commit-task.
79
107
  ```
80
108
 
109
+ **Consultation audit (counterpart to Rule 9).** Whenever you inject a non-empty skill block, BEFORE spawning the executor record the expected set so the post-critics gate can verify the executor actually consulted them:
110
+
111
+ ```bash
112
+ node .nubos-pilot/bin/np-tools.cjs skill-audit expect --task "$TASK_ID" --skills "<skill-1>,<skill-2>,..."
113
+ ```
114
+
115
+ The executor stamps each skill it reads via `skill-audit ack`. At post-critics, any injected-but-unconsulted skill becomes a `skill-bar-unconsulted` finding that routes the task back to the executor (once per round, bounded by `loop.maxRounds`) — exactly like a Rule-9 search miss. Skip the `expect` call only when zero skills were injected.
116
+
81
117
  If zero skills match, omit the block — do **not** invent skills. Adding new skills under `skills/np-*/` in the source repo is sufficient: the next `npx nubos-pilot update` rolls them out and you extend this mapping in one PR.
82
118
 
83
119
  ## Pre-Flight — orphan-checkpoint guard
@@ -262,6 +298,7 @@ for WAVE_INDEX in 0 1 2 ...; do
262
298
  TASK_JSON=$(node .nubos-pilot/bin/np-tools.cjs init execute-milestone execute-task "$PHASE" "$TASK_ID")
263
299
  if [[ "$TASK_JSON" == @file:* ]]; then TASK_JSON=$(cat "${TASK_JSON#@file:}"); fi
264
300
  TASK_QUERY=$(echo "$TASK_JSON" | node -e "process.stdin.on('data', d => { const j=JSON.parse(d); console.log(j.query || j.name || ''); })")
301
+ TASK_TIER=$(echo "$TASK_JSON" | node -e "process.stdin.on('data', d => { const j=JSON.parse(d); console.log(j.tier || 'sonnet'); })")
265
302
 
266
303
  EXECUTOR_START=$(node .nubos-pilot/bin/np-tools.cjs metrics start-timestamp)
267
304
  CONSENSUS_PATTERN=""
@@ -371,7 +408,18 @@ for WAVE_INDEX in 0 1 2 ...; do
371
408
  else
372
409
  EXECUTOR_AGENT="np-build-fixer"
373
410
  fi
374
- EXECUTOR_MODEL=$(node .nubos-pilot/bin/np-tools.cjs resolve-model "$EXECUTOR_AGENT" --profile frontier)
411
+ # Model resolution. Default (tier_routing off): the executor always runs at
412
+ # the `frontier` profile — every task gets the strongest model. Opt-in
413
+ # tier-routing (config `workflow.tier_routing: true`) instead honours the
414
+ # planner's per-task `tier` under the project's configured `model_profile`
415
+ # (default `balanced`), so trivial→haiku / standard→sonnet / large→opus —
416
+ # ECC-style cost-aware routing. Round-2+ build-fixer always stays frontier:
417
+ # fixing a failing task wants the strongest model regardless of routing.
418
+ if [[ "$TIER_ROUTING" == "true" && "$ROUND" -eq 1 ]]; then
419
+ EXECUTOR_MODEL=$(node .nubos-pilot/bin/np-tools.cjs resolve-model "$TASK_TIER")
420
+ else
421
+ EXECUTOR_MODEL=$(node .nubos-pilot/bin/np-tools.cjs resolve-model "$EXECUTOR_AGENT" --profile frontier)
422
+ fi
375
423
  # → execute group (1) per ACTION CONTRACT above, then:
376
424
 
377
425
  node .nubos-pilot/bin/np-tools.cjs checkpoint transition "$TASK_ID" verifying
@@ -380,6 +428,20 @@ for WAVE_INDEX in 0 1 2 ...; do
380
428
  VERIFY_LOG="${TMPDIR:-/tmp}/np-verify-${TASK_ID}-r${ROUND}.log"
381
429
  # Orchestrator (NOT the agent) runs the task's <verify> command + stack
382
430
  # linters; redirect stdout+stderr to $VERIFY_LOG.
431
+ #
432
+ # pass@k reliability (opt-in, $VERIFY_RUNS, default 1): run the SAME verify
433
+ # command $VERIFY_RUNS times, collecting one exit code per run into a
434
+ # comma-separated list ($VERIFY_CODES, e.g. "0,1,0"). With the default of 1
435
+ # this is a single run, identical to before. Then fold the runs:
436
+ # VERIFY_EXIT=$? # when $VERIFY_RUNS == 1
437
+ # # when $VERIFY_RUNS > 1:
438
+ # REL=$(node .nubos-pilot/bin/np-tools.cjs verify-reliability --codes "$VERIFY_CODES")
439
+ # VERIFY_EXIT=$(echo "$REL" | node -e 'process.stdin.on("data",d=>console.log(JSON.parse(d).aggregate_exit_code))')
440
+ # # append the human verdict so a FLAKY task tells the build-fixer why it is red:
441
+ # echo "$REL" | node -e 'process.stdin.on("data",d=>console.log(JSON.parse(d).description))' >> "$VERIFY_LOG"
442
+ # aggregate_exit_code is 0 only when EVERY run passed (pass^k); a flaky task
443
+ # (some pass, some fail) aggregates to red and flows through the normal
444
+ # spawn-build-fixer path below — no new critic category, no spurious stuck.
383
445
  VERIFY_EXIT=$?
384
446
  # Stamp executor spawn-evidence into the audit log. EXECUTOR_TOOL_LOG is
385
447
  # the tool-name JSON array harvested from the spawn's tool_use stream
@@ -38,15 +38,28 @@ Parse: `milestone`, `milestone_id`, `milestone_dir`, `milestone_name`, `success_
38
38
 
39
39
  ## Skills (Nubos library)
40
40
 
41
- For UI/UX-flavoured success criteria, instruct the verifier (in its spawn prompt) to load the matching Nubos skill before classifying:
41
+ Instruct the verifier (in its spawn prompt) to load the matching Nubos skill before classifying — the skill's "Verification bar" is the standard the SC is judged against, not just the SC's own wording:
42
42
 
43
43
  | SC type | Skill to use |
44
44
  |---|---|
45
45
  | Visual polish, layout, hierarchy, motion | `np-impeccable` (`.claude/skills/np-impeccable/SKILL.md`) |
46
- | Accessibility, semantic HTML, UX heuristics | `np-web-design-guidelines` |
46
+ | Accessibility, semantic HTML, keyboard/contrast | `np-web-design-guidelines`, `np-accessibility-audit` |
47
47
  | Component architecture, design-system fit | `np-design` |
48
-
49
- For borderline Pass/Fail calls in Pass 2 (deterministic evidence inconclusive **and** the SC carries real consequences), pressure-test with **`np-council`** before flipping `needs_user_confirm` `Pass`/`Fail`. Backend/infra/data SCs do not need any skill — verdict on evidence alone.
48
+ | API / endpoint / contract behaviour | `np-api-design` |
49
+ | Security, auth, input handling, secrets, crypto | `np-secure-code-review` (and `np-threat-model` if a new trust boundary) |
50
+ | Authorization — roles, permissions, ownership, access rules | `np-access-control` |
51
+ | Encryption, hashing, TLS, key/secret management | `np-encryption` |
52
+ | Personal/sensitive data handling, retention, logging | `np-data-privacy` |
53
+ | Schema / migration / data correctness | `np-data-modeling` |
54
+ | Error handling, retries, failure modes | `np-error-handling` |
55
+ | Resilience under dependency failure — timeout, circuit-breaker, fallback | `np-resilience-patterns` |
56
+ | Caching correctness / invalidation | `np-caching-strategy` |
57
+ | Async job / queue / worker behaviour — idempotency, ordering, DLQ | `np-queue-design` |
58
+ | Module/service boundary, coupling, contract integrity | `np-service-boundary` |
59
+ | Performance, latency, query/loop cost | `np-performance` |
60
+ | LLM / agent / retrieval behaviour | `np-llm-app-architecture`, `np-rag-design` |
61
+
62
+ For borderline Pass/Fail calls in Pass 2 (deterministic evidence inconclusive **and** the SC carries real consequences), pressure-test with **`np-council`** before flipping `needs_user_confirm` → `Pass`/`Fail`. An SC with no matching skill is judged on evidence alone.
50
63
 
51
64
  ## Output-Schema (pre-spawn injection)
52
65