@entrorove/skill 0.1.61 → 0.1.64

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 (54) hide show
  1. package/CAPABILITY-MAP.md +7 -2
  2. package/CHANGELOG.md +15 -0
  3. package/IDE-EXECUTION.md +39 -6
  4. package/REUSE-DISCIPLINE.md +1 -1
  5. package/SKILL.md +6 -2
  6. package/cli-input.mjs +22 -0
  7. package/cli.mjs +2 -8
  8. package/cloud-task-client.mjs +10 -2
  9. package/cloud-task-images.mjs +39 -0
  10. package/ide-exit.mjs +49 -9
  11. package/ide-hook.mjs +2 -2
  12. package/local-contracts.mjs +4 -1
  13. package/local-discipline-gate.mjs +14 -3
  14. package/local-discipline-repository.mjs +11 -5
  15. package/local-finder-plist.mjs +87 -0
  16. package/local-finder-store.mjs +115 -0
  17. package/local-mutation-authority.mjs +11 -0
  18. package/local-mutation-completion-evidence.mjs +83 -0
  19. package/local-mutation-consumption.mjs +39 -14
  20. package/local-mutation-environment-observation.mjs +85 -0
  21. package/local-mutation-finder-observation.mjs +58 -0
  22. package/local-mutation-wire.mjs +28 -9
  23. package/local-preserved-mutation-protection.mjs +8 -1
  24. package/local-preserved-mutation-wire.mjs +7 -3
  25. package/local-scope-files.mjs +3 -1
  26. package/local-scope-font.mjs +45 -0
  27. package/local-scope-repository.mjs +16 -3
  28. package/local-scope-zip.mjs +93 -0
  29. package/manifest.json +1 -1
  30. package/member-producer-repair-authority.mjs +48 -0
  31. package/model-images.d.mts +9 -0
  32. package/model-images.mjs +87 -0
  33. package/mutation-challenge-refresh.mjs +51 -0
  34. package/mutation-client.mjs +45 -27
  35. package/mutation-connection-state.mjs +17 -0
  36. package/package.json +18 -2
  37. package/release-state.json +52 -36
  38. package/release.mjs +12 -4
  39. package/releases.json +18 -0
  40. package/remote-client.mjs +1 -1
  41. package/remote-transport.mjs +48 -16
  42. package/scope-amendment-client.mjs +1 -1
  43. package/scope-amendment-consumption.mjs +32 -0
  44. package/scope-amendment-mutation.mjs +3 -4
  45. package/scope-amendment-observer.mjs +7 -3
  46. package/scope-amendment-remote.mjs +12 -2
  47. package/scope-amendment-retirement.mjs +54 -0
  48. package/scope-amendment-state.mjs +7 -4
  49. package/scope-amendment-wire.mjs +3 -2
  50. package/task-entry-client.mjs +1 -0
  51. package/workflow-observation-client.mjs +11 -0
  52. package/workflow-observation-connection.mjs +2 -1
  53. package/workflow-observation-remote.mjs +26 -1
  54. package/workflow-observation-wire.mjs +6 -3
@@ -2,7 +2,7 @@ import path from 'node:path';
2
2
  import { canonical, sha256 } from './local-integrity.mjs';
3
3
  import { withStateLock } from './local-state-lock.mjs';
4
4
  import { mutationId14, mutationPaths14, mutationTarget14, mutationFail14, privateMutationDirectory14,
5
- readMutationJson14, atomicMutationJson14 } from './local-mutation-files.mjs';
5
+ atomicMutationJson14 } from './local-mutation-files.mjs';
6
6
  import { preparePreservedMutationSigner, preservedMutationLocation } from './local-preserved-mutation-signer.mjs';
7
7
  import { snapshotPlan14, snapshotVerify14 } from './local-mutation-snapshot.mjs';
8
8
  import { attestMutationSnapshot14 } from './local-mutation-binding.mjs';
@@ -17,8 +17,10 @@ import { appendInvocation, readInvocations } from './local-invocations.mjs';
17
17
  import { bootstrapCloudMutationAuthority } from './cloud-mutation-authority.mjs';
18
18
  import { attestMutationConsumption14, preservedMutationConsumptionState } from './local-mutation-consumption.mjs';
19
19
  import { scopeAmendmentRefreshAction } from './scope-amendment-reference.mjs';
20
+ import { readMutationConnection as readConnection } from './mutation-connection-state.mjs';
21
+ import { readMutationEnvironmentObservation } from './local-mutation-environment-observation.mjs';
22
+ import { refreshExpiredMutationChallenge } from './mutation-challenge-refresh.mjs';
20
23
 
21
- const schema = 'entrorove.mutation-connection-state/1.0';
22
24
  const fields = ['taskId', 'flowId', 'stepId', 'leaseId', 'generation', 'runnerId', 'paths'];
23
25
  const fail = message => mutationFail14('ENTROROVE_MUTATION_CONNECTION_BINDING', message);
24
26
  const unknown = requestId => Object.assign(new Error(`Mutation connection outcome is unknown; recover original requestId=${requestId} without repeating its POST`),
@@ -36,18 +38,6 @@ function inputIdentity(input) {
36
38
  if (Object.hasOwn(input, 'previousPassId')) mutationId14(input.previousPassId, 'previousPassId');
37
39
  return { ...input, paths: mutationPaths14(input.paths) };
38
40
  }
39
- async function readConnection(location, identity) {
40
- let value;
41
- try { value = await readMutationJson14(location.file); }
42
- catch (error) { if (error.code !== 'ENOENT') throw error; }
43
- if (!value) return { schemaVersion: schema, identity };
44
- if (value.schemaVersion !== schema || canonical(value.identity) !== canonical(identity)
45
- || value.pending && (value.pending.requestId !== buildInvocation(value.pending.operation, value.pending.input).requestId
46
- || !['mutation-snapshot-challenge', 'mutation-pass-issue', 'mutation-pass-settle'].includes(value.pending.operation))) {
47
- fail('Mutation connection journal differs from the original repository, request or physical key');
48
- }
49
- return value;
50
- }
51
41
  async function recoverRemote(pending, dependencies) {
52
42
  try {
53
43
  const token = await dependencies.readCredential(dependencies.home), origin = trustedOrigin(dependencies.apiOrigin());
@@ -90,7 +80,11 @@ async function remote(stage, operation, input, state, location, dependencies) {
90
80
  }
91
81
  }
92
82
  delete state.pending;
83
+ if (result.feedback) state.feedback = result.feedback;
93
84
  if (!response.ok || !['succeeded', 'reported'].includes(result?.output?.status)) {
85
+ const failure = { operation, requestId, code: result?.output?.code ?? null, ...(result?.output ? { output: result.output } : {}),
86
+ ...(result.feedback ? { feedback: result.feedback } : {}) };
87
+ if (canonical(state.failures?.at(-1) ?? null) !== canonical(failure)) state.failures = [...(state.failures ?? []), failure];
94
88
  try { await save(location, state); } catch { throw unknown(requestId); }
95
89
  throw Object.assign(new Error(result?.output?.message ?? `Mutation connection blocked at ${operation}`),
96
90
  { code: result?.output?.code ?? 'ENTROROVE_MUTATION_CONNECTION_BLOCKED', output: result?.output, requestId });
@@ -103,7 +97,7 @@ async function remote(stage, operation, input, state, location, dependencies) {
103
97
  function challengeBinding(challenge, identity, mutator, options) {
104
98
  mutationChallenge14(challenge, options);
105
99
  if ([...fields, 'previousPassId'].some(field => canonical(challenge[field]) !== canonical(identity[field])) || challenge.repositoryDigest !== sha256(identity.repositoryRoot).slice(0, 32)
106
- || challenge.newFilePaths.length || !challenge.writeDelegation
100
+ || !challenge.writeDelegation
107
101
  || challenge.writeDelegation.mutationKeyId !== mutator.mutationKeyId || challenge.writeDelegation.mutationPublicKey !== mutator.mutationPublicKey) {
108
102
  fail('Mutation challenge must retain the original task, lease, physical repository, paths and separate M signer');
109
103
  }
@@ -147,17 +141,21 @@ async function authorizeCachedConnection(identity, pass, dependencies) {
147
141
  mutationFail14('ENTROROVE_MUTATION_CONNECTION_AUTHORIZATION', 'Current account could not confirm the original active mutation flow');
148
142
  }
149
143
  if (!response.ok || status?.schemaVersion !== 'entrorove.flow-status/1.0' || status.flow?.flowId !== identity.flowId
150
- || status.flow.ownerId !== pass.ownerId || status.flow.stepId !== identity.stepId || status.flow.status !== 'running'
144
+ || status.flow.ownerId !== pass.ownerId || status.flow.stepId !== identity.stepId
145
+ && !memberProducerRepairStepMatches(status, pass, { settledPass: true }) || status.flow.status !== 'running'
151
146
  || !['execute', 'merge', 'deliver'].includes(status.workflow?.phase) || status.workflow.terminalAt
152
147
  || ['pending', 'declined'].includes(status.workflow.authorization)) {
153
148
  mutationFail14('ENTROROVE_MUTATION_CONNECTION_AUTHORIZATION', 'Current account must retain the original owned active flow and business step');
154
149
  }
150
+ return status;
155
151
  }
156
152
  async function connect(identity, local, mutator, location, dependencies) {
157
153
  const state = await readConnection(location, identity);
158
- const challenged = state.challenged ?? await remote('challenged', 'mutation-snapshot-challenge',
154
+ let challenged = state.challenged ?? await remote('challenged', 'mutation-snapshot-challenge',
159
155
  { ...Object.fromEntries(fields.map(field => [field, identity[field]])),
160
156
  ...(identity.previousPassId ? { previousPassId: identity.previousPassId } : {}), mutationPublicKey: mutator.mutationPublicKey }, state, location, dependencies);
157
+ challenged = await refreshExpiredMutationChallenge({ state, identity, mutator, location, dependencies, fields },
158
+ { remote, save, challengeBinding });
161
159
  const challenge = challenged.challenge;
162
160
  challengeBinding(challenge, identity, mutator, { live: !state.gatePassPath });
163
161
  const input = { ...local, snapshotId: challenge.snapshotId };
@@ -167,9 +165,14 @@ async function connect(identity, local, mutator, location, dependencies) {
167
165
  if (canonical(stored) !== canonical(state.issued.pass)) fail('Installed mutation pass differs from its original connection');
168
166
  await authorizeCachedConnection(identity, stored, dependencies);
169
167
  const consumption = await preservedMutationConsumptionState({ ...input, gatePassPath: state.gatePassPath });
170
- if (consumption.complete) return { schemaVersion: 'entrorove.mutation-connection/1.0', status: 'blocked', flowId: identity.flowId,
171
- code: 'ENTROROVE_MUTATION_SETTLEMENT_REQUIRED', gatePassPath: state.gatePassPath,
172
- message: 'Original physical writes are consumed; settle their actual M receipt with fresh S evidence before requesting the next restricted pass',
168
+ const expiredIncomplete = !consumption.complete && Date.parse(stored.expiresAt) <= Date.now();
169
+ const hasWrites = Object.values(consumption.ledger.writes).some(value => value.status === 'written');
170
+ if (consumption.complete || expiredIncomplete) return { schemaVersion: 'entrorove.mutation-connection/1.0', status: 'blocked', flowId: identity.flowId,
171
+ code: expiredIncomplete ? hasWrites ? 'ENTROROVE_MUTATION_PARTIAL_SETTLEMENT_REQUIRED' : 'ENTROROVE_MUTATION_UNUSED_SETTLEMENT_REQUIRED'
172
+ : 'ENTROROVE_MUTATION_SETTLEMENT_REQUIRED', gatePassPath: state.gatePassPath,
173
+ message: expiredIncomplete && !hasWrites
174
+ ? 'Close only the original expired unused pass with fresh S and exact unchanged unwritten targets. Zero writes do not complete work or authorize tests; unknown pending effects remain refused'
175
+ : 'Settle only the actual original completed writes with fresh S. Preserve original protection, failed records and any exact unchanged unwritten targets; unknown pending effects remain refused',
173
176
  localAction: await scopeAmendmentRefreshAction({ ...input, gatePassPath: state.gatePassPath }, stored) ?? { command: 'npx @entrorove/skill mutation-settle <absolute repositoryRoot>',
174
177
  input: { taskId: stored.taskId, flowId: stored.flowId, stepId: stored.stepId, gatePassPath: state.gatePassPath } } };
175
178
  passBinding(state.issued.pass, challenge, state.attestation);
@@ -193,7 +196,7 @@ async function connect(identity, local, mutator, location, dependencies) {
193
196
  function connected(identity, state) {
194
197
  return { schemaVersion: 'entrorove.mutation-connection/1.0', status: 'succeeded', taskId: identity.taskId,
195
198
  flowId: identity.flowId, stepId: identity.stepId, gatePassPath: state.gatePassPath, pass: state.issued.pass,
196
- purpose: 'preserved-existing-modify', grantsExecutionAuthority: false, grantsValidatorAuthority: false,
199
+ purpose: state.issued.pass.writeDelegation.purpose, grantsExecutionAuthority: false, grantsValidatorAuthority: false,
197
200
  ...(state.feedback ? { feedback: state.feedback } : {}) };
198
201
  }
199
202
  export async function connectMutation(repositoryRoot, input, dependencies) {
@@ -203,7 +206,7 @@ export async function connectMutation(repositoryRoot, input, dependencies) {
203
206
  local.repositoryRoot = location.root;
204
207
  for (const relative of original.paths) {
205
208
  const target = await mutationTarget14(location.root, relative, true);
206
- if (!target.exists || !target.stat.isFile()) fail('Mutation connection permits only concrete existing files');
209
+ if (target.exists && !target.stat.isFile()) fail('Mutation connection permits only an absent approved creation or a concrete existing file');
207
210
  }
208
211
  await bootstrapCloudMutationAuthority(dependencies);
209
212
  const mutator = await preparePreservedMutationSigner(local);
@@ -226,7 +229,7 @@ async function settleMutation(repositoryRoot, input, dependencies) {
226
229
  await bootstrapCloudMutationAuthority(dependencies);
227
230
  const local = { ...input, repositoryRoot, home: dependencies.home }, original = await preservedMutationConsumptionState(local);
228
231
  const { pass, binding } = original;
229
- await authorizeCachedConnection({ flowId: pass.flowId, stepId: pass.stepId }, pass, dependencies);
232
+ const flowStatus = await authorizeCachedConnection({ flowId: pass.flowId, stepId: pass.stepId }, pass, dependencies);
230
233
  const directory = path.join(binding.directory, 'settlements'); await privateMutationDirectory14(directory, { privateFrom: binding.stateRoot });
231
234
  const location = { ...binding, file: path.join(directory, `${pass.passId}.json`) };
232
235
  const identity = { flowId: pass.flowId, stepId: pass.stepId, passDigest: sha256(canonical(pass)),
@@ -250,17 +253,31 @@ async function settleMutation(repositoryRoot, input, dependencies) {
250
253
  }
251
254
  settlementBinding(output, pass, state.consumptionReceipt, state.settlementId);
252
255
  if (state.settlementId === undefined) { state.settlementId = output.settlementId; await save(location, state); }
256
+ const remaining = state.consumptionReceipt.unwritten?.map(file => file.path);
257
+ const environmentObservation = await readMutationEnvironmentObservation(local, pass);
253
258
  return { schemaVersion: 'entrorove.mutation-settlement/1.0', status: 'reported', settled: true,
254
259
  flowId: pass.flowId, taskId: pass.taskId, passId: pass.passId, settlementId: output.settlementId,
255
260
  consumptionReceiptDigest: output.consumptionReceiptDigest,
261
+ ...(environmentObservation ? { environmentObservation, environmentObservationAcknowledgedByServer: false } : {}),
256
262
  claimsVerifiedExecution: false, claimsCompletion: false, ...(state.feedback ? { feedback: state.feedback } : {}),
257
- observationAction: { command: 'npx @entrorove/skill workflow-observe-step <absolute repositoryRoot>', independentValidation: 'pending',
258
- input: { taskId: pass.taskId, flowId: pass.flowId, stepId: pass.stepId, leaseId: pass.leaseId,
259
- generation: pass.generation, settlementId: output.settlementId } },
263
+ ...(remaining ? { partial: true, unused: state.consumptionReceipt.writes.length === 0,
264
+ writtenPaths: state.consumptionReceipt.writes.map(file => file.path), unwrittenPaths: remaining } : {}),
265
+ ...(!remaining ? { observationAction: { command: 'npx @entrorove/skill workflow-observe-step <absolute repositoryRoot>', independentValidation: 'pending',
266
+ input: settlementObservationInput(output, pass, flowStatus) } } : {}),
260
267
  localAction: { command: 'npx @entrorove/skill mutation-connect <absolute repositoryRoot>',
261
- input: { ...Object.fromEntries(fields.map(field => [field, pass[field]])), previousPassId: pass.passId } } };
268
+ input: { ...Object.fromEntries(fields.map(field => [field, pass[field]])), ...(remaining ? { paths: remaining } : {}), previousPassId: pass.passId } } };
262
269
  });
263
270
  }
271
+ function settlementObservationInput(output, pass, flowStatus) {
272
+ const original = Object.fromEntries(['taskId', 'flowId', 'stepId', 'leaseId', 'generation'].map(k => [k, pass[k]]));
273
+ original.settlementId = output.settlementId;
274
+ const dependencyRepairDigest = memberProducerRepairDependency(flowStatus, pass);
275
+ const input = output.observationInput ?? { ...original, ...(dependencyRepairDigest ? { dependencyRepairDigest } : {}) };
276
+ const { dependencyRepairDigest: dependency, ...identity } = input;
277
+ if (canonical(identity) !== canonical(original) || dependency !== undefined && !/^[a-f0-9]{64}$/.test(dependency)
278
+ || dependencyRepairDigest && dependency !== dependencyRepairDigest) fail('Observation guidance lost its original settled identity or accepted ancestor repair');
279
+ return input;
280
+ }
264
281
  async function runMutationClient(operation, repositoryRoot, input, dependencies, work) {
265
282
  let preflight = true;
266
283
  try {
@@ -290,3 +307,4 @@ async function runMutationClient(operation, repositoryRoot, input, dependencies,
290
307
  }
291
308
  export const runMutationConnect = (repositoryRoot, input, dependencies) => runMutationClient('mutation-connect', repositoryRoot, input, dependencies, connectMutation);
292
309
  export const runMutationSettle = (repositoryRoot, input, dependencies) => runMutationClient('mutation-settle', repositoryRoot, input, dependencies, settleMutation);
310
+ import { memberProducerRepairStepMatches, memberProducerRepairDependency } from './member-producer-repair-authority.mjs';
@@ -0,0 +1,17 @@
1
+ import { canonical } from './local-integrity.mjs';
2
+ import { readMutationJson14, mutationFail14 } from './local-mutation-files.mjs';
3
+ import { buildInvocation } from './remote-client.mjs';
4
+
5
+ export const mutationConnectionSchema = 'entrorove.mutation-connection-state/1.0';
6
+ export async function readMutationConnection(location, identity) {
7
+ let value;
8
+ try { value = await readMutationJson14(location.file); }
9
+ catch (error) { if (error.code !== 'ENOENT') throw error; }
10
+ if (!value) return { schemaVersion: mutationConnectionSchema, identity };
11
+ if (value.schemaVersion !== mutationConnectionSchema || canonical(value.identity) !== canonical(identity)
12
+ || value.pending && (value.pending.requestId !== buildInvocation(value.pending.operation, value.pending.input).requestId
13
+ || !['mutation-snapshot-challenge', 'mutation-pass-issue', 'mutation-pass-settle'].includes(value.pending.operation))) {
14
+ mutationFail14('ENTROROVE_MUTATION_CONNECTION_BINDING', 'Mutation connection journal differs from the original repository, request or physical key');
15
+ }
16
+ return value;
17
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@entrorove/skill",
3
- "version": "0.1.61",
3
+ "version": "0.1.64",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "entrorove": "cli.mjs"
@@ -93,10 +93,18 @@
93
93
  "scope-amendment-state.mjs",
94
94
  "scope-amendment-wire.mjs",
95
95
  "scope-amendment-remote.mjs",
96
+ "scope-amendment-retirement.mjs",
96
97
  "scope-amendment-observer.mjs",
97
98
  "scope-amendment-mutation.mjs",
99
+ "scope-amendment-consumption.mjs",
100
+ "mutation-connection-state.mjs",
101
+ "mutation-challenge-refresh.mjs",
98
102
  "scope-amendment-reference.mjs",
99
103
  "cloud-task-client.mjs",
104
+ "cloud-task-images.mjs",
105
+ "cli-input.mjs",
106
+ "model-images.mjs",
107
+ "model-images.d.mts",
100
108
  "task-entry-client.mjs",
101
109
  "task-identity.mjs",
102
110
  "task-identity.d.mts",
@@ -147,6 +155,8 @@
147
155
  "local-scope-candidate.mjs",
148
156
  "local-scope-context.mjs",
149
157
  "local-scope-files.mjs",
158
+ "local-scope-font.mjs",
159
+ "local-scope-zip.mjs",
150
160
  "local-scope-import-expressions.mjs",
151
161
  "local-scope-create-require.mjs",
152
162
  "local-scope-require-resolution.mjs",
@@ -257,12 +267,18 @@
257
267
  "local-approved-process.mjs",
258
268
  "local-approved-supervisor.mjs",
259
269
  "local-mutation-consumption.mjs",
270
+ "local-mutation-completion-evidence.mjs",
271
+ "local-mutation-environment-observation.mjs",
272
+ "local-mutation-finder-observation.mjs",
273
+ "local-finder-store.mjs",
274
+ "local-finder-plist.mjs",
260
275
  "workflow-observation-client.mjs",
261
276
  "workflow-observation-connection.mjs",
262
277
  "workflow-observation-remote.mjs",
263
278
  "workflow-observation-runner.mjs",
264
279
  "workflow-observation-state.mjs",
265
- "workflow-observation-wire.mjs"
280
+ "workflow-observation-wire.mjs",
281
+ "member-producer-repair-authority.mjs"
266
282
  ],
267
283
  "scripts": {
268
284
  "test": "node test/run.mjs",
@@ -1,29 +1,45 @@
1
1
  {
2
2
  "schemaVersion": "entrorove.release-state/1.0",
3
- "version": "0.1.61",
4
- "digest": "8211a23e233808dfc8f43dd0b28af5eae9b8bea5127b9550da8e8c50d9447052",
3
+ "version": "0.1.64",
4
+ "digest": "56a07e4deb7b361010313c592e4b95e5f9b3f2398726ea626f1172114dcff019",
5
5
  "files": {
6
+ "cloud-task-images.mjs": "a260a94b6b1b47df97a8cc8657dfdce1fd37ec752f1cc2bad2542eaa28622bdb",
7
+ "model-images.mjs": "ab85ac0c44d857c1f460de3e9c06eb1d37b57688b4a6061405c0a44ae4d40bd7",
8
+ "model-images.d.mts": "f1506cfb8ad287869f92f4d9074c7c759c6c28b182aeb325dd5f22a38926f24c",
9
+ "cli-input.mjs": "44dc2692714023b622a9370c13cabc09c7c39e6aea6e7183b80ae5bcd2e8d24e",
10
+ "scope-amendment-retirement.mjs": "849f2b5fc8ec5204d7a58222f7ee775b7514244b854439ef3549563cd44c14c2",
11
+ "scope-amendment-consumption.mjs": "12a1dfd1429350cc9503957224398524c077aed6c697228c9870aa95c245ee7d",
12
+ "mutation-connection-state.mjs": "05bed65a4636a2128e9a48d2e910c5f5a25f0e990f181f58008dd09cac0fbcb5",
13
+ "mutation-challenge-refresh.mjs": "eac9b18bdfbd968d815321e66c4f6e482fb1be59662abb9dc8b02f35b9ced809",
14
+ "local-scope-font.mjs": "a69f9da932ed41aa4718036f98f75c0b17ba7f616a5c8bf5623fa9ed697499fa",
15
+ "local-scope-zip.mjs": "b8a5f2a75394c23e570c28218a8c0b3bcd626ccc87eba550e759b6c38a68871e",
16
+ "member-producer-repair-authority.mjs": "1e84e5e77ba5ee9a0dcaa4d843061c7b5447191852d7b2fb603b91cfa7c796e4",
17
+ "local-mutation-completion-evidence.mjs": "d894f7f7d3b5a906e4c869b02ab0abacbd16dc35987a2fe14ff8fa2cf264a62b",
18
+ "local-mutation-environment-observation.mjs": "8afffe21cb9a7f6cc889e5af9b5c9953684635a90ca4b98d797547bd7831bafb",
19
+ "local-mutation-finder-observation.mjs": "438dd33e62e03e02b55897a28b3ba59d12734b6e5142525b299f77c21537280b",
20
+ "local-finder-store.mjs": "227191c52174386ace6391e072b78a6e4cc658a6d9dd37036ffd7e97bbf4336a",
21
+ "local-finder-plist.mjs": "c83ddab2375a54d612d395a5518db8ae05212437d82bf3f8b76930a8859c8481",
6
22
  "connected-cli.mjs": "79c3359303957a9ebb8987e3dfb181f189d380fa02ef4462683b786aedfc7802",
7
23
  "local-approved-process.mjs": "442856df788e63f38757439ba0657d1c689aaf797631a955fae3dd639e844e6d",
8
24
  "local-approved-supervisor.mjs": "87142a4c13d27c8265cc1fd7fc9088988da9bbb02134164e1a7c5417da926ac7",
9
- "local-mutation-consumption.mjs": "cd8650b9be894639ceb35af88d23c8002b4acff27afad2e64174eb21a9424cfb",
25
+ "local-mutation-consumption.mjs": "1b033655f817ec576410b7f91f1640b8651f3cff0668154fb8e6e14e7b31d8f4",
10
26
  "workflow-local-acceptance.mjs": "743ae19c1edff473af2596c7356ddff3892ff9acfb3bcaa660b662eacba463a8",
11
- "workflow-observation-client.mjs": "4ad34e5a467954ad1943a0f003e07dd6c4fb919d197ae9175a8b0c9b6e2aff32",
12
- "workflow-observation-connection.mjs": "00e887c1430b13fc49c3f51ae814edb7a05c6d61ed7091262ae91a0706fad084",
13
- "workflow-observation-remote.mjs": "26f7d741d2e00e4cb05240d8999378b6db3cb1c52eaa586ac20f9448fe296e4b",
27
+ "workflow-observation-client.mjs": "5032a6cd7d1e0fa6b80170a7c1298cf14f2c21cf017426465aa48e2a944bcf08",
28
+ "workflow-observation-connection.mjs": "b1958417d9f94bf7b9474c69acc82fa5de7f7c4e37aa7f3977a8f7e3836a82b1",
29
+ "workflow-observation-remote.mjs": "3a444cab88b426e6af018625cfb4aaddcc5d7c05c505ed18715494dd18a6e1de",
14
30
  "workflow-observation-runner.mjs": "3eb8280ec7abffcb30398e3f4e5f7d0ec3df4385fa720f188ed83757b87cd977",
15
31
  "workflow-observation-state.mjs": "a525046df9b3de75b10d2bf35c2b6d7719f12a647e4aee1f1e85dbdbfb167321",
16
- "workflow-observation-wire.mjs": "90047ca4fe028e4931406ff26d4fe871bcafb28a59c456795aae4f5c4b739e43",
17
- "local-preserved-mutation-protection.mjs": "95041d4f75253a153c7fd85573ba0457513ffe47a6a6bd00c4f59379b81ce580",
32
+ "workflow-observation-wire.mjs": "df0d5e4f8fde0be8bf06c6c4590cd158b4da05ebe6ef3169d2366db706f3327f",
33
+ "local-preserved-mutation-protection.mjs": "5186a2f682e66c6828d1504ee074554cbae0fda58a5f446fbadfb868e1682dae",
18
34
  "local-preserved-mutation-signer.mjs": "2b0771cbdd18ba00267aa441b7892cd04feab9f8543ae5e2703430b1e580747f",
19
35
  "local-preserved-mutation-state.mjs": "337a172b2d0a03b0d5a89b8483afdd9a043a4999fe38f87679633c98c450126b",
20
- "local-preserved-mutation-wire.mjs": "2f2f623e768d49af59dbb9bb8245627cb7e72184e5a5d3239d91f395152cf9bf",
36
+ "local-preserved-mutation-wire.mjs": "6768ce5713d70f7c0bd05f2286bc4b32cd9b8bb1d3c8b9cc7a451cb9b176824d",
21
37
  "local-delegated-modify-analysis.mjs": "f87148ddb023b79e241ca97db582991da8d0e1a51b26b1d9bc2799a76efd7297",
22
- "mutation-client.mjs": "6455c35b483d6d22e42e7be708630db07d9fd1d3cdf639294b126b69db2eae2f",
38
+ "mutation-client.mjs": "da09b2aa301da8cbc7b830a3dfe1fbf2617798ae26e4ccddea802443a8253527",
23
39
  "cloud-mutation-authority.mjs": "c7226e882a4f3be4d2f55728f515d5a815c0aa1f21aa5e4689314e6e6a8c66a2",
24
40
  "ide-code-mode.mjs": "f8ba4de33632ab4c6df52dab52f392414b4632c7e94b218b8065677970c075c7",
25
41
  "ide-command.mjs": "dbdb4cbf8e870c93a746ca176cbbdeffc0458de1293583d3eb9af4c256541370",
26
- "ide-hook.mjs": "c44d37997fae55bd113ff9044947c54152aaccdf081d0f39d437179d33e9a4e2",
42
+ "ide-hook.mjs": "f2a00be9293ce13ba8b8547142744a7edc43d4e2e82727e9f7923ba79a244d75",
27
43
  "ide-install.mjs": "1c80e191ddc2ac8789f0c71edc7bc8c3c8cea6bfab537cdf6baffa4a6ce3419c",
28
44
  "ide-session.mjs": "5277a6ea3445bfa9b2e28847372d963da77787d472d0414c0e253d4fe29f74ec",
29
45
  "break-glass.mjs": "6ec9f97c5d68bb33121b2374c06b9d4c8eb3419b52d00849fec7124bc63e4582",
@@ -37,10 +53,10 @@
37
53
  "local-scope-import-expressions.mjs": "20f1e065582c68d2334e0dfaa130a559ff19886a57f9038dc569f65993bb06c8",
38
54
  "local-discipline-contracts.mjs": "ab0c11dcc4a6ffd3cb79b53862c19308eaf0d159deee7f9958266852d977363e",
39
55
  "local-discipline-contracts.d.mts": "defc684c78dc88afa1c54340ab4a01ae36db7aa11257cbe1f5cd323f608c78c4",
40
- "local-discipline-gate.mjs": "e3851157bf1d8bc86eb44212a88acd20acfc2d1152e7d87af6dc2a37afffcd6f",
56
+ "local-discipline-gate.mjs": "d7e92a541fbb5bce60285ab2e1a6e210d478a6b4c8404961f33e40ade962e829",
41
57
  "local-discipline-native.mjs": "8b99b5ce951cab3c1426428ad807650c61c0ffb2c346d747b73b99057b382049",
42
58
  "local-discipline-operations.mjs": "9fcb7b8889b7718d42e1d37936485d8198d5017d405e0cdbbabdbbd12fcc9d48",
43
- "local-discipline-repository.mjs": "b6392e02ecae333dfdc8df41f203fd69bed035d88b15b16d112ab1897b3c297c",
59
+ "local-discipline-repository.mjs": "ca997be4289180600cb97ba2938b6b99210e5d5d5317374b130a886cb712d624",
44
60
  "local-discipline-snapshot.mjs": "8fd35b2cfbece8f64579f144f589a66dec9b6022d50fe931c4c1f886cb83134d",
45
61
  "local-runner-discipline.mjs": "8d4ada838f81d54963adbb7e433f1ca80ae1934ea126f90c59a49d29742979c4",
46
62
  "local-integrity.d.mts": "21357f306234bd841c0d3d90bf2d09f7663f63746f897b9f38190428ae8198b3",
@@ -50,8 +66,8 @@
50
66
  "runtime/validator-runtime-v7.0.44.d.mts": "7797edbfe2f7de24da370204dce4dfd22822a1bd80df93514fff900b98afe36f",
51
67
  "snapshot-retention.mjs": "ca46aeb36b1a5a24fe7e967031a71b9a3d33f40cb715d344402cbe0dc9c425cb",
52
68
  "snapshot-cleanup-journal.mjs": "76a9684cc95b4eb076e1298d78a9dff37948b00d9607b8f546c599072d3ed331",
53
- "IDE-EXECUTION.md": "203aa4ae47cc45915e1a89bd7fbb56bf57aebccef444599b3a2d1d2816f01907",
54
- "REUSE-DISCIPLINE.md": "5b214cf313e7f715f52d54e28093a2d038f0f196ca64b15d1c49587b9d8eecf8",
69
+ "IDE-EXECUTION.md": "e7e9c19f19f095f5483784bb8de1e610eb008e8e62504b4229e38a9728b89573",
70
+ "REUSE-DISCIPLINE.md": "377df04e93bca02731f15055857bd93b3b9656acdcf121735a46a0114516880c",
55
71
  "reuse-discipline-release.mjs": "7f55ae10ec3396ed3bc5430a0c64f94c33c2dfbc57b32084caab92fd5fd1586f",
56
72
  "local-final-gate16.mjs": "083aec470670e6cdb7ad2ab27b7a51b53a9ec3a8b4121cb9cbfa17d9940892c2",
57
73
  "local-final-gate16-checks.mjs": "1dd30e9666d458d8b12ca6e4975f6f0ac8450c3ea9cbecc7401ae037f66b589a",
@@ -94,19 +110,19 @@
94
110
  "local-autocoord17-waits.mjs": "2b0a713987822548a94e1ed3a9a891532db45383797dfc5d5bc8d1e35593cf25",
95
111
  "local-validator-isolation17.mjs": "48e94604e28b8fddd567dfb35ff60b73fd094a5803bd49f076388b7f310f92aa",
96
112
  "local-calctool-composition17.mjs": "ac89fcb41ab0d0d9b47c1b5696945281b0894eb064820775e36a011c76314e6a",
97
- "cli.mjs": "b28bfda3d9ec610c7865725eff4e5d551bcbdfc8847f6fd43eca845ce3881ea8",
113
+ "cli.mjs": "2198b5b0bc6c9a5fcba8b2c488c548c22b63ed56c4f7cdbc93d41784a2650bdf",
98
114
  "ide-selection.mjs": "e11e2b363c06444f1dcb4cdab1eaa0eb748a379b84354e0e71fd9c2dc79a4815",
99
- "ide-exit.mjs": "c890c7b34fa6f12e0ccff7a7b85738d515fb13ad93f671a8547ae6570b66488d",
115
+ "ide-exit.mjs": "39d60a15b1517d402c208d22a17033976e43733be8a10dc6da386837c59b37b2",
100
116
  "install-cleanup.mjs": "8a8e1a7dfe37427f86cd4d6e317890d0829894a9949d4216674a716b36edbc54",
101
117
  "review-client.mjs": "3491eef68ed533174b31db3c53febb6519b8f088f71a9964644714a9a4c03c77",
102
118
  "version.mjs": "1f392147d72c40af4b03b307ea607075fb815af5174fa07e254b95fe12dbf3e7",
103
- "SKILL.md": "f04566431da716ff61812118004ca69f2a8f9f24fe4e032f2a1fff5073b8071b",
104
- "CAPABILITY-MAP.md": "e420bbc202c27d983635ae33b823b39dd445cf5cdf40ffe88e210a755cb7424d",
119
+ "SKILL.md": "3f1f4d586a712a790ebb4247840ce6345511226ead7b26154d76b0322f8b753a",
120
+ "CAPABILITY-MAP.md": "c8f211755d106acdc47ed512119089d406712088ed167847b791ca9c47ce103e",
105
121
  "AGREEMENT.md": "f93a68e92c457200dd024610e65f74e478b8f60860f951da818b70561f1b9bf8",
106
122
  "DELIVERY-BOUNDARIES.md": "9b9db50ed1bcce9e77ff6527b6bb7eaf12f3b913162ea9cb7fe90db06b393a4f",
107
- "package.json": "ce0f78910ec9aeb36a7d61a30a68c6b117c9b29ca34cc8446a46604b251c131e",
123
+ "package.json": "2ebbf6ceaf4c2622073e51659c91a6917cabe260d11b60aa370edc2a42c4464d",
108
124
  "manifest.json": "ab06e307795bc9da5add926752b6c4dbdaf18625090261a035aa356a679c504f",
109
- "release.mjs": "90e4c5beb05e263c2cacf09c476480ac3599a965d62e0adda68226a8baaa968c",
125
+ "release.mjs": "046cff9905ed74a467bcc08227ece55e640950d06bf8a2d3268387691b493400",
110
126
  "local-cli.mjs": "41e2a737c8587cb5ce469a7661f6d14b5ea4cd073f8286822fc4dc96b67f56a1",
111
127
  "local-state-lock.mjs": "1dbf64264642a0851faf043e07ee9f66d2ad0508e9f799b0626246e42fae893e",
112
128
  "local-execution.mjs": "185f34e917440a360b3c4bafd3af245243807d964ae3820b3cffaaa2e6348cc6",
@@ -144,8 +160,8 @@
144
160
  "local-stage-boundary.mjs": "84c3bb5beab29306274c5ca8a78f19a83ed664ae1b93a8372bb493158b304fe3",
145
161
  "local-scope-candidate.mjs": "8f0bd9606e70d4a0ebacdd3cd600ec3afed85e2bb3e1760aa1144cf55d4e028a",
146
162
  "local-scope-context.mjs": "79753abfc6c76089d17f003a1be537dfaea10d6731c542f7fc53f2a9996ed164",
147
- "local-scope-files.mjs": "4c14a5e226dd5518aeb37f199b1aa896943a66d41e5a1757a3b3fd8a79446d76",
148
- "local-scope-repository.mjs": "941eb895c8210da1ca90e8b3d1d6936c24408d10139fe6c3eba2761329248392",
163
+ "local-scope-files.mjs": "db8b3baf8118c6cfd5525cbc008e054f9f33390b9ffce5ba72ee986b832f33e3",
164
+ "local-scope-repository.mjs": "55f130f7c54a378cb12ab9b81c07b14bf17f96a8d994314b0c8f35803bbdca1c",
149
165
  "local-scope-create-require.mjs": "6b6a209bfcad8fe1398e99c5c8cc3af189c120b9c38e244a73dd1a99c3d91295",
150
166
  "local-scope-require-resolution.mjs": "b24596462c8776cbefa6f0a74749d665aa928d1643c68d44798eb93e2dd5ad42",
151
167
  "local-scope-git.mjs": "53bbbb6c4795db711b5bc164591a6ad79a561427da046d6bbe997dae6eb82829",
@@ -178,15 +194,15 @@
178
194
  "local-scope-state.mjs": "8b600a91fc0068d7a8c0bb752ddba7ed30ada93daafb118d6cba2368fd94cb27",
179
195
  "local-scope-workspaces.mjs": "a44c34537e5ed2dcaf193a985e5bc05957989fbb160a650f9e37ba7d66eb2de8",
180
196
  "local-task-routing.mjs": "6e2e506b2fb0e2e8d8c5147d7df32849b57a4e94a23634f01a355d45735858e4",
181
- "remote-client.mjs": "0d1ec6506fe53a1e33c31c5ba19d14e30e00e85e11eaf7ff8277ea798b9f36c9",
182
- "cloud-task-client.mjs": "11acb1a033c94cdfbdfb177a3402ad97f6a5226f577138c8cf6395dc3ebb1a39",
197
+ "remote-client.mjs": "d1fdc4a65fb6d7f79af0bf5a6551319386f1127a0632927fd11600a178d41769",
198
+ "cloud-task-client.mjs": "603a7de8e1d56a77588f08f7d1ae93685b553b40815e268d7bd17018eb767c37",
183
199
  "scope-runner-client.mjs": "2afcbb8bc8a26d03f26787cb2ffd9994c4377757d16d54aa0c83752a29e833ea",
184
- "scope-amendment-client.mjs": "2161daaee131cc209d7ab75cde91a920cbca98153e7e7fd058ba5aacdf6789a3",
185
- "scope-amendment-state.mjs": "045375115cdca8c265f1bfd14d5cb052fcd24a97c5cc1e50a44a6f6725319698",
186
- "scope-amendment-wire.mjs": "bc4c80fda3154b7151006f7bed6cc0884050868e7ba936309b6516ed5c20512f",
187
- "scope-amendment-remote.mjs": "e73bc3e67b8adb663d679cdcc46f0f1a18529d0bf14dd1f6cdf21ad87ead7c71",
188
- "scope-amendment-observer.mjs": "6c0539e4ac0f738939a169826400d822d68c1e70ca2d87a9fe10a26945158770",
189
- "scope-amendment-mutation.mjs": "9b120b60aef4d04790a75d599595c5251649b843996f66ebe02e9ac40ffb99b2",
200
+ "scope-amendment-client.mjs": "64a38deddc2dbfae543fead2cff8c9c78771b576391cc903aa58db925a138ad7",
201
+ "scope-amendment-state.mjs": "ad82af0ff06e4969f733328a68d18e1ff3553b8ed93400c19963744083918ab9",
202
+ "scope-amendment-wire.mjs": "3c4823e23bbdf330616bb675f07f9fcad7423266bd50b92e1134d226060e9b83",
203
+ "scope-amendment-remote.mjs": "15a0b3126248f3101a52e3d7742f9a816dd3d8e58f21bac33e99e810e86cc4fd",
204
+ "scope-amendment-observer.mjs": "473f08d66ebd35d87db7e651c0521d1d4bdb6fa337afaedb241bcf9c6289d9d3",
205
+ "scope-amendment-mutation.mjs": "fa24191df290efad29d41eca3d1a081981fefde02b7dc4a11c75c6118a69106e",
190
206
  "scope-amendment-reference.mjs": "0537e53a1bea4b695f4804c5051261778c88f05b1ae4aff86c709dcfe83aa148",
191
207
  "native-client.mjs": "6f5575909bae9daba643287f876ffa0f9ff1c53a367b32a40145d740456d6605",
192
208
  "native-notification.mjs": "8859a26c6f13d222711f763acf49ed8546b3306cf71f990643ac31a5ccaf1ba1",
@@ -195,10 +211,10 @@
195
211
  "cloud-event-stream.mjs": "e0eec9fc3e0613094523929634f25030df5ca5c5b5fe2c1e1a4586ab10574808",
196
212
  "ide-presentation.mjs": "3bac21bfc824fcdad63aafb0d7c3326cd6456923f4224106dd5c38682060f315",
197
213
  "automatic-feedback-client.mjs": "532312d29e66fa211ea3fe879d9add1dd48841ee5ce82800b4b06252a160a255",
198
- "task-entry-client.mjs": "869f234402c4149eadf1ec138705fc140e2fa16b2a3ea5dc2b2f51dfb189d7de",
214
+ "task-entry-client.mjs": "940fb068afe28a2a34fe96e285e149afdd9ba79649c0c65cde37ec4ed71ae39d",
199
215
  "task-identity.mjs": "e0e6cf1f48bfa5ee3c5cb86a3c21adfce6d66b4220f4a164ca099263c7a09fb4",
200
216
  "task-identity.d.mts": "55472e1ffc81b9d5e5c5bd56c0bf1d18ecde03ee5170a58a15ce9caf222d8761",
201
- "remote-transport.mjs": "93caaca646fca298a4e08142678b134ecc3a657e00de5b9939e2364b2db9d6c4",
217
+ "remote-transport.mjs": "cf0e31a0319518b6c7e1ce2ac99766a98fe9c936d26bbbec05952aaf0c33efb0",
202
218
  "local-credential.mjs": "2a302a7f67b5ea8dc73453fc96ab33db349b59ca11fa9456e48ca1d9669d877c",
203
219
  "local-invocations.mjs": "f6ac4c41c1a5ec34de358c4cca210ca8e403b3a913150a43bb55ec9be55d9998",
204
220
  "local-task-handoff-fence.mjs": "5532a359ee29b885f7ce0cf7178f76dba0fc9245bdd92ef460982275baf0d557",
@@ -218,7 +234,7 @@
218
234
  "workflow-local-request.mjs": "4e24c543ce386292a87dc9cd41f90d23375f12079cacffc515c8cd01fd571780",
219
235
  "task-message-entry.mjs": "31d10056cb905237cd5649e8eb067009ff1612ec5dc1061e0373209fbc0b646a",
220
236
  "task-message-cli.mjs": "3ca65e96c28129b3bd5cac962d106e0859a1f17df1f6a66ee543c6efc22f918d",
221
- "local-contracts.mjs": "b59fcdace17b0b56117c564f8c15322465243e69adede182c5dde9204836c99c",
237
+ "local-contracts.mjs": "e739967e3ffade96589c0a3fd519829452b44e1982aa3af11d6802ddfbb7f53a",
222
238
  "local-contract-types.mjs": "85e71fa4dd67e351a4b67573c740bcdb1661cede53f097189f11837771e75e91",
223
239
  "local-archguard-ast.mjs": "7ff7df9dab0d98ed62983add751c80edea598bc94ef4f38ede0ebd4d41226c87",
224
240
  "local-archguard-checkpoint.mjs": "37896902520cc995720c96288e4a5ed3585952b55c9c35be281f91fa754c71ec",
@@ -248,10 +264,10 @@
248
264
  "local-mutation-files.mjs": "087b00e8424a135e783eb432271012a71e55eeb4a5e30119490d1bc0b2160320",
249
265
  "local-mutation-snapshot.mjs": "f9077539680fb8d3ff33a962657756a8fe6afa8409b6191334509534216ebfe8",
250
266
  "local-mutation-audit.mjs": "5a30ee3446f632e032ffcfe46bcd97d6dfc0f099a76ea5185c3f9a9118c4f6cb",
251
- "local-mutation-wire.mjs": "fe251b3112d2394c5a0ab108f067ec17fb8569db7be9b3ceb86fab25c68e98e9",
267
+ "local-mutation-wire.mjs": "6d00400e531c693c3e8bfd0c2a24fcc486127f84aafc56ee450dcec7f534eb05",
252
268
  "local-mutation-binding.mjs": "4440d792453a07a375b635fa5a91db607e58162824baced5c79a9a513f4ec918",
253
269
  "local-mutation-pass-store.mjs": "1edc5fcc537dfa04b8ae8b07af554d61ea5911a5da281423ad57214ccf753ad4",
254
- "local-mutation-authority.mjs": "e6b79430ee6b5eb28173843a5faaf1c277da1e5ca7c1dcbd6d96cd60c4460c59",
270
+ "local-mutation-authority.mjs": "e60e7150e6d887a51ce5903ab947606b30088231d22e85a0c8bf3f29f1d1fd1f",
255
271
  "local-mutation-batch.mjs": "de27686b5f99a99b02f0218a3fa159e9469d6b19c595117287d6dd37a6efcb3b",
256
272
  "local-mutation-batch-receipt.mjs": "b0e6a8522867255d899e60b66677885933f6a1c4c771cbb52f84dbbbdcf5e5c2",
257
273
  "calctool-runtime-entry.mjs": "98d2bc8df38d16131fc56db0a3d4d260531ba4df412baa5ddc4b8b5c5ca99fe9",
package/release.mjs CHANGED
@@ -47,6 +47,10 @@ const memberContinuationSourceFiles = Object.freeze([
47
47
  'workflow-observation-wire.mjs',
48
48
  ])
49
49
  const sourceFiles = [
50
+ 'cloud-task-images.mjs', 'model-images.mjs', 'model-images.d.mts', 'cli-input.mjs',
51
+ 'scope-amendment-retirement.mjs', 'scope-amendment-consumption.mjs', 'mutation-connection-state.mjs', 'mutation-challenge-refresh.mjs',
52
+ 'local-scope-font.mjs', 'local-scope-zip.mjs', 'member-producer-repair-authority.mjs',
53
+ 'local-mutation-completion-evidence.mjs', 'local-mutation-environment-observation.mjs', 'local-mutation-finder-observation.mjs', 'local-finder-store.mjs', 'local-finder-plist.mjs',
50
54
  ...memberContinuationSourceFiles,
51
55
  ...preservedMutationSourceFiles,
52
56
  ...REUSE_DISCIPLINE_SOURCE_FILES,
@@ -295,10 +299,6 @@ const taskEntryReleaseLabels = {
295
299
  }
296
300
 
297
301
  function releaseNote(changed) {
298
- if (changed.some(file => file.startsWith('scope-amendment-'))) return {
299
- zh: '新增同一任务的精确范围补正:原账号审核文件哈希与写入/只读角色,原S签名真实事实并重评原合同;计划、写入和结算绑定不可变范围修订,改后刷新保留原M消费证据与失败历史。',
300
- en: 'Add same-task exact scope amendment with original owner review of file hashes and write/read-only roles, original S observations and native contract reassessment; bind plans, writes and settlement to immutable scope revisions and retain actual M consumption and failure history during post-write refresh.',
301
- }
302
302
  const suppliedZh = process.env.ENTROROVE_RELEASE_NOTE_ZH?.trim()
303
303
  const suppliedEn = process.env.ENTROROVE_RELEASE_NOTE_EN?.trim()
304
304
  if (Boolean(suppliedZh) !== Boolean(suppliedEn)) {
@@ -307,6 +307,10 @@ function releaseNote(changed) {
307
307
  if (suppliedZh && suppliedEn) return {
308
308
  zh: suppliedZh.replaceAll(/\s+/g, ' '), en: suppliedEn.replaceAll(/\s+/g, ' '),
309
309
  }
310
+ if (changed.some(file => file.startsWith('scope-amendment-'))) return {
311
+ zh: '新增同一任务的精确范围补正:原账号审核文件哈希与写入/只读角色,原S签名真实事实并重评原合同;计划、写入和结算绑定不可变范围修订,改后刷新保留原M消费证据与失败历史。',
312
+ en: 'Add same-task exact scope amendment with original owner review of file hashes and write/read-only roles, original S observations and native contract reassessment; bind plans, writes and settlement to immutable scope revisions and retain actual M consumption and failure history during post-write refresh.',
313
+ }
310
314
  if (changed.includes('scope-runner-client.mjs')) return {
311
315
  zh: '补齐账号与任务隔离的本地签名器和真实快照接入,解析实际别名及类型声明;动态依赖仅进入受限规划,保留独立写入核验。',
312
316
  en: 'Connected account-bound scope signers and real snapshots, resolved actual aliases and declarations, and retained restricted planning for unresolved dynamic imports with separate mutation verification.',
@@ -334,6 +338,10 @@ const archguardReleaseLabels = {
334
338
  }
335
339
  function releaseLabels() {
336
340
  return withFinalGate16ReleaseLabels({ ...reuseDisciplineReleaseLabels, ...calctoolReleaseLabels, ...mutationReleaseLabels, ...swarmReleaseLabels, ...coordination17ReleaseLabels, ...nativeReadReleaseLabels, ...feedbackReleaseLabels, ...invocationReleaseLabels, ...chainReleaseLabels, ...taskEntryReleaseLabels, ...archguardReleaseLabels,
341
+ ...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' }])),
342
+ ...Object.fromEntries(['scope-amendment-retirement.mjs', 'scope-amendment-consumption.mjs', 'mutation-connection-state.mjs', 'mutation-challenge-refresh.mjs', 'member-producer-repair-authority.mjs'].map(name => [name, { zh: '原授权恢复与请求生命周期', en: 'original-authority recovery and request lifecycle' }])),
343
+ ...Object.fromEntries(['local-scope-font.mjs', 'local-scope-zip.mjs'].map(name => [name, { zh: '字体与 ZIP 完整结构核验', en: 'font and ZIP structural verification' }])),
344
+ ...Object.fromEntries(['local-mutation-completion-evidence.mjs', 'local-mutation-environment-observation.mjs', 'local-mutation-finder-observation.mjs', 'local-finder-store.mjs', 'local-finder-plist.mjs'].map(name => [name, { zh: '原写入完成证据与系统元数据观察', en: 'original write completion evidence and system metadata observation' }])),
337
345
  'blueprint-criterion-wire.mjs': { zh: '蓝图验收标准执行授权', en: 'Blueprint criterion execution authority' },
338
346
  'blueprint-criterion-runner.mjs': { zh: '蓝图验收标准实际执行器', en: 'Blueprint criterion process runner' },
339
347
  'cli.mjs': { zh: '技能运行和受管安装', en: 'skill runtime and managed installation' },
package/releases.json CHANGED
@@ -1,4 +1,22 @@
1
1
  [
2
+ {
3
+ "version": "0.1.64",
4
+ "date": "2026-10-19",
5
+ "zh": "统一交付原合同连续执行与失败恢复修复:受限完整响应、原请求结算恢复、过期挑战与未用授权处理、已批准依赖与二进制核验、系统元数据观察;新增图片输入并适配 DeepSeek V4.1 Flash,完善中英文明确退出及无 IDE 记录的离线退出。保留范围、签名、预算及失败和未知记录;缺少进程终局证据的观察仍拒绝重跑。",
6
+ "en": "Deliver original-contract continuation and recovery fixes for bounded complete responses, original-request settlement, expired challenges and unused grants, approved dependencies, verified binary inputs and system metadata observations. Add image inputs for DeepSeek V4.1 Flash and bilingual explicit offline exit, including sessions without an IDE record. Preserve scope, signatures, budgets, failures and unknown outcomes; observations without terminal process evidence still cannot rerun."
7
+ },
8
+ {
9
+ "version": "0.1.63",
10
+ "date": "2026-10-18",
11
+ "zh": "修复精确大范围补正的组合回执保存;原 M 授权支持真实二进制字节,保留源代码分析、原路径及结算校验。范围风险提高必须另经原账号明确重评。",
12
+ "en": "Retain combined receipts for exact large scope amendments and write actual binary bytes through the original M authority, preserving source analysis, paths and settlement checks. Higher scope risk requires explicit original-owner reassessment."
13
+ },
14
+ {
15
+ "version": "0.1.62",
16
+ "date": "2026-10-18",
17
+ "zh": "补齐本地新项目的受控创建与原生产步骤内迭代:原账号审批精确不存在路径和生产节点,S 与独立 M 签名校验真实基线,保留源文件只读保护、合同预算及失败历史。支持 PHP、JSON、原生模板、WXML、WXSS,通过实际创建、结算、测试和最终本地验收;钩子仍可关闭。",
18
+ "en": "Support governed creation and iteration of new local project files within their original producer and accepted plan. Bind exact absent paths and producers to owner approval, actual S and separate M evidence, protected sources, contract budgets and immutable failures. Cover PHP, JSON, native templates, WXML and WXSS through real writes, settlement, tests and final local acceptance while keeping hooks optional."
19
+ },
2
20
  {
3
21
  "version": "0.1.61",
4
22
  "date": "2026-10-18",
package/remote-client.mjs CHANGED
@@ -35,7 +35,7 @@ function discoveredAjv() {
35
35
  }
36
36
 
37
37
  export function buildInvocation(operation, input) {
38
- if (!['capabilities', 'task-describe', 'message-route', 'message-accept', 'task-resume', 'task-checkpoint', 'flow-cancel', 'flow-abandon',
38
+ if (!['capabilities', 'scope-challenge-retire', 'task-describe', 'message-route', 'message-accept', 'task-resume', 'task-checkpoint', 'flow-cancel', 'flow-abandon',
39
39
  'message-status', 'message-delivery-start', 'message-delivery-report', 'message-resolve', 'message-complete',
40
40
  'handoff-prepare', 'handoff-release', 'handoff-claim', 'handoff-status', 'handoff-resume', 'handoff-execution-authority', 'mutation-snapshot-challenge', 'mutation-pass-issue', 'mutation-pass-settle',
41
41
  'member-observation-admit', 'member-observation-report', 'member-observation-status',
@@ -1,9 +1,14 @@
1
1
  import http from 'node:http';
2
2
  import https from 'node:https';
3
+ import { createGunzip } from 'node:zlib';
3
4
 
4
5
  const PRE_CONNECT = new Set(['ECONNREFUSED', 'ECONNRESET', 'EAI_AGAIN', 'ENOTFOUND', 'ENETUNREACH',
5
6
  'ENETDOWN', 'EHOSTUNREACH', 'ETIMEDOUT', 'ECONNABORTED']);
6
- const MAX_BYTES = 1_048_576;
7
+ // A scope response retains its exact role map, signed S/W proof and recovery
8
+ // records together. Bound the whole envelope rather than one embedded record.
9
+ const MAX_BYTES = 8_388_608;
10
+ const RESPONSE_CODES = new Set(['RESPONSE_TOO_LARGE', 'RESPONSE_INTERRUPTED',
11
+ 'RESPONSE_ENCODING_INVALID', 'RESPONSE_ENCODING_UNSUPPORTED']);
7
12
 
8
13
  export function trustedOrigin(value) {
9
14
  let url;
@@ -15,34 +20,60 @@ export function trustedOrigin(value) {
15
20
  return url.origin;
16
21
  }
17
22
 
18
- function failure(code, established) {
19
- return Object.assign(new Error(established ? 'Entrorove response was interrupted after connection establishment'
23
+ function failure(code, established, detail = {}) {
24
+ return Object.assign(new Error(code === 'RESPONSE_TOO_LARGE' ? 'Entrorove response exceeds the bounded eight MiB envelope limit'
25
+ : code === 'RESPONSE_ENCODING_INVALID' ? 'Entrorove response has invalid compressed content'
26
+ : code === 'RESPONSE_ENCODING_UNSUPPORTED' ? 'Entrorove response uses an unnegotiated content encoding'
27
+ : established ? 'Entrorove response was interrupted after connection establishment'
20
28
  : 'Entrorove connection failed before request transmission'), {
21
29
  code: 'ENTROROVE_TRANSPORT', established, retryableBeforeTransmission: !established && PRE_CONNECT.has(code),
22
- transportCode: PRE_CONNECT.has(code) ? code : 'CONNECTION_REJECTED',
30
+ transportCode: PRE_CONNECT.has(code) || RESPONSE_CODES.has(code) ? code : 'CONNECTION_REJECTED',
31
+ ...(code === 'RESPONSE_TOO_LARGE' ? { responseLimitBytes: MAX_BYTES, receivedBytes: detail.receivedBytes } : {}),
23
32
  });
24
33
  }
25
34
 
35
+ function readResponse(response, request, done) {
36
+ const encoding = response.headers['content-encoding']?.trim().toLowerCase();
37
+ const decoded = encoding === 'gzip' ? createGunzip() : response;
38
+ const chunks = []; let size = 0; let wireBytes = 0; let ended = false;
39
+ const fail = cause => {
40
+ if (ended) return; ended = true; done(cause);
41
+ if (decoded !== response) decoded.destroy(); response.destroy(); request.destroy();
42
+ };
43
+ response.on('aborted', () => fail({ code: 'RESPONSE_INTERRUPTED' }));
44
+ response.on('error', cause => fail(cause));
45
+ if (encoding && !['identity', 'gzip'].includes(encoding)) {
46
+ fail({ code: 'RESPONSE_ENCODING_UNSUPPORTED' }); return;
47
+ }
48
+ if (decoded !== response) decoded.on('error', () => fail({ code: 'RESPONSE_ENCODING_INVALID' }));
49
+ response.on('data', chunk => {
50
+ if (ended) return; wireBytes += chunk.length;
51
+ if (wireBytes > MAX_BYTES) fail({ code: 'RESPONSE_TOO_LARGE', receivedBytes: wireBytes });
52
+ });
53
+ decoded.on('data', chunk => {
54
+ if (ended) return; size += chunk.length;
55
+ if (size > MAX_BYTES) fail({ code: 'RESPONSE_TOO_LARGE', receivedBytes: size });
56
+ else chunks.push(chunk);
57
+ });
58
+ decoded.on('end', () => {
59
+ if (ended) return; ended = true;
60
+ done(null, { ok: response.statusCode >= 200 && response.statusCode < 300,
61
+ status: response.statusCode, headers: response.headers, body: Buffer.concat(chunks).toString('utf8') });
62
+ });
63
+ if (decoded !== response) response.pipe(decoded);
64
+ }
65
+
26
66
  async function attempt(url, options) {
27
67
  return new Promise((resolve, reject) => {
28
68
  let established = false; let settled = false;
29
69
  const done = (cause, result) => {
30
70
  if (settled) return; settled = true; clearTimeout(timer);
31
- if (cause) reject(failure(cause.code, established)); else resolve(result);
71
+ if (cause) reject(failure(cause.code, established, cause)); else resolve(result);
32
72
  };
33
73
  const client = url.protocol === 'https:' ? https : http;
34
74
  const request = client.request(url, { method: options.method, headers: options.headers,
35
75
  agent: false }, response => {
36
- established = true; const chunks = []; let size = 0;
37
- response.on('data', chunk => {
38
- size += chunk.length;
39
- if (size > MAX_BYTES) { done({ code: 'RESPONSE_TOO_LARGE' }); response.destroy(); request.destroy(); }
40
- else chunks.push(chunk);
41
- });
42
- response.on('aborted', () => done({ code: 'RESPONSE_INTERRUPTED' }));
43
- response.on('error', cause => done(cause));
44
- response.on('end', () => done(null, { ok: response.statusCode >= 200 && response.statusCode < 300,
45
- status: response.statusCode, headers: response.headers, body: Buffer.concat(chunks).toString('utf8') }));
76
+ established = true; readResponse(response, request, done);
46
77
  });
47
78
  request.on('socket', socket => {
48
79
  socket.once(url.protocol === 'https:' ? 'secureConnect' : 'connect', () => { established = true; });
@@ -57,7 +88,8 @@ export async function requestTransport(origin, pathname, options = {}) {
57
88
  const trusted = trustedOrigin(origin);
58
89
  if (typeof pathname !== 'string' || !pathname.startsWith('/api/') || pathname.includes('://')) throw new Error('Invalid Entrorove API path');
59
90
  const url = new URL(pathname, trusted);
60
- const configured = { timeoutMs: 15_000, method: 'GET', ...options };
91
+ const configured = { timeoutMs: 15_000, method: 'GET', ...options,
92
+ headers: { ...options.headers, 'accept-encoding': 'gzip' } };
61
93
  const originalGeneration = configured.method === 'GET' && /^\/api\/skill\/feedback\/[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(url.pathname)
62
94
  && /^\?generation=[1-9][0-9]{0,14}$/.test(url.search) && Number.isSafeInteger(Number(url.searchParams.get('generation')));
63
95
  if (url.origin !== trusted || url.hash || url.search && !originalGeneration) throw new Error('Invalid Entrorove API path');