wicked-crew 0.7.30 → 0.7.31

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 (107) hide show
  1. package/dist/api/chat-scope.d.ts +15 -2
  2. package/dist/api/chat-scope.d.ts.map +1 -1
  3. package/dist/api/chat-scope.js +7 -2
  4. package/dist/api/chat-scope.js.map +1 -1
  5. package/dist/api/eval-sample.d.ts +12 -12
  6. package/dist/api/routes.d.ts +10 -0
  7. package/dist/api/routes.d.ts.map +1 -1
  8. package/dist/api/routes.js +231 -37
  9. package/dist/api/routes.js.map +1 -1
  10. package/dist/api/run-files.d.ts +26 -0
  11. package/dist/api/run-files.d.ts.map +1 -1
  12. package/dist/api/run-files.js +78 -0
  13. package/dist/api/run-files.js.map +1 -1
  14. package/dist/api/seat-health.d.ts +33 -0
  15. package/dist/api/seat-health.d.ts.map +1 -1
  16. package/dist/api/seat-health.js +86 -2
  17. package/dist/api/seat-health.js.map +1 -1
  18. package/dist/api/seat-signin.d.ts +8 -0
  19. package/dist/api/seat-signin.d.ts.map +1 -1
  20. package/dist/api/seat-signin.js +48 -3
  21. package/dist/api/seat-signin.js.map +1 -1
  22. package/dist/api/seat-standing.d.ts +14 -2
  23. package/dist/api/seat-standing.d.ts.map +1 -1
  24. package/dist/api/seat-standing.js +14 -4
  25. package/dist/api/seat-standing.js.map +1 -1
  26. package/dist/api/server.d.ts.map +1 -1
  27. package/dist/api/server.js +41 -4
  28. package/dist/api/server.js.map +1 -1
  29. package/dist/api/skills.d.ts +2 -2
  30. package/dist/api/testing.d.ts +28 -1
  31. package/dist/api/testing.d.ts.map +1 -1
  32. package/dist/api/testing.js +190 -0
  33. package/dist/api/testing.js.map +1 -1
  34. package/dist/campaigns/rollup.d.ts +4 -0
  35. package/dist/campaigns/rollup.d.ts.map +1 -1
  36. package/dist/campaigns/rollup.js.map +1 -1
  37. package/dist/campaigns/routes.d.ts +3 -1
  38. package/dist/campaigns/routes.d.ts.map +1 -1
  39. package/dist/campaigns/routes.js +3 -0
  40. package/dist/campaigns/routes.js.map +1 -1
  41. package/dist/core/adapter.d.ts.map +1 -1
  42. package/dist/core/adapter.js +23 -2
  43. package/dist/core/adapter.js.map +1 -1
  44. package/dist/core/deliver-text.d.ts +7 -0
  45. package/dist/core/deliver-text.d.ts.map +1 -1
  46. package/dist/core/deliver-text.js +41 -2
  47. package/dist/core/deliver-text.js.map +1 -1
  48. package/dist/core/engine-roster.d.ts +68 -0
  49. package/dist/core/engine-roster.d.ts.map +1 -0
  50. package/dist/core/engine-roster.js +156 -0
  51. package/dist/core/engine-roster.js.map +1 -0
  52. package/dist/interactive/chat-events.d.ts.map +1 -1
  53. package/dist/interactive/chat-events.js +26 -4
  54. package/dist/interactive/chat-events.js.map +1 -1
  55. package/dist/interactive/council-outcome.d.ts +28 -1
  56. package/dist/interactive/council-outcome.d.ts.map +1 -1
  57. package/dist/interactive/council-outcome.js +51 -1
  58. package/dist/interactive/council-outcome.js.map +1 -1
  59. package/dist/interactive/demo-events.d.ts.map +1 -1
  60. package/dist/interactive/demo-events.js +26 -4
  61. package/dist/interactive/demo-events.js.map +1 -1
  62. package/dist/interactive/doc-run-index.d.ts +56 -0
  63. package/dist/interactive/doc-run-index.d.ts.map +1 -0
  64. package/dist/interactive/doc-run-index.js +100 -0
  65. package/dist/interactive/doc-run-index.js.map +1 -0
  66. package/dist/interactive/docs-index.d.ts +68 -0
  67. package/dist/interactive/docs-index.d.ts.map +1 -0
  68. package/dist/interactive/docs-index.js +114 -0
  69. package/dist/interactive/docs-index.js.map +1 -0
  70. package/dist/interactive/draft-events.d.ts +18 -0
  71. package/dist/interactive/draft-events.d.ts.map +1 -1
  72. package/dist/interactive/draft-events.js +36 -3
  73. package/dist/interactive/draft-events.js.map +1 -1
  74. package/dist/interactive/edit-events.d.ts.map +1 -1
  75. package/dist/interactive/edit-events.js +26 -4
  76. package/dist/interactive/edit-events.js.map +1 -1
  77. package/dist/interactive/ledger.d.ts +2 -0
  78. package/dist/interactive/ledger.d.ts.map +1 -1
  79. package/dist/interactive/ledger.js +4 -0
  80. package/dist/interactive/ledger.js.map +1 -1
  81. package/dist/qe/author-workflow.d.ts +165 -0
  82. package/dist/qe/author-workflow.d.ts.map +1 -0
  83. package/dist/qe/author-workflow.js +377 -0
  84. package/dist/qe/author-workflow.js.map +1 -0
  85. package/dist/qe/test-sets.d.ts +112 -0
  86. package/dist/qe/test-sets.d.ts.map +1 -0
  87. package/dist/qe/test-sets.js +170 -0
  88. package/dist/qe/test-sets.js.map +1 -0
  89. package/dist/skills/refs.d.ts +37 -0
  90. package/dist/skills/refs.d.ts.map +1 -1
  91. package/dist/skills/refs.js +22 -0
  92. package/dist/skills/refs.js.map +1 -1
  93. package/dist/skills/runtime.d.ts +13 -1
  94. package/dist/skills/runtime.d.ts.map +1 -1
  95. package/dist/skills/runtime.js +88 -1
  96. package/dist/skills/runtime.js.map +1 -1
  97. package/dist/skills/store.d.ts +82 -5
  98. package/dist/skills/store.d.ts.map +1 -1
  99. package/dist/skills/store.js +109 -21
  100. package/dist/skills/store.js.map +1 -1
  101. package/dist/studio/assets/{index-_ydd-jKd.css → index-C0UZ2BxT.css} +1 -1
  102. package/dist/studio/assets/index-Clm0MXDF.js +544 -0
  103. package/dist/studio/index.html +2 -2
  104. package/dist/studio/testid-inventory.json +251 -5
  105. package/endpoint-manifest.json +24 -1
  106. package/package.json +3 -3
  107. package/dist/studio/assets/index-CWUS9Ump.js +0 -542
@@ -118,11 +118,23 @@
118
118
  * (codex round 2: a verification cached by link text was ineffective after its first success; a
119
119
  * snapshot modified under a running daemon is refused by the same store instance). Any failure is
120
120
  * `SkillsCurrentInvalidError` — a loud config error, never a silent "not published".
121
+ *
122
+ * One thing is NOT a failure (F-083): a generation published under OTHER portability rules. Every
123
+ * publish records the rules identity (`rulesVersion` / `rulesSha256` — refs.ts
124
+ * `PORTABILITY_RULES_IDENTITY`); when the running daemon's identity differs, or the snapshot
125
+ * predates the field (every pre-0.7.31 publish), the row re-derivation reports the rows that derive
126
+ * differently as `CurrentSnapshot.drift` and the generation is ACCEPTED — the runtime raises ONE
127
+ * `skills.stale-rules` warning naming them and the re-publish remedy. A rule change is not
128
+ * tampering, and an upgrade must never turn a valid generation into a refusal (0.7.29 → 0.7.30 did
129
+ * exactly that: every seat launched without skills until an operator re-published). Under the SAME
130
+ * identity a row that derives differently is refused as before; a content or metadata hash
131
+ * mismatch is refused under any identity.
121
132
  */
122
- import type { CoreEvent, SkillAnalyzeResult, SkillEntry, SkillFileTree, SkillKind, SkillManifest, SkillMutationResult, SkillPortability, SkillPublishResult, SkillReadResult, SkillRefreshResult, SkillSourceKind, SkillVenvState } from '../core/types.js';
133
+ import type { CoreEvent, SkillAnalyzeResult, SkillConflictFinding, SkillEntry, SkillFileTree, SkillKind, SkillManifest, SkillMutationResult, SkillPortability, SkillPortabilityReason, SkillPublishResult, SkillReadResult, SkillRefreshResult, SkillSourceKind, SkillVenvState } from '../core/types.js';
123
134
  import { NotAPluginRootError } from './bundle.js';
124
135
  import { LiveGenerations } from './live-generations.js';
125
136
  import { type PluginSource } from './plugin-source.js';
137
+ import { type PortabilityRulesIdentity } from './refs.js';
126
138
  /** The root-level names the store creates live in ONE table (`root-names.ts`, design v3.5 §2) — re-exported for the tests that observe the flip. */
127
139
  export { CURRENT_TMP_PREFIX } from './root-names.js';
128
140
  import { type VenvProvisioner } from './venv.js';
@@ -266,12 +278,52 @@ export interface SnapshotManifest {
266
278
  };
267
279
  /** The baseline env's state at publish: `synced` ⇒ `.venv` links it; `skipped` ⇒ no link (nothing to provision). */
268
280
  venv: SkillVenvState;
281
+ /** The portability rules the rows were judged under (F-083): `rulesVersion` = the canonical
282
+ * fixture's `version`, `rulesSha256` = the digest of the live rule table
283
+ * (`PORTABILITY_RULES_IDENTITY`). Written as a PAIR by every publish since 0.7.31; ABSENT on every
284
+ * older generation. `current` verification compares it with the running identity: a generation
285
+ * published under OTHER (or unrecorded) rules is ACCEPTED — its rows are re-derived for readers
286
+ * (`CurrentSnapshot.drift`) and reported as `skills.stale-rules` — never refused for deriving
287
+ * differently. The immutable snapshot is never rewritten; a re-publish records the running identity. */
288
+ rulesVersion?: number;
289
+ rulesSha256?: string;
269
290
  skills: SnapshotSkillRow[];
270
291
  /** The generated delivery views (design v3.2 §4) — today only `copilot`. */
271
292
  views: {
272
293
  copilot: SnapshotView;
273
294
  };
274
295
  }
296
+ /** One skill row whose recorded portability is not what its files derive under the RUNNING rules (F-083). */
297
+ export interface SnapshotRowDrift {
298
+ name: string;
299
+ /** What the generation records: `portable`, and the per-reason claim when the row carries one (`null` on a pre-0.7.30 row). */
300
+ recorded: {
301
+ portable: boolean;
302
+ reasons: SkillPortabilityReason[] | null;
303
+ };
304
+ /** What the row's own files derive under the rules this daemon runs — what a re-publish would record. */
305
+ derived: SkillPortability;
306
+ }
307
+ /**
308
+ * The verified current generation — what `currentSnapshot()` answers, `GET /skills` reports as
309
+ * `current`, and the engine is handed (`path`). `rules` names the portability rules the generation
310
+ * was published under (`recorded`; `null` when the snapshot predates the identity — every
311
+ * pre-0.7.31 publish) beside the ones this daemon runs (`running`); `stale` when they differ or the
312
+ * recorded one is absent. `drift` is the rows that derive differently today — non-empty only under
313
+ * stale rules (under the SAME rules a row that derives differently is tampering, and the generation
314
+ * is refused). `gen` and `path` are the wire shape api-types 0.35.0 declares; `rules` and `drift`
315
+ * are additive (declared by the next api-types cut).
316
+ */
317
+ export interface CurrentSnapshot {
318
+ gen: number;
319
+ path: string;
320
+ rules: {
321
+ recorded: PortabilityRulesIdentity | null;
322
+ running: PortabilityRulesIdentity;
323
+ stale: boolean;
324
+ };
325
+ drift: SnapshotRowDrift[];
326
+ }
275
327
  /** Whether a skill dir is nested: anything deeper than `skills/<dir>`. */
276
328
  export declare function isNestedSkillDir(dir: string): boolean;
277
329
  export interface SeedResult {
@@ -386,10 +438,7 @@ export declare class SkillsStore {
386
438
  * link text (codex round 2): the answer holds for the daemon's whole lifetime only because it is
387
439
  * re-derived each time it is handed out.
388
440
  */
389
- currentSnapshot(): {
390
- gen: number;
391
- path: string;
392
- } | null;
441
+ currentSnapshot(): CurrentSnapshot | null;
393
442
  private verifyCurrent;
394
443
  /**
395
444
  * Re-derive every claim of a skill row from the generation's OWN files (codex round 7; the
@@ -401,6 +450,12 @@ export declare class SkillsStore {
401
450
  * registered set may legitimately move afterwards), so it is authenticated by the metadata hash
402
451
  * rather than re-derived. Read-only mode bits are re-checked by nobody: they are a guard against
403
452
  * accidents, never the integrity boundary — the hashes are.
453
+ *
454
+ * `staleRules` (F-083): the generation records a portability rules identity other than the running
455
+ * one (or none). The portability re-derivation then answers the rows that derive differently as
456
+ * `drift` instead of a problem — the bytes are authenticated, only the verdict moved. Everything
457
+ * else (a missing SKILL.md, a kind claim, the view shape against the RECORDED rows) is judged the
458
+ * same under any rules: none of it depends on the rule table.
404
459
  */
405
460
  private snapshotRowsProblem;
406
461
  /** Hash over a snapshot tree — files (`snapshot.json` excluded), link entries (path + link text) AND directory entries (codex round 9: an extra empty directory changes it). */
@@ -639,6 +694,28 @@ export declare class SkillsStore {
639
694
  private publishedBundleView;
640
695
  /** The recompute's refusals as WARNINGS — for a mutation that landed on another skill (the blocking form is publish's). */
641
696
  private recomputeWarnings;
697
+ /**
698
+ * Re-derive every manifest entry's derived fields under the RUNNING portability rules and commit
699
+ * when any moved (F-083, review M2). `recomputeDerived` otherwise runs only on seed / refresh /
700
+ * mutation / publish — never at boot — so after an upgrade `GET /skills` kept the previous daemon's
701
+ * verdicts beside a `current.drift` that said otherwise: two halves of one response disagreeing.
702
+ * The runtime calls this when the current generation is STALE (its recorded rules identity is not
703
+ * the running one). The manifest is the EDITOR side — judged over `effective/` against the running
704
+ * rules, what the next publish would record; the snapshot is what seats run by, and it is never
705
+ * rewritten. Commits ONLY when a `kind` / `core` / `portable` / `portability` value actually
706
+ * changed, so a stale-but-agreeing root does not move its revision on every boot (idempotent).
707
+ * Answers the entries whose `portable` moved and the recompute's path refusals (warnings — a
708
+ * refused skill keeps its previous values, as everywhere else).
709
+ */
710
+ rederiveUnderRunningRules(): {
711
+ moved: Array<{
712
+ name: string;
713
+ from: boolean;
714
+ to: boolean;
715
+ }>;
716
+ refused: SkillConflictFinding[];
717
+ revision: number;
718
+ };
642
719
  /**
643
720
  * The bytes of the REGULAR file at plugin-relative `rel` in `effective/`, every component
644
721
  * lstat-walked from the skills root (`containedEffective`; a link anywhere on the way is a
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/skills/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/skills/store.ts"],"names":[],"mappings":"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"}
@@ -118,6 +118,17 @@
118
118
  * (codex round 2: a verification cached by link text was ineffective after its first success; a
119
119
  * snapshot modified under a running daemon is refused by the same store instance). Any failure is
120
120
  * `SkillsCurrentInvalidError` — a loud config error, never a silent "not published".
121
+ *
122
+ * One thing is NOT a failure (F-083): a generation published under OTHER portability rules. Every
123
+ * publish records the rules identity (`rulesVersion` / `rulesSha256` — refs.ts
124
+ * `PORTABILITY_RULES_IDENTITY`); when the running daemon's identity differs, or the snapshot
125
+ * predates the field (every pre-0.7.31 publish), the row re-derivation reports the rows that derive
126
+ * differently as `CurrentSnapshot.drift` and the generation is ACCEPTED — the runtime raises ONE
127
+ * `skills.stale-rules` warning naming them and the re-publish remedy. A rule change is not
128
+ * tampering, and an upgrade must never turn a valid generation into a refusal (0.7.29 → 0.7.30 did
129
+ * exactly that: every seat launched without skills until an operator re-published). Under the SAME
130
+ * identity a row that derives differently is refused as before; a content or metadata hash
131
+ * mismatch is refused under any identity.
121
132
  */
122
133
  import { randomBytes } from 'node:crypto';
123
134
  import { chmodSync, existsSync, lstatSync, mkdirSync, readdirSync, readlinkSync, realpathSync, renameSync, rmSync, statSync, symlinkSync, } from 'node:fs';
@@ -131,7 +142,7 @@ import { derivedSkillName, parseFrontmatter, PLUGIN_NAME, SKILL_NAME_PREFIX, ski
131
142
  import { collisionGuard, coreDisableGuard, finding, frontmatterGuard, nameGuard, nestedSkillCreateGuard, noBaselineGuard, nonPortableGuard, SKILL_NAME_RE, supportFileGuard, verdictOf, } from './guards.js';
132
143
  import { LiveGenerations } from './live-generations.js';
133
144
  import { discoverLivePluginDetailed, gitStateOf, PluginSourceSymlinkError } from './plugin-source.js';
134
- import { existsIn, extractPluginRootRefs, extractRelativeRefs, looksBinary, PORTABILITY_EVIDENCE_CAP, PORTABILITY_REASONS, portabilityEvidenceOf, portabilityIssuesOf, portabilityReasonsOf, resolvePluginRootRef, resolveRelativeRef, } from './refs.js';
145
+ import { existsIn, extractPluginRootRefs, extractRelativeRefs, looksBinary, PORTABILITY_EVIDENCE_CAP, PORTABILITY_REASONS, PORTABILITY_RULES_IDENTITY, portabilityEvidenceOf, portabilityIssuesOf, portabilityReasonsOf, resolvePluginRootRef, resolveRelativeRef, } from './refs.js';
135
146
  import { CURRENT_TMP_PREFIX, STAGING_PREFIX } from './root-names.js';
136
147
  import { assertNoSymlinkComponents, copyFiles, EntrySwappedError, hashFileSet, hashTree, impliedDirs, isCarriedFile, makeTreeReadOnly, pruneEmptyDirs, readFileNoFollow, removeTreeForce, sha256Hex, SKIP_DIR_NAMES, SymlinkComponentError, walkEntries, walkFiles, walkTree, writeFileAtomic, } from './tree.js';
137
148
  /** The root-level names the store creates live in ONE table (`root-names.ts`, design v3.5 §2) — re-exported for the tests that observe the flip. */
@@ -906,13 +917,22 @@ export class SkillsStore {
906
917
  if (hash !== parsed.contentHash) {
907
918
  return invalid(`content hash mismatch — snapshot.json records ${parsed.contentHash}, the tree hashes ${hash}: the immutable snapshot was modified`);
908
919
  }
909
- const rowProblem = this.snapshotRowsProblem(parsed, tree);
910
- if (rowProblem !== null)
911
- return invalid(rowProblem);
920
+ // The rules identity (F-083): the generation records which portability rule table judged its
921
+ // rows; this daemon carries its own. A DIFFERENT (or unrecorded — every pre-0.7.31 publish)
922
+ // identity means the rows may derive differently today without a byte having changed — a rule
923
+ // change is not tampering, so the row re-derivation reports drift instead of refusing. Under the
924
+ // SAME identity a row that derives differently IS a refusal, as before. The identity is compared,
925
+ // never trusted to name anything: the hashes above already authenticated every byte.
926
+ const running = { ...PORTABILITY_RULES_IDENTITY };
927
+ const recorded = parsed.rulesVersion === undefined || parsed.rulesSha256 === undefined ? null : { version: parsed.rulesVersion, sha256: parsed.rulesSha256 };
928
+ const stale = recorded === null || recorded.version !== running.version || recorded.sha256 !== running.sha256;
929
+ const rows = this.snapshotRowsProblem(parsed, tree, stale);
930
+ if ('problem' in rows)
931
+ return invalid(rows.problem);
912
932
  const linkProblem = this.snapshotLinkProblem(real, tree.links, parsed);
913
933
  if (linkProblem !== null)
914
934
  return invalid(linkProblem);
915
- return { gen: parsed.gen, path: real };
935
+ return { gen: parsed.gen, path: real, rules: { recorded, running, stale }, drift: rows.drift };
916
936
  }
917
937
  /**
918
938
  * Re-derive every claim of a skill row from the generation's OWN files (codex round 7; the
@@ -924,8 +944,16 @@ export class SkillsStore {
924
944
  * registered set may legitimately move afterwards), so it is authenticated by the metadata hash
925
945
  * rather than re-derived. Read-only mode bits are re-checked by nobody: they are a guard against
926
946
  * accidents, never the integrity boundary — the hashes are.
947
+ *
948
+ * `staleRules` (F-083): the generation records a portability rules identity other than the running
949
+ * one (or none). The portability re-derivation then answers the rows that derive differently as
950
+ * `drift` instead of a problem — the bytes are authenticated, only the verdict moved. Everything
951
+ * else (a missing SKILL.md, a kind claim, the view shape against the RECORDED rows) is judged the
952
+ * same under any rules: none of it depends on the rule table.
927
953
  */
928
- snapshotRowsProblem(parsed, tree) {
954
+ snapshotRowsProblem(parsed, tree, staleRules) {
955
+ const problem = (detail) => ({ problem: detail });
956
+ const drift = [];
929
957
  const files = tree.files;
930
958
  const byRel = new Map(files.map((f) => [f.rel, f]));
931
959
  const dirs = new Set(parsed.skills.map((r) => r.dir));
@@ -937,13 +965,13 @@ export class SkillsStore {
937
965
  for (const row of parsed.skills) {
938
966
  const skillMd = byRel.get(`${row.dir}/SKILL.md`);
939
967
  if (skillMd === undefined)
940
- return `skill row ${row.name} names ${row.dir}, but the generation carries no ${row.dir}/SKILL.md`;
968
+ return problem(`skill row ${row.name} names ${row.dir}, but the generation carries no ${row.dir}/SKILL.md`);
941
969
  const fm = parseFrontmatter(readFileNoFollow(skillMd.abs).toString('utf8'));
942
970
  if (!fm.ok)
943
- return `${row.dir}/SKILL.md frontmatter does not parse (${fm.reason}) — its row cannot be re-derived`;
971
+ return problem(`${row.dir}/SKILL.md frontmatter does not parse (${fm.reason}) — its row cannot be re-derived`);
944
972
  const kind = skillKindOf(fm.fields);
945
973
  if (kind !== row.kind)
946
- return `skill row ${row.name} claims kind ${row.kind}, but its SKILL.md derives ${kind}`;
974
+ return problem(`skill row ${row.name} claims kind ${row.kind}, but its SKILL.md derives ${kind}`);
947
975
  const hits = [];
948
976
  const prefix = `${row.dir}/`;
949
977
  for (const f of files) {
@@ -952,16 +980,27 @@ export class SkillsStore {
952
980
  const buf = readFileNoFollow(f.abs);
953
981
  if (looksBinary(buf))
954
982
  continue;
955
- hits.push(...portabilityIssuesOf(buf.toString('utf8'), { fileRel: f.rel, skillDir: row.dir, skillDirs: dirs, exists }));
983
+ for (const hit of portabilityIssuesOf(buf.toString('utf8'), { fileRel: f.rel, skillDir: row.dir, skillDirs: dirs, exists }))
984
+ hits.push({ ...hit, fileRel: f.rel });
956
985
  }
957
986
  const reasons = portabilityReasonsOf(hits);
958
987
  const portable = reasons.length === 0;
959
- if (portable !== row.portable)
960
- return `skill row ${row.name} claims portable: ${String(row.portable)}, but its files derive ${String(portable)}`;
961
- // The per-reason claim (F-079) is re-derived too — a row cannot name reasons its files do not carry.
962
- if (row.portability !== undefined && !sameStrings(row.portability.reasons, reasons)) {
963
- return `skill row ${row.name} claims portability reasons [${row.portability.reasons.join(', ')}], but its files derive [${reasons.join(', ')}]`;
964
- }
988
+ const recordedReasons = row.portability?.reasons ?? null;
989
+ // The per-reason claim (F-079) is re-derived like `portable` is — a row cannot name reasons its files do not carry.
990
+ const differs = portable !== row.portable || (recordedReasons !== null && !sameStrings(recordedReasons, reasons));
991
+ if (!differs)
992
+ continue;
993
+ if (!staleRules) {
994
+ if (portable !== row.portable)
995
+ return problem(`skill row ${row.name} claims portable: ${String(row.portable)}, but its files derive ${String(portable)}`);
996
+ return problem(`skill row ${row.name} claims portability reasons [${(recordedReasons ?? []).join(', ')}], but its files derive [${reasons.join(', ')}]`);
997
+ }
998
+ // Published under OTHER rules (F-083): the same authenticated bytes, a different verdict — drift, not tampering.
999
+ drift.push({
1000
+ name: row.name,
1001
+ recorded: { portable: row.portable, reasons: recordedReasons === null ? null : [...recordedReasons] },
1002
+ derived: { portable, reasons, evidence: portabilityEvidenceOf(hits) },
1003
+ });
965
1004
  }
966
1005
  // The copilot view as a WHOLE tree (codex round 9): EXACTLY `views/copilot/.github/skills/<name>/…`
967
1006
  // for the sorted portable rows — the files each row owns, the directories they imply — and nothing
@@ -984,18 +1023,18 @@ export class SkillsStore {
984
1023
  const shape = `the copilot view is exactly ${COPILOT_VIEW_SKILLS_REL}/<name>/… for [${expectedView.join(', ')}] (each skill's own files and the directories they imply); a view entry is missing or extra`;
985
1024
  for (const f of files)
986
1025
  if (underViews(f.rel) && !expectedFiles.has(f.rel))
987
- return `unexpected view file ${f.rel} — ${shape}`;
1026
+ return problem(`unexpected view file ${f.rel} — ${shape}`);
988
1027
  for (const d of tree.dirs)
989
1028
  if (underViews(d) && !expectedDirs.has(d))
990
- return `unexpected view directory ${d} — ${shape}`;
1029
+ return problem(`unexpected view directory ${d} — ${shape}`);
991
1030
  for (const f of expectedFiles)
992
1031
  if (!byRel.has(f))
993
- return `the copilot view is missing ${f} — ${shape}`;
1032
+ return problem(`the copilot view is missing ${f} — ${shape}`);
994
1033
  const dirSet = new Set(tree.dirs);
995
1034
  for (const d of expectedDirs)
996
1035
  if (!dirSet.has(d))
997
- return `the copilot view is missing directory ${d} — ${shape}`;
998
- return null;
1036
+ return problem(`the copilot view is missing directory ${d} — ${shape}`);
1037
+ return { drift };
999
1038
  }
1000
1039
  /** Hash over a snapshot tree — files (`snapshot.json` excluded), link entries (path + link text) AND directory entries (codex round 9: an extra empty directory changes it). */
1001
1040
  snapshotHash(tree) {
@@ -1127,6 +1166,18 @@ export class SkillsStore {
1127
1166
  }
1128
1167
  if (!VENV_STATES.has(String(s.venv)))
1129
1168
  return `${SNAPSHOT_MANIFEST_FILENAME} has no venv state (${[...VENV_STATES].join('|')})`;
1169
+ // The rules identity (F-083) is optional as a PAIR — absent on every generation published before
1170
+ // 0.7.31 — and typed when present: an integer version ≥ 1 and a 64-hex digest. It is compared,
1171
+ // never trusted to name anything; a half-recorded or malformed pair is not what publish writes.
1172
+ const hasVersion = Object.hasOwn(s, 'rulesVersion');
1173
+ const hasSha = Object.hasOwn(s, 'rulesSha256');
1174
+ if (hasVersion !== hasSha) {
1175
+ return `${SNAPSHOT_MANIFEST_FILENAME} records ${hasVersion ? 'rulesVersion without rulesSha256' : 'rulesSha256 without rulesVersion'} — the portability rules identity is written as a pair`;
1176
+ }
1177
+ if (hasVersion && (typeof s.rulesVersion !== 'number' || !Number.isInteger(s.rulesVersion) || s.rulesVersion < 1))
1178
+ return `${SNAPSHOT_MANIFEST_FILENAME} rulesVersion is not an integer ≥ 1`;
1179
+ if (hasSha && (typeof s.rulesSha256 !== 'string' || !CONTENT_HASH_RE.test(s.rulesSha256)))
1180
+ return `${SNAPSHOT_MANIFEST_FILENAME} rulesSha256 is not a sha256 hex digest`;
1130
1181
  if (!isSnapshotViews(s.views, s.skills)) {
1131
1182
  return `${SNAPSHOT_MANIFEST_FILENAME} has no well-formed views block ({copilot: {dir: "${COPILOT_VIEW_REL}", skills: EXACTLY the sorted portable names}})`;
1132
1183
  }
@@ -1914,6 +1965,38 @@ export class SkillsStore {
1914
1965
  recomputeWarnings(m) {
1915
1966
  return this.recomputeDerived(m).map((f) => ({ ...f, severity: 'warning' }));
1916
1967
  }
1968
+ /**
1969
+ * Re-derive every manifest entry's derived fields under the RUNNING portability rules and commit
1970
+ * when any moved (F-083, review M2). `recomputeDerived` otherwise runs only on seed / refresh /
1971
+ * mutation / publish — never at boot — so after an upgrade `GET /skills` kept the previous daemon's
1972
+ * verdicts beside a `current.drift` that said otherwise: two halves of one response disagreeing.
1973
+ * The runtime calls this when the current generation is STALE (its recorded rules identity is not
1974
+ * the running one). The manifest is the EDITOR side — judged over `effective/` against the running
1975
+ * rules, what the next publish would record; the snapshot is what seats run by, and it is never
1976
+ * rewritten. Commits ONLY when a `kind` / `core` / `portable` / `portability` value actually
1977
+ * changed, so a stale-but-agreeing root does not move its revision on every boot (idempotent).
1978
+ * Answers the entries whose `portable` moved and the recompute's path refusals (warnings — a
1979
+ * refused skill keeps its previous values, as everywhere else).
1980
+ */
1981
+ rederiveUnderRunningRules() {
1982
+ const m = this.manifest();
1983
+ const derived = (e) => JSON.stringify({ kind: e.kind, core: e.core, portable: e.portable, portability: e.portability ?? null });
1984
+ const before = new Map(Object.entries(m.skills).map(([name, e]) => [name, { key: derived(e), portable: e.portable }]));
1985
+ const refused = this.recomputeWarnings(m);
1986
+ const moved = [];
1987
+ let changed = false;
1988
+ for (const [name, e] of Object.entries(m.skills)) {
1989
+ const was = before.get(name);
1990
+ if (was === undefined || was.key === derived(e))
1991
+ continue;
1992
+ changed = true;
1993
+ if (was.portable !== e.portable)
1994
+ moved.push({ name, from: was.portable, to: e.portable });
1995
+ }
1996
+ if (changed)
1997
+ this.commit(m);
1998
+ return { moved, refused, revision: m.revision };
1999
+ }
1917
2000
  /**
1918
2001
  * The bytes of the REGULAR file at plugin-relative `rel` in `effective/`, every component
1919
2002
  * lstat-walked from the skills root (`containedEffective`; a link anywhere on the way is a
@@ -3175,6 +3258,11 @@ export class SkillsStore {
3175
3258
  baseline: m.baseline,
3176
3259
  },
3177
3260
  venv,
3261
+ // The rules identity the rows were judged under (F-083) — what `current` verification compares
3262
+ // with the running daemon's: a later daemon with other rules accepts this generation and reports
3263
+ // the rows that now derive differently (`skills.stale-rules`) instead of refusing the root.
3264
+ rulesVersion: PORTABILITY_RULES_IDENTITY.version,
3265
+ rulesSha256: PORTABILITY_RULES_IDENTITY.sha256,
3178
3266
  skills: v.enabledSkills
3179
3267
  .map(({ name, entry }) => ({
3180
3268
  name,