@remembrance-ai/opencode-plugin 0.2.3 → 0.2.4

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/opencode.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "command": [
7
7
  "npx",
8
8
  "-y",
9
- "@remembrance-ai/mcp-server@0.2.3"
9
+ "@remembrance-ai/mcp-server@0.2.4"
10
10
  ],
11
11
  "enabled": true,
12
12
  "environment": {
@@ -16,6 +16,6 @@
16
16
  }
17
17
  },
18
18
  "plugin": [
19
- "@remembrance-ai/opencode-plugin@0.2.3"
19
+ "@remembrance-ai/opencode-plugin@0.2.4"
20
20
  ]
21
21
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remembrance-ai/opencode-plugin",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "license": "Apache-2.0",
5
5
  "description": "opencode plugin for Remembrance session hooks, tool observation, and contribution nudges.",
6
6
  "type": "module",
@@ -12058,7 +12058,7 @@ function findIndependentlyEncodedPrivateKeyFrameProof(tokens, metrics) {
12058
12058
  const recoverableLength = recoverableProof?.length ?? null;
12059
12059
  const length = completeLength ?? recoverableLength;
12060
12060
  if (length === null) continue;
12061
- const continuation = recoverableProof?.basis === "factors" ? independentlyEncodedRsaCrtContinuationRanges(
12061
+ const continuation2 = recoverableProof?.basis === "factors" ? independentlyEncodedRsaCrtContinuationRanges(
12062
12062
  tokens,
12063
12063
  frames,
12064
12064
  bytes,
@@ -12073,10 +12073,10 @@ function findIndependentlyEncodedPrivateKeyFrameProof(tokens, metrics) {
12073
12073
  bytes,
12074
12074
  encoding,
12075
12075
  frames,
12076
- continuationRanges: continuation.ranges,
12076
+ continuationRanges: continuation2.ranges,
12077
12077
  start: frame.start,
12078
12078
  end: frame.start + length,
12079
- ambiguous: continuation.ambiguous,
12079
+ ambiguous: continuation2.ambiguous,
12080
12080
  complete: completeLength !== null,
12081
12081
  factorBacked: recoverableProof?.basis === "factors",
12082
12082
  recoverable: completeLength === null
@@ -14713,19 +14713,19 @@ function recordCryptographicMatchedTerminalOwnership(tokens, assessment, metrics
14713
14713
  }
14714
14714
  function matchedTerminalSourcePieceRanges(tokens, assessment) {
14715
14715
  const sourceStart = assessment.sourcePieceRanges[0].start;
14716
- const continuation = assessment.rsaCrtContinuations.filter(
14716
+ const continuation2 = assessment.rsaCrtContinuations.filter(
14717
14717
  (candidate) => candidate.start === sourceStart && candidate.status === "match" && candidate.mismatchAt === null
14718
14718
  ).sort((left, right) => right.matchedEnd - left.matchedEnd)[0];
14719
- if (!continuation) return [];
14719
+ if (!continuation2) return [];
14720
14720
  const ranges = [];
14721
14721
  for (const [pieceIndex, token] of tokens.entries()) {
14722
14722
  const source = assessment.sourcePieceRanges[pieceIndex];
14723
- if (source.end <= continuation.matchedEnd) {
14723
+ if (source.end <= continuation2.matchedEnd) {
14724
14724
  ranges.push({ pieceIndex, start: 0, end: token.value.length });
14725
14725
  continue;
14726
14726
  }
14727
- if (source.start >= continuation.matchedEnd) continue;
14728
- const matchedLength = continuation.matchedEnd - source.start;
14727
+ if (source.start >= continuation2.matchedEnd) continue;
14728
+ const matchedLength = continuation2.matchedEnd - source.start;
14729
14729
  if (matchedLength > 0 && /^=+$/u.test(token.value.slice(matchedLength))) {
14730
14730
  ranges.push({ pieceIndex, start: 0, end: token.value.length });
14731
14731
  }
@@ -15604,13 +15604,13 @@ function assessEncodedPieceSequence(pieces, textOf, metrics, requireBoundedRecov
15604
15604
  (completeRange) => completeRange.start < end && start < completeRange.end
15605
15605
  );
15606
15606
  const authenticatedFactorRange = scanned.rsaCrtContinuations.some(
15607
- (continuation) => {
15608
- const ownedEnd = Math.min(end, continuation.matchedEnd);
15609
- if (continuation.start >= ownedEnd || start >= continuation.matchedEnd) {
15607
+ (continuation2) => {
15608
+ const ownedEnd = Math.min(end, continuation2.matchedEnd);
15609
+ if (continuation2.start >= ownedEnd || start >= continuation2.matchedEnd) {
15610
15610
  return false;
15611
15611
  }
15612
- if (position.start < continuation.factorEnd) return true;
15613
- return ownedEnd - Math.max(position.start, continuation.factorEnd) >= continuation.minimumAuthenticatedCharacters;
15612
+ if (position.start < continuation2.factorEnd) return true;
15613
+ return ownedEnd - Math.max(position.start, continuation2.factorEnd) >= continuation2.minimumAuthenticatedCharacters;
15614
15614
  }
15615
15615
  );
15616
15616
  if (!authoritativeComplete2 && !authenticatedFactorRange) continue;
@@ -15774,7 +15774,7 @@ function encodedAssessmentHasMatchedCrtContinuationThroughEnd(assessment, pieceC
15774
15774
  const sourceStart = assessment.sourcePieceRanges[0].start;
15775
15775
  const sourceEnd = assessment.sourcePieceRanges[pieceCount - 1].end;
15776
15776
  return assessment.rsaCrtContinuations.some(
15777
- (continuation) => continuation.start === sourceStart && continuation.status === "match" && continuation.mismatchAt === null && continuation.matchedEnd <= sourceEnd && sourceEnd - continuation.matchedEnd <= MAX_ADJACENT_ENCODED_PREFIX_CHARACTERS
15777
+ (continuation2) => continuation2.start === sourceStart && continuation2.status === "match" && continuation2.mismatchAt === null && continuation2.matchedEnd <= sourceEnd && sourceEnd - continuation2.matchedEnd <= MAX_ADJACENT_ENCODED_PREFIX_CHARACTERS
15778
15778
  );
15779
15779
  }
15780
15780
  function encodedAssessmentOwnsEverySourcePiece(assessment, pieceCount) {
@@ -15796,7 +15796,7 @@ function encodedAssessmentOwnsEverySourcePiece(assessment, pieceCount) {
15796
15796
  }
15797
15797
  const terminalSource = assessment.sourcePieceRanges[terminalIndex];
15798
15798
  return assessment.rsaCrtContinuations.some(
15799
- (continuation) => continuation.status === "match" && continuation.mismatchAt === null && continuation.factorEnd < terminalSource.end && continuation.matchedEnd === terminalSource.end
15799
+ (continuation2) => continuation2.status === "match" && continuation2.mismatchAt === null && continuation2.factorEnd < terminalSource.end && continuation2.matchedEnd === terminalSource.end
15800
15800
  );
15801
15801
  }
15802
15802
  function encodedAssessmentAllowsFactorOmission(assessment, pieceIndex) {
@@ -15807,11 +15807,11 @@ function encodedAssessmentAllowsFactorOmission(assessment, pieceIndex) {
15807
15807
  )) {
15808
15808
  return false;
15809
15809
  }
15810
- return assessment.rsaCrtContinuations.every((continuation) => {
15811
- if (piece.end <= continuation.start || piece.start >= continuation.end) {
15810
+ return assessment.rsaCrtContinuations.every((continuation2) => {
15811
+ if (piece.end <= continuation2.start || piece.start >= continuation2.end) {
15812
15812
  return true;
15813
15813
  }
15814
- return continuation.mismatchAt !== null && continuation.mismatchAt < piece.end && continuation.matchedEnd <= piece.start;
15814
+ return continuation2.mismatchAt !== null && continuation2.mismatchAt < piece.end && continuation2.matchedEnd <= piece.start;
15815
15815
  });
15816
15816
  }
15817
15817
  function encodedAssessmentAllowsRecognizableFactorOmission(assessment, pieceIndex) {
@@ -15819,11 +15819,11 @@ function encodedAssessmentAllowsRecognizableFactorOmission(assessment, pieceInde
15819
15819
  return true;
15820
15820
  }
15821
15821
  const piece = assessment.sourcePieceRanges[pieceIndex];
15822
- return assessment.rsaCrtContinuations.every((continuation) => {
15823
- if (piece.end <= continuation.start || piece.start >= continuation.end) {
15822
+ return assessment.rsaCrtContinuations.every((continuation2) => {
15823
+ if (piece.end <= continuation2.start || piece.start >= continuation2.end) {
15824
15824
  return true;
15825
15825
  }
15826
- return continuation.factorEnd <= piece.start && (continuation.matchedEnd <= piece.start || continuation.mismatchAt !== null && continuation.mismatchAt < piece.end);
15826
+ return continuation2.factorEnd <= piece.start && (continuation2.matchedEnd <= piece.start || continuation2.mismatchAt !== null && continuation2.mismatchAt < piece.end);
15827
15827
  });
15828
15828
  }
15829
15829
  function encodedAssessmentStartsAtSource(assessment) {
@@ -17368,7 +17368,7 @@ function scanEncodedPrivateKeyRanges(value, metrics, allowAdjacentPrefix = true,
17368
17368
  if (recoverableProof?.basis === "factors") {
17369
17369
  const sourceStart = offsets ? offsets[cursor] : cursor;
17370
17370
  const sourceEnd = offsets ? offsets[segment.end - 1] + 1 : segment.end;
17371
- const continuation = rsaPrivateKeyCrtContinuationConsistency(
17371
+ const continuation2 = rsaPrivateKeyCrtContinuationConsistency(
17372
17372
  recoverableProof,
17373
17373
  text,
17374
17374
  cursor,
@@ -17385,9 +17385,9 @@ function scanEncodedPrivateKeyRanges(value, metrics, allowAdjacentPrefix = true,
17385
17385
  bitOffset
17386
17386
  );
17387
17387
  const sourceFactorEnd = offsets ? offsets[exactEnd - 1] + 1 : exactEnd;
17388
- const sourceMatchedEnd = offsets ? offsets[continuation.matchedEnd - 1] + 1 : continuation.matchedEnd;
17388
+ const sourceMatchedEnd = offsets ? offsets[continuation2.matchedEnd - 1] + 1 : continuation2.matchedEnd;
17389
17389
  const minimumAuthenticatedCharacters = minimumRsaCrtContinuationSourceCharacters(framing);
17390
- const authenticatedMatchedEnd = continuation.matchedEnd - exactEnd >= minimumAuthenticatedCharacters ? continuation.matchedEnd : exactEnd;
17390
+ const authenticatedMatchedEnd = continuation2.matchedEnd - exactEnd >= minimumAuthenticatedCharacters ? continuation2.matchedEnd : exactEnd;
17391
17391
  matchedFactorEnd = Math.max(exactEnd, authenticatedMatchedEnd);
17392
17392
  rsaCrtContinuations.push({
17393
17393
  start: sourceStart,
@@ -17395,8 +17395,8 @@ function scanEncodedPrivateKeyRanges(value, metrics, allowAdjacentPrefix = true,
17395
17395
  factorEnd: sourceFactorEnd,
17396
17396
  matchedEnd: sourceMatchedEnd,
17397
17397
  minimumAuthenticatedCharacters,
17398
- mismatchAt: continuation.mismatchAt === null ? null : offsets ? offsets[continuation.mismatchAt] : continuation.mismatchAt,
17399
- status: continuation.status
17398
+ mismatchAt: continuation2.mismatchAt === null ? null : offsets ? offsets[continuation2.mismatchAt] : continuation2.mismatchAt,
17399
+ status: continuation2.status
17400
17400
  });
17401
17401
  }
17402
17402
  const exactFactorEnd = recoverableProof?.basis === "factors" && recoverableLength !== null ? encodedPrivateKeyInteriorEnd(
@@ -21891,7 +21891,7 @@ function strictIndependentPrivateSourceRanges(scope, metrics, document) {
21891
21891
  );
21892
21892
  claims.push({ token: frame.token, ...range });
21893
21893
  }
21894
- const continuation = complete ? completeRsaPrivateKeyCopies(
21894
+ const continuation2 = complete ? completeRsaPrivateKeyCopies(
21895
21895
  scope,
21896
21896
  frames,
21897
21897
  bytes,
@@ -21912,16 +21912,16 @@ function strictIndependentPrivateSourceRanges(scope, metrics, document) {
21912
21912
  tokenIndexes,
21913
21913
  metrics
21914
21914
  ) : completion;
21915
- if (!continuation) continue;
21916
- if (continuation.ambiguous || detachedRsaContinuationReadsSpent(metrics) > MAX_DETACHED_RSA_CONTINUATION_READS) {
21915
+ if (!continuation2) continue;
21916
+ if (continuation2.ambiguous || detachedRsaContinuationReadsSpent(metrics) > MAX_DETACHED_RSA_CONTINUATION_READS) {
21917
21917
  for (const frame of frames) {
21918
21918
  metrics.ownershipSteps += 1;
21919
21919
  claims.push(wholeTokenSourceRange(frame.token));
21920
21920
  }
21921
- claims.push(...continuation.closed);
21922
- if (continuation.ambiguous) continue;
21921
+ claims.push(...continuation2.closed);
21922
+ if (continuation2.ambiguous) continue;
21923
21923
  }
21924
- for (const range of continuation.ranges) {
21924
+ for (const range of continuation2.ranges) {
21925
21925
  if (range.token === detached) continue;
21926
21926
  claims.push(range);
21927
21927
  }
@@ -23849,6 +23849,52 @@ ${geminiRule(tool)}`;
23849
23849
  ].join("\n\n")
23850
23850
  });
23851
23851
 
23852
+ // ../core/src/private-skill-completion.ts
23853
+ var PRIVATE_SKILL_COMPLETION_VERSION = "private-skill-completion-v1";
23854
+ var opaqueId = external_exports.string().min(1).max(MAX_SHORT_TEXT_LENGTH);
23855
+ var privateSkillCompletionRevisionIdSchema = external_exports.string().regex(/^pscr_[a-f0-9]{18}$/u);
23856
+ var privateSkillCompletionRequestIdSchema = external_exports.string().regex(/^pscc_[a-f0-9]{32}$/u);
23857
+ var privateSkillCompletionStatusRequestSchema = external_exports.object({
23858
+ contract_version: external_exports.literal(PRIVATE_SKILL_COMPLETION_VERSION),
23859
+ public_id: opaqueId
23860
+ }).strict();
23861
+ var privateSkillCompletionSourceRequestSchema = privateSkillCompletionStatusRequestSchema.extend({
23862
+ revision_id: privateSkillCompletionRevisionIdSchema
23863
+ }).strict();
23864
+ var privateSkillCompletionApprovedSourceSchema = privateSkillIdeaRequestSchema.omit({ agent: true, idempotency_key: true, enterprise_encryption: true }).strict();
23865
+ var privateSkillCompletionSourceResponseSchema = privateSkillCompletionSourceRequestSchema.extend({
23866
+ capture: privateSkillCompletionApprovedSourceSchema.describe("Current approved submission; proposed_skill_md may be null or absent. New revisions still require a complete skill body.")
23867
+ }).strict();
23868
+ var privateSkillCompletionRequestStatusSchema = privateSkillCompletionStatusRequestSchema.extend({
23869
+ request_id: privateSkillCompletionRequestIdSchema
23870
+ }).strict();
23871
+ var continuation = privateSkillCompletionRequestStatusSchema.extend({
23872
+ expected: external_exports.object({
23873
+ completion_id: opaqueId,
23874
+ revision_id: privateSkillCompletionRevisionIdSchema,
23875
+ version: external_exports.number().int().nonnegative()
23876
+ }).strict()
23877
+ });
23878
+ var revisedCapture = privateSkillCaptureSchema.superRefine((capture2, context) => {
23879
+ const pending = [{ value: capture2.proposed_metadata, path: ["proposed_metadata"] }];
23880
+ while (pending.length) {
23881
+ const { value, path } = pending.pop();
23882
+ if (!value || typeof value !== "object") continue;
23883
+ for (const [key, entry] of Object.entries(value)) {
23884
+ if (key.startsWith("_remembrance_")) {
23885
+ context.addIssue({ code: "custom", path: [...path, key], message: "Server provenance fields are reserved." });
23886
+ return;
23887
+ }
23888
+ pending.push({ value: entry, path: [...path, key] });
23889
+ }
23890
+ }
23891
+ });
23892
+ var privateSkillCompletionContinuationSchema = external_exports.discriminatedUnion("operation", [
23893
+ continuation.extend({ operation: external_exports.literal("declare_intent"), intent: external_exports.literal("skill_output") }).strict(),
23894
+ continuation.extend({ operation: external_exports.literal("revise"), capture: revisedCapture }).strict(),
23895
+ continuation.extend({ operation: external_exports.literal("resume"), mode: external_exports.literal("changed_revision"), deadline_at: external_exports.number().int().positive() }).strict()
23896
+ ]);
23897
+
23852
23898
  // ../core/src/seed.ts
23853
23899
  var siteUrl = "https://remembrance.dev";
23854
23900
  var feedbackUrl = `${siteUrl}/api/v1/agent/remembrances`;
@@ -26474,6 +26520,34 @@ var verifierOutputSchema = external_exports.object({
26474
26520
  topology_assessment: skillTopologyAssessmentSchema.nullable().default(null).catch(null)
26475
26521
  });
26476
26522
 
26523
+ // src/private-skill-protection-recovery.ts
26524
+ var PRIVATE_SKILL_CONFIGURATION_REFUSAL = "private_admission_configuration_error";
26525
+ var PRIVATE_SKILL_PERMANENT_SERVICE_REFUSAL = "private_skill_permanent_service_refusal";
26526
+ function isPrivateSkillConfigurationHold(draft) {
26527
+ return draft.state === "held_validation" && draft.last_error_code === PRIVATE_SKILL_CONFIGURATION_REFUSAL;
26528
+ }
26529
+ function privateSkillPermanentRefusalGuidance(draft) {
26530
+ if (isPrivateSkillConfigurationHold(draft)) {
26531
+ return {
26532
+ next_action: null,
26533
+ action_required: "Private protection configuration refused this submission. Keep the exact encrypted draft. Ask the organization administrator to correct the selected protection configuration; customer-held submissions require a valid customer-encrypted envelope. Do not change key ownership, protection mode, destination, or consent automatically. Only after an authorized correction, explicitly retry this same draft once with retry_private_skill_candidate. An unchanged refusal remains held; no replacement or acceptance is claimed.",
26534
+ recovery_after_correction: {
26535
+ automatic_retry: false,
26536
+ condition: "organization_administrator_corrected_private_protection_configuration",
26537
+ tool: "retry_private_skill_candidate",
26538
+ arguments: { draft_id: draft.draft_id }
26539
+ }
26540
+ };
26541
+ }
26542
+ if (draft.state === "held_validation" && draft.last_error_code === PRIVATE_SKILL_PERMANENT_SERVICE_REFUSAL) {
26543
+ return {
26544
+ next_action: null,
26545
+ action_required: "The private service explicitly refused unchanged retries. Keep the encrypted draft and inspect this retained hold. No automatic retry, alternate transport, replacement, or successful recovery is authorized by this unknown refusal."
26546
+ };
26547
+ }
26548
+ return {};
26549
+ }
26550
+
26477
26551
  // src/server.ts
26478
26552
  import { existsSync as existsSync6 } from "node:fs";
26479
26553
  import { mkdir as mkdir5, writeFile as writeFile2 } from "node:fs/promises";
@@ -28391,7 +28465,7 @@ var declaredToolDefinitions = [
28391
28465
  ),
28392
28466
  localNetworkTool(
28393
28467
  "retry_private_skill_candidate",
28394
- "Retry one retained private-skill draft through the same private_skill approval lane as submit_private_skill_candidate. Network access is allowed only for authorization-pending or due transient retry states, and for a draft an older server refused only for length: that waits out any delay the server set, then reads its signed capability and resends the exact draft only if it admits it. A fresh ready draft is rejected locally. It never switches transport or visibility.",
28468
+ "Retry one retained private-skill draft through the same private_skill approval lane as submit_private_skill_candidate. Network access is allowed only for authorization-pending or due transient retry states, an explicit same-draft retry after an administrator corrected a private-protection configuration hold, and for a draft an older server refused only for length: that waits out any delay the server set, then reads its signed capability and resends the exact draft only if it admits it. Configuration holds never schedule automatic retries; an unchanged refusal remains held. A fresh ready draft is rejected locally. It never switches transport, visibility, key ownership, or protection mode.",
28395
28469
  "retry_private_skill_candidate",
28396
28470
  privateSkillDraftReferenceSchema,
28397
28471
  "content_write"
@@ -62461,7 +62535,8 @@ async function reinspectPrivateSkillSubmissionCandidate(draftId, options = {}) {
62461
62535
  const resumingReinspectionHold = isPrivateSkillSubmissionReinspectionHold(current);
62462
62536
  const resumingDestinationHold = isPrivateSkillDestinationHold(current) && !isPrivateSkillDestinationRecoveryBlocked(current, destination);
62463
62537
  const resumingResolution = current.delivery_resolution !== null;
62464
- const resumingHold = resumingReinspectionHold || resumingDestinationHold || resumingResolution;
62538
+ const resumingConfigurationHold = options.resumeConfigurationHold === true && isPrivateSkillConfigurationHold(current);
62539
+ const resumingHold = resumingReinspectionHold || resumingDestinationHold || resumingResolution || resumingConfigurationHold;
62465
62540
  if (resumingReinspectionHold && !resumingResolution && current.inspection?.inspector_digest === PRIVATE_LEARNING_INSPECTOR_DIGEST && current.inspection.outcome !== "unchanged" && current.inspection.outcome !== "redacted") {
62466
62541
  return Object.freeze({ status: "held", draft: current });
62467
62542
  }
@@ -65328,6 +65403,7 @@ async function inspectPrivateLearningOutbox(input, persistence) {
65328
65403
  status: skillResult.value.recovery_items.length > 0 ? "recovery_required" : "ok",
65329
65404
  drafts: skillResult.value.drafts.map((draft) => ({
65330
65405
  ...draft,
65406
+ ...privateSkillPermanentRefusalGuidance(draft),
65331
65407
  recovery_context: { status: "context_unavailable" },
65332
65408
  agent_recovery: privateSkillExactInspectionRecovery(draft)
65333
65409
  })),
@@ -65633,6 +65709,7 @@ function privateSkillSelectedDraftResult(draft) {
65633
65709
  draft,
65634
65710
  PRIVATE_LEARNING_CAPTURE_VERSION
65635
65711
  ),
65712
+ ...privateSkillPermanentRefusalGuidance(draft),
65636
65713
  recovery_context: recoveryContext,
65637
65714
  native_recovery_context: nativeContext ? {
65638
65715
  ...nativeContext,
@@ -67868,7 +67945,7 @@ function inspectPrivateLearningOutbox2(input, dependencies = {}) {
67868
67945
  }
67869
67946
  var MAX_REMOTE_RESPONSE_BYTES = 4 * 1024 * 1024;
67870
67947
  var DOCTOR_PROBE_TIMEOUT_MS = 7500;
67871
- var SERVER_VERSION = true ? "0.2.3" : "0.0.0-dev";
67948
+ var SERVER_VERSION = true ? "0.2.4" : "0.0.0-dev";
67872
67949
  var tools2 = toolDefinitions;
67873
67950
  var doctorCliRequested = process.argv[2] === "doctor";
67874
67951
  var nativeContextCliRequested = process.argv[2] === "--native-context";
@@ -68570,6 +68647,10 @@ async function deliverPrivateSkillDraft(draftId, access, mode, transport) {
68570
68647
  });
68571
68648
  }
68572
68649
  let draft = await readPrivateSkillDraft(draftId);
68650
+ const resumingConfigurationHold = mode === "retry" && isPrivateSkillConfigurationHold(draft);
68651
+ if (isPrivateSkillConfigurationHold(draft) && !resumingConfigurationHold) {
68652
+ return privateSkillDraftActionResult2(draft, { status: "not_submitted" });
68653
+ }
68573
68654
  const destination = privateSkillDestinationForAccess(access);
68574
68655
  const resumingReinspectionHold = isPrivateSkillSubmissionReinspectionHold(draft);
68575
68656
  const resumingDestinationHold = isPrivateSkillDestinationHold(draft) && !isPrivateSkillDestinationRecoveryBlocked(draft, destination);
@@ -68582,10 +68663,10 @@ async function deliverPrivateSkillDraft(draftId, access, mode, transport) {
68582
68663
  next_action: null
68583
68664
  });
68584
68665
  }
68585
- const resumingLocalHold = resumingReinspectionHold || resumingDestinationHold || resumingResolution;
68666
+ const resumingLocalHold = resumingReinspectionHold || resumingDestinationHold || resumingResolution || resumingConfigurationHold;
68586
68667
  const deferredDestinationProof = draft.state === "retry_scheduled" && draft.last_error_code === "private_skill_destination_audience_proof_unavailable";
68587
68668
  const awaitingDestinationCapability = isPrivateSkillDestinationCapabilityHold(draft) && !resumingResolution;
68588
- if ((mode === "retry" && !resumingResolution || deferredDestinationProof || resumingResolution && draft.state === "retry_scheduled") && !resumingReinspectionHold && !resumingDestinationHold && !awaitingDestinationCapability) {
68669
+ if ((mode === "retry" && !resumingResolution || deferredDestinationProof || resumingResolution && draft.state === "retry_scheduled") && !resumingReinspectionHold && !resumingDestinationHold && !resumingConfigurationHold && !awaitingDestinationCapability) {
68589
68670
  const retryGate = privateSkillRetryGate(draft);
68590
68671
  if (retryGate) {
68591
68672
  return privateSkillDraftActionResult2(draft, retryGate);
@@ -68614,7 +68695,8 @@ async function deliverPrivateSkillDraft(draftId, access, mode, transport) {
68614
68695
  });
68615
68696
  }
68616
68697
  const reinspection = await reinspectPrivateSkillSubmissionCandidate(draftId, {
68617
- destination
68698
+ destination,
68699
+ resumeConfigurationHold: resumingConfigurationHold
68618
68700
  });
68619
68701
  draft = reinspection.draft;
68620
68702
  if (reinspection.status === "held") {
@@ -68927,6 +69009,16 @@ async function holdPrivateSkillDestination(draft, errorCode) {
68927
69009
  async function persistPrivateSkillFailure(draft, result, destinationBodyLimit) {
68928
69010
  return updatePrivateSkillDraft(draft.draft_id, (current) => {
68929
69011
  const attempts = current.attempts;
69012
+ const failure = remembranceMcpToolFailure(result, "propose_private_skill");
69013
+ if (failure && failure.http_status >= 500 && failure.http_status <= 599 && !failure.retryable) {
69014
+ return {
69015
+ ...current,
69016
+ state: "held_validation",
69017
+ next_retry_at: null,
69018
+ last_error_code: failure.code === PRIVATE_SKILL_CONFIGURATION_REFUSAL ? PRIVATE_SKILL_CONFIGURATION_REFUSAL : PRIVATE_SKILL_PERMANENT_SERVICE_REFUSAL,
69019
+ updated_at: (/* @__PURE__ */ new Date()).toISOString()
69020
+ };
69021
+ }
68930
69022
  if (destinationBodyLimit !== null) {
68931
69023
  const nextRetryAt = privateSkillRetryAt(attempts);
68932
69024
  return {
@@ -69255,7 +69347,8 @@ function privateSkillDraftActionResult2(draft, extra = {}) {
69255
69347
  last_error_code: draft.last_error_code,
69256
69348
  retained_locally: true,
69257
69349
  next_action: privateSkillDraftNextAction(draft),
69258
- ...extra
69350
+ ...extra,
69351
+ ...privateSkillPermanentRefusalGuidance(draft)
69259
69352
  };
69260
69353
  }
69261
69354
  function privateSkillDraftNextAction(draft) {