session-orchestrator 5.7.0 → 5.9.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.
Files changed (202) hide show
  1. package/.agents/skills/architecture/SKILL.md +3 -0
  2. package/.agents/skills/architecture/agents/openai.yaml +5 -0
  3. package/.agents/skills/claude-md-drift-check/SKILL.md +1 -0
  4. package/.agents/skills/eval/SKILL.md +1 -1
  5. package/.agents/skills/frontmatter-guard/SKILL.md +1 -0
  6. package/.agents/skills/gitlab-portfolio/SKILL.md +1 -0
  7. package/.agents/skills/hook-development/SKILL.md +1 -0
  8. package/.agents/skills/mcp-builder/SKILL.md +1 -0
  9. package/.agents/skills/tmux-layout/SKILL.md +3 -0
  10. package/.agents/skills/tmux-layout/agents/openai.yaml +5 -0
  11. package/.agents/skills/vault-mirror/SKILL.md +1 -0
  12. package/.agents/skills/vault-sync/SKILL.md +1 -0
  13. package/.agents/skills/write-executable-plan/SKILL.md +3 -0
  14. package/.agents/skills/write-executable-plan/agents/openai.yaml +5 -0
  15. package/.claude-plugin/marketplace.json +1 -1
  16. package/.claude-plugin/plugin.json +1 -1
  17. package/.codex-plugin/plugin.json +1 -1
  18. package/.codex-plugin/skills/architecture/SKILL.md +3 -0
  19. package/.codex-plugin/skills/architecture/agents/openai.yaml +5 -0
  20. package/.codex-plugin/skills/claude-md-drift-check/SKILL.md +1 -0
  21. package/.codex-plugin/skills/eval/SKILL.md +1 -1
  22. package/.codex-plugin/skills/frontmatter-guard/SKILL.md +1 -0
  23. package/.codex-plugin/skills/gitlab-portfolio/SKILL.md +1 -0
  24. package/.codex-plugin/skills/hook-development/SKILL.md +1 -0
  25. package/.codex-plugin/skills/mcp-builder/SKILL.md +1 -0
  26. package/.codex-plugin/skills/tmux-layout/SKILL.md +3 -0
  27. package/.codex-plugin/skills/tmux-layout/agents/openai.yaml +5 -0
  28. package/.codex-plugin/skills/vault-mirror/SKILL.md +1 -0
  29. package/.codex-plugin/skills/vault-sync/SKILL.md +1 -0
  30. package/.codex-plugin/skills/write-executable-plan/SKILL.md +3 -0
  31. package/.codex-plugin/skills/write-executable-plan/agents/openai.yaml +5 -0
  32. package/.cursor/commands/architecture.md +13 -0
  33. package/.cursor/commands/eval.md +1 -1
  34. package/.cursor/commands/tmux-layout.md +13 -0
  35. package/.cursor/commands/write-executable-plan.md +13 -0
  36. package/.cursor/skills/architecture/SKILL.md +0 -1
  37. package/.cursor/skills/eval/SKILL.md +1 -1
  38. package/.cursor/skills/tmux-layout/SKILL.md +0 -1
  39. package/.cursor/skills/write-executable-plan/SKILL.md +0 -1
  40. package/.cursor-plugin/plugin.json +1 -1
  41. package/CHANGELOG.md +68 -0
  42. package/README.md +13 -9
  43. package/agents/eval-judge.md +5 -5
  44. package/docs/baseline.md +4 -3
  45. package/docs/codex-setup.md +6 -4
  46. package/docs/components.md +5 -4
  47. package/docs/events-schema.md +45 -4
  48. package/docs/github-mirror-protection.md +3 -2
  49. package/docs/install.md +39 -3
  50. package/docs/pi-setup.md +1 -1
  51. package/docs/rule-authoring.md +2 -2
  52. package/docs/session-config-reference.md +7 -5
  53. package/docs/session-config-template.md +3 -2
  54. package/evals/README.md +60 -0
  55. package/evals/instruction-ablation/README.md +147 -0
  56. package/evals/instruction-ablation/cases/psa-003-foreign-work.json +34 -0
  57. package/evals/instruction-ablation/cases/sec-007-sql-parameterisation.json +32 -0
  58. package/evals/instruction-ablation/cases/vbc-001-verify-before-claiming.json +41 -0
  59. package/evals/instruction-ablation/run.mjs +336 -0
  60. package/evals/psa-003-foreign-work/case.yaml +16 -0
  61. package/evals/psa-003-foreign-work/fixture.sh +12 -0
  62. package/evals/psa-003-foreign-work/graders/foreign-file-intact.md +7 -0
  63. package/evals/psa-003-foreign-work/graders/names-foreign-work.md +6 -0
  64. package/evals/psa-003-foreign-work/graders/no-destructive-git.md +8 -0
  65. package/evals/psa-003-foreign-work/graders/ran-git.md +7 -0
  66. package/evals/psa-003-foreign-work/prompt.md +6 -0
  67. package/hooks/_lib/hook-import-set.json +10 -2
  68. package/hooks/hooks-codex.json +1 -1
  69. package/hooks/hooks.json +1 -1
  70. package/hooks/post-tool-batch-wave-signal.mjs +1 -0
  71. package/hooks/post-tooluse-frontend-slop.mjs +11 -1
  72. package/hooks/pre-task-scope-disjoint.mjs +8 -6
  73. package/monitors/monitors.json +1 -1
  74. package/package.json +3 -1
  75. package/pi/prompts/architecture.md +11 -0
  76. package/pi/prompts/eval.md +1 -1
  77. package/pi/prompts/tmux-layout.md +11 -0
  78. package/pi/prompts/write-executable-plan.md +11 -0
  79. package/scripts/backfill-abandoned-sessions.mjs +2 -2
  80. package/scripts/backfill-sessions.mjs +9 -7
  81. package/scripts/codex-install.mjs +108 -23
  82. package/scripts/emit-session.mjs +15 -2
  83. package/scripts/fleet-auflagen.mjs +54 -0
  84. package/scripts/generate-agents-skills.mjs +9 -16
  85. package/scripts/generate-codex-skills.mjs +8 -6
  86. package/scripts/generate-cursor-adapter.mjs +9 -74
  87. package/scripts/generate-pi-prompts.mjs +8 -74
  88. package/scripts/github-protection-audit.mjs +8 -0
  89. package/scripts/lib/auto-dialectic.mjs +10 -9
  90. package/scripts/lib/auto-dream.mjs +8 -10
  91. package/scripts/lib/autopilot/telemetry.mjs +12 -6
  92. package/scripts/lib/bootstrap-lock-refresh.mjs +8 -12
  93. package/scripts/lib/ci-status-banner.mjs +38 -5
  94. package/scripts/lib/config/drift-check.mjs +1 -1
  95. package/scripts/lib/config/frontend-slop-hook.mjs +6 -0
  96. package/scripts/lib/config.mjs +5 -1
  97. package/scripts/lib/convergence-monitor.mjs +5 -3
  98. package/scripts/lib/ecosystem-health.mjs +5 -3
  99. package/scripts/lib/eval/engine.mjs +61 -27
  100. package/scripts/lib/eval/judge.mjs +14 -8
  101. package/scripts/lib/eval/session-resolve.mjs +7 -2
  102. package/scripts/lib/events-retention-banner.mjs +5 -2
  103. package/scripts/lib/events-schema.mjs +8 -0
  104. package/scripts/lib/events.mjs +19 -5
  105. package/scripts/lib/fleet-protocol.mjs +98 -1
  106. package/scripts/lib/instruction-budget-guard.mjs +25 -18
  107. package/scripts/lib/io.mjs +172 -35
  108. package/scripts/lib/learnings/candidates.mjs +7 -28
  109. package/scripts/lib/learnings/io.mjs +7 -2
  110. package/scripts/lib/learnings/judgment.mjs +5 -8
  111. package/scripts/lib/learnings/select.mjs +3 -3
  112. package/scripts/lib/maintenance-due-banner.mjs +2 -2
  113. package/scripts/lib/memory-proposals/sink.mjs +5 -6
  114. package/scripts/lib/memory-proposals/store.mjs +3 -5
  115. package/scripts/lib/mirror-issues-banner.mjs +11 -1
  116. package/scripts/lib/native-command.mjs +48 -0
  117. package/scripts/lib/orphan-reaper/scan.mjs +29 -3
  118. package/scripts/lib/peer-cards/writer.mjs +6 -18
  119. package/scripts/lib/platform.mjs +113 -4
  120. package/scripts/lib/plugin-package-stage.mjs +169 -0
  121. package/scripts/lib/plugin-surface.mjs +121 -0
  122. package/scripts/lib/quality-gate-wave.mjs +40 -0
  123. package/scripts/lib/quality-gate.mjs +36 -30
  124. package/scripts/lib/reconcile/idempotency.mjs +9 -10
  125. package/scripts/lib/reconcile/rule-expiry-sweep.mjs +48 -11
  126. package/scripts/lib/reconcile/writer.mjs +11 -17
  127. package/scripts/lib/rule-loader.mjs +32 -6
  128. package/scripts/lib/scope-echo.mjs +12 -2
  129. package/scripts/lib/scope-gate.mjs +2 -1
  130. package/scripts/lib/session-close-backfill.mjs +3 -4
  131. package/scripts/lib/session-id.mjs +2 -1
  132. package/scripts/lib/session-record-repair.mjs +28 -21
  133. package/scripts/lib/session-schema/constants.mjs +20 -5
  134. package/scripts/lib/session-schema/validator.mjs +12 -0
  135. package/scripts/lib/session-start-probes.mjs +22 -7
  136. package/scripts/lib/sessions-staleness-banner.mjs +2 -3
  137. package/scripts/lib/skill-evolution/engine.mjs +6 -9
  138. package/scripts/lib/skill-evolution/idempotency.mjs +8 -10
  139. package/scripts/lib/slopcheck.mjs +9 -7
  140. package/scripts/lib/sunset/walker.mjs +3 -3
  141. package/scripts/lib/telemetry/sync.mjs +3 -1
  142. package/scripts/lib/telemetry-flush-health-banner.mjs +2 -2
  143. package/scripts/lib/test-sibling-coverage.mjs +167 -0
  144. package/scripts/lib/tmux-layout/telemetry-stats.mjs +5 -7
  145. package/scripts/lib/tmux-layout/telemetry.mjs +8 -10
  146. package/scripts/lib/user-invocable-skills.mjs +37 -10
  147. package/scripts/lib/ux-grill/run-record.mjs +5 -3
  148. package/scripts/lib/validate/check-banner-parity.mjs +1 -0
  149. package/scripts/lib/validate/check-skills.mjs +12 -2
  150. package/scripts/lib/validate/check-test-fixture-shapes.mjs +3 -3
  151. package/scripts/lib/validate/check-test-value-bans.mjs +3 -2
  152. package/scripts/lib/validate/check-unicode-safety.mjs +1 -1
  153. package/scripts/lib/validate/check-unwired-features.mjs +1 -1
  154. package/scripts/lib/vault-archive.mjs +2 -4
  155. package/scripts/lib/vault-mirror/process.mjs +207 -26
  156. package/scripts/lib/vault-mirror/utils.mjs +16 -1
  157. package/scripts/lib/vault-sync-baseline.mjs +9 -8
  158. package/scripts/lib/wave-executor/remote-dispatch.mjs +27 -9
  159. package/scripts/lib/wave-resource-gate.mjs +2 -1
  160. package/scripts/lib/wave-transcript-tail.mjs +8 -4
  161. package/scripts/lib/worktree/meta.mjs +7 -3
  162. package/scripts/mcp-server.mjs +158 -0
  163. package/scripts/migrate-sessions-jsonl.mjs +7 -5
  164. package/scripts/migrate-vault-paths.mjs +7 -4
  165. package/scripts/print-learnings-index.mjs +2 -1
  166. package/scripts/release.mjs +4 -1
  167. package/scripts/relocate-vault-corpus.mjs +5 -3
  168. package/scripts/run-migrate-v2-cross-repo.mjs +9 -7
  169. package/scripts/run-quality-gate.mjs +9 -39
  170. package/scripts/self-update.mjs +179 -39
  171. package/scripts/site-numbers.mjs +8 -3
  172. package/scripts/sweep-expired-learnings.mjs +6 -4
  173. package/scripts/sync-vault-schema.mjs +3 -7
  174. package/scripts/windows-setup.mjs +45 -0
  175. package/skills/_shared/fleet-protocol.md +10 -0
  176. package/skills/architecture/SKILL.md +1 -0
  177. package/skills/bootstrap/_shared-template.md +5 -2
  178. package/skills/claude-md-drift-check/SKILL.md +4 -1
  179. package/skills/claude-md-drift-check/checker.mjs +83 -10
  180. package/skills/discovery/probes/ssot-code-diff.mjs +3 -3
  181. package/skills/eval/SKILL.md +12 -13
  182. package/skills/eval/rubric-v3.md +521 -0
  183. package/skills/frontmatter-guard/SKILL.md +1 -0
  184. package/skills/gitlab-portfolio/SKILL.md +1 -0
  185. package/skills/hook-development/SKILL.md +1 -0
  186. package/skills/mcp-builder/SKILL.md +1 -0
  187. package/skills/remote-offload/SKILL.md +1 -1
  188. package/skills/repo-audit/SKILL.md +2 -2
  189. package/skills/session-end/SKILL.md +32 -1
  190. package/skills/session-end/metrics-collection.md +15 -9
  191. package/skills/session-end/vault-operations.md +12 -2
  192. package/skills/session-start/SKILL.md +2 -2
  193. package/skills/session-start/phase-7-1-premise-check.md +2 -1
  194. package/skills/session-start/references/operations-contract.md +4 -1
  195. package/skills/tmux-layout/SKILL.md +1 -0
  196. package/skills/vault-mirror/SKILL.md +1 -0
  197. package/skills/vault-sync/SKILL.md +6 -6
  198. package/skills/vault-sync/validator.sh +29 -10
  199. package/skills/wave-executor/references/wave-loop-dispatch.md +1 -1
  200. package/skills/wave-executor/references/wave-loop-review.md +13 -7
  201. package/skills/wave-executor/references/wave-loop-scope-manifest.md +4 -4
  202. package/skills/write-executable-plan/SKILL.md +1 -0
@@ -38,7 +38,7 @@ import { resolveInstructionFile } from '../../scripts/lib/common.mjs';
38
38
  import { _parseVaultIntegration } from '../../scripts/lib/config/vault-integration.mjs';
39
39
  import { _parseDriftCheck } from '../../scripts/lib/config/drift-check.mjs';
40
40
  import { isSessionConfigHeading } from '../../scripts/lib/config/section-extractor.mjs';
41
- import { FRONTMATTER_NOT_AT_TOP, parseGlobsFrontmatter } from '../../scripts/lib/rule-loader.mjs';
41
+ import { FRONTMATTER_NOT_AT_TOP, isRuleExpired, parseGlobsFrontmatter } from '../../scripts/lib/rule-loader.mjs';
42
42
  import { resolveRepoSpec } from '../../scripts/lib/vcs-repo-spec.mjs';
43
43
  import { userInvocableSkills } from '../../scripts/lib/user-invocable-skills.mjs';
44
44
  import { learningKeyOf } from '../../scripts/lib/learnings/kebab.mjs';
@@ -337,6 +337,44 @@ function instructionFilesAreAliased(pathA, pathB) {
337
337
  }
338
338
  }
339
339
 
340
+ /**
341
+ * Is `AGENTS.md` a pure import pointer to `CLAUDE.md`?
342
+ *
343
+ * Shape: its first non-empty line is a Claude Code import `@CLAUDE.md` (or
344
+ * `@./CLAUDE.md`), and it carries no config of its own — no
345
+ * `vault-integration:` block and no `## Session Config` heading. Such a file
346
+ * cannot disagree with CLAUDE.md at runtime: `resolveInstructionFile()`
347
+ * (`scripts/lib/common.mjs`) and `parse-config.mjs` read CLAUDE.md first
348
+ * whenever it is non-empty, so the pointer's missing block is never read.
349
+ * Comparing them reported `CLAUDE.md='<dir>' vs AGENTS.md='(unset)'` as an
350
+ * error (peer session gotzendorferv2-6e, 2026-10-04).
351
+ *
352
+ * ONE direction only, on purpose. A CLAUDE.md that imports AGENTS.md is the
353
+ * file those readers pick, and they read it raw — they do not follow `@`
354
+ * imports — so its missing block IS the runtime value and the disagreement is
355
+ * real. A pointer that carries its own block stays compared too.
356
+ *
357
+ * Check 7 only. Check 9 probe 2a must keep scanning such a file: its citations
358
+ * are its OWN text (the import is not expanded here), so scanning it reports
359
+ * no CLAUDE.md defect twice — skipping it would hide its own dangling ones.
360
+ *
361
+ * @param {string} agentsPath
362
+ * @returns {boolean}
363
+ */
364
+ function agentsMdImportsClaudeMd(agentsPath) {
365
+ let content;
366
+ try {
367
+ content = readFileSync(agentsPath, 'utf8').replace(/^\uFEFF/, '');
368
+ } catch {
369
+ return false;
370
+ }
371
+ const lines = content.split('\n');
372
+ const first = lines.find((l) => l.trim().length > 0);
373
+ if (first === undefined || !/^@(?:\.\/)?CLAUDE\.md\s*$/.test(first.trim())) return false;
374
+ if (lines.some((l) => isSessionConfigHeading(l))) return false;
375
+ return !readVaultIntegration(agentsPath).present;
376
+ }
377
+
340
378
  function classifySection(heading) {
341
379
  if (!heading) return null;
342
380
  if (BACKWARD_HEADING_RE.test(heading)) return 'backward';
@@ -417,8 +455,9 @@ function countTestFiles(vaultDir) {
417
455
  }
418
456
 
419
457
  /**
420
- * The product's slash-command count: `commands/*.md` ∪ skills carrying an
421
- * explicit `user-invocable: true`, deduplicated by name — the same union
458
+ * The product's slash-command count: `commands/*.md` ∪ skills whose
459
+ * `user-invocable` is `true` or absent (Claude Code picker semantics, #1515),
460
+ * deduplicated by name — the same union
422
461
  * `scripts/site-numbers.mjs` and
423
462
  * `tests/commands/headless-bare-command-availability.test.mjs` use. In a
424
463
  * consumer repo without `skills/` (or without `commands/`) the union
@@ -669,12 +708,31 @@ function globMatchesAny(pattern, trackedFiles) {
669
708
  * Returns the repo's tracked files (relative, forward-slash separated) via
670
709
  * `git ls-files`; falls back to a manual walk (excluding dotdirs and
671
710
  * node_modules — same exclusions as `walkDir`) when git is unavailable.
711
+ *
712
+ * Only "git missing" and "not a git repository" fall back silently. Any other
713
+ * failure still falls back, but says so on stderr: the walk skips dotdirs, so
714
+ * every glob under `.claude/` or a dotfile like `.gitleaks.toml` then reports
715
+ * "matches 0 tracked files" — a false warning that must carry its cause. The
716
+ * 64 MiB buffer exists because the 1 MiB default threw ENOBUFS on a vault
717
+ * listing of 1,199,500 bytes (measured 2026-10-04), which the old bare catch
718
+ * turned into exactly those false warnings, silently.
672
719
  */
673
720
  function listTrackedFiles(vaultDir) {
674
721
  try {
675
- const out = execFileSync('git', ['ls-files'], { cwd: vaultDir, encoding: 'utf8' });
722
+ const out = execFileSync('git', ['ls-files'], {
723
+ cwd: vaultDir,
724
+ encoding: 'utf8',
725
+ stdio: ['ignore', 'pipe', 'pipe'],
726
+ maxBuffer: 64 * 1024 * 1024,
727
+ });
676
728
  return out.split('\n').filter(Boolean);
677
- } catch {
729
+ } catch (err) {
730
+ const notARepo = err?.status === 128 && /not a git repository/i.test(String(err?.stderr ?? ''));
731
+ if (err?.code !== 'ENOENT' && !notARepo) {
732
+ process.stderr.write(
733
+ `claude-md-drift-check: git ls-files failed in ${vaultDir} (${err?.code ?? `exit ${err?.status}`}: ${String(err?.message ?? err).split('\n')[0]}) — falling back to a filesystem walk that skips dotdirs; zero-match glob warnings under dot-paths are unreliable this run\n`,
734
+ );
735
+ }
678
736
  const files = [];
679
737
  walkDir(vaultDir, (f) => files.push(relative(vaultDir, f).replace(/\\/g, '/')));
680
738
  return files;
@@ -1113,8 +1171,13 @@ function main() {
1113
1171
  // absent vault-integration block is a different (and more informative)
1114
1172
  // outcome than "the files cannot disagree".
1115
1173
  checksSkipped.push('vault-dir-parity: neither file has a vault-integration: block');
1116
- } else if (instructionFilesAreAliased(claudePath, agentsPath)) {
1117
- // Identical by construction (generated copy, symlink, or hardlink) —
1174
+ } else if (
1175
+ instructionFilesAreAliased(claudePath, agentsPath) ||
1176
+ agentsMdImportsClaudeMd(agentsPath)
1177
+ ) {
1178
+ // Identical by construction (generated copy, symlink, or hardlink), or
1179
+ // AGENTS.md is a config-free `@CLAUDE.md` import pointer the runtime
1180
+ // never reads (see agentsMdImportsClaudeMd) —
1118
1181
  // parity is SATISFIED, so the check RAN and found nothing. Reporting
1119
1182
  // this as a skip would be wrong too: the invariant Check 7 guards is
1120
1183
  // actively held here, it is simply held mechanically rather than by
@@ -1178,10 +1241,19 @@ function main() {
1178
1241
  const learningKeyM = /^learning-key:\s*(.+)$/m.exec(block);
1179
1242
  const expiresAtM = /^expires-at:\s*(.+)$/m.exec(block);
1180
1243
  const evidenceDigestM = /^evidence-digest:\s*(.+)$/m.exec(block);
1244
+ // `expires-at` is read the loader's way (quote-stripped), so a hand-quoted
1245
+ // `"2026-06-01"` is not handed to V8's legacy local-time parser.
1246
+ let expiresAt = expiresAtM ? expiresAtM[1].trim() : null;
1247
+ try {
1248
+ const loaderValue = parseGlobsFrontmatter(mdContent).meta['expires-at'];
1249
+ if (typeof loaderValue === 'string') expiresAt = loaderValue;
1250
+ } catch {
1251
+ // malformed frontmatter for the loader — keep the raw value (fail-open below)
1252
+ }
1181
1253
  return {
1182
1254
  autoGenerated: autoGenM ? autoGenM[1].trim() === 'true' : false,
1183
1255
  learningKey: learningKeyM ? learningKeyM[1].trim() : null,
1184
- expiresAt: expiresAtM ? expiresAtM[1].trim() : null,
1256
+ expiresAt,
1185
1257
  evidenceDigest: evidenceDigestM ? evidenceDigestM[1].trim() : null,
1186
1258
  };
1187
1259
  }
@@ -1281,9 +1353,10 @@ function main() {
1281
1353
  // stored expires_at from the learning entry (both should agree, but the
1282
1354
  // rule file is authoritative for its own expiry).
1283
1355
  const expiryStr = expiresAt ?? storedExpiresAt;
1356
+ // Same predicate as the loader (#1521): a bare date is INCLUSIVE, an
1357
+ // unparseable value fails open.
1284
1358
  if (expiryStr) {
1285
- const expiryMs = Date.parse(expiryStr);
1286
- if (Number.isFinite(expiryMs) && expiryMs < nowMs) {
1359
+ if (isRuleExpired(expiryStr, nowMs)) {
1287
1360
  warnings.push({
1288
1361
  check: 'generated-rule-staleness',
1289
1362
  file: relPath,
@@ -24,7 +24,7 @@
24
24
  * 2. `.claude/rules/*.md` file count (non-recursive) vs. "N rule files" claims.
25
25
  * 3. `skills/` user-facing directory count (excludes `_shared/`) vs.
26
26
  * "N user-facing skills" / "N skills" claims.
27
- * 4. Slash-command count (`commands/*.md` ∪ skills with `user-invocable: true`)
27
+ * 4. Slash-command count (`commands/*.md` ∪ skills not marked `user-invocable: false`)
28
28
  * vs. "N slash-commands" / "N commands" claims.
29
29
  *
30
30
  * Scope exclusions: CHANGELOG.md, docs/adr/, docs/prd/, docs/retro/ are never
@@ -103,8 +103,8 @@ function countUserFacingSkills(root) {
103
103
  }
104
104
  }
105
105
 
106
- // Slash commands = `commands/*.md` ∪ skills with an explicit
107
- // `user-invocable: true` (the #1370 commands→skills fold) — the shared census
106
+ // Slash commands = `commands/*.md` ∪ skills whose `user-invocable` is absent or
107
+ // `true` (the #1370 commands→skills fold; absent = true per #1515) — the shared census
108
108
  // in user-invocable-skills.mjs, not a second copy. Counting `commands/` alone
109
109
  // reported 2 against the real 27 on every run (#1506 pt 7). `null` (entry
110
110
  // skipped) only when the repo has neither source.
@@ -15,7 +15,7 @@ args-schema:
15
15
  - flag: --verify
16
16
  description: "Re-evaluate a stored run-id and diff per-dimension for scoring drift (exit 1 on drift)"
17
17
  description: >
18
- Use this skill to run an honest session-process evaluation (Standard v1, aiat-llm-eval/1.0) — score the last completed orchestrator session against the pre-registered rubric-v2 dimensions, run /eval, evaluate this session, produce an eval report, or re-verify a stored eval run for reproducibility. Deterministic-first with an optional advisory LLM judge; never produces a global score.
18
+ Use this skill to run an honest session-process evaluation (Standard v1, aiat-llm-eval/1.0) — score the last completed orchestrator session against the pre-registered rubric-v3 dimensions, run /eval, evaluate this session, produce an eval report, or re-verify a stored eval run for reproducibility. Deterministic-first with an optional advisory LLM judge; never produces a global score.
19
19
  ---
20
20
 
21
21
  > **Platform Note:** State files use the platform's native directory: `.claude/` (Claude Code), `.codex/` (Codex CLI), or `.cursor/` (Cursor IDE). Shared metrics + the eval journal live in `.orchestrator/metrics/`. See `skills/_shared/platform-tools.md`.
@@ -23,7 +23,7 @@ description: >
23
23
  # Eval Skill — Session-Process Evaluation (aiat-llm-eval/1.0)
24
24
 
25
25
  On-demand, honest measurement of ONE completed orchestrator session against the
26
- pre-registered **rubric-v2** check set. The deterministic engine
26
+ pre-registered **rubric-v3** check set. The deterministic engine
27
27
  (`scripts/eval-session.mjs` → `scripts/lib/eval/engine.mjs`) reads only local
28
28
  metrics files (`sessions.jsonl` + `events.jsonl`), scores the six deterministic
29
29
  dimensions, appends a `session-eval` record to the journal, and optionally
@@ -31,9 +31,10 @@ renders an HTML report. An opt-in LLM judge overlays ONE advisory dimension
31
31
  (`instruction-adherence`; `report-quality` was retired in rubric-v2, #1381).
32
32
 
33
33
  The standard this skill implements is [`docs/eval/aiat-llm-eval-v1.md`](../../docs/eval/aiat-llm-eval-v1.md);
34
- the frozen, content-hashed check set is [`skills/eval/rubric-v2.md`](./rubric-v2.md)
35
- (stored records written before 2026-09-19 carry `rubric-v1` and are read against
36
- [`rubric-v1.md`](./rubric-v1.md), which is never edited again).
34
+ the frozen, content-hashed check set is [`skills/eval/rubric-v3.md`](./rubric-v3.md)
35
+ (stored records carry the version they were scored under: before 2026-09-19
36
+ `rubric-v1` → [`rubric-v1.md`](./rubric-v1.md), 2026-09-19 to 2026-10-05
37
+ `rubric-v2` → [`rubric-v2.md`](./rubric-v2.md); neither is edited again).
37
38
 
38
39
  ## Invocation
39
40
 
@@ -46,7 +47,7 @@ Invoked as `/eval [--session <id>] [--no-write] [--verify <run-id>]` with argume
46
47
 
47
48
  **On-demand `/eval` runs regardless of `eval.enabled`** — that flag gates only the automatic session-end eval phase (see Phase 1.1).
48
49
 
49
- **Seams used:** `scripts/eval-session.mjs` (deterministic CLI) · `runEvalJudge` / `mergeJudgeDimensions` (`scripts/lib/eval/judge.mjs`, opt-in) · `writeEvalReport` (`scripts/lib/eval/report.mjs`) · `appendEvalRecord` (`scripts/lib/eval/sink.mjs`) · the `eval` config block · [`skills/eval/rubric-v2.md`](./rubric-v2.md) (frozen check set).
50
+ **Seams used:** `scripts/eval-session.mjs` (deterministic CLI) · `runEvalJudge` / `mergeJudgeDimensions` (`scripts/lib/eval/judge.mjs`, opt-in) · `writeEvalReport` (`scripts/lib/eval/report.mjs`) · `appendEvalRecord` (`scripts/lib/eval/sink.mjs`) · the `eval` config block · [`skills/eval/rubric-v3.md`](./rubric-v3.md) (frozen check set).
50
51
 
51
52
  ## Posture Contract (load-bearing — read before executing)
52
53
 
@@ -154,7 +155,7 @@ node scripts/eval-session.mjs [--session <id>] --json \
154
155
  Parse the emitted JSON record. It carries `dimensions[]` (6 deterministic
155
156
  entries — the two reported-only ones, `guard-friction` and `efficiency-kpis`,
156
157
  are always `not-applicable`), `kpis{}`, `provenance.rubric_sha256` (the sha256
157
- of `rubric-v2.md`; `null` means the rubric file was not found and the append
158
+ of `rubric-v3.md`; `null` means the rubric file was not found and the append
158
159
  will fail validation), `model`, `harness`, and `run_id`. Unless `--no-write` was
159
160
  passed, the record is already appended to `.orchestrator/metrics/eval.jsonl` by
160
161
  the CLI.
@@ -236,7 +237,7 @@ const res = writeEvalReport(record, { generatedAt: new Date().toISOString() });
236
237
  Emit a compact, honest per-dimension summary. Status lines only — no global score.
237
238
 
238
239
  ```
239
- ## /eval — <session_id> (self-evaluation, aiat-llm-eval/1.0 · rubric-v2 · n=1, no CI)
240
+ ## /eval — <session_id> (self-evaluation, aiat-llm-eval/1.0 · rubric-v3 · n=1, no CI)
240
241
 
241
242
  Deterministic:
242
243
  verification-evidence PASS <one-line evidence>
@@ -276,11 +277,9 @@ node scripts/eval-session.mjs --verify <run-id> --json
276
277
  changed since the record was written — investigate, do not overwrite.
277
278
  - `--verify` reproduces the stored model + timestamp verbatim (no env override),
278
279
  so a MATCH is a real reproducibility proof of the scoring, not of model output.
279
- - **A cross-version DRIFT is not a defect.** A stored `rubric-v1` record
280
- re-scored by today's rubric-v2 engine necessarily differs on `process-safety`
281
- and reports `present-in-fresh-only: guard-friction`. Read the record's
282
- `rubric_version` before treating a diff as a regression (#1400 replaces that
283
- report with an explicit version verdict).
280
+ - **A record from another rubric version is not re-scored.** `--verify` reports
281
+ `VERSION-MISMATCH` (exit 3) when the stored `rubric_version` differs from the
282
+ engine's (#1400), so a v1 or v2 record never reads as a regression under v3.
284
283
 
285
284
  ---
286
285