@entrorove/skill 0.1.83 → 0.1.84

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.84 — 2026-10-23
4
+
5
+ - 修复能力发现失败误报业务请求未知的问题:分别保留原业务与发现请求编号、传输原因和未发送记录,阻止轮询无持久结果的发现编号,并保留同一业务请求此前的未知执行记录。
6
+ - Separate discovery failures from business execution with original and discovery request IDs, transport causes and unsent-attempt records; reject discovery status polling while preserving earlier unknown business transmissions.
7
+
3
8
  ## 0.1.83 — 2026-10-23
4
9
 
5
10
  - 补齐 Blueprint 验收申请、查询与报告的 SDK 调用入口,修复只读查询的反馈回执判定;兼容原冻结计划的时间戳格式,修正 Calctool 打包与加载的完整性绑定。
package/IDE-EXECUTION.md CHANGED
@@ -47,6 +47,8 @@ Initialize the SDK/task/signer/snapshot once and reuse valid records. Public key
47
47
 
48
48
  Recovery has a durable bound: two automatic retries per unchanged verified prerequisite set or signing transition, three original GET recovery observations, and two retries of an explicitly known pre-admission prerequisite. Repeating the same reserved recovery after a crash does not allocate a new attempt. A known pre-effect request may continue after its original workflow records new verified execution, acceptance or approved stage progress. Preserve its original envelope, fenced generations, total attempts and append-only failures. Budgets for previous progress points remain spent; caller hints, a fresh signature, status polling, a new nonce, an empty journal or an altered task cannot reset them. `ENTROROVE_RECOVERY_EXHAUSTED` preserves the original result and pending evidence and disables retries without progress. Report the specific failure once for repair. Never replay unknown POST/PUT, clear records or repeatedly stop/ask the same permission.
49
49
 
50
+ If discovery fails before the business call, the SDK returns `ENTROROVE_DISCOVERY_FAILED` with the original business `requestId`, separate discovery `sourceRequestId`, `knownBeforeTransmission: true`, and available transport/HTTP cause. Do not poll the discovery ID: it has no persisted execution result. Resolve discovery before continuing the unchanged original command. This observation covers only that attempt and never resolves a previous unknown business transmission; the SDK preserves that prior ledger state. `status` rejects the discovery ID locally with `ENTROROVE_DISCOVERY_NOT_PERSISTED`, without sending repeated GETs.
51
+
50
52
 
51
53
  ### IDE display and cloud planning entry
52
54
 
package/SKILL.md CHANGED
@@ -5,7 +5,7 @@ description: Route a task selected for Entrorove among its eight skills, approve
5
5
 
6
6
  # entrorove · 熵巡
7
7
 
8
- Version: 0.1.83.
8
+ Version: 0.1.84.
9
9
 
10
10
  Entrorove applies only to the task for which it is selected; reading these instructions, discovering capabilities or installing the package never selects or governs another task. Hooks are optional. Reading this document or calling an entry once does not execute the task. On every later turn, including after compaction, continue the original task and its required next operation before dependent work. Keep the original goal, scope, account, flow, cloud task and failure records. Never describe planning, a reported step or model output as verified delivery.
11
11
 
@@ -19,6 +19,8 @@ Reuse the task binding, installed public key pin, accepted snapshot identity, sc
19
19
 
20
20
  Automatic recovery is finite: at most two retries with unchanged verified prerequisites, two retries of an unchanged signing transition, and three original GET recovery observations. A known pre-effect request can continue when its original workflow records new verified prerequisites; its original input, total attempts and failure history remain intact. A process restart, status poll, fresh signature or new nonce does not reset the saved counter. When exhausted without progress, preserve the original state and report the concrete failure once; do not generate further attempts, ask the same approval again, clear history or force Stop to loop. Unknown effects remain GET-only. See [IDE-EXECUTION.md](IDE-EXECUTION.md#one-task-entrance-approval).
21
21
 
22
+ Capability discovery failures are separate from business execution. `ENTROROVE_DISCOVERY_FAILED` identifies the pending business `requestId` and the discovery `sourceRequestId`; `knownBeforeTransmission` describes only that unsent attempt. Capability discovery has no stored execution status, so never poll its ID as business recovery. Preserve any earlier unknown transmission of the same business request; a failed discovery cannot clear it or authorize a replay.
23
+
22
24
  ## Required execution
23
25
 
24
26
  1. Install `npx --yes --prefer-online @entrorove/skill@latest install --host codex` only when the user chooses to install this skill. The default installs the skill with hooks disabled and removes its recorded Codex hooks on upgrade, preserving other host settings. SDK calls work directly in an IDE without a hook callback or supported hook adapter; retain the actual host identity. Missing credentials, failed discovery and the SDK/API's scope, approval and evidence checks still return explicit failures.
package/manifest.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": "entrorove.skill-manifest/1.0",
3
3
  "name": "entrorove",
4
- "version": "0.1.83",
4
+ "version": "0.1.84",
5
5
  "endpoint": "https://entrorove.com",
6
6
  "requestSchemaVersion": "entrorove.skill.request/2.0",
7
7
  "supportedRequestSchemaVersions": [
package/native-client.mjs CHANGED
@@ -1,9 +1,8 @@
1
1
  import Ajv from 'ajv';
2
2
  import { canonical, sha256 } from './local-integrity.mjs';
3
- import { postInvocation } from './remote-client.mjs';
3
+ import { invokeDiscovery, postInvocation } from './remote-client.mjs';
4
4
  import { presentInvocationNotices } from './ide-presentation.mjs';
5
5
  import { trustedOrigin } from './remote-transport.mjs';
6
- import { discoveryPrerequisite } from './service-prerequisite.mjs';
7
6
 
8
7
  const domains = new Set(['aimlock', 'blueprint', 'calctool', 'swarm', 'validator', 'mergeguard', 'archguard', 'confirm-protocol']);
9
8
  const runtimeCodes = { aimlock: 'R3mQ8kWpXn', blueprint: 'wvz6zmRWmX', calctool: 'KKyA6xljUX', swarm: 'zj7fTPVh4p',
@@ -48,10 +47,7 @@ export async function invokeNativeResult(domain, operation, input, dependencies)
48
47
  const token = await dependencies.readCredential(home);
49
48
  let feedbackRequired = operation !== 'capabilities';
50
49
  if (operation !== 'capabilities') {
51
- let discovery;
52
- try { discovery = await postInvocation(buildNativeInvocation(domain, 'capabilities', {}, dependencies.apiOrigin()), token, home); }
53
- catch (error) { throw discoveryPrerequisite(error, call.requestId); }
54
- if (!discovery.response.ok || discovery.result.output.status !== 'succeeded') throw new Error('Native capability discovery failed');
50
+ const discovery = await invokeDiscovery(call, buildNativeInvocation(domain, 'capabilities', {}, dependencies.apiOrigin()), token, home);
55
51
  const found = discovery.result.output;
56
52
  const extension = (found.capabilities ?? found).responseExtensions;
57
53
  if (extension?.automaticFeedback === 'entrorove.automatic-feedback/1.0') feedbackRequired = !extension.automaticFeedbackObservations.includes(operation);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@entrorove/skill",
3
- "version": "0.1.83",
3
+ "version": "0.1.84",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "entrorove": "cli.mjs"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": "entrorove.release-state/1.0",
3
- "version": "0.1.83",
4
- "digest": "2a81190915dd2751aabaca0cf73018081e26a30c24d2bbacb8c6ace10968213e",
3
+ "version": "0.1.84",
4
+ "digest": "5329be638282179dadf323b72d02062c84ac1e6fbedcefb57ac29cf0c8271079",
5
5
  "files": {
6
6
  "local-recovery-budget.mjs": "be3af07db8e4cc96782edb130e827039c7a99bbe8275a92f0f741533716017f3",
7
7
  "remote-capability-cache.mjs": "9c22067e1a21eb2a209747a8ab2f27c0496b14a22a7e0f5654840e2035148df0",
@@ -92,7 +92,7 @@
92
92
  "runtime/validator-runtime-v7.0.44.d.mts": "7797edbfe2f7de24da370204dce4dfd22822a1bd80df93514fff900b98afe36f",
93
93
  "snapshot-retention.mjs": "ca46aeb36b1a5a24fe7e967031a71b9a3d33f40cb715d344402cbe0dc9c425cb",
94
94
  "snapshot-cleanup-journal.mjs": "76a9684cc95b4eb076e1298d78a9dff37948b00d9607b8f546c599072d3ed331",
95
- "IDE-EXECUTION.md": "8376b69934ad02b268fd66a704821c0ebcd2c7eda04c0a2c6dec2ea6d393d8b8",
95
+ "IDE-EXECUTION.md": "14172eb6d0d69b410fa630996fbf1f1769d528dbab884d1489667ebb0794a8ba",
96
96
  "REUSE-DISCIPLINE.md": "f1d9c2002c0214bad0aa72aa696b39a4bd6ee4b5a236e804799e22de3418c686",
97
97
  "install-identity.mjs": "41b8c8d8b3e265d2057a07bf7dc98066c34d6b05c65bf7159ca9609c01ee4646",
98
98
  "package-archive.mjs": "e06db8d709db8710bead254ee950b78928088be01c58dcea383beaa5eb574e59",
@@ -174,7 +174,7 @@
174
174
  "install-cleanup.mjs": "8a8e1a7dfe37427f86cd4d6e317890d0829894a9949d4216674a716b36edbc54",
175
175
  "review-client.mjs": "3491eef68ed533174b31db3c53febb6519b8f088f71a9964644714a9a4c03c77",
176
176
  "version.mjs": "85284d4cd5e3314b449e6ae124243f96397bcc274817b5983a79cfdd903d46fd",
177
- "SKILL.md": "5f68fe2742dfd64feeff7e5071719c1de5d09dd7f33f44cb742499f6dab3d3c9",
177
+ "SKILL.md": "c2baf4c0d6661526944caad19f63c16d7d560c7519f9452bd7f5c50e59e166a8",
178
178
  "CAPABILITY-MAP.md": "57805ba6a4b4fc79ffadb3bd1436999f82c295feac7bdc230bdc123f67662546",
179
179
  "AGREEMENT.md": "f93a68e92c457200dd024610e65f74e478b8f60860f951da818b70561f1b9bf8",
180
180
  "DELIVERY-BOUNDARIES.md": "cb23ce71b2197085c8441ba7c5b6c05fb21f2a954bf66b4d60cfef8b15895b8b",
@@ -257,8 +257,8 @@
257
257
  "local-scope-state.mjs": "7a6d275d6267a4d0bb55582e1bcc7654c502ecba9221b84b2149a98f0ee7518f",
258
258
  "local-scope-workspaces.mjs": "8a75ce7b6639b5682370b5738c5c2a90408e3130729608e008f03053cd50351f",
259
259
  "local-task-routing.mjs": "6e2e506b2fb0e2e8d8c5147d7df32849b57a4e94a23634f01a355d45735858e4",
260
- "remote-client.mjs": "218843be687c147f60b2a231f678faac66d5e675336b860873e682daf77f08d9",
261
- "service-prerequisite.mjs": "2361168ea12ca95faee75c79657a486af5e7edaf1ec8182f8f1afdf59f15c9a5",
260
+ "remote-client.mjs": "cb7be06201305da7b53cd21bb73b3dcdc3c8fb263855fdf731d6aeb39e080184",
261
+ "service-prerequisite.mjs": "7ac5a66d8b423941a5a2cef3aecce18a681aaf2b1a61612fecfa17f5d99f302d",
262
262
  "local-source-execution.mjs": "88f6ce1ea50d0a7b92e0cb47d535f8140491c52d9c6c0dfddf91ea90397a36f5",
263
263
  "fs-request-trace.mjs": "972eacbe21537bc102047127327449a6a4b0f0c65d75e3472370de91dedf4d2f",
264
264
  "cloud-task-client.mjs": "ab3e0296363b6af10eaa38a09dd43b4ae6e5704d699c7a5032fee1b7817fa0dc",
@@ -270,7 +270,7 @@
270
270
  "scope-amendment-observer.mjs": "9091f2e11b094b8a8cd27ad1454031d11a34ecb6923295fd6edfaa07c54899ee",
271
271
  "scope-amendment-mutation.mjs": "fa24191df290efad29d41eca3d1a081981fefde02b7dc4a11c75c6118a69106e",
272
272
  "scope-amendment-reference.mjs": "dc1768131beb7db224dd2ff8522dbf6361f73e01f466c9334cdfa24118720078",
273
- "native-client.mjs": "522228a97d5d7dafde18b778856b3c499b6c6f75b13eae6f57c0050521233692",
273
+ "native-client.mjs": "1ad18c402fd1eadb3c186b547dbd075be35af34cfd46b8e5c8a0d15aac3ad4c2",
274
274
  "native-notification.mjs": "8859a26c6f13d222711f763acf49ed8546b3306cf71f990643ac31a5ccaf1ba1",
275
275
  "local-peer-status.mjs": "a971bcc69d60bb32b875ca5bb4297d948631d5d2821b812c279613ea059a8b4f",
276
276
  "cloud-watch-client.mjs": "eccce52bce1c915a71fe9a1fa3e435dba5af9a5455afdf478f04684901b6fb7b",
package/releases.json CHANGED
@@ -1,4 +1,10 @@
1
1
  [
2
+ {
3
+ "version": "0.1.84",
4
+ "date": "2026-10-23",
5
+ "zh": "修复能力发现失败误报业务请求未知的问题:分别保留原业务与发现请求编号、传输原因和未发送记录,阻止轮询无持久结果的发现编号,并保留同一业务请求此前的未知执行记录。",
6
+ "en": "Separate discovery failures from business execution with original and discovery request IDs, transport causes and unsent-attempt records; reject discovery status polling while preserving earlier unknown business transmissions."
7
+ },
2
8
  {
3
9
  "version": "0.1.83",
4
10
  "date": "2026-10-23",
package/remote-client.mjs CHANGED
@@ -2,7 +2,7 @@ import { createHash } from 'node:crypto';
2
2
  import { pathToFileURL } from 'node:url';
3
3
  import Ajv from 'ajv';
4
4
  import { parseTransportResponse, requestTransport, trustedOrigin } from './remote-transport.mjs';
5
- import { appendInvocation } from './local-invocations.mjs';
5
+ import { appendInvocation, readInvocations } from './local-invocations.mjs';
6
6
  import { acknowledgeAutomaticFeedback, verifyAutomaticFeedback } from './automatic-feedback-client.mjs';
7
7
  import { ideClientHeaders, presentInvocationNotices } from './ide-presentation.mjs';
8
8
  import { routeTaskEntry } from './task-entry-client.mjs';
@@ -104,10 +104,7 @@ async function invokeDiscovered(data, token, { home, apiOrigin }) {
104
104
  let feedbackRequired = false;
105
105
  if (data.operation !== 'capabilities') {
106
106
  const fetch = async () => {
107
- let discovery;
108
- try { discovery = await postInvocation({ ...buildInvocation('capabilities', {}), url: call.url }, token, home); }
109
- catch (error) { throw discoveryPrerequisite(error, call.requestId); }
110
- if (!discovery.response.ok || discovery.result.output.status !== 'succeeded') throw new Error(`Capability discovery failed: HTTP ${discovery.response.status}`);
107
+ const discovery = await invokeDiscovery(call, { ...buildInvocation('capabilities', {}), url: call.url }, token, home);
111
108
  return discovery.result.output.capabilities;
112
109
  };
113
110
  let capabilities = await discoveredCapabilities(new URL(call.url).origin, token, home, fetch);
@@ -123,6 +120,26 @@ async function invokeDiscovered(data, token, { home, apiOrigin }) {
123
120
  return postInvocation(call, token, home,feedbackRequired);
124
121
  }
125
122
 
123
+ export async function invokeDiscovery(original, discovery, token, home) {
124
+ try {
125
+ const observed = await postInvocation(discovery, token, home);
126
+ if (!observed.response.ok || observed.result.output.status !== 'succeeded') {
127
+ throw Object.assign(new Error('Capability discovery was rejected'), { httpStatus: observed.response.status });
128
+ }
129
+ return observed;
130
+ } catch (cause) {
131
+ const error = discoveryPrerequisite(cause, original.requestId, discovery.requestId);
132
+ // A failed discovery did not send this attempt. Never let that observation
133
+ // overwrite an earlier unresolved transmission of the same business ID.
134
+ const rows = await readInvocations(home);
135
+ const previous = rows.filter(row => row.kind === 'remote' && row.requestId === original.requestId).at(-1);
136
+ if (!previous || previous.event === 'not-sent') {
137
+ await appendInvocation({ kind: 'remote', operation: original.body.operation, requestId: original.requestId, event: 'not-sent' }, home);
138
+ }
139
+ throw error;
140
+ }
141
+ }
142
+
126
143
  export async function postInvocation(call, token, home, feedbackRequired = false) {
127
144
  const metadata = { kind: 'remote', operation: call.body.operation, requestId: call.requestId };
128
145
  const logged = async value => {
@@ -139,12 +156,12 @@ export async function postInvocation(call, token, home, feedbackRequired = false
139
156
  } catch (cause) {
140
157
  if (cause.established) await logged({ event: 'outcome-unknown' });
141
158
  else await appendInvocation({ ...metadata, event: 'not-sent' }, home);
142
- if (cause.established) throw unknownInvocation(call.requestId);
159
+ if (cause.established) throw unknownInvocation(call.requestId, cause);
143
160
  throw Object.assign(new Error(`Entrorove request was not sent; connection failed after ${cause.attempts ?? 1} attempt(s); requestId=${call.requestId}`),
144
161
  { requestId: call.requestId, retryableBeforeTransmission: Boolean(cause.retryableBeforeTransmission), attempts: cause.attempts ?? 1 });
145
162
  }
146
- try { result = await readResponse(response, 'invocation'); } catch {
147
- await logged({ event: 'outcome-unknown' }); throw unknownInvocation(call.requestId);
163
+ try { result = await readResponse(response, 'invocation'); } catch (cause) {
164
+ await logged({ event: 'outcome-unknown' }); throw unknownInvocation(call.requestId, { ...cause, httpStatus: response.status });
148
165
  }
149
166
  if (!response.ok && !result?.output) {
150
167
  const prerequisite = prerequisiteError(response, result, { requestId: call.requestId });
@@ -153,7 +170,7 @@ export async function postInvocation(call, token, home, feedbackRequired = false
153
170
  throw Object.assign(prerequisite, prerequisite.knownBeforeEffects ? {} : { outcomeUnknown: true });
154
171
  }
155
172
  await logged({ event: response.status >= 500 ? 'outcome-unknown' : 'rejected' });
156
- if (response.status >= 500) throw unknownInvocation(call.requestId);
173
+ if (response.status >= 500) throw unknownInvocation(call.requestId, { httpStatus: response.status });
157
174
  const code = typeof result?.error === 'string' && /^[a-z][a-z0-9-]{0,63}$/.test(result.error) ? result.error : 'request-rejected';
158
175
  throw new Error(`entrorove invocation failed: HTTP ${response.status}; ${code}; requestId=${call.requestId}`);
159
176
  }
@@ -180,9 +197,12 @@ export async function postInvocation(call, token, home, feedbackRequired = false
180
197
  return { response, result };
181
198
  }
182
199
 
183
- function unknownInvocation(requestId) {
184
- return Object.assign(new Error(`Invocation outcome is unknown; requestId=${requestId}. Do not automatically resend this request.`),
185
- { requestId, outcomeUnknown: true });
200
+ function unknownInvocation(requestId, cause = {}) {
201
+ const causeCode = [cause.transportCode, cause.code].find(value => typeof value === 'string' && /^[A-Z][A-Z0-9_]{0,63}$/.test(value));
202
+ const httpStatus = Number.isInteger(cause.httpStatus) ? cause.httpStatus : undefined;
203
+ const detail = `${causeCode ? `; cause=${causeCode}` : ''}${httpStatus ? `; HTTP=${httpStatus}` : ''}`;
204
+ return Object.assign(new Error(`Invocation outcome is unknown; requestId=${requestId}${detail}. Do not automatically resend this request.`),
205
+ { requestId, outcomeUnknown: true, ...(causeCode ? { causeCode } : {}), ...(httpStatus ? { httpStatus } : {}) });
186
206
  }
187
207
  async function machineCredential(dependencies) {
188
208
  await dependencies.install();
@@ -216,10 +236,7 @@ export function createTaskMessageClient(dependencies) {
216
236
  let feedbackRequired = false;
217
237
  if (operation !== 'capabilities') {
218
238
  const discovery = buildInvocation('capabilities', {});
219
- let discovered;
220
- try { discovered = await postInvocation({ ...discovery, url: `${origin}/api/skill/invoke` }, token, dependencies.home); }
221
- catch (error) { throw discoveryPrerequisite(error, original.requestId); }
222
- if (!discovered.response.ok || discovered.result.output.status !== 'succeeded') throw new Error('Task message capability discovery failed');
239
+ const discovered = await invokeDiscovery(original, { ...discovery, url: `${origin}/api/skill/invoke` }, token, dependencies.home);
223
240
  validateMachineCapability(operation, input, discovered.result.output.capabilities);
224
241
  feedbackRequired = requiresAutomaticFeedback(operation,input,discovered.result.output.capabilities);
225
242
  }
@@ -250,6 +267,10 @@ export function createTaskMessageClient(dependencies) {
250
267
 
251
268
  export async function queryStatus(requestId, dependencies) {
252
269
  if (typeof requestId !== 'string' || !/^[a-f0-9]{64}$/.test(requestId)) throw new Error('status requires a sha256 requestId');
270
+ if (requestId === buildInvocation('capabilities', {}).requestId) {
271
+ throw Object.assign(new Error('This ID belongs to capability discovery, which has no stored execution result. Stop polling this ID and recover the original business command or workflow; a discovery lookup cannot establish its execution outcome.'),
272
+ { code: 'ENTROROVE_DISCOVERY_NOT_PERSISTED', requestId, repeatStatus: false });
273
+ }
253
274
  const token = await dependencies.readCredential(dependencies.home);
254
275
  const response = await readOnlyGet(dependencies.apiOrigin(), `/api/skill/status/${encodeURIComponent(requestId)}`, { authorization: `Bearer ${token}` }, 'status')
255
276
  const result = await readResponse(response, 'status');
@@ -32,10 +32,20 @@ export function prerequisiteFields(error) {
32
32
  ...(error.knownBeforeTransmission ? { knownBeforeTransmission: true } : {}),
33
33
  ...(error.knownBeforeEffects ? { knownBeforeEffects: true } : {}) } : {};
34
34
  }
35
- export function discoveryPrerequisite(error, requestId) {
36
- if (!servicePrerequisite({ status: 403 }, error?.servicePrerequisite)) return error;
37
- Object.assign(error, { sourceRequestId: error.requestId, requestId, knownBeforeTransmission: true });
38
- delete error.outcomeUnknown; return error;
35
+ export function discoveryPrerequisite(error, requestId, discoveryRequestId = error?.requestId) {
36
+ const sourceRequestId = discoveryRequestId;
37
+ if (servicePrerequisite({ status: 403 }, error?.servicePrerequisite)) {
38
+ Object.assign(error, { sourceRequestId, requestId, knownBeforeTransmission: true });
39
+ delete error.outcomeUnknown; return error;
40
+ }
41
+ const causeCode = [error?.causeCode, error?.transportCode, error?.code].find(value => typeof value === 'string' && /^[A-Z][A-Z0-9_]{0,63}$/.test(value));
42
+ const detail = `${causeCode ? `; cause=${causeCode}` : ''}${Number.isInteger(error?.httpStatus) ? `; HTTP=${error.httpStatus}` : ''}`;
43
+ return Object.assign(new Error(`Capability discovery failed before this business request was sent; requestId=${requestId}; discoveryRequestId=${sourceRequestId}${detail}. Do not poll the discovery ID: capability queries have no stored execution result. Repair discovery, then continue the original command with unchanged input.`), {
44
+ code: 'ENTROROVE_DISCOVERY_FAILED', requestId, sourceRequestId, knownBeforeTransmission: true,
45
+ discoveryOutcomeUnknown: error?.outcomeUnknown === true, grantsExecutionAuthority: false,
46
+ ...(causeCode ? { causeCode } : {}),
47
+ ...(Number.isInteger(error?.httpStatus) ? { httpStatus: error.httpStatus } : {}),
48
+ });
39
49
  }
40
50
  export async function retainPrerequisite(error, state, location, save, field = 'pending') {
41
51
  const pending = state[field], value = servicePrerequisite({ status: 403 }, error?.servicePrerequisite);