archctx 0.5.9 → 0.5.11

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": "archcontext.practice-catalog-manifest/v1",
3
3
  "catalogVersion": "2026.06.0",
4
- "productVersion": "0.5.9",
4
+ "productVersion": "0.5.11",
5
5
  "generatedAt": "1970-01-01T00:00:00.000Z",
6
6
  "entries": [
7
7
  {
@@ -389,5 +389,5 @@
389
389
  "structurizr.dsl",
390
390
  "twelve-factor"
391
391
  ],
392
- "catalogDigest": "sha256:7838ef15b3da8f2c4528b7eadcbf9263adeee2e95ca2608c5819fd2b0b3708f9"
392
+ "catalogDigest": "sha256:674bb22ba5dd6562e15f80689b171a98789b5a9c21cdb59c89aada354b61abd8"
393
393
  }
package/bin/archctx.mjs CHANGED
@@ -1039,6 +1039,87 @@ function projectionApplyRecoveryBindingInvariantIssues(binding, receipt) {
1039
1039
  }
1040
1040
  return issues;
1041
1041
  }
1042
+ function projectionApplyReadbackRequestInvariantIssues(request) {
1043
+ const issues = projectionRequestInvariantIssues(request);
1044
+ const allowed = new Set(["schemaVersion", "requestId", "profile", "mode", "targets", "changedPaths", "expected", "acceptedChange"]);
1045
+ if (Object.keys(request).some((key) => !allowed.has(key)))
1046
+ issues.push("readback request contains unsupported fields");
1047
+ if (request.mode !== "apply" || !request.acceptedChange)
1048
+ issues.push("readback requires an accepted apply request");
1049
+ if (request.schemaVersion !== PROJECTION_REQUEST_SCHEMA_VERSION || request.profile !== "repo-harness/v1")
1050
+ issues.push("readback request protocol is invalid");
1051
+ if (typeof request.requestId !== "string" || request.targets.some((target) => !PROJECTION_TARGETS.includes(target)) || request.changedPaths.some((path) => typeof path !== "string" || !isRepoRelativePosixPath(path)))
1052
+ issues.push("readback request fields are invalid");
1053
+ const expectedKeys = ["repositoryId", "workspaceId", "headSha", "worktreeDigest"];
1054
+ if (Object.keys(request.expected).some((key) => !expectedKeys.includes(key)) || expectedKeys.some((key) => typeof request.expected[key] !== "string") || !request.expected.repositoryId || !request.expected.workspaceId || !/^[a-f0-9]{40}$/.test(request.expected.headSha) || !SHA256_DIGEST.test(request.expected.worktreeDigest))
1055
+ issues.push("readback expected snapshot is invalid");
1056
+ if (request.acceptedChange && Object.keys(request.acceptedChange).some((key) => !["changeSetId", "eventId", "reasonCodes", "affectedNodeIds"].includes(key))) {
1057
+ issues.push("readback accepted change contains unsupported fields");
1058
+ }
1059
+ return issues;
1060
+ }
1061
+ function projectionApplyAbsenceInvariantIssues(input, request) {
1062
+ const issues = projectionApplyReadbackRequestInvariantIssues(request);
1063
+ if (input.schemaVersion !== "archcontext.projection-apply-absence/v1")
1064
+ issues.push("absence schemaVersion is invalid");
1065
+ if (Object.keys(input).some((key) => !["schemaVersion", "requestId", "requestDigest", "lookupKey", "current", "absenceDigest"].includes(key)))
1066
+ issues.push("absence contains unsupported fields");
1067
+ const { absenceDigest, ...body } = input;
1068
+ if (absenceDigest !== digestJson(body))
1069
+ issues.push("absenceDigest must bind the complete absence result");
1070
+ if (input.requestId !== request.requestId || input.requestDigest !== digestJson(request))
1071
+ issues.push("absence request identity mismatch");
1072
+ if (digestJson(input.current) !== digestJson(request.expected))
1073
+ issues.push("absence current snapshot differs from request");
1074
+ if (!request.acceptedChange || input.lookupKey !== projectionApplyLookupKey({
1075
+ repositoryId: request.expected.repositoryId,
1076
+ workspaceId: request.expected.workspaceId,
1077
+ acceptedChange: request.acceptedChange
1078
+ }))
1079
+ issues.push("absence lookup identity mismatch");
1080
+ return issues;
1081
+ }
1082
+ function projectionApplyReadbackResultDigest(input) {
1083
+ return digestJson(input);
1084
+ }
1085
+ function projectionApplyReadbackResultInvariantIssues(input, request) {
1086
+ const issues = projectionApplyReceiptInvariantIssues(input.receipt);
1087
+ const { readbackDigest, ...body } = input;
1088
+ if (input.schemaVersion !== PROJECTION_APPLY_READBACK_RESULT_SCHEMA_VERSION)
1089
+ issues.push("readback schemaVersion is invalid");
1090
+ if (projectionApplyReadbackResultDigest(body) !== readbackDigest)
1091
+ issues.push("readbackDigest must bind the complete readback result");
1092
+ if (!/^[a-zA-Z0-9_.:-]+$/.test(input.requestId))
1093
+ issues.push("readback requestId is invalid");
1094
+ for (const value of [input.requestDigest, input.current.ownedOutputDigest, input.current.fixedPointDigest]) {
1095
+ if (!/^sha256:[a-f0-9]{64}$/.test(value))
1096
+ issues.push("readback digest is invalid");
1097
+ }
1098
+ const receipt = input.receipt;
1099
+ if (receipt.schemaVersion !== PROJECTION_APPLY_RECEIPT_SCHEMA_VERSION)
1100
+ issues.push("readback receipt schemaVersion is invalid");
1101
+ const binding = receipt.recovery;
1102
+ if (!binding)
1103
+ return [...issues, "committed receipt lacks its original recovery binding"];
1104
+ for (const field of ["repositoryId", "workspaceId", "headSha", "worktreeDigest"]) {
1105
+ if (input.current.snapshot[field] !== binding.originalExpectedSnapshot[field])
1106
+ issues.push(`readback current ${field} differs from approval`);
1107
+ }
1108
+ if (input.current.snapshot.generatedFrom.codeGraphStatus !== "ready" || input.current.snapshot.rendererVersion !== binding.rendererVersion || input.current.snapshot.layoutVersion !== binding.layoutVersion || input.current.snapshot.projectionInputDigest !== receipt.result.outputSnapshot.projectionInputDigest || input.current.snapshot.codeGraphDigest !== receipt.result.outputSnapshot.codeGraphDigest || digestJson(input.current.snapshot.generatedFrom) !== digestJson(binding.generatedFrom) || digestJson(input.current.resultingDigests) !== digestJson(binding.expectedResultingDigests) || input.current.ownedOutputDigest !== binding.ownedOutputDigest) {
1109
+ issues.push("readback current state differs from committed recovery binding");
1110
+ }
1111
+ if (input.requestId !== receipt.result.requestId)
1112
+ issues.push("readback requestId differs from committed request");
1113
+ if (request) {
1114
+ issues.push(...projectionApplyReadbackRequestInvariantIssues(request));
1115
+ if (input.requestDigest !== digestJson(request) || input.requestId !== request.requestId)
1116
+ issues.push("readback request identity mismatch");
1117
+ if (digestJson(request.expected) !== digestJson(binding.originalExpectedSnapshot) || digestJson(request.acceptedChange) !== digestJson(receipt.identity.acceptedChange) || digestJson(request.targets) !== digestJson(binding.targets) || digestJson(request.changedPaths) !== digestJson(binding.changedPaths)) {
1118
+ issues.push("readback request differs from committed approval binding");
1119
+ }
1120
+ }
1121
+ return issues;
1122
+ }
1042
1123
  function projectionApplyRecoveryIntentInvariantIssues(input) {
1043
1124
  const issues = [];
1044
1125
  if (input.schemaVersion !== PROJECTION_APPLY_RECOVERY_INTENT_SCHEMA_VERSION)
@@ -1168,7 +1249,7 @@ function sortedUniqueIssues(label, values) {
1168
1249
  const expected = [...new Set(values)].sort();
1169
1250
  return expected.length === values.length && expected.every((value, index) => value === values[index]) ? [] : [`${label} must be sorted and unique`];
1170
1251
  }
1171
- var PROJECTION_REQUEST_SCHEMA_VERSION = "archcontext.projection-request/v1", PROJECTION_RESULT_SCHEMA_VERSION = "archcontext.projection-result/v2", PROJECTION_APPLY_IDENTITY_SCHEMA_VERSION = "archcontext.projection-apply-identity/v1", PROJECTION_APPLY_RECOVERY_BINDING_SCHEMA_VERSION = "archcontext.projection-apply-recovery-binding/v1", PROJECTION_APPLY_RECOVERY_INTENT_SCHEMA_VERSION = "archcontext.projection-apply-recovery-intent/v1", PROJECTION_APPLY_RECOVERY_PROOF_SCHEMA_VERSION = "archcontext.projection-apply-recovery-proof/v1", PROJECTION_APPLY_RECOVERY_RESULT_SCHEMA_VERSION = "archcontext.projection-apply-recovery-result/v1", ARCHITECTURE_REFRESH_SIGNAL_SCHEMA_VERSION = "archcontext.architecture-refresh-signal/v1", ARCHCTX_CAPABILITIES_SCHEMA_VERSION = "archcontext.capabilities/v1", ARCHITECTURE_DOCS_RENDERER_VERSION = "archcontext.docs-renderer/v4", AGENT_CONTEXT_RENDERER_VERSION = "archcontext.agent-context-renderer/v1", PROJECTION_MODES, PROJECTION_PRIOR_COMMITTED_APPLY_OPERATIONS, PROJECTION_TARGETS, ARCHITECTURE_MAJOR_CHANGE_REASON_CODES, ARCHCTX_FEATURES, SHA256_DIGEST, ISO_INSTANT;
1252
+ var PROJECTION_REQUEST_SCHEMA_VERSION = "archcontext.projection-request/v1", PROJECTION_RESULT_SCHEMA_VERSION = "archcontext.projection-result/v2", PROJECTION_APPLY_IDENTITY_SCHEMA_VERSION = "archcontext.projection-apply-identity/v1", PROJECTION_APPLY_RECEIPT_SCHEMA_VERSION = "archcontext.projection-apply-receipt/v1", PROJECTION_APPLY_RECOVERY_BINDING_SCHEMA_VERSION = "archcontext.projection-apply-recovery-binding/v1", PROJECTION_APPLY_RECOVERY_INTENT_SCHEMA_VERSION = "archcontext.projection-apply-recovery-intent/v1", PROJECTION_APPLY_RECOVERY_PROOF_SCHEMA_VERSION = "archcontext.projection-apply-recovery-proof/v1", PROJECTION_APPLY_RECOVERY_RESULT_SCHEMA_VERSION = "archcontext.projection-apply-recovery-result/v1", PROJECTION_APPLY_READBACK_RESULT_SCHEMA_VERSION = "archcontext.projection-apply-readback-result/v1", ARCHITECTURE_REFRESH_SIGNAL_SCHEMA_VERSION = "archcontext.architecture-refresh-signal/v1", ARCHCTX_CAPABILITIES_SCHEMA_VERSION = "archcontext.capabilities/v1", ARCHITECTURE_DOCS_RENDERER_VERSION = "archcontext.docs-renderer/v4", AGENT_CONTEXT_RENDERER_VERSION = "archcontext.agent-context-renderer/v1", PROJECTION_MODES, PROJECTION_PRIOR_COMMITTED_APPLY_OPERATIONS, PROJECTION_TARGETS, ARCHITECTURE_MAJOR_CHANGE_REASON_CODES, ARCHCTX_FEATURES, SHA256_DIGEST, ISO_INSTANT;
1172
1253
  var init_projection = __esm(() => {
1173
1254
  init_schema();
1174
1255
  PROJECTION_MODES = ["check", "plan", "apply", "adopt"];
@@ -1193,6 +1274,7 @@ var init_projection = __esm(() => {
1193
1274
  "architecture-docs-renderer-v2",
1194
1275
  "architecture-refresh-signal-v1",
1195
1276
  "module-statistics-v1",
1277
+ "projection-apply-readback-v1",
1196
1278
  "projection-apply-receipt-v1",
1197
1279
  "projection-apply-recovery-v1",
1198
1280
  "projection-prior-committed-applies-v1",
@@ -1259,7 +1341,7 @@ function productVersionManifest() {
1259
1341
  }
1260
1342
  };
1261
1343
  }
1262
- var ARCHCONTEXT_PRODUCT_NAME = "archctx", ARCHCONTEXT_PRODUCT_VERSION = "0.5.9", ARCHCONTEXT_PACKAGE_MANAGER = "bun@1.4.0", ARCHCONTEXT_NODE_RANGE = ">=22.22 <26", LOCAL_RUNTIME_RPC_SCHEMA_VERSION = "archcontext.runtime-rpc/v1", ARCHCONTEXT_SCHEMA_SET_VERSION = "2026-07-11.explorer-view-v2";
1344
+ var ARCHCONTEXT_PRODUCT_NAME = "archctx", ARCHCONTEXT_PRODUCT_VERSION = "0.5.11", ARCHCONTEXT_PACKAGE_MANAGER = "bun@1.4.0", ARCHCONTEXT_NODE_RANGE = ">=22.22 <26", LOCAL_RUNTIME_RPC_SCHEMA_VERSION = "archcontext.runtime-rpc/v1", ARCHCONTEXT_SCHEMA_SET_VERSION = "2026-07-11.explorer-view-v2";
1263
1345
 
1264
1346
  // packages/contracts/src/refactor.ts
1265
1347
  function refactorProposalDigest(proposal) {
@@ -2604,7 +2686,7 @@ var init_src2 = __esm(() => {
2604
2686
 
2605
2687
  // node_modules/.bun/@colbymchenry+codegraph@1.5.0/node_modules/@colbymchenry/codegraph/npm-sdk.js
2606
2688
  var require_npm_sdk = __commonJS(function(exports, module) {
2607
- var __dirname = "/Users/ancienttwo/Projects/arch-context-wt-release-0.5.9/node_modules/.bun/@colbymchenry+codegraph@1.5.0/node_modules/@colbymchenry/codegraph";
2689
+ var __dirname = "/Users/ancienttwo/Projects/arch-context-wt-projection-receipt-readback/node_modules/.bun/@colbymchenry+codegraph@1.5.0/node_modules/@colbymchenry/codegraph";
2608
2690
  var path = __require("path");
2609
2691
  var os = __require("os");
2610
2692
  var fs = __require("fs");
@@ -34166,6 +34248,9 @@ class ArchctxDaemon {
34166
34248
  }
34167
34249
  if (draft.base.modelDigest !== currentModel.modelDigest)
34168
34250
  throw new Error("ChangeSet model digest changed before apply");
34251
+ if (input.projectionApplyReceipt && await this.localStore.inspectProjectionApplyReceipt(input.projectionApplyReceipt.identity.lookupKey)) {
34252
+ return errorEnvelope("apply_update", "AC_PRECONDITION_FAILED", "committed projection receipt requires explicit projection recover");
34253
+ }
34169
34254
  const approved = input.approved ? this.changeSetEngine.approve(draft) : draft;
34170
34255
  let ledgerAppend;
34171
34256
  const writesLedger = architectureLedgerWriteAppendsEvents(this.architectureLedger.writeMode);
@@ -34212,7 +34297,6 @@ class ArchctxDaemon {
34212
34297
  }
34213
34298
  async listProjectionPriorCommittedApplies(root, requestId) {
34214
34299
  this.assertRunning();
34215
- await this.openSession(root);
34216
34300
  let committed;
34217
34301
  try {
34218
34302
  committed = await this.localStore.listCommittedChangeSetsForTaskSession(root, requestId);
@@ -34238,6 +34322,65 @@ class ArchctxDaemon {
34238
34322
  }
34239
34323
  return okEnvelope("projection.prior-committed-applies", { applies });
34240
34324
  }
34325
+ async readbackProjectionApply(root, request) {
34326
+ this.assertRunning();
34327
+ try {
34328
+ const issues = projectionApplyReadbackRequestInvariantIssues(request);
34329
+ if (issues.length > 0)
34330
+ return errorEnvelope("projection.readback", "AC_SCHEMA_INVALID", issues.join("; "));
34331
+ } catch (error) {
34332
+ return errorEnvelope("projection.readback", "AC_SCHEMA_INVALID", error instanceof Error ? error.message : String(error));
34333
+ }
34334
+ return this.withWriter(async () => {
34335
+ try {
34336
+ const session = await this.openSession(root);
34337
+ const inspection = await this.localStore.inspectProjectionApplyReceipt(projectionApplyLookupKey({
34338
+ repositoryId: request.expected.repositoryId,
34339
+ workspaceId: request.expected.workspaceId,
34340
+ acceptedChange: request.acceptedChange
34341
+ }));
34342
+ if (!inspection) {
34343
+ const body2 = {
34344
+ schemaVersion: "archcontext.projection-apply-absence/v1",
34345
+ requestId: request.requestId,
34346
+ requestDigest: digestJson(request),
34347
+ lookupKey: projectionApplyLookupKey({ repositoryId: request.expected.repositoryId, workspaceId: request.expected.workspaceId, acceptedChange: request.acceptedChange }),
34348
+ current: {
34349
+ repositoryId: session.workspace.repositoryId,
34350
+ workspaceId: runtimeProjectionWorkspaceId(root),
34351
+ headSha: readHeadSha2(root),
34352
+ worktreeDigest: runtimeWorktreeDigest(root, "architecture-documentation-projection")
34353
+ }
34354
+ };
34355
+ const absence = { ...body2, absenceDigest: digestJson(body2) };
34356
+ const issues2 = projectionApplyAbsenceInvariantIssues(absence, request);
34357
+ return issues2.length === 0 ? okEnvelope("projection.readback", absence) : errorEnvelope("projection.readback", "AC_PRECONDITION_FAILED", issues2.join("; "));
34358
+ }
34359
+ const receipt = inspection.receipt;
34360
+ const fixedPoint = buildRuntimeProjectionRecoveryFixedPoint(root);
34361
+ const issues = runtimeProjectionRecoveryFixedPointIssues(receipt, fixedPoint);
34362
+ if (issues.length > 0)
34363
+ return errorEnvelope("projection.readback", "AC_PRECONDITION_FAILED", `projection readback proof failed: ${issues.join("; ")}`);
34364
+ const body = {
34365
+ schemaVersion: PROJECTION_APPLY_READBACK_RESULT_SCHEMA_VERSION,
34366
+ requestId: request.requestId,
34367
+ requestDigest: digestJson(request),
34368
+ receipt,
34369
+ current: runtimeProjectionRecoveryCurrent(fixedPoint)
34370
+ };
34371
+ const result = { ...body, readbackDigest: projectionApplyReadbackResultDigest(body) };
34372
+ const resultIssues = projectionApplyReadbackResultInvariantIssues(result, request);
34373
+ if (session.workspace.repositoryId !== result.current.snapshot.repositoryId || session.workspace.headSha !== result.current.snapshot.headSha || runtimeWorktreeDigest(root, "architecture-documentation-projection") !== result.current.snapshot.worktreeDigest) {
34374
+ resultIssues.push("projection readback authority changed before response");
34375
+ }
34376
+ if (resultIssues.length > 0)
34377
+ return errorEnvelope("projection.readback", "AC_PRECONDITION_FAILED", resultIssues.join("; "));
34378
+ return okEnvelope("projection.readback", result);
34379
+ } catch (error) {
34380
+ return errorEnvelope("projection.readback", "AC_PRECONDITION_FAILED", error instanceof Error ? error.message : String(error));
34381
+ }
34382
+ });
34383
+ }
34241
34384
  async recoverProjectionApply(root, intent) {
34242
34385
  this.assertRunning();
34243
34386
  const intentIssues = projectionApplyRecoveryIntentInvariantIssues(intent);
@@ -37060,6 +37203,9 @@ class RuntimeRpcClient {
37060
37203
  listProjectionPriorCommittedApplies(root, requestId) {
37061
37204
  return this.call("listProjectionPriorCommittedApplies", [root, requestId]);
37062
37205
  }
37206
+ readbackProjectionApply(root, request) {
37207
+ return this.call("readbackProjectionApply", [root, request]);
37208
+ }
37063
37209
  recoverProjectionApply(root, intent) {
37064
37210
  return this.call("recoverProjectionApply", [root, intent]);
37065
37211
  }
@@ -37420,6 +37566,8 @@ class ArchctxRuntimeRpcServer {
37420
37566
  return this.daemon.inspectProjectionApplyReceipt(params[0], params[1]);
37421
37567
  case "listProjectionPriorCommittedApplies":
37422
37568
  return this.daemon.listProjectionPriorCommittedApplies(params[0], params[1]);
37569
+ case "readbackProjectionApply":
37570
+ return this.daemon.readbackProjectionApply(params[0], params[1]);
37423
37571
  case "recoverProjectionApply":
37424
37572
  return this.daemon.recoverProjectionApply(params[0], params[1]);
37425
37573
  case "ledgerState":
@@ -37807,8 +37955,8 @@ function runtimeProjectionRecoveryFixedPointIssues(receipt, fixedPoint) {
37807
37955
  issues.push("current proof snapshot requires CodeGraph ready");
37808
37956
  return issues;
37809
37957
  }
37810
- function createRuntimeProjectionRecoveryProof(intent, receipt, fixedPoint) {
37811
- const current = {
37958
+ function runtimeProjectionRecoveryCurrent(fixedPoint) {
37959
+ return {
37812
37960
  snapshot: fixedPoint.snapshot,
37813
37961
  resultingDigests: fixedPoint.projection.architectureDigests,
37814
37962
  ownedOutputDigest: fixedPoint.ownedOutputDigest,
@@ -37822,6 +37970,9 @@ function createRuntimeProjectionRecoveryProof(intent, receipt, fixedPoint) {
37822
37970
  refreshSignalIds: fixedPoint.projection.refreshSignals.map((signal) => signal.signalId)
37823
37971
  })
37824
37972
  };
37973
+ }
37974
+ function createRuntimeProjectionRecoveryProof(intent, receipt, fixedPoint) {
37975
+ const current = runtimeProjectionRecoveryCurrent(fixedPoint);
37825
37976
  const payload = {
37826
37977
  schemaVersion: "archcontext.projection-apply-recovery-proof/v1",
37827
37978
  requestId: intent.requestId,
@@ -39674,6 +39825,9 @@ class RuntimeRpcClient2 {
39674
39825
  listProjectionPriorCommittedApplies(root, requestId) {
39675
39826
  return this.call("listProjectionPriorCommittedApplies", [root, requestId]);
39676
39827
  }
39828
+ readbackProjectionApply(root, request) {
39829
+ return this.call("readbackProjectionApply", [root, request]);
39830
+ }
39677
39831
  recoverProjectionApply(root, intent) {
39678
39832
  return this.call("recoverProjectionApply", [root, intent]);
39679
39833
  }
@@ -41330,6 +41484,9 @@ async function runArchitectureDocsAdoptionCommand(args2, root, daemon, projectio
41330
41484
  const canonicalExistingByPath = new Map(simulatedByPath);
41331
41485
  for (const file of canonicalFirst.files)
41332
41486
  canonicalExistingByPath.set(file.path, file);
41487
+ const canonicalBaseline = buildArchitectureDocsProjection(root, generatedAt, profile, [...canonicalExistingByPath.values()]);
41488
+ for (const file of canonicalBaseline.files)
41489
+ canonicalExistingByPath.set(file.path, file);
41333
41490
  const canonical = buildArchitectureDocsProjection(root, generatedAt, profile, [...canonicalExistingByPath.values()]);
41334
41491
  if (!canonical.plan.drift.ok || canonical.plan.rejected.length > 0 || canonical.plan.projectionDigest !== canonicalFirst.plan.projectionDigest) {
41335
41492
  const reasons = canonical.plan.rejected.map((entry) => entry.reasonCode).join(",") || "none";
@@ -41450,10 +41607,12 @@ async function applyProjectionProtocolFixedPoint(request, input, fixedPoint, cha
41450
41607
  }
41451
41608
  async function runProjectionProtocolCommand(args2, cwd, daemon) {
41452
41609
  const subcommand = args2[0] ?? "run";
41610
+ if (subcommand === "readback")
41611
+ return runProjectionApplyReadbackCommand(args2.slice(1), cwd, daemon);
41453
41612
  if (subcommand === "recover")
41454
41613
  return runProjectionApplyRecoveryCommand(args2.slice(1), cwd, daemon);
41455
41614
  if (subcommand !== "run")
41456
- return errorEnvelope("projection", "AC_SCHEMA_INVALID", "projection requires run|recover --request-json <request>");
41615
+ return errorEnvelope("projection", "AC_SCHEMA_INVALID", "projection requires run|recover|readback --request-json <request>");
41457
41616
  const raw = readFlag(args2, "--request-json");
41458
41617
  if (!raw)
41459
41618
  return errorEnvelope("projection.run", "AC_SCHEMA_INVALID", "projection run requires --request-json");
@@ -41548,6 +41707,29 @@ function parseProjectionPriorCommittedApplies(value, requestId) {
41548
41707
  throw new Error(`prior committed apply invariant failed: ${issues.join("; ")}`);
41549
41708
  return applies;
41550
41709
  }
41710
+ async function runProjectionApplyReadbackCommand(args2, cwd, daemon) {
41711
+ const raw = readFlag(args2, "--request-json");
41712
+ if (!raw)
41713
+ return errorEnvelope("projection.readback", "AC_SCHEMA_INVALID", "projection readback requires --request-json");
41714
+ let request;
41715
+ try {
41716
+ request = parseProjectionProtocolRequest(raw);
41717
+ const issues = projectionApplyReadbackRequestInvariantIssues(request);
41718
+ if (issues.length > 0)
41719
+ throw new Error(issues.join("; "));
41720
+ } catch (error) {
41721
+ return errorEnvelope("projection.readback", "AC_SCHEMA_INVALID", error instanceof Error ? error.message : String(error));
41722
+ }
41723
+ try {
41724
+ const result = await daemon.readbackProjectionApply(findRepositoryRoot(cwd), request);
41725
+ if (!result.ok)
41726
+ return result;
41727
+ const issues = result.data?.schemaVersion === "archcontext.projection-apply-absence/v1" ? projectionApplyAbsenceInvariantIssues(result.data, request) : projectionApplyReadbackResultInvariantIssues(result.data, request);
41728
+ return issues.length === 0 ? result : errorEnvelope("projection.readback", "AC_SCHEMA_INVALID", issues.join("; "));
41729
+ } catch (error) {
41730
+ return errorEnvelope("projection.readback", "AC_PRECONDITION_FAILED", error instanceof Error ? error.message : String(error));
41731
+ }
41732
+ }
41551
41733
  async function runProjectionApplyRecoveryCommand(args2, cwd, daemon) {
41552
41734
  const raw = readFlag(args2, "--request-json");
41553
41735
  if (!raw)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "archctx",
3
- "version": "0.5.9",
3
+ "version": "0.5.11",
4
4
  "description": "Local architecture context CLI for agentic coding workflows.",
5
5
  "private": false,
6
6
  "type": "module",
@@ -39,7 +39,7 @@
39
39
  "type": "array",
40
40
  "minItems": 3,
41
41
  "uniqueItems": true,
42
- "items": { "enum": ["architecture-docs-renderer-v2", "architecture-refresh-signal-v1", "module-statistics-v1", "projection-apply-receipt-v1", "projection-apply-recovery-v1", "projection-prior-committed-applies-v1", "projection-protocol-v2", "recommendation-v3", "refactor-assessment-v1", "refactor-resolution-v1"] }
42
+ "items": { "enum": ["architecture-docs-renderer-v2", "architecture-refresh-signal-v1", "module-statistics-v1", "projection-apply-readback-v1", "projection-apply-receipt-v1", "projection-apply-recovery-v1", "projection-prior-committed-applies-v1", "projection-protocol-v2", "recommendation-v3", "refactor-assessment-v1", "refactor-resolution-v1"] }
43
43
  }
44
44
  }
45
45
  }