@entrorove/skill 0.1.73 → 0.1.78

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 (65) hide show
  1. package/CAPABILITY-MAP.md +5 -0
  2. package/CHANGELOG.md +37 -0
  3. package/DESIGN-GATES.md +5 -9
  4. package/DESIGN-STAGED-ACCEPTANCE.md +103 -0
  5. package/IDE-EXECUTION.md +21 -4
  6. package/REUSE-DISCIPLINE.md +3 -3
  7. package/SKILL.md +14 -4
  8. package/cli.mjs +8 -4
  9. package/cloud-mutation-authority.mjs +8 -2
  10. package/cloud-task-client.mjs +10 -0
  11. package/cloud-watch-client.mjs +8 -2
  12. package/design-browser-checks.mjs +18 -5
  13. package/design-browser-pages.mjs +96 -0
  14. package/design-browser-state.mjs +1 -0
  15. package/design-browser.mjs +36 -40
  16. package/design-contracts.mjs +4 -1
  17. package/design-declaration.mjs +3 -0
  18. package/design-frameworks.mjs +2 -1
  19. package/design-gate.mjs +3 -0
  20. package/design-operations.mjs +4 -1
  21. package/design-policy.mjs +12 -4
  22. package/design-release.mjs +6 -0
  23. package/design-research-network.mjs +82 -0
  24. package/design-research.mjs +8 -25
  25. package/design-runner.mjs +3 -0
  26. package/design-stage-contracts.mjs +12 -0
  27. package/design-stage.mjs +78 -0
  28. package/design-storage.mjs +63 -0
  29. package/fs-request-trace.mjs +67 -0
  30. package/local-contracts.mjs +1 -1
  31. package/local-discipline-repository.mjs +4 -2
  32. package/local-invocations.mjs +6 -0
  33. package/local-mutation-files.mjs +13 -5
  34. package/local-probe.mjs +8 -4
  35. package/local-recovery-budget.mjs +31 -0
  36. package/local-scope-repository.mjs +18 -3
  37. package/local-scope-signature.mjs +2 -2
  38. package/local-source-execution.mjs +47 -0
  39. package/manifest.json +1 -1
  40. package/mutation-challenge-refresh.mjs +3 -0
  41. package/mutation-client.mjs +17 -5
  42. package/native-client.mjs +4 -1
  43. package/package.json +14 -1
  44. package/release-state.json +63 -50
  45. package/release.mjs +6 -1
  46. package/releases.json +30 -0
  47. package/remote-capability-cache.mjs +20 -0
  48. package/remote-client.mjs +24 -4
  49. package/scope-amendment-client.mjs +62 -6
  50. package/scope-amendment-observer.mjs +9 -3
  51. package/scope-amendment-remote.mjs +20 -6
  52. package/scope-amendment-retirement.mjs +4 -2
  53. package/scope-amendment-state.mjs +9 -5
  54. package/scope-context-client.mjs +7 -0
  55. package/scope-context-journal.mjs +8 -2
  56. package/scope-context-remote.mjs +16 -5
  57. package/scope-evidence-remote.mjs +16 -7
  58. package/scope-runner-client.mjs +34 -7
  59. package/scope-runner-journal.mjs +82 -5
  60. package/scope-write-observation.d.mts +4 -0
  61. package/scope-write-observation.mjs +43 -0
  62. package/service-prerequisite.mjs +87 -0
  63. package/task-entry-client.mjs +3 -0
  64. package/workflow-observation-client.mjs +2 -0
  65. package/workflow-observation-remote.mjs +13 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@entrorove/skill",
3
- "version": "0.1.73",
3
+ "version": "0.1.78",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "entrorove": "cli.mjs"
@@ -14,6 +14,8 @@
14
14
  "local-contracts.mjs",
15
15
  "local-contract-types.mjs",
16
16
  "local-state-lock.mjs",
17
+ "local-recovery-budget.mjs",
18
+ "remote-capability-cache.mjs",
17
19
  "local-stage-boundary.mjs",
18
20
  "local-execution.mjs",
19
21
  "local-swarm-authority.mjs",
@@ -88,6 +90,9 @@
88
90
  "local-task-handoff-write-archive.mjs",
89
91
  "local-task-handoff-write-receipts.mjs",
90
92
  "remote-client.mjs",
93
+ "service-prerequisite.mjs",
94
+ "local-source-execution.mjs",
95
+ "fs-request-trace.mjs",
91
96
  "scope-runner-client.mjs",
92
97
  "scope-context-client.mjs",
93
98
  "scope-context-observer.mjs",
@@ -168,6 +173,8 @@
168
173
  "local-scope-create-require.mjs",
169
174
  "local-scope-require-resolution.mjs",
170
175
  "local-scope-repository.mjs",
176
+ "scope-write-observation.mjs",
177
+ "scope-write-observation.d.mts",
171
178
  "local-scope-signature.mjs",
172
179
  "local-scope-config-imports.mjs",
173
180
  "local-scope-config-extends.mjs",
@@ -288,6 +295,7 @@
288
295
  "member-producer-repair-authority.mjs",
289
296
  "design-browser-checks.mjs",
290
297
  "design-browser-identity.mjs",
298
+ "design-browser-pages.mjs",
291
299
  "design-browser-state.mjs",
292
300
  "design-browser.mjs",
293
301
  "design-context.mjs",
@@ -302,10 +310,15 @@
302
310
  "design-policy.d.mts",
303
311
  "design-policy.mjs",
304
312
  "design-research.mjs",
313
+ "design-research-network.mjs",
305
314
  "design-runner.mjs",
306
315
  "design-store.mjs",
316
+ "design-stage.mjs",
317
+ "design-stage-contracts.mjs",
318
+ "design-storage.mjs",
307
319
  "design-ui.mjs",
308
320
  "DESIGN-GATES.md",
321
+ "DESIGN-STAGED-ACCEPTANCE.md",
309
322
  "design-release.mjs",
310
323
  "install-identity.mjs",
311
324
  "package-archive.mjs",
@@ -1,8 +1,12 @@
1
1
  {
2
2
  "schemaVersion": "entrorove.release-state/1.0",
3
- "version": "0.1.73",
4
- "digest": "06693e8422b76b4037a70c0be657104b918234d74fa4c5dd1e29a394d5c83e0e",
3
+ "version": "0.1.78",
4
+ "digest": "0c66f92de864ffddbaa006725eb8177f5a57cd138359d03700c04ef262ef914d",
5
5
  "files": {
6
+ "local-recovery-budget.mjs": "be3af07db8e4cc96782edb130e827039c7a99bbe8275a92f0f741533716017f3",
7
+ "remote-capability-cache.mjs": "9c22067e1a21eb2a209747a8ab2f27c0496b14a22a7e0f5654840e2035148df0",
8
+ "scope-write-observation.mjs": "d832adce75cbe005d683bc6bd2571220e13ad7b0651235688b02993e8f2c3796",
9
+ "scope-write-observation.d.mts": "52fb0b805494d83673fb4d0ffb5f6b1bc39854b400a8799fe2446681696ed8b3",
6
10
  "release-source-groups.mjs": "876b8c8bcf459d3b469bf4f2021d4206de5b199add545597a5c8f6dea7385b38",
7
11
  "local-scope-build-read.mjs": "361d4b461cfa2c77b4ec22bc59a0a1c78fed2cfb0ea2e05a8da5c2551ecd88ac",
8
12
  "local-scope-build-io.mjs": "8af69722738fa094780f9a2dfcddaf12993fc3b936a75c56c4b0d4f90cb20fd1",
@@ -11,15 +15,15 @@
11
15
  "local-scope-build-readset.mjs": "fd1cb1470c54b3902a4612056281746e947cf96d1f5c03a09ea0becbcd79cc45",
12
16
  "scope-evidence-wire.mjs": "d283bbfd002b034e1deb539633b4970b430a97065388288ab3398e2bc0285633",
13
17
  "scope-evidence-local.mjs": "25b22ba2cc5a17978d2422e290ee015299f05d639b4b4b9551001afefab55c0d",
14
- "scope-evidence-remote.mjs": "27077bb8238f3d11e6e18453e2ea8a6e096a104bbee5ee43a82b8c099d253c1e",
15
- "scope-runner-journal.mjs": "cddb2f20a2812e8bcc3268d8ebdd486c22d0c7f5740e958d0b35cd2cc8819f92",
16
- "scope-context-client.mjs": "115d82022f71396bab137e9af06421a6d0aa9671838f0df64e6aa83d9d7fb039",
18
+ "scope-evidence-remote.mjs": "41da8f314ecc825a5d8b7f88c1975e651da2bca0a7164441ee540e98cbe8a2ea",
19
+ "scope-runner-journal.mjs": "223936b34ceec6d44246d7852218bd15b3fb9e38386bb68571863d17f7db2fb2",
20
+ "scope-context-client.mjs": "fa2e2128e1ccea6df7e100ca8406052ddef531bb542e580621ffd5f06c9fa0ae",
17
21
  "scope-context-observer.mjs": "25a84339512c1e80711aca53baed20da556fa2ae5d84e83fa95d58dcdca7cf7d",
18
22
  "scope-context-observation.mjs": "d92f2fca3c923caa6f0c5c9cc60b4f12bdae212071da64da6692e3e99b251969",
19
- "scope-context-remote.mjs": "cbcef3fb0b9e1cf11b68f877c227ac9b0c617432221dc6e661bce9bc4667b87a",
23
+ "scope-context-remote.mjs": "3c2bdf4f67c91ec25f808438dcfddc195a1740032588109bb3676cc88eb8215f",
20
24
  "scope-context-state.mjs": "dc47da57e411ef11677560a767f2e6d50f8a2fae17706b44715d8cd115ffcf8e",
21
25
  "scope-context-wire.mjs": "1aa8c86223e54927a209de59d3514393b4c905ee2fc520d49819aec0f1e97162",
22
- "scope-context-journal.mjs": "0d9aa1315204d3600f62075fe9a4b0b958b21a04c3a50a743eb5dce1eb16e18a",
26
+ "scope-context-journal.mjs": "deb80ec08345d65951e0ecc45c50196fb86a24870fdb609bf669b23de2fac08b",
23
27
  "scope-context-release.mjs": "3b6f5d3bf7abe25e1a1edd0521053f4c1b1e3487b7f37d5f7c6080d32bc0c044",
24
28
  "cloud-locale.mjs": "0627ac75b98b439563b61ab217aacb55a099c1d0c8ed3b118776d2007c52dd70",
25
29
  "cloud-locale.d.mts": "aff4bced9bbac140f73fd0de24681287349389be5750d89d96abe0f8a2167664",
@@ -27,10 +31,10 @@
27
31
  "model-images.mjs": "ab85ac0c44d857c1f460de3e9c06eb1d37b57688b4a6061405c0a44ae4d40bd7",
28
32
  "model-images.d.mts": "f1506cfb8ad287869f92f4d9074c7c759c6c28b182aeb325dd5f22a38926f24c",
29
33
  "cli-input.mjs": "44dc2692714023b622a9370c13cabc09c7c39e6aea6e7183b80ae5bcd2e8d24e",
30
- "scope-amendment-retirement.mjs": "849f2b5fc8ec5204d7a58222f7ee775b7514244b854439ef3549563cd44c14c2",
34
+ "scope-amendment-retirement.mjs": "44ceec3200c4b1e8fb45e38436f34e173803b5051074d6041a670bb8c4bc2215",
31
35
  "scope-amendment-consumption.mjs": "12a1dfd1429350cc9503957224398524c077aed6c697228c9870aa95c245ee7d",
32
36
  "mutation-connection-state.mjs": "05bed65a4636a2128e9a48d2e910c5f5a25f0e990f181f58008dd09cac0fbcb5",
33
- "mutation-challenge-refresh.mjs": "eac9b18bdfbd968d815321e66c4f6e482fb1be59662abb9dc8b02f35b9ced809",
37
+ "mutation-challenge-refresh.mjs": "f24be466c65bdea543e23e71c4c2d8f65ab611a0380a1464e45908e7f35c3e3b",
34
38
  "local-scope-font.mjs": "a69f9da932ed41aa4718036f98f75c0b17ba7f616a5c8bf5623fa9ed697499fa",
35
39
  "local-scope-zip.mjs": "46c61d201a570c769fc4896fc19090e790765af5f28596557a288bd9b762c69e",
36
40
  "member-producer-repair-authority.mjs": "1e84e5e77ba5ee9a0dcaa4d843061c7b5447191852d7b2fb603b91cfa7c796e4",
@@ -44,9 +48,9 @@
44
48
  "local-approved-supervisor.mjs": "87142a4c13d27c8265cc1fd7fc9088988da9bbb02134164e1a7c5417da926ac7",
45
49
  "local-mutation-consumption.mjs": "1b033655f817ec576410b7f91f1640b8651f3cff0668154fb8e6e14e7b31d8f4",
46
50
  "workflow-local-acceptance.mjs": "743ae19c1edff473af2596c7356ddff3892ff9acfb3bcaa660b662eacba463a8",
47
- "workflow-observation-client.mjs": "5032a6cd7d1e0fa6b80170a7c1298cf14f2c21cf017426465aa48e2a944bcf08",
51
+ "workflow-observation-client.mjs": "f7b0162097f5d4b276263243fed4a4745caa7f8f7010519a0e0e506b7771b2b0",
48
52
  "workflow-observation-connection.mjs": "b1958417d9f94bf7b9474c69acc82fa5de7f7c4e37aa7f3977a8f7e3836a82b1",
49
- "workflow-observation-remote.mjs": "3a444cab88b426e6af018625cfb4aaddcc5d7c05c505ed18715494dd18a6e1de",
53
+ "workflow-observation-remote.mjs": "9d4120b94892e58b815f7dfcc1773623749fd5d75b0bb0f4a7548b60412fd8e6",
50
54
  "workflow-observation-runner.mjs": "3eb8280ec7abffcb30398e3f4e5f7d0ec3df4385fa720f188ed83757b87cd977",
51
55
  "workflow-observation-state.mjs": "a525046df9b3de75b10d2bf35c2b6d7719f12a647e4aee1f1e85dbdbfb167321",
52
56
  "workflow-observation-wire.mjs": "df0d5e4f8fde0be8bf06c6c4590cd158b4da05ebe6ef3169d2366db706f3327f",
@@ -55,8 +59,8 @@
55
59
  "local-preserved-mutation-state.mjs": "337a172b2d0a03b0d5a89b8483afdd9a043a4999fe38f87679633c98c450126b",
56
60
  "local-preserved-mutation-wire.mjs": "6768ce5713d70f7c0bd05f2286bc4b32cd9b8bb1d3c8b9cc7a451cb9b176824d",
57
61
  "local-delegated-modify-analysis.mjs": "f8769bd9890a041be48db5cb6724873d59300c102a5ddaf0a937e5e4f3f1983a",
58
- "mutation-client.mjs": "8f1066db3246f7639dd0b557e7b2c6175181e52f9087146e218d0912f791808e",
59
- "cloud-mutation-authority.mjs": "c7226e882a4f3be4d2f55728f515d5a815c0aa1f21aa5e4689314e6e6a8c66a2",
62
+ "mutation-client.mjs": "7c5651e12fef417f5f61e71ba6aef3c69d7381a162adbe38c1c61d7234d812ff",
63
+ "cloud-mutation-authority.mjs": "8898b4e5cd18b3574523d58d0b6337f72869c6e3ae58dcffe827f36f551700d3",
60
64
  "ide-code-mode.mjs": "f8ba4de33632ab4c6df52dab52f392414b4632c7e94b218b8065677970c075c7",
61
65
  "ide-command.mjs": "b3c008816f53e3cd3aa97bc792baf0b7fc068e839b150bd2cfc6cb06d17a6825",
62
66
  "ide-hook.mjs": "688e39193575e20f833a4f9e8f0975351d03869452acd46c8860e86ce05bccdc",
@@ -76,7 +80,7 @@
76
80
  "local-discipline-gate.mjs": "f80c560a4eb7c153e1637d072f0a6b4e13d4caba745317a01ff7f9b5e9143f69",
77
81
  "local-discipline-native.mjs": "8b99b5ce951cab3c1426428ad807650c61c0ffb2c346d747b73b99057b382049",
78
82
  "local-discipline-operations.mjs": "9fcb7b8889b7718d42e1d37936485d8198d5017d405e0cdbbabdbbd12fcc9d48",
79
- "local-discipline-repository.mjs": "748f691ad65366a68f2a7f8106a95b223a3027d3ff86481a111b27385e9aef57",
83
+ "local-discipline-repository.mjs": "4fb9b535bcf9ee5e103f2ae888136d79268cf86978a4cb5c23bd4c44003a832d",
80
84
  "local-discipline-snapshot.mjs": "ff1fc42a89d1eeb4977062c8698f700fc4f6ad727e1ea2ed0f255d00d63f497b",
81
85
  "local-runner-discipline.mjs": "99935b1be0d660d6cd45f5facd911bf1e1203ec74953acef5f12a7ebafacffb2",
82
86
  "local-integrity.d.mts": "21357f306234bd841c0d3d90bf2d09f7663f63746f897b9f38190428ae8198b3",
@@ -86,35 +90,41 @@
86
90
  "runtime/validator-runtime-v7.0.44.d.mts": "7797edbfe2f7de24da370204dce4dfd22822a1bd80df93514fff900b98afe36f",
87
91
  "snapshot-retention.mjs": "ca46aeb36b1a5a24fe7e967031a71b9a3d33f40cb715d344402cbe0dc9c425cb",
88
92
  "snapshot-cleanup-journal.mjs": "76a9684cc95b4eb076e1298d78a9dff37948b00d9607b8f546c599072d3ed331",
89
- "IDE-EXECUTION.md": "3da7cbfafc1a4e7d4059c6fe8e69d14dacd2c72e300fe8e056581faea7f23aeb",
90
- "REUSE-DISCIPLINE.md": "a2452911c2b50c4762b4a1374f1958059eb03efd59f63e1b50e1650c52b0dc98",
93
+ "IDE-EXECUTION.md": "8376b69934ad02b268fd66a704821c0ebcd2c7eda04c0a2c6dec2ea6d393d8b8",
94
+ "REUSE-DISCIPLINE.md": "f1d9c2002c0214bad0aa72aa696b39a4bd6ee4b5a236e804799e22de3418c686",
91
95
  "install-identity.mjs": "41b8c8d8b3e265d2057a07bf7dc98066c34d6b05c65bf7159ca9609c01ee4646",
92
96
  "package-archive.mjs": "e06db8d709db8710bead254ee950b78928088be01c58dcea383beaa5eb574e59",
93
97
  "package-replacement.mjs": "02ca3fa4ada2addc479f8cb1b8099cd1b574adfeaa2f3c8ecf612ac2cb9127d3",
94
98
  "rollback-history.mjs": "0ebd59e1d25ad5f95fa58ce5050cb67b018a391cad162d7643bde3aa4c176528",
95
99
  "rollback-runner.mjs": "02f237b8802a2dc4cd5b545904fa102481277898938e723218fa6e75b18b24a7",
96
100
  "reuse-discipline-release.mjs": "f51997624a959d2c133d4ce189eff0724ce65e1b62f9406497251fd2f2257b0c",
97
- "design-browser-checks.mjs": "2aefcd074f55568259bebbd760866fac437527bcd0358b5b2438da56524a27e2",
101
+ "design-browser-checks.mjs": "68eac0748b7bdd517108b2386b83ba916a2f1ffef7fee303d4511e73f4cdf92f",
98
102
  "design-browser-identity.mjs": "cb06f4429d0ee84d6608f87a44fb530af46636dd645cf857778c7d8c4d73e12f",
99
- "design-browser-state.mjs": "386a76d418aa8445ba94ae9497a91445c7899e148ea19418188d48cb757170af",
100
- "design-browser.mjs": "4811b1f039dc7a5b41336b20b9feef88fbc3d653f8b03cede2dd06315736f155",
103
+ "design-browser-pages.mjs": "0789512c1fcb54d7ab153af1ba7bfe6f1f8c79704124ff050c787554263af6d8",
104
+ "design-browser-state.mjs": "9de8cc6edb7d9a67667be3f5ba42407dfb6699abfc0e28faf366ac1ff0a51e67",
105
+ "design-browser.mjs": "ced192caefabef6001c27bc15f33b265e326a57271384952e2729cdfec64b722",
101
106
  "design-context.mjs": "2e0d764a2a55d05e00477f984135d77808307afb1fc8668f35910612b5e4cea5",
102
107
  "design-contracts.d.mts": "af1a5740557d2c8ce90702179e78797a618544c89dbbb3962cf92bef24f9c2b8",
103
- "design-contracts.mjs": "e5bd6f6e05f40f229f6244672926615ebfb6f5764530ffcf054d548fc8639f36",
104
- "design-declaration.mjs": "f6c7f56e4697a05a0a832fcdb5a3b07ffe60aa602ba0681cfd09948bdcafc8ad",
105
- "design-frameworks.mjs": "5d09a8e56068302f951a6236f36cb50e655fb6d6ffbeb2e4eb4b19f025c8a411",
106
- "design-gate.mjs": "567eb666937704123ef72f26ad1145d9d32f7dfde59553381286de083e4146cb",
108
+ "design-contracts.mjs": "e4798d3369c0047b5b663f22b9858033cad418f1602c441f5283c05d1c885408",
109
+ "design-declaration.mjs": "4c4be3731bcf169e15a100c5261a34686ddd43b780dfa8667a8d7c36766e5237",
110
+ "design-frameworks.mjs": "57c316420269d3b46044f14306c5f807e0e87d5a527b3c9995a7066b2b3da952",
111
+ "design-gate.mjs": "7d06a7065951f97b6abc10bba4bb517200c3d0b2720354b878f98f5cdeab3b19",
107
112
  "design-lint.mjs": "76adb33d0faf0cfcdef7583a2f4835eccc7e49811480e2fd2b09779a81c0cbab",
108
113
  "design-local-contracts.mjs": "f331bd1d21f30994596bd9c46008e551f3ed2b6d5eea19d4546c7da0663b768a",
109
- "design-operations.mjs": "e21e9fcf9fd16115c72558c7cd7a57f7213a30934bde0f1b649aec647d1205f7",
114
+ "design-operations.mjs": "6348af322627a4ba53205e0256e0d6fe5bd627acfef6954ba305dab960ac3e6c",
110
115
  "design-policy.d.mts": "48fed97fca0f97fef786f182f666d7e6e33efb814cda1991239e1c38984cf80e",
111
- "design-policy.mjs": "0ffd3cd9381589f7fd3b817d7ee34e6b2bd284a86fd9f31d64fd2c9cde28ca2f",
112
- "design-research.mjs": "d1552f47dffec787acf2b702a6bb2a31b50ba5a3f82a6cb1c02fb2ffae2aee7f",
113
- "design-runner.mjs": "85ffbdc133e58da465ec1229c1c9a0e2c4c694bf7b7be185fa4aafabe58fde45",
116
+ "design-policy.mjs": "6ca60298777667502616eaad4aff92b92947ee1538f69be9e398be076367c759",
117
+ "design-research.mjs": "6cdc5d6ab96e47dd3a3abc4f31c3bc800a469ce1522b7e49aa73eb86d44b988d",
118
+ "design-research-network.mjs": "7ed4c670eff767b6b4783d032b4fea14f9a4aeed15c1340451967dead7ce8e2f",
119
+ "design-runner.mjs": "2aaeb4a2e6034b7566943719cfef1b78dbb8f5d3a812d155a8a328ded4340797",
114
120
  "design-store.mjs": "51420d66dd1c4350e4577d73634b51b62ffbcc99c614b3b02f17e82537170af8",
121
+ "design-stage.mjs": "545a9f2e027b2333ffb09df4516f6d3866d9585a19a43a39dbff16145dc75bca",
122
+ "design-stage-contracts.mjs": "f4242876fd6472096dd22609868e955a54c9269d6edd7bff399c6083ece52848",
123
+ "design-storage.mjs": "af02cf3fb59f9ef7c7d6276b43e6a53e3d305a77492e3cb824dd05d52adc2fd3",
115
124
  "design-ui.mjs": "6dd3c5a97ec67e8f1c23e57bcab5eb64380c520befada6f264c4bfcf6b11c9f7",
116
- "DESIGN-GATES.md": "17b7db53b84df11d70a1d93a21a068ec1257c14c0f24af64e917d52ba1c91549",
117
- "design-release.mjs": "5fbfa74f2de9a7adbee4e14136b874bca2c12414c0fe21cc2520f2029e8caa30",
125
+ "DESIGN-GATES.md": "28230c7de537a7321f2d1d38d98661e2fd7bad2434b3e472ab8fbf2697687c52",
126
+ "DESIGN-STAGED-ACCEPTANCE.md": "90ee32e08fa4bfd56fcb8f9ffb19f6a10217203448b6676bcf58c4ea6e03ba6c",
127
+ "design-release.mjs": "03863c95bec899782c1bed09c14f0e302ec2ec7bc221a36a4f7c91e501734b72",
118
128
  "local-final-gate16.mjs": "083aec470670e6cdb7ad2ab27b7a51b53a9ec3a8b4121cb9cbfa17d9940892c2",
119
129
  "local-final-gate16-checks.mjs": "1dd30e9666d458d8b12ca6e4975f6f0ac8450c3ea9cbecc7401ae037f66b589a",
120
130
  "local-final-gate16-worker.mjs": "344d64b6c1c5552b96960e0d8514a876a3dbfa9762ab9eb749038e8351727121",
@@ -156,19 +166,19 @@
156
166
  "local-autocoord17-waits.mjs": "2b0a713987822548a94e1ed3a9a891532db45383797dfc5d5bc8d1e35593cf25",
157
167
  "local-validator-isolation17.mjs": "48e94604e28b8fddd567dfb35ff60b73fd094a5803bd49f076388b7f310f92aa",
158
168
  "local-calctool-composition17.mjs": "ac89fcb41ab0d0d9b47c1b5696945281b0894eb064820775e36a011c76314e6a",
159
- "cli.mjs": "c1fc6c58c10f00189de93ddaa8cbe4f889c62cc16c8c45d55c7b4a1498eead8e",
169
+ "cli.mjs": "90320b9db041ea1ec8de6e69af18daa748c964f436e4e137de011b53abaf4d8c",
160
170
  "ide-selection.mjs": "e11e2b363c06444f1dcb4cdab1eaa0eb748a379b84354e0e71fd9c2dc79a4815",
161
171
  "ide-exit.mjs": "39d60a15b1517d402c208d22a17033976e43733be8a10dc6da386837c59b37b2",
162
172
  "install-cleanup.mjs": "8a8e1a7dfe37427f86cd4d6e317890d0829894a9949d4216674a716b36edbc54",
163
173
  "review-client.mjs": "3491eef68ed533174b31db3c53febb6519b8f088f71a9964644714a9a4c03c77",
164
174
  "version.mjs": "85284d4cd5e3314b449e6ae124243f96397bcc274817b5983a79cfdd903d46fd",
165
- "SKILL.md": "1c1509924526711c92df7fd0600e4165353cc602663d83b225e083676501bba3",
166
- "CAPABILITY-MAP.md": "517809bb20750e5de89b2dab5705c902a27fa68cf4f3f392a5d8cf2f19818888",
175
+ "SKILL.md": "5f68fe2742dfd64feeff7e5071719c1de5d09dd7f33f44cb742499f6dab3d3c9",
176
+ "CAPABILITY-MAP.md": "24f392d4f45e81c4c04a22be4ce7cd9a4e0ac2477ef7cc2cf857449a1ff33091",
167
177
  "AGREEMENT.md": "f93a68e92c457200dd024610e65f74e478b8f60860f951da818b70561f1b9bf8",
168
178
  "DELIVERY-BOUNDARIES.md": "cb23ce71b2197085c8441ba7c5b6c05fb21f2a954bf66b4d60cfef8b15895b8b",
169
- "package.json": "9a3bb032185a679b7b0146cc6bd1b46ed44e59d16cbab236c5e90fd4f167ad7c",
179
+ "package.json": "07082d32e00eb0386b2de73f378613178f58825d622ed3b2333c7398cc0d4b3d",
170
180
  "manifest.json": "ab06e307795bc9da5add926752b6c4dbdaf18625090261a035aa356a679c504f",
171
- "release.mjs": "c3a5af873db43872e5a6bdc16eb3d859e8d69f6b21bd1c3b754f4a2b6c305360",
181
+ "release.mjs": "2070c03cbaaa64387452d07687c6ce8d6c4ff6cfeb2b10094082621e10e8588f",
172
182
  "local-cli.mjs": "058ac9a4653bc12e0d031b72034ebfe6a72b91b9b23353b9fee04881c7d2e098",
173
183
  "local-state-lock.mjs": "1dbf64264642a0851faf043e07ee9f66d2ad0508e9f799b0626246e42fae893e",
174
184
  "local-execution.mjs": "721ed7d29bbe4ce6d088909cd84ffc440978c3c9eb0946c49a4281ee685fe3aa",
@@ -191,7 +201,7 @@
191
201
  "local-chain-results.mjs": "0455f72cad574cfef87c2c6c0928d6432bba7e5dbaff521a2b62a9575299ca10",
192
202
  "local-approved-plan.mjs": "c2c88ab4085ff35a1811fe43e9a28699cfc9387eda54bfeafae3e7dd9e8cdb19",
193
203
  "local-budget-renewal.mjs": "6b436358066fe33b2f6d871fc90d8e7c551edd6255efd73c0d255d0fd35d5ef8",
194
- "local-probe.mjs": "398f5dd4973503ccad280e0224e4f567c9763d21555a0816afdd83c75987d33a",
204
+ "local-probe.mjs": "d275595b81e3eef745e794d3de3fcc30a5531f15fa504b7f5a2212326e751b6d",
195
205
  "local-budget-grants.mjs": "c5f6542f5d2c3bfe07f3ca5b5bc849bf05d886b06014f720322d530510775d3d",
196
206
  "local-budget-handoff.mjs": "85a8f006dad9c0153843c7b7748ee7fcd756fdba159c97c3905d7fe0c4f604af",
197
207
  "local-budget-handoff-contracts.mjs": "bb53ebf135ec7ecfbecee858cfb354f03fee9cfb3940fa5d967d45008bf9aac5",
@@ -207,7 +217,7 @@
207
217
  "local-scope-candidate.mjs": "8f0bd9606e70d4a0ebacdd3cd600ec3afed85e2bb3e1760aa1144cf55d4e028a",
208
218
  "local-scope-context.mjs": "79753abfc6c76089d17f003a1be537dfaea10d6731c542f7fc53f2a9996ed164",
209
219
  "local-scope-files.mjs": "b8c98b8ca8bb4953f3d2d9ae1fa71b2a54286032c9dd660d3061b584e77778cb",
210
- "local-scope-repository.mjs": "fe5187824744233b9fce59d7b964a3f24349a3fe31415181654a1b3a70e8de9c",
220
+ "local-scope-repository.mjs": "fcf156e99a6f877df4368e0b3382000f7d2868a56959b3b6959cae7779fc4f54",
211
221
  "local-scope-read-set.mjs": "a5137d2e7ecffe669143fb51f0f3fba7526a881b512269858ea1e3504d9a50b2",
212
222
  "local-scope-uni-expressions.mjs": "626247c87a4fd5f6162e548aa907d3f983d5a77d341e640b6f42a539f0c84405",
213
223
  "local-scope-uni-directives.mjs": "e546be317962e30a3547aea376db9a7b8d7641055daf9e3dce4a9ef55cd872af",
@@ -238,36 +248,39 @@
238
248
  "local-budget-git-system-attributes.mjs": "367a4e5a88490c4d4c3717bc893a271970fe70d7705f0c1c72d6f76a442d5d21",
239
249
  "runtime/git-native-linux-v1.mjs": "cf5cb91426a105e62c0f07a8a230dec592dba46f85a3f708b4c4e8cfcd1126c6",
240
250
  "runtime/git-native-darwin-v1.mjs": "f88aab72dc86f94eb1115784872957cb8ed0f74205ae70e1ecd1939e7790e310",
241
- "local-scope-signature.mjs": "3804b84d5ddca5c1ac991b31151d84cddc508517eff7500351ba1bcffdf3c672",
251
+ "local-scope-signature.mjs": "f199fdab06e3d43270a52b9fedc77889f57c9d25bca6926197937eb026a28703",
242
252
  "local-scope-config-imports.mjs": "a399407227bbdd14468633bb6d25586df7c6a30a1ef0d1a80ab7c7b499d3fadf",
243
253
  "local-scope-config-extends.mjs": "3ab4150b846b247e9e0851221123f220c5574699af651830e751f026ab33659e",
244
254
  "local-scope-snapshot.mjs": "c0f851470b98863a1d187825ed61ee6072d1c057b178fdc85ae29af02a3b250f",
245
255
  "local-scope-state.mjs": "7a6d275d6267a4d0bb55582e1bcc7654c502ecba9221b84b2149a98f0ee7518f",
246
256
  "local-scope-workspaces.mjs": "8a75ce7b6639b5682370b5738c5c2a90408e3130729608e008f03053cd50351f",
247
257
  "local-task-routing.mjs": "6e2e506b2fb0e2e8d8c5147d7df32849b57a4e94a23634f01a355d45735858e4",
248
- "remote-client.mjs": "6cf62706f8ac5f69368d951cd697f912040b2e58ac480dfb151bddb18b09b20d",
249
- "cloud-task-client.mjs": "f9085c5e6af6f179282670d2e872b85bfabac2657d3d232b1246dc23f5a6ccdd",
250
- "scope-runner-client.mjs": "cc4fe202d5f777a0ec4c46f9b41a18aaf024c0d2e769a0b26bc6505f2f69f460",
251
- "scope-amendment-client.mjs": "022ec88ecf12a98dd6e9e7915158fc9111cdadfda12cf714804948c8027a57d3",
252
- "scope-amendment-state.mjs": "9f88cc7029f62eed3b1a0cc1c03b6a98c5713b467a2112278692de90c973b2be",
258
+ "remote-client.mjs": "1db62896d3c0b97fdf9a4add85a34ed7de45b9399c33e482c884ed96a376c58a",
259
+ "service-prerequisite.mjs": "2361168ea12ca95faee75c79657a486af5e7edaf1ec8182f8f1afdf59f15c9a5",
260
+ "local-source-execution.mjs": "88f6ce1ea50d0a7b92e0cb47d535f8140491c52d9c6c0dfddf91ea90397a36f5",
261
+ "fs-request-trace.mjs": "972eacbe21537bc102047127327449a6a4b0f0c65d75e3472370de91dedf4d2f",
262
+ "cloud-task-client.mjs": "ab3e0296363b6af10eaa38a09dd43b4ae6e5704d699c7a5032fee1b7817fa0dc",
263
+ "scope-runner-client.mjs": "4690bd8b72f37b40c8e83e619f00002ca3a589ef58fbdc4db6b8dceeff6108c7",
264
+ "scope-amendment-client.mjs": "04109dd0b11ffe02b33ba2faeaadef0a8fb0026604835ec2f5c756085a8c1ea8",
265
+ "scope-amendment-state.mjs": "85240255f20650403e7fab084d5baace6710b5d3ecb1541b64ec3e9657fc71a9",
253
266
  "scope-amendment-wire.mjs": "3c4823e23bbdf330616bb675f07f9fcad7423266bd50b92e1134d226060e9b83",
254
- "scope-amendment-remote.mjs": "15a0b3126248f3101a52e3d7742f9a816dd3d8e58f21bac33e99e810e86cc4fd",
255
- "scope-amendment-observer.mjs": "de796f2aca2f3bc7f33ae3323b07d98096c0f16b1ffde70e3055610d70d18020",
267
+ "scope-amendment-remote.mjs": "a9925319418a45f657ea5f5a52903af27728f226647ebc8b36099cfdc5554964",
268
+ "scope-amendment-observer.mjs": "9091f2e11b094b8a8cd27ad1454031d11a34ecb6923295fd6edfaa07c54899ee",
256
269
  "scope-amendment-mutation.mjs": "fa24191df290efad29d41eca3d1a081981fefde02b7dc4a11c75c6118a69106e",
257
270
  "scope-amendment-reference.mjs": "dc1768131beb7db224dd2ff8522dbf6361f73e01f466c9334cdfa24118720078",
258
- "native-client.mjs": "6f5575909bae9daba643287f876ffa0f9ff1c53a367b32a40145d740456d6605",
271
+ "native-client.mjs": "76f4c35cdef670f4e1cceaecde397869e8f7b4a41654ff5127345ed15d7b3888",
259
272
  "native-notification.mjs": "8859a26c6f13d222711f763acf49ed8546b3306cf71f990643ac31a5ccaf1ba1",
260
273
  "local-peer-status.mjs": "a971bcc69d60bb32b875ca5bb4297d948631d5d2821b812c279613ea059a8b4f",
261
- "cloud-watch-client.mjs": "2042392cd62f1596a35ef3f6cb376f8ed67790351576b007e32f134ce018aec1",
274
+ "cloud-watch-client.mjs": "eccce52bce1c915a71fe9a1fa3e435dba5af9a5455afdf478f04684901b6fb7b",
262
275
  "cloud-event-stream.mjs": "e0eec9fc3e0613094523929634f25030df5ca5c5b5fe2c1e1a4586ab10574808",
263
276
  "ide-presentation.mjs": "d826afe0dfcc38906ba76dcbbe021807731587c38026148624546c334057e7f3",
264
277
  "automatic-feedback-client.mjs": "532312d29e66fa211ea3fe879d9add1dd48841ee5ce82800b4b06252a160a255",
265
- "task-entry-client.mjs": "940fb068afe28a2a34fe96e285e149afdd9ba79649c0c65cde37ec4ed71ae39d",
278
+ "task-entry-client.mjs": "ca08f1adc20319d0e33c02f0160c5e85d84c5034720892b3ca61cf17c1534459",
266
279
  "task-identity.mjs": "e0e6cf1f48bfa5ee3c5cb86a3c21adfce6d66b4220f4a164ca099263c7a09fb4",
267
280
  "task-identity.d.mts": "55472e1ffc81b9d5e5c5bd56c0bf1d18ecde03ee5170a58a15ce9caf222d8761",
268
281
  "remote-transport.mjs": "e9ecb3b9cd4d3bcc7abe1f7097069a07a15319ca0d5641fee752d094eb039194",
269
282
  "local-credential.mjs": "2a302a7f67b5ea8dc73453fc96ab33db349b59ca11fa9456e48ca1d9669d877c",
270
- "local-invocations.mjs": "f6ac4c41c1a5ec34de358c4cca210ca8e403b3a913150a43bb55ec9be55d9998",
283
+ "local-invocations.mjs": "3e0b436a8feef7240944f6f5d8b15fbef312d6e9b3895d7762762ba8730a3e9d",
271
284
  "local-task-handoff-fence.mjs": "5532a359ee29b885f7ce0cf7178f76dba0fc9245bdd92ef460982275baf0d557",
272
285
  "local-task-handoff-storage.mjs": "f4d5046d54658e8092e035b31fdaeaed6fdbef55a6953827417c857f2e9e6638",
273
286
  "local-task-handoff-overlay-wire.mjs": "4fbe3f9d1ed8b6ddf839e9525cdc52c930a22e9d4f4ad562c6f193f621ee6527",
@@ -285,7 +298,7 @@
285
298
  "workflow-local-request.mjs": "4e24c543ce386292a87dc9cd41f90d23375f12079cacffc515c8cd01fd571780",
286
299
  "task-message-entry.mjs": "31d10056cb905237cd5649e8eb067009ff1612ec5dc1061e0373209fbc0b646a",
287
300
  "task-message-cli.mjs": "3ca65e96c28129b3bd5cac962d106e0859a1f17df1f6a66ee543c6efc22f918d",
288
- "local-contracts.mjs": "0548faf3ecc4f3124c823ccd926f811580f4ba50a15bd334ff6d550e6eca013d",
301
+ "local-contracts.mjs": "153e08c92f4fb42c2c8c16e3ce338c3b570d17d88be59fc729e259cdc14cb718",
289
302
  "local-contract-types.mjs": "85e71fa4dd67e351a4b67573c740bcdb1661cede53f097189f11837771e75e91",
290
303
  "local-archguard-ast.mjs": "7ff7df9dab0d98ed62983add751c80edea598bc94ef4f38ede0ebd4d41226c87",
291
304
  "local-archguard-checkpoint.mjs": "37896902520cc995720c96288e4a5ed3585952b55c9c35be281f91fa754c71ec",
@@ -312,7 +325,7 @@
312
325
  "local-calctool-contracts.mjs": "d8fccf662b2dd7aefd5cc6770b2473014af7a28855074fcf294937ca5a49eae8",
313
326
  "local-calctool-runtime.mjs": "9070b6900d1782bf77357fea1cc522bf796898d56929f96d7cb935b3036ac82f",
314
327
  "local-calctool-storage.mjs": "4c3f352847aeb368dea1247759a1055beeab25534adf25b6e7323196d76fd684",
315
- "local-mutation-files.mjs": "087b00e8424a135e783eb432271012a71e55eeb4a5e30119490d1bc0b2160320",
328
+ "local-mutation-files.mjs": "cd27197fd25cb3ec3d0733e932c2ff2394b0665ad4afb771edc3e4a49526e428",
316
329
  "local-mutation-snapshot.mjs": "69c0ff0b67b2e6913b1d9f8247bf48c31d62f4f5ae1668c573a0ade06c01d105",
317
330
  "local-mutation-audit.mjs": "5a30ee3446f632e032ffcfe46bcd97d6dfc0f099a76ea5185c3f9a9118c4f6cb",
318
331
  "local-mutation-wire.mjs": "6d00400e531c693c3e8bfd0c2a24fcc486127f84aafc56ee450dcec7f534eb05",
package/release.mjs CHANGED
@@ -11,6 +11,7 @@ import { chainReleaseLabels } from './local-chain-release-labels.mjs'
11
11
  const directory = path.dirname(fileURLToPath(import.meta.url))
12
12
  import { swarmSourceFiles, coordination17SourceFiles, preservedMutationSourceFiles, memberContinuationSourceFiles, scopeEvidenceSourceFiles, scopeEvidenceReleaseNote } from './release-source-groups.mjs'
13
13
  const sourceFiles = [
14
+ 'local-recovery-budget.mjs', 'remote-capability-cache.mjs', 'scope-write-observation.mjs', 'scope-write-observation.d.mts',
14
15
  'release-source-groups.mjs', 'local-scope-build-read.mjs', 'local-scope-build-io.mjs', 'local-scope-build-facts.mjs', 'local-scope-build-data.mjs', 'local-scope-build-readset.mjs',
15
16
  ...scopeEvidenceSourceFiles, ...SCOPE_CONTEXT_SOURCE_FILES, 'cloud-locale.mjs', 'cloud-locale.d.mts', 'cloud-task-images.mjs', 'model-images.mjs', 'model-images.d.mts', 'cli-input.mjs',
16
17
  'scope-amendment-retirement.mjs', 'scope-amendment-consumption.mjs', 'mutation-connection-state.mjs', 'mutation-challenge-refresh.mjs',
@@ -86,7 +87,7 @@ const sourceFiles = [
86
87
  'local-scope-snapshot.mjs',
87
88
  'local-scope-state.mjs',
88
89
  'local-scope-workspaces.mjs',
89
- 'local-task-routing.mjs', 'remote-client.mjs', 'cloud-task-client.mjs',
90
+ 'local-task-routing.mjs', 'remote-client.mjs', 'service-prerequisite.mjs', 'local-source-execution.mjs', 'fs-request-trace.mjs', 'cloud-task-client.mjs',
90
91
  'scope-runner-client.mjs',
91
92
  'scope-amendment-client.mjs', 'scope-amendment-state.mjs', 'scope-amendment-wire.mjs',
92
93
  'scope-amendment-remote.mjs', 'scope-amendment-observer.mjs', 'scope-amendment-mutation.mjs',
@@ -306,6 +307,10 @@ const archguardReleaseLabels = {
306
307
  }
307
308
  function releaseLabels() {
308
309
  return withFinalGate16ReleaseLabels({ ...designGateReleaseLabels, ...reuseDisciplineReleaseLabels, ...calctoolReleaseLabels, ...mutationReleaseLabels, ...swarmReleaseLabels, ...coordination17ReleaseLabels, ...nativeReadReleaseLabels, ...feedbackReleaseLabels, ...invocationReleaseLabels, ...chainReleaseLabels, ...taskEntryReleaseLabels, ...archguardReleaseLabels,
310
+ ...Object.fromEntries(['local-recovery-budget.mjs', 'remote-capability-cache.mjs'].map(name => [name,
311
+ { zh: '持久有界恢复与能力发现复用', en: 'durable bounded recovery and capability discovery reuse' }])),
312
+ ...Object.fromEntries(['scope-write-observation.mjs', 'scope-write-observation.d.mts'].map(name => [name,
313
+ { zh: '完整范围内可写角色独立签名计量', en: 'independently signed write-role metering within complete scope evidence' }])),
309
314
  ...Object.fromEntries(['local-scope-build-read.mjs', 'local-scope-build-io.mjs', 'local-scope-build-facts.mjs', 'local-scope-build-data.mjs', 'local-scope-build-readset.mjs', 'local-scope-uni-build.mjs', 'local-scope-uni-expressions.mjs', 'local-scope-uni-directives.mjs', 'local-scope-uni-conditional.mjs'].map(name => [name, { zh: '源码事实与未知构建行为分离', en: 'raw source facts and opaque build observation' }])),
310
315
  'release-source-groups.mjs': { zh: '自动版本源文件清单', en: 'automatic version source inventory' },
311
316
  ...Object.fromEntries(['cloud-task-images.mjs', 'model-images.mjs', 'model-images.d.mts', 'cli-input.mjs'].map(name => [name, { zh: '受限图片输入通道', en: 'bounded image input channel' }])),
package/releases.json CHANGED
@@ -1,4 +1,34 @@
1
1
  [
2
+ {
3
+ "version": "0.1.78",
4
+ "date": "2026-10-21",
5
+ "zh": "完整交付原八技能的一次入口授权、范围内衔接与有界恢复;修复已实际取消的弹窗先于点击回执关闭时的原窗口接续,不重发点击,原父窗口、精确路由、安全签名、快照及回执保护保持。",
6
+ "en": "Deliver the original eight skills with one task entrance approval, scoped handoffs and bounded recovery. Preserve the original opener when an actual popup cancellation closes before its click acknowledgement, without replaying the click or weakening exact routes, signatures, snapshots or receipts."
7
+ },
8
+ {
9
+ "version": "0.1.77",
10
+ "date": "2026-10-21",
11
+ "zh": "未发布候选,内容并入 0.1.78:正式发布八技能一次入口授权、范围内衔接和有界恢复,保留原八技能核心、安全签名、快照及回执;兼容旧范围续签,并验证已发现能力清单复用时仍拒绝非法输入。",
12
+ "en": "Unpublished candidate, incorporated into 0.1.78: Publish the complete original eight skills with one task entrance approval, scoped handoffs and bounded recovery, preserving native cores, signatures, snapshots and receipts; retain legacy scope renewal compatibility and verify invalid input rejection with reused capability discovery."
13
+ },
14
+ {
15
+ "version": "0.1.76",
16
+ "date": "2026-10-21",
17
+ "zh": "未发布候选,内容并入 0.1.78:正式交付八技能的一次入口授权、范围内衔接与有界恢复;兼容旧凭据续签的独立写入计量,保留签名、快照、回执和原批准范围校验。",
18
+ "en": "Unpublished candidate, incorporated into 0.1.78: Ship the eight-skill single-entrance authorization, scoped handoff and bounded recovery; preserve signed write accounting across legacy proof renewal without changing approved scope, signatures, snapshots or receipt checks."
19
+ },
20
+ {
21
+ "version": "0.1.75",
22
+ "date": "2026-10-21",
23
+ "zh": "未发布候选,内容并入 0.1.78:正式发布复用已验证的八技能任务衔接与恢复改进;移除发布测试中未发布法律模块的夹具耦合。八技能核心实现保持原版。",
24
+ "en": "Unpublished candidate, incorporated into 0.1.78: Release the verified eight-skill task handoff and recovery improvements; remove unreleased legal-module coupling from release test fixtures. The eight original skill cores remain unchanged."
25
+ },
26
+ {
27
+ "version": "0.1.74",
28
+ "date": "2026-10-21",
29
+ "zh": "未发布候选,内容并入 0.1.78:八技能衔接共用一次明确的任务入口批准,范围内复用原审批与已完成计算;修复范围状态读取、元数据扫描、独立可写计量及带查询参数/弹窗的设计验收。恢复次数持久有界,合法前置进度可继续,保留签名、快照、回执与未知结果只查询的保护,禁止跨项目耦合。",
30
+ "en": "Unpublished candidate, incorporated into 0.1.78: Reuse one explicit task entrance approval and completed skill computations within the approved boundary. Fix scope state reads, metadata scanning, independently signed write-role metering and query/popup design acceptance. Bound recovery durably while allowing verified prerequisite progress, preserving signatures, snapshots, receipts, GET-only unknown recovery and project isolation."
31
+ },
2
32
  {
3
33
  "version": "0.1.73",
4
34
  "date": "2026-10-20",
@@ -0,0 +1,20 @@
1
+ import { createHash } from 'node:crypto';
2
+
3
+ // Schemas are discovery data, never authority. Each process still validates
4
+ // actual request/response bindings and the service enforces current permissions.
5
+ const entries = new Map(), maximumEntries = 8, lifetimeMs = 300_000;
6
+ const key = (origin, credential, home) => createHash('sha256').update(JSON.stringify([origin, credential, home])).digest('hex');
7
+ export async function discoveredCapabilities(origin, credential, home, fetch, { refresh = false } = {}) {
8
+ const identity = key(origin, credential, home), previous = entries.get(identity);
9
+ if (!refresh && previous && previous.expiresAt > Date.now()) return structuredClone(previous.value);
10
+ // Coalesce concurrent discovery for the same authenticated endpoint.
11
+ if (!refresh && previous?.pending) return structuredClone(await previous.pending);
12
+ const pending = fetch();
13
+ if (!entries.has(identity) && entries.size >= maximumEntries) entries.delete(entries.keys().next().value);
14
+ entries.set(identity, { pending });
15
+ try {
16
+ const value = structuredClone(await pending);
17
+ if (entries.get(identity)?.pending === pending) entries.set(identity, { value, expiresAt: Date.now() + lifetimeMs });
18
+ return structuredClone(value);
19
+ } catch (error) { if (entries.get(identity)?.pending === pending) entries.delete(identity); throw error; }
20
+ }
package/remote-client.mjs CHANGED
@@ -7,6 +7,8 @@ import { acknowledgeAutomaticFeedback, verifyAutomaticFeedback } from './automat
7
7
  import { ideClientHeaders, presentInvocationNotices } from './ide-presentation.mjs';
8
8
  import { routeTaskEntry } from './task-entry-client.mjs';
9
9
  import { cleanupCompletedSnapshots } from './snapshot-retention.mjs';
10
+ import { prerequisiteError, discoveryPrerequisite } from './service-prerequisite.mjs';
11
+ import { discoveredCapabilities } from './remote-capability-cache.mjs';
10
12
 
11
13
  export const apiUrl = 'https://entrorove.com/api/skill/invoke';
12
14
 
@@ -98,9 +100,16 @@ async function invokeDiscovered(data, token, { home, apiOrigin }) {
98
100
  const call = { ...buildInvocation(data.operation, data.input), url: `${trustedOrigin(apiOrigin())}/api/skill/invoke` };
99
101
  let feedbackRequired = false;
100
102
  if (data.operation !== 'capabilities') {
101
- const discovery = await postInvocation({ ...buildInvocation('capabilities', {}), url: call.url }, token, home);
102
- if (!discovery.response.ok || discovery.result.output.status !== 'succeeded') throw new Error(`Capability discovery failed: HTTP ${discovery.response.status}`);
103
- const capabilities = discovery.result.output.capabilities;
103
+ const fetch = async () => {
104
+ let discovery;
105
+ try { discovery = await postInvocation({ ...buildInvocation('capabilities', {}), url: call.url }, token, home); }
106
+ catch (error) { throw discoveryPrerequisite(error, call.requestId); }
107
+ if (!discovery.response.ok || discovery.result.output.status !== 'succeeded') throw new Error(`Capability discovery failed: HTTP ${discovery.response.status}`);
108
+ return discovery.result.output.capabilities;
109
+ };
110
+ let capabilities = await discoveredCapabilities(new URL(call.url).origin, token, home, fetch);
111
+ if (!capabilities?.operations?.includes(data.operation) || !capabilities?.operationSchemas?.[data.operation]) capabilities = await discoveredCapabilities(new URL(call.url).origin,
112
+ token, home, fetch, { refresh: true });
104
113
  feedbackRequired = requiresAutomaticFeedback(data.operation,data.input,capabilities);
105
114
  const schema = capabilities?.operationSchemas?.[data.operation];
106
115
  if (!capabilities?.operations?.includes(data.operation) || !schema) throw new Error(`Capability discovery does not support ${data.operation}`);
@@ -135,6 +144,11 @@ export async function postInvocation(call, token, home, feedbackRequired = false
135
144
  await logged({ event: 'outcome-unknown' }); throw unknownInvocation(call.requestId);
136
145
  }
137
146
  if (!response.ok && !result?.output) {
147
+ const prerequisite = prerequisiteError(response, result, { requestId: call.requestId });
148
+ if (prerequisite) {
149
+ await logged({ event: 'rejected', servicePrerequisite: prerequisite.servicePrerequisite });
150
+ throw Object.assign(prerequisite, prerequisite.knownBeforeEffects ? {} : { outcomeUnknown: true });
151
+ }
138
152
  await logged({ event: response.status >= 500 ? 'outcome-unknown' : 'rejected' });
139
153
  if (response.status >= 500) throw unknownInvocation(call.requestId);
140
154
  const code = typeof result?.error === 'string' && /^[a-z][a-z0-9-]{0,63}$/.test(result.error) ? result.error : 'request-rejected';
@@ -199,7 +213,9 @@ export function createTaskMessageClient(dependencies) {
199
213
  let feedbackRequired = false;
200
214
  if (operation !== 'capabilities') {
201
215
  const discovery = buildInvocation('capabilities', {});
202
- const discovered = await postInvocation({ ...discovery, url: `${origin}/api/skill/invoke` }, token, dependencies.home);
216
+ let discovered;
217
+ try { discovered = await postInvocation({ ...discovery, url: `${origin}/api/skill/invoke` }, token, dependencies.home); }
218
+ catch (error) { throw discoveryPrerequisite(error, original.requestId); }
203
219
  if (!discovered.response.ok || discovered.result.output.status !== 'succeeded') throw new Error('Task message capability discovery failed');
204
220
  validateMachineCapability(operation, input, discovered.result.output.capabilities);
205
221
  feedbackRequired = requiresAutomaticFeedback(operation,input,discovered.result.output.capabilities);
@@ -218,6 +234,8 @@ export function createTaskMessageClient(dependencies) {
218
234
  const response = await readOnlyGet(machineOrigin(dependencies), `/api/skill/status/${id}`,
219
235
  { authorization: `Bearer ${token}` }, 'original task message status');
220
236
  const result = await readResponse(response, 'task message status');
237
+ const prerequisite = prerequisiteError(response, result, { requestId: id, outcomeUnknown: true });
238
+ if (prerequisite) throw prerequisite;
221
239
  if (!response.ok || !result?.output || result.output.requestId !== id) throw new Error('Original task message status is unavailable or invalid');
222
240
  if (result.feedback) verifyAutomaticFeedback(result.feedback,id);
223
241
  presentInvocationNotices(result,dependencies.onIdeEvent);
@@ -232,6 +250,8 @@ export async function queryStatus(requestId, dependencies) {
232
250
  const token = await dependencies.readCredential(dependencies.home);
233
251
  const response = await readOnlyGet(dependencies.apiOrigin(), `/api/skill/status/${encodeURIComponent(requestId)}`, { authorization: `Bearer ${token}` }, 'status')
234
252
  const result = await readResponse(response, 'status');
253
+ const prerequisite = prerequisiteError(response, result, { requestId, outcomeUnknown: true });
254
+ if (prerequisite) throw prerequisite;
235
255
  if (!response.ok || result?.output?.requestId !== requestId) throw new Error(`entrorove status failed: HTTP ${response.status}; requestId=${requestId}`);
236
256
  await appendInvocation({ kind: 'remote', operation: 'status', requestId, event: 'status', usage: result.usage ?? [] }, dependencies.home);
237
257
  if (result.feedback) verifyAutomaticFeedback(result.feedback,requestId);
@@ -1,3 +1,4 @@
1
+ import { prerequisiteFields } from './service-prerequisite.mjs';
1
2
  import path from 'node:path';
2
3
  import { randomUUID } from 'node:crypto';
3
4
  import { canonical, sha256 } from './local-integrity.mjs';
@@ -10,8 +11,56 @@ import { amendmentRemote, scopeAmendmentStatus } from './scope-amendment-remote.
10
11
  import { observeScopeAmendment } from './scope-amendment-observer.mjs';
11
12
  import { retainScopeAmendmentReference } from './scope-amendment-reference.mjs';
12
13
  import { saveLocalScopeEvidence, ensureScopeEvidence, validateAppliedEvidence } from './scope-evidence-remote.mjs';
14
+ import { consumeRecovery, recoveryFailureFields } from './local-recovery-budget.mjs';
13
15
 
14
16
  const schemaVersion = 'entrorove.scope-amendment-connection/1.0';
17
+ const submissionFields = ['evidencePending', 'evidenceDescriptor', 'evidencePrepared', 'evidenceSignature',
18
+ 'attestation', 'attestationDigest', 'attestationRef', 'evidenceResult', 'applied', 'rejection'];
19
+ const signingChallenge = state => (state.signingChallenge ?? state.challenged).challenge;
20
+ function sameChallenge(value, original, location, attemptId, options) {
21
+ const fresh = scopeAmendmentChallenge(value, location, options);
22
+ const changing = new Set(['authorityReceipt', 'attemptId', 'challengeId', 'challenge', 'issuedAt', 'expiresAt']);
23
+ const immutable = challenge => Object.fromEntries(Object.entries(challenge).filter(([field]) => !changing.has(field)));
24
+ if (canonical(immutable(fresh)) !== canonical(immutable(original)) || fresh.attemptId !== attemptId
25
+ || fresh.challenge === original.challenge || fresh.challengeId === original.challengeId) {
26
+ amendmentFail('Fresh amendment challenge changed its original task, signer, step, roles or authority head');
27
+ }
28
+ return fresh;
29
+ }
30
+ async function archiveSigningObservation(location, state) {
31
+ const checksum = sha256(canonical(state)), archive = path.join(location.directory, `${state.attemptId}-${checksum}.json`);
32
+ try { if (canonical(await readMutationJson14(archive)) !== canonical(state)) amendmentFail('Original signing observation history changed'); }
33
+ catch (error) { if (error.code !== 'ENOENT') throw error; await atomicMutationJson14(archive, state, { privateFrom: location.stateRoot }); }
34
+ return checksum;
35
+ }
36
+ export async function renewScopeAmendmentChallenge(location, state, remote) {
37
+ if (submissionFields.some(field => Object.hasOwn(state, field)) || canonical(state.identity) !== canonical(location.identity)
38
+ || state.snapshotStarted !== true || !state.snapshot || state.snapshot.snapshotId !== state.snapshotId
39
+ || state.snapshot.flowId !== location.identity.flowId || state.snapshot.contractDigest !== location.identity.proposalDigest) {
40
+ amendmentFail('Fresh amendment challenge requires the same verified snapshot before any signed evidence or application');
41
+ }
42
+ const original = scopeAmendmentChallenge(state.challenged?.challenge, location, { allowExpired: true });
43
+ if (state.snapshot.stepId !== original.stepId) amendmentFail('Amendment snapshot replaced its original challenge step');
44
+ if (state.pending && (state.pending.stage !== 'signingChallenge' || !state.signingAttemptId)) {
45
+ amendmentFail('Recover the original pending amendment request before signing challenge renewal');
46
+ }
47
+ const retained = state.signingChallenge && sameChallenge(state.signingChallenge.challenge, original, location,
48
+ state.signingAttemptId, { allowExpired: true });
49
+ if (!state.pending && retained && Date.parse(retained.expiresAt) > Date.now()) {
50
+ return retained;
51
+ }
52
+ if (!state.pending && (!state.signingAttemptId || state.signingChallenge)) {
53
+ const archivedDigest = await archiveSigningObservation(location, state);
54
+ consumeRecovery(state, 'signing', state.signingAttemptId ?? state.attemptId);
55
+ delete state.signingChallenge; state.signingAttemptId = randomUUID();
56
+ state.signingRecovery = { archivedDigest, snapshotId: state.snapshotId, requiresSnapshotVerification: true,
57
+ grantsExecutionAuthority: false, recoveredAt: new Date().toISOString() };
58
+ await saveScopeAmendmentState(location, state);
59
+ }
60
+ const issued = await remote('signingChallenge', 'workflow-scope-challenge', { proposalId: location.identity.proposalId,
61
+ proposalDigest: location.identity.proposalDigest, receiverId: location.binding.runnerId, attemptId: state.signingAttemptId });
62
+ return sameChallenge(issued.challenge, original, location, state.signingAttemptId);
63
+ }
15
64
  function validateProposal(status, input) {
16
65
  const proposal = status.proposal;
17
66
  if (!proposal || proposal.proposalId !== input.proposalId || proposal.proposalDigest !== input.proposalDigest
@@ -21,7 +70,7 @@ function validateProposal(status, input) {
21
70
  async function validateApplied(output, state, location) {
22
71
  const effective = output.effectiveAuthority, version = effective?.record?.schemaVersion === 'entrorove.scope-revision-authority/2.0' ? '2.0' : '1.0';
23
72
  const record = scopeRevisionAuthority(effective?.record, `entrorove.scope-revision-authority/${version}`);
24
- const challenge = scopeAmendmentChallenge(state.challenged.challenge, location, { allowExpired: true }), refresh = challenge.purpose === 'scope-revision-refresh';
73
+ const challenge = scopeAmendmentChallenge(signingChallenge(state), location, { allowExpired: true }), refresh = challenge.purpose === 'scope-revision-refresh';
25
74
  if (output.status !== 'succeeded' || output.grantsExecutionAuthority !== false || output.claimsCompletion !== false
26
75
  || output.scopeRevisionDigest !== sha256(canonical(record)) || effective.revisionDigest !== output.scopeRevisionDigest
27
76
  || output.revision !== effective.revision || record.revision !== effective.revision
@@ -59,18 +108,22 @@ async function archiveAttempt(location, state) {
59
108
  const archive = path.join(location.directory, `${state.attemptId}.json`);
60
109
  try { if (canonical(await readMutationJson14(archive)) !== canonical(state)) amendmentFail('Original scope amendment attempt history changed'); }
61
110
  catch (error) { if (error.code !== 'ENOENT') throw error; await atomicMutationJson14(archive, state, { privateFrom: location.stateRoot }); }
62
- for (const key of Object.keys(state)) if (!['schemaVersion', 'identity'].includes(key)) delete state[key];
111
+ if (!state.applied) consumeRecovery(state, 'attempt', state.attemptId);
112
+ const completed = Boolean(state.applied);
113
+ for (const key of Object.keys(state)) if (!['schemaVersion', 'identity', ...(completed ? [] : ['recovery'])].includes(key)) delete state[key];
63
114
  await saveScopeAmendmentState(location, state);
64
115
  }
65
116
  async function finish(location, state, dependencies) {
66
117
  if (!state.evidenceDescriptor && !state.applied) {
67
- const attestation = state.attestation ?? await observeScopeAmendment(location, state);
68
- const challenge = scopeAmendmentChallenge(state.challenged.challenge, location, { allowExpired: true });
118
+ const attestation = state.attestation ?? await observeScopeAmendment(location, state, {
119
+ beforeSign: () => renewScopeAmendmentChallenge(location, state,
120
+ (stage, operation, payload) => amendmentRemote(stage, operation, payload, state, location, dependencies)) });
121
+ const challenge = scopeAmendmentChallenge(signingChallenge(state), location, { allowExpired: true });
69
122
  await saveLocalScopeEvidence(attestation, challenge.purpose === 'scope-revision-refresh' ? 'scope-refresh' : 'scope-revision',
70
123
  challenge, state, location, saveScopeAmendmentState);
71
124
  }
72
125
  if (!state.applied) {
73
- const attestationRef = await ensureScopeEvidence(state, location, dependencies, state.challenged.challenge, saveScopeAmendmentState);
126
+ const attestationRef = await ensureScopeEvidence(state, location, dependencies, signingChallenge(state), saveScopeAmendmentState);
74
127
  await amendmentRemote('applied', 'workflow-scope-apply', { proposalId: location.identity.proposalId,
75
128
  proposalDigest: location.identity.proposalDigest, attestationRef }, state, location, dependencies);
76
129
  }
@@ -96,7 +149,8 @@ async function amend(location, dependencies) {
96
149
  requiresOriginalOwnerApproval: true, scopeExpansionAutomaticallyAuthorized: false } };
97
150
  if (state.challenged && !state.applied && !state.rejection) {
98
151
  const challenge = scopeAmendmentChallenge(state.challenged.challenge, location, { allowExpired: true });
99
- if (Date.parse(challenge.expiresAt) > Date.now()) return finish(location, state, dependencies);
152
+ if (Date.parse(challenge.expiresAt) > Date.now() || state.snapshot && state.snapshotStarted === true
153
+ && !submissionFields.some(field => Object.hasOwn(state, field))) return finish(location, state, dependencies);
100
154
  state.rejection = { code: 'ENTROROVE_SCOPE_AMENDMENT_CHALLENGE_EXPIRED', effects: 'none',
101
155
  reason: 'signed-unused-challenge-expired-before-next-post' }; await saveScopeAmendmentState(location, state);
102
156
  }
@@ -123,12 +177,14 @@ export async function runScopeAmend(repositoryRoot, input, dependencies) {
123
177
  } catch (error) {
124
178
  const requestId = /^[a-f0-9]{64}$/.test(error?.requestId ?? '') ? error.requestId : undefined;
125
179
  return { schemaVersion, status: 'blocked', flowId: input?.flowId,
180
+ ...prerequisiteFields(error),
126
181
  code: error?.code?.startsWith('ENTROROVE_') ? error.code : 'ENTROROVE_SCOPE_AMENDMENT_PREREQUISITE',
127
182
  message: ['ENTROROVE_SCOPE_AMENDMENT_BINDING', 'ENTROROVE_SCOPE_AMENDMENT_STATE', 'ENTROROVE_SCOPE_AMENDMENT_UNKNOWN',
128
183
  'ENTROROVE_SCOPE_AMENDMENT_NOT_SENT', 'ENTROROVE_SCOPE_AMENDMENT_MUTATION_PENDING'].includes(error?.code) ? error.message
129
184
  : 'Scope amendment stopped; preserve the original proposal, signer, journal and actual evidence.',
130
185
  ...(requestId ? { requestId } : {}), ...(error?.uploadId ? { uploadId: error.uploadId } : {}), ...(error?.output ? { output: error.output } : {}),
131
186
  ...(error?.feedback ? { feedback: error.feedback } : {}),
187
+ ...recoveryFailureFields(error),
132
188
  ...(error?.outcomeUnknown ? { outcomeUnknown: true, nextAction: { operation: 'scope-amend', ...(requestId ? { requestId } : { uploadId: error.uploadId }),
133
189
  method: 'GET', reuseOriginalInput: true, repeatPost: false } } : {}) };
134
190
  }