archctx 0.4.0 → 0.4.2

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.4.0",
4
+ "productVersion": "0.4.2",
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:61835a0efb9c5a19cb4fd16482026918785d01b94b6e60f2c2a06b64a4c713be"
392
+ "catalogDigest": "sha256:7fc97d6c05657eeeee604a302a22e0afe77dc2d0ffea89442de193e570d9b8bf"
393
393
  }
package/bin/archctx.mjs CHANGED
@@ -783,7 +783,11 @@ function archctxCapabilities(packageVersion) {
783
783
  function projectionRequestInvariantIssues(input) {
784
784
  const issues = [
785
785
  ...sortedUniqueIssues("targets", input.targets),
786
- ...sortedUniqueIssues("changedPaths", input.changedPaths)
786
+ ...sortedUniqueIssues("changedPaths", input.changedPaths),
787
+ ...input.acceptedChange ? [
788
+ ...sortedUniqueIssues("acceptedChange.reasonCodes", input.acceptedChange.reasonCodes),
789
+ ...sortedUniqueIssues("acceptedChange.affectedNodeIds", input.acceptedChange.affectedNodeIds)
790
+ ] : []
787
791
  ];
788
792
  if (input.targets.length === 0)
789
793
  issues.push("targets must contain at least one projection target");
@@ -793,6 +797,25 @@ function projectionRequestInvariantIssues(input) {
793
797
  issues.push("adoptionPlanId is required when mode=adopt");
794
798
  if (input.mode !== "adopt" && input.adoptionPlanId !== undefined)
795
799
  issues.push("adoptionPlanId is only allowed when mode=adopt");
800
+ if (input.acceptedChange) {
801
+ if (input.acceptedChange.changeSetId.trim() === "")
802
+ issues.push("acceptedChange.changeSetId must not be empty");
803
+ if (input.acceptedChange.eventId.trim() === "")
804
+ issues.push("acceptedChange.eventId must not be empty");
805
+ if (input.acceptedChange.reasonCodes.length === 0)
806
+ issues.push("acceptedChange.reasonCodes must contain at least one reason");
807
+ if (input.acceptedChange.affectedNodeIds.length === 0)
808
+ issues.push("acceptedChange.affectedNodeIds must contain at least one node");
809
+ const allowedReasons = new Set(ARCHITECTURE_MAJOR_CHANGE_REASON_CODES);
810
+ for (const reason of input.acceptedChange.reasonCodes) {
811
+ if (!allowedReasons.has(reason))
812
+ issues.push(`acceptedChange.reasonCodes contains unsupported reason: ${reason}`);
813
+ }
814
+ for (const nodeId of input.acceptedChange.affectedNodeIds) {
815
+ if (nodeId.trim() === "")
816
+ issues.push("acceptedChange.affectedNodeIds must not contain empty node ids");
817
+ }
818
+ }
796
819
  return issues;
797
820
  }
798
821
  function projectionResultInvariantIssues(input) {
@@ -977,7 +1000,7 @@ function productVersionManifest() {
977
1000
  }
978
1001
  };
979
1002
  }
980
- var ARCHCONTEXT_PRODUCT_NAME = "archctx", ARCHCONTEXT_PRODUCT_VERSION = "0.4.0", ARCHCONTEXT_PACKAGE_MANAGER = "bun@1.3.10", ARCHCONTEXT_NODE_RANGE = ">=24 <26", LOCAL_RUNTIME_RPC_SCHEMA_VERSION = "archcontext.runtime-rpc/v1", ARCHCONTEXT_SCHEMA_SET_VERSION = "2026-07-11.explorer-view-v2";
1003
+ var ARCHCONTEXT_PRODUCT_NAME = "archctx", ARCHCONTEXT_PRODUCT_VERSION = "0.4.2", ARCHCONTEXT_PACKAGE_MANAGER = "bun@1.3.10", ARCHCONTEXT_NODE_RANGE = ">=24 <26", LOCAL_RUNTIME_RPC_SCHEMA_VERSION = "archcontext.runtime-rpc/v1", ARCHCONTEXT_SCHEMA_SET_VERSION = "2026-07-11.explorer-view-v2";
981
1004
 
982
1005
  // packages/contracts/src/validator.ts
983
1006
  function validateJsonSchema(schema, value) {
@@ -5590,6 +5613,8 @@ var DEFAULT_IGNORES = new Set([
5590
5613
  "_ops",
5591
5614
  "_ref",
5592
5615
  ".archcontext/.local",
5616
+ ".claude/.session-id",
5617
+ ".claude/.trace.jsonl",
5593
5618
  ".DS_Store"
5594
5619
  ]);
5595
5620
  function repositoryFingerprint(root) {
@@ -5736,6 +5761,8 @@ var DEFAULT_IGNORES2 = new Set([
5736
5761
  "_ops",
5737
5762
  "_ref",
5738
5763
  ".archcontext/.local",
5764
+ ".claude/.session-id",
5765
+ ".claude/.trace.jsonl",
5739
5766
  ".DS_Store"
5740
5767
  ]);
5741
5768
  function repositoryFingerprint2(root) {
@@ -40285,9 +40312,11 @@ async function runArchitectureDocsProjectionCommand(args2, cwd, daemon) {
40285
40312
  const generatedAt = readFlag(args2, "--generated-at") ?? new Date(0).toISOString();
40286
40313
  let profile;
40287
40314
  let projection3;
40315
+ let acceptedChange;
40288
40316
  try {
40289
40317
  profile = architectureProjectionProfile(args2);
40290
- projection3 = buildArchitectureDocsProjection(root, generatedAt, profile, undefined, acceptedArchitectureChange(args2));
40318
+ acceptedChange = acceptedArchitectureChange(args2);
40319
+ projection3 = buildArchitectureDocsProjection(root, generatedAt, profile, undefined, acceptedChange);
40291
40320
  } catch (error) {
40292
40321
  return errorEnvelope(`docs.${subcommand}`, "AC_PRECONDITION_FAILED", error instanceof Error ? error.message : String(error));
40293
40322
  }
@@ -40320,7 +40349,7 @@ async function runArchitectureDocsProjectionCommand(args2, cwd, daemon) {
40320
40349
  });
40321
40350
  }
40322
40351
  if (subcommand === "adopt") {
40323
- return runArchitectureDocsAdoptionCommand(args2, root, daemon, projection3, profile, generatedAt);
40352
+ return runArchitectureDocsAdoptionCommand(args2, root, daemon, projection3, profile, generatedAt, acceptedChange);
40324
40353
  }
40325
40354
  if (projection3.plan.rejected.length > 0) {
40326
40355
  return errorEnvelope("docs.plan", "AC_PRECONDITION_FAILED", `Architecture documentation projection requires explicit adoption or ownership repair: ${projection3.plan.rejected.map((diff) => `${diff.path} (${diff.reasonCode})`).join(", ")}`);
@@ -40415,7 +40444,7 @@ function buildArchitectureDocsProjection(root, generatedAt, profile = "default",
40415
40444
  generatedAt,
40416
40445
  refreshContext: {
40417
40446
  repositoryId: repositoryFingerprint(root),
40418
- workspaceId: `workspace.${digestJson({ root }).replace(/^sha256:/, "").slice(0, 16)}`,
40447
+ workspaceId: projectionWorkspaceId(root),
40419
40448
  headSha: provenance.baseHeadSha,
40420
40449
  worktreeDigest: provenance.worktreeDigest,
40421
40450
  ...acceptedChange ? { acceptedChange } : {}
@@ -40456,7 +40485,7 @@ function architectureProjectionProfile(args2) {
40456
40485
  }
40457
40486
  return profile;
40458
40487
  }
40459
- async function runArchitectureDocsAdoptionCommand(args2, root, daemon, projection3, profile, generatedAt) {
40488
+ async function runArchitectureDocsAdoptionCommand(args2, root, daemon, projection3, profile, generatedAt, acceptedChange) {
40460
40489
  if (profile !== REPO_HARNESS_PROJECTION_PROFILE) {
40461
40490
  return errorEnvelope("docs.adopt", "AC_SCHEMA_INVALID", `docs adopt requires --profile ${REPO_HARNESS_PROJECTION_PROFILE}`);
40462
40491
  }
@@ -40497,11 +40526,11 @@ async function runArchitectureDocsAdoptionCommand(args2, root, daemon, projectio
40497
40526
  const simulatedByPath = new Map(projection3.loaded.existingFiles.map((file) => [file.path, file]));
40498
40527
  for (const file of [...projection3.plan.files, ...adoption2.files])
40499
40528
  simulatedByPath.set(file.path, file);
40500
- const canonicalFirst = buildArchitectureDocsProjection(root, generatedAt, profile, [...simulatedByPath.values()]);
40529
+ const canonicalFirst = buildArchitectureDocsProjection(root, generatedAt, profile, [...simulatedByPath.values()], acceptedChange);
40501
40530
  const canonicalExistingByPath = new Map(simulatedByPath);
40502
40531
  for (const file of canonicalFirst.files)
40503
40532
  canonicalExistingByPath.set(file.path, file);
40504
- const canonical = buildArchitectureDocsProjection(root, generatedAt, profile, [...canonicalExistingByPath.values()]);
40533
+ const canonical = buildArchitectureDocsProjection(root, generatedAt, profile, [...canonicalExistingByPath.values()], acceptedChange);
40505
40534
  if (!canonical.plan.drift.ok || canonical.plan.rejected.length > 0 || canonical.plan.projectionDigest !== canonicalFirst.plan.projectionDigest) {
40506
40535
  return errorEnvelope("docs.adopt", "AC_PRECONDITION_FAILED", "projection-adoption-fixed-point-unproven");
40507
40536
  }
@@ -40544,7 +40573,7 @@ async function runProjectionProtocolCommand(args2, cwd, daemon) {
40544
40573
  const generatedAt = new Date(0).toISOString();
40545
40574
  let projection3;
40546
40575
  try {
40547
- projection3 = buildArchitectureDocsProjection(root, generatedAt, REPO_HARNESS_PROJECTION_PROFILE);
40576
+ projection3 = buildArchitectureDocsProjection(root, generatedAt, REPO_HARNESS_PROJECTION_PROFILE, undefined, request.acceptedChange);
40548
40577
  assertProjectionExpectedSnapshot(request, root, projection3);
40549
40578
  } catch (error) {
40550
40579
  return errorEnvelope("projection.run", "AC_PRECONDITION_FAILED", error instanceof Error ? error.message : String(error));
@@ -40565,12 +40594,12 @@ async function runProjectionProtocolCommand(args2, cwd, daemon) {
40565
40594
  expectedWorktreeDigest,
40566
40595
  "--task-session-id",
40567
40596
  request.requestId
40568
- ], root, daemon, projection3, REPO_HARNESS_PROJECTION_PROFILE, generatedAt);
40597
+ ], root, daemon, projection3, REPO_HARNESS_PROJECTION_PROFILE, generatedAt, request.acceptedChange);
40569
40598
  if (!adopted.ok)
40570
40599
  return adopted;
40571
40600
  let output;
40572
40601
  try {
40573
- output = buildArchitectureDocsProjection(root, generatedAt, REPO_HARNESS_PROJECTION_PROFILE);
40602
+ output = buildArchitectureDocsProjection(root, generatedAt, REPO_HARNESS_PROJECTION_PROFILE, undefined, request.acceptedChange);
40574
40603
  if (!output.plan.drift.ok || output.plan.rejected.length > 0) {
40575
40604
  return errorEnvelope("projection.run", "AC_PRECONDITION_FAILED", "projection adoption did not reach the architecture-docs fixed point");
40576
40605
  }
@@ -40632,14 +40661,35 @@ function parseProjectionProtocolRequest(raw) {
40632
40661
  throw new Error("projection request expected.headSha is invalid");
40633
40662
  if (typeof snapshot.worktreeDigest !== "string" || !/^sha256:[a-f0-9]{64}$/.test(snapshot.worktreeDigest))
40634
40663
  throw new Error("projection request expected.worktreeDigest is invalid");
40664
+ if (input.acceptedChange !== undefined)
40665
+ validateProjectionAcceptedChange(input.acceptedChange);
40635
40666
  const request = input;
40636
40667
  const issues = projectionRequestInvariantIssues(request);
40637
40668
  if (issues.length > 0)
40638
40669
  throw new Error(`projection request invariant failed: ${issues.join("; ")}`);
40639
40670
  return request;
40640
40671
  }
40672
+ function validateProjectionAcceptedChange(value) {
40673
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
40674
+ throw new Error("projection request acceptedChange must be an object");
40675
+ }
40676
+ const accepted = value;
40677
+ const supportedKeys = new Set(["changeSetId", "eventId", "reasonCodes", "affectedNodeIds"]);
40678
+ const unsupportedKey = Object.keys(accepted).find((key) => !supportedKeys.has(key));
40679
+ if (unsupportedKey)
40680
+ throw new Error(`projection request acceptedChange contains unsupported property: ${unsupportedKey}`);
40681
+ if (typeof accepted.changeSetId !== "string" || typeof accepted.eventId !== "string") {
40682
+ throw new Error("projection request acceptedChange changeSetId and eventId are required");
40683
+ }
40684
+ if (!Array.isArray(accepted.reasonCodes) || accepted.reasonCodes.some((reason) => typeof reason !== "string")) {
40685
+ throw new Error("projection request acceptedChange reasonCodes must be a string array");
40686
+ }
40687
+ if (!Array.isArray(accepted.affectedNodeIds) || accepted.affectedNodeIds.some((nodeId) => typeof nodeId !== "string")) {
40688
+ throw new Error("projection request acceptedChange affectedNodeIds must be a string array");
40689
+ }
40690
+ }
40641
40691
  function assertProjectionExpectedSnapshot(request, root, projection3) {
40642
- const workspaceId = `workspace.${digestJson({ root }).replace(/^sha256:/, "").slice(0, 16)}`;
40692
+ const workspaceId = projectionWorkspaceId(root);
40643
40693
  const actual = {
40644
40694
  repositoryId: repositoryFingerprint(root),
40645
40695
  workspaceId,
@@ -40651,6 +40701,10 @@ function assertProjectionExpectedSnapshot(request, root, projection3) {
40651
40701
  throw new Error(`projection request expected snapshot mismatch: ${field}`);
40652
40702
  }
40653
40703
  }
40704
+ function projectionWorkspaceId(root) {
40705
+ const canonicalRoot = canonicalRepositoryRoot(root);
40706
+ return `workspace.${digestJson({ root: canonicalRoot }).replace(/^sha256:/, "").slice(0, 16)}`;
40707
+ }
40654
40708
  function projectionProtocolHumanStatus(request, projection3) {
40655
40709
  const humanSignal = projection3.plan.refreshSignals.some((signal) => signal.mode === "human-action-required");
40656
40710
  const adoption2 = projection3.plan.rejected.some((diff) => diff.reasonCode === "projection-adoption-required");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "archctx",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "Local architecture context CLI for agentic coding workflows.",
5
5
  "private": false,
6
6
  "type": "module",
@@ -24,7 +24,8 @@
24
24
  "items": { "$ref": "#/$defs/repoPath" }
25
25
  },
26
26
  "expected": { "$ref": "#/$defs/expectedSnapshot" },
27
- "adoptionPlanId": { "type": "string", "pattern": "^adoption_plan\\.[a-zA-Z0-9_.-]+$" }
27
+ "adoptionPlanId": { "type": "string", "pattern": "^adoption_plan\\.[a-zA-Z0-9_.-]+$" },
28
+ "acceptedChange": { "$ref": "#/$defs/acceptedChange" }
28
29
  },
29
30
  "allOf": [
30
31
  {
@@ -46,6 +47,45 @@
46
47
  ]
47
48
  }
48
49
  },
50
+ "acceptedChange": {
51
+ "type": "object",
52
+ "additionalProperties": false,
53
+ "required": ["changeSetId", "eventId", "reasonCodes", "affectedNodeIds"],
54
+ "properties": {
55
+ "changeSetId": { "type": "string", "minLength": 1 },
56
+ "eventId": { "type": "string", "minLength": 1 },
57
+ "reasonCodes": {
58
+ "type": "array",
59
+ "minItems": 1,
60
+ "uniqueItems": true,
61
+ "description": "Canonical wire order is lexicographic and is enforced by projectionRequestInvariantIssues.",
62
+ "items": {
63
+ "enum": [
64
+ "constraint-changed",
65
+ "entrypoint-changed",
66
+ "interface-changed",
67
+ "lifecycle-changed",
68
+ "node-added",
69
+ "node-moved",
70
+ "node-removed",
71
+ "node-renamed",
72
+ "ownership-changed",
73
+ "relation-changed",
74
+ "responsibility-changed",
75
+ "risk-boundary-changed",
76
+ "verified-flow-proof-changed"
77
+ ]
78
+ }
79
+ },
80
+ "affectedNodeIds": {
81
+ "type": "array",
82
+ "minItems": 1,
83
+ "uniqueItems": true,
84
+ "description": "Canonical wire order is lexicographic and is enforced by projectionRequestInvariantIssues.",
85
+ "items": { "type": "string", "minLength": 1 }
86
+ }
87
+ }
88
+ },
49
89
  "expectedSnapshot": {
50
90
  "type": "object",
51
91
  "additionalProperties": false,