snipara-companion 3.6.3 → 3.6.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/CHANGELOG.md CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  Release notes for `snipara-companion`, newest first.
4
4
 
5
+ ## New In 3.6.4
6
+
7
+ - Correlates hosted Judgment responses with their immutable snapshot, append-only
8
+ exposure, run, and served-Judgment identities.
9
+ - Sends those canonical identities back with advisor influence receipts so the
10
+ backend can reject mismatched client correlation data.
11
+ - Keeps hosted Judgment failures best-effort for local runs while reporting the
12
+ failure boundary explicitly.
13
+
5
14
  ## New In 3.6.3
6
15
 
7
16
  - Labels every semantic `confidence` value as an uncalibrated
package/dist/index.d.ts CHANGED
@@ -688,6 +688,9 @@ interface AdvisorInfluenceRecommendationInput {
688
688
  }
689
689
  interface RecordAdvisorInfluenceReceiptInput {
690
690
  servedJudgmentId: string;
691
+ judgmentSnapshotId?: string;
692
+ judgmentExposureId?: string;
693
+ runId?: string;
691
694
  recommendation: AdvisorInfluenceRecommendationInput;
692
695
  agentDecision: AdvisorInfluenceAgentDecision;
693
696
  behaviorChange: string;
@@ -725,6 +728,16 @@ interface ProjectIntelligenceBriefRequest {
725
728
  changedFiles?: string[];
726
729
  symbols?: string[];
727
730
  routes?: string[];
731
+ codeContext?: {
732
+ localHeadSha?: string;
733
+ branch?: string;
734
+ workingTreeDirty?: boolean;
735
+ };
736
+ correlation?: {
737
+ surface?: "companion";
738
+ runId?: string;
739
+ sessionId?: string;
740
+ };
728
741
  }
729
742
  interface HostedProjectIntelligenceBriefResult {
730
743
  project: {
@@ -733,6 +746,8 @@ interface HostedProjectIntelligenceBriefResult {
733
746
  slug: string;
734
747
  };
735
748
  servedJudgmentId: string | null;
749
+ judgmentSnapshotId: string | null;
750
+ judgmentExposureId: string | null;
736
751
  persistedShadowSignalCount: number;
737
752
  brief: {
738
753
  version: string;
@@ -2933,6 +2948,8 @@ interface ProjectRunHostedJudgmentLink {
2933
2948
  status: "linked" | "unlinked" | "unavailable";
2934
2949
  timeoutMs: number;
2935
2950
  servedJudgmentId?: string;
2951
+ judgmentSnapshotId?: string;
2952
+ judgmentExposureId?: string;
2936
2953
  error?: string;
2937
2954
  }
2938
2955
  interface ProjectIntelligenceRunResult {
package/dist/index.js CHANGED
@@ -13878,6 +13878,9 @@ var why_capture_confidence_v1_default = {
13878
13878
  var WHY_CAPTURE_CONFIDENCE_VERSION = why_capture_confidence_v1_default.version;
13879
13879
  var WHY_CAPTURE_CONFIDENCE_TEST_VECTORS = why_capture_confidence_v1_default.vectors;
13880
13880
 
13881
+ // ../project-intelligence-contracts/src/judgment-integrity.ts
13882
+ var import_node_crypto4 = require("crypto");
13883
+
13881
13884
  // src/commands/decision-requests.ts
13882
13885
  var fs12 = __toESM(require("fs"));
13883
13886
  var path11 = __toESM(require("path"));
@@ -15828,7 +15831,7 @@ var import_chalk10 = __toESM(require("chalk"));
15828
15831
  var fs27 = __toESM(require("fs"));
15829
15832
  var path26 = __toESM(require("path"));
15830
15833
  var import_node_child_process13 = require("child_process");
15831
- var import_node_crypto10 = require("crypto");
15834
+ var import_node_crypto11 = require("crypto");
15832
15835
  var import_chalk9 = __toESM(require("chalk"));
15833
15836
 
15834
15837
  // src/runtime/orchestrator-handoff.ts
@@ -16306,7 +16309,7 @@ function normalizeStringList2(values) {
16306
16309
  // src/commands/activity.ts
16307
16310
  var fs17 = __toESM(require("fs"));
16308
16311
  var path16 = __toESM(require("path"));
16309
- var import_node_crypto4 = require("crypto");
16312
+ var import_node_crypto5 = require("crypto");
16310
16313
  var ACTIVITY_TIMELINE_VERSION = "snipara.activity_timeline.v0";
16311
16314
  var SESSION_SNAPSHOT_VERSION = "snipara.session_snapshot.v0";
16312
16315
  var ACTIVITY_RELATIVE_DIR = path16.join(".snipara", "activity");
@@ -16330,7 +16333,7 @@ function sortJsonValue3(value) {
16330
16333
  return value;
16331
16334
  }
16332
16335
  function hashEvent(input) {
16333
- return (0, import_node_crypto4.createHash)("sha256").update(stableJson(input)).digest("hex").slice(0, 16);
16336
+ return (0, import_node_crypto5.createHash)("sha256").update(stableJson(input)).digest("hex").slice(0, 16);
16334
16337
  }
16335
16338
  function safeReadJson(filePath) {
16336
16339
  try {
@@ -16637,7 +16640,7 @@ async function appendJournalCheckpoint(payload) {
16637
16640
  // src/commands/coding-ledger.ts
16638
16641
  var fs18 = __toESM(require("fs"));
16639
16642
  var path17 = __toESM(require("path"));
16640
- var import_node_crypto5 = require("crypto");
16643
+ var import_node_crypto6 = require("crypto");
16641
16644
  var import_node_child_process5 = require("child_process");
16642
16645
  var CODING_INTELLIGENCE_LEDGER_VERSION = "snipara.coding_intelligence_ledger.v0";
16643
16646
  var MAX_SECTION_ITEMS = 24;
@@ -17093,7 +17096,7 @@ function itemId(section, index, value) {
17093
17096
  return `${section}:${stableHash([section, String(index), value]).slice(0, 16)}`;
17094
17097
  }
17095
17098
  function stableHash(parts) {
17096
- return (0, import_node_crypto5.createHash)("sha256").update(parts.join("\0")).digest("hex");
17099
+ return (0, import_node_crypto6.createHash)("sha256").update(parts.join("\0")).digest("hex");
17097
17100
  }
17098
17101
  function stringValue5(value) {
17099
17102
  if (typeof value === "string") {
@@ -17424,7 +17427,7 @@ function toProjectRelativePath2(absolutePath, cwd) {
17424
17427
 
17425
17428
  // src/commands/collaboration.ts
17426
17429
  var import_node_child_process6 = require("child_process");
17427
- var import_node_crypto6 = require("crypto");
17430
+ var import_node_crypto7 = require("crypto");
17428
17431
  var fs20 = __toESM(require("fs"));
17429
17432
  var os6 = __toESM(require("os"));
17430
17433
  var path19 = __toESM(require("path"));
@@ -19153,7 +19156,7 @@ function printGuardActionCards(cards) {
19153
19156
  }
19154
19157
  }
19155
19158
  function buildLocalSessionId(context, task, files) {
19156
- const hash = (0, import_node_crypto6.createHash)("sha1").update([context.actor.actorId, context.branch ?? "", task ?? "", files.join(",")].join("\n")).digest("hex").slice(0, 12);
19159
+ const hash = (0, import_node_crypto7.createHash)("sha1").update([context.actor.actorId, context.branch ?? "", task ?? "", files.join(",")].join("\n")).digest("hex").slice(0, 12);
19157
19160
  return `local_${hash}`;
19158
19161
  }
19159
19162
  function normalizeFiles(files) {
@@ -19258,7 +19261,7 @@ function fingerprintReviewOnlyGuardEvaluation(evaluation) {
19258
19261
  workSessionId: conflict.workSessionId ?? null,
19259
19262
  reason: conflict.reason
19260
19263
  })).sort((a, b) => JSON.stringify(a).localeCompare(JSON.stringify(b)));
19261
- return (0, import_node_crypto6.createHash)("sha256").update(JSON.stringify(findings)).digest("hex");
19264
+ return (0, import_node_crypto7.createHash)("sha256").update(JSON.stringify(findings)).digest("hex");
19262
19265
  }
19263
19266
  function persistReviewOnlyAcknowledgement(state, profile, action, findingFingerprint, now = /* @__PURE__ */ new Date()) {
19264
19267
  invalidateReviewOnlyAcknowledgements(state, profile, action);
@@ -19391,7 +19394,7 @@ function sleep2(ms) {
19391
19394
  var fs22 = __toESM(require("fs"));
19392
19395
  var path21 = __toESM(require("path"));
19393
19396
  var import_node_child_process8 = require("child_process");
19394
- var import_node_crypto7 = require("crypto");
19397
+ var import_node_crypto8 = require("crypto");
19395
19398
 
19396
19399
  // src/commands/why-capture.ts
19397
19400
  var import_node_child_process7 = require("child_process");
@@ -21359,7 +21362,7 @@ function formatError2(error) {
21359
21362
  return error instanceof Error ? error.message : String(error);
21360
21363
  }
21361
21364
  function buildRecordId(prefix, createdAt, summary, files) {
21362
- const hash = (0, import_node_crypto7.createHash)("sha1").update([createdAt, summary, files.join(",")].join("\n")).digest("hex").slice(0, 10);
21365
+ const hash = (0, import_node_crypto8.createHash)("sha1").update([createdAt, summary, files.join(",")].join("\n")).digest("hex").slice(0, 10);
21363
21366
  return `${prefix}_${hash}`;
21364
21367
  }
21365
21368
 
@@ -22264,7 +22267,7 @@ function printKeyValue(label, value) {
22264
22267
  }
22265
22268
 
22266
22269
  // src/commands/final-commit-report.ts
22267
- var import_node_crypto8 = require("crypto");
22270
+ var import_node_crypto9 = require("crypto");
22268
22271
  var import_node_child_process10 = require("child_process");
22269
22272
  var fs24 = __toESM(require("fs"));
22270
22273
  var path23 = __toESM(require("path"));
@@ -22545,7 +22548,7 @@ function writeFinalCommitReport(report, cwd = process.cwd()) {
22545
22548
  version: FINAL_COMMIT_REPORT_VERSION,
22546
22549
  path: outputPath,
22547
22550
  relativePath: FINAL_COMMIT_REPORT_RELATIVE_PATH,
22548
- hash: `sha256:${(0, import_node_crypto8.createHash)("sha256").update(content).digest("hex")}`
22551
+ hash: `sha256:${(0, import_node_crypto9.createHash)("sha256").update(content).digest("hex")}`
22549
22552
  };
22550
22553
  } catch (error) {
22551
22554
  return {
@@ -22617,7 +22620,7 @@ function formatFinalCommitReport(report) {
22617
22620
 
22618
22621
  // src/commands/run.ts
22619
22622
  var import_node_child_process12 = require("child_process");
22620
- var import_node_crypto9 = require("crypto");
22623
+ var import_node_crypto10 = require("crypto");
22621
22624
  var fs26 = __toESM(require("fs"));
22622
22625
  var path25 = __toESM(require("path"));
22623
22626
  var import_chalk8 = __toESM(require("chalk"));
@@ -24717,7 +24720,7 @@ function buildProjectIntelligenceRunEnvelope(startedAt = /* @__PURE__ */ new Dat
24717
24720
  const codexSessionId = stringValue10(process.env.CODEX_SESSION_ID)?.slice(0, 200);
24718
24721
  return {
24719
24722
  version: "project-intelligence.judgment-run-envelope.v1",
24720
- runId: sniparaSessionId ?? codexSessionId ?? `judgment-run:${(0, import_node_crypto9.randomUUID)()}`,
24723
+ runId: sniparaSessionId ?? codexSessionId ?? `judgment-run:${(0, import_node_crypto10.randomUUID)()}`,
24721
24724
  identitySource: sniparaSessionId ? "snipara_session" : codexSessionId ? "codex_session" : "generated",
24722
24725
  startedAt: startedAt.toISOString()
24723
24726
  };
@@ -24725,6 +24728,24 @@ function buildProjectIntelligenceRunEnvelope(startedAt = /* @__PURE__ */ new Dat
24725
24728
  function normalizeStringList5(values) {
24726
24729
  return [...new Set((values ?? []).map((value) => value.trim()).filter(Boolean))];
24727
24730
  }
24731
+ function localCodeContext(branch) {
24732
+ const context = {};
24733
+ if (branch?.trim()) context.branch = branch.trim();
24734
+ try {
24735
+ const localHeadSha = (0, import_node_child_process12.execFileSync)("git", ["rev-parse", "--verify", "HEAD"], {
24736
+ encoding: "utf8",
24737
+ stdio: ["ignore", "pipe", "ignore"]
24738
+ }).trim();
24739
+ if (localHeadSha) context.localHeadSha = localHeadSha;
24740
+ const status = (0, import_node_child_process12.execFileSync)("git", ["status", "--porcelain"], {
24741
+ encoding: "utf8",
24742
+ stdio: ["ignore", "pipe", "ignore"]
24743
+ }).trim();
24744
+ context.workingTreeDirty = status.length > 0;
24745
+ } catch {
24746
+ }
24747
+ return context;
24748
+ }
24728
24749
  function uniqueStrings20(values) {
24729
24750
  return [...new Set(values.map((value) => value.trim()).filter(Boolean))];
24730
24751
  }
@@ -24958,6 +24979,9 @@ function advisorReceiptMetadata(args) {
24958
24979
  firstParty: true,
24959
24980
  runVersion: "project-intelligence.production-run.v1",
24960
24981
  runId: args.runEnvelope.runId,
24982
+ servedJudgmentId: args.hostedJudgment?.servedJudgmentId ?? null,
24983
+ judgmentSnapshotId: args.hostedJudgment?.judgmentSnapshotId ?? null,
24984
+ judgmentExposureId: args.hostedJudgment?.judgmentExposureId ?? null,
24961
24985
  runEnvelope: args.runEnvelope,
24962
24986
  generatedAt: args.judgmentCard.generatedAt,
24963
24987
  release: Boolean(args.options.release),
@@ -25219,6 +25243,9 @@ async function recordFirstPartyAdvisorReceipts(args) {
25219
25243
  });
25220
25244
  const result = await client.recordAdvisorInfluenceReceipt({
25221
25245
  servedJudgmentId,
25246
+ ...args.hostedJudgment?.judgmentSnapshotId ? { judgmentSnapshotId: args.hostedJudgment.judgmentSnapshotId } : {},
25247
+ ...args.hostedJudgment?.judgmentExposureId ? { judgmentExposureId: args.hostedJudgment.judgmentExposureId } : {},
25248
+ ...args.hostedJudgment?.status === "linked" ? { runId: args.runEnvelope.runId } : {},
25222
25249
  recommendation: advisorReceiptRecommendation(recommendation),
25223
25250
  agentDecision,
25224
25251
  behaviorChange,
@@ -25237,7 +25264,8 @@ async function recordFirstPartyAdvisorReceipts(args) {
25237
25264
  lifecycle,
25238
25265
  planScope,
25239
25266
  measurementState,
25240
- runEnvelope: args.runEnvelope
25267
+ runEnvelope: args.runEnvelope,
25268
+ hostedJudgment: args.hostedJudgment
25241
25269
  })
25242
25270
  });
25243
25271
  return {
@@ -25387,7 +25415,12 @@ async function buildProjectIntelligenceRun(options) {
25387
25415
  ).createProjectIntelligenceBrief({
25388
25416
  ...options.task ? { task: options.task } : {},
25389
25417
  ...options.diffSummary ? { diffSummary: options.diffSummary } : {},
25390
- ...changedFiles.length > 0 ? { changedFiles: changedFiles.slice(0, 120) } : {}
25418
+ ...changedFiles.length > 0 ? { changedFiles: changedFiles.slice(0, 120) } : {},
25419
+ codeContext: localCodeContext(options.branch),
25420
+ correlation: {
25421
+ surface: "companion",
25422
+ runId: runEnvelope.runId
25423
+ }
25391
25424
  });
25392
25425
  if (hostedProjectIntelligenceBrief.servedJudgmentId) {
25393
25426
  brief.servedJudgmentId = hostedProjectIntelligenceBrief.servedJudgmentId;
@@ -25395,7 +25428,9 @@ async function buildProjectIntelligenceRun(options) {
25395
25428
  version: "project-intelligence.hosted-judgment-link.v1",
25396
25429
  status: "linked",
25397
25430
  timeoutMs: HOSTED_PROJECT_INTELLIGENCE_BRIEF_TIMEOUT_MS,
25398
- servedJudgmentId: hostedProjectIntelligenceBrief.servedJudgmentId
25431
+ servedJudgmentId: hostedProjectIntelligenceBrief.servedJudgmentId,
25432
+ ...hostedProjectIntelligenceBrief.judgmentSnapshotId ? { judgmentSnapshotId: hostedProjectIntelligenceBrief.judgmentSnapshotId } : {},
25433
+ ...hostedProjectIntelligenceBrief.judgmentExposureId ? { judgmentExposureId: hostedProjectIntelligenceBrief.judgmentExposureId } : {}
25399
25434
  };
25400
25435
  } else {
25401
25436
  hostedJudgment = {
@@ -25485,7 +25520,8 @@ async function buildProjectIntelligenceRun(options) {
25485
25520
  judgmentCard,
25486
25521
  verificationEvidence: verificationEvidence2,
25487
25522
  outcomeReceipts,
25488
- runEnvelope
25523
+ runEnvelope,
25524
+ hostedJudgment
25489
25525
  });
25490
25526
  const suggestedCommands3 = [
25491
25527
  ...brief.suggestedCommands,
@@ -25886,7 +25922,7 @@ function contentBufferForHash(content) {
25886
25922
  return Buffer.from(content, "utf8");
25887
25923
  }
25888
25924
  function hashContent(content) {
25889
- return (0, import_node_crypto10.createHash)("sha256").update(contentBufferForHash(content)).digest("hex");
25925
+ return (0, import_node_crypto11.createHash)("sha256").update(contentBufferForHash(content)).digest("hex");
25890
25926
  }
25891
25927
  function toPreview(value, maxLength = 160) {
25892
25928
  if (typeof value === "string") {
@@ -28557,7 +28593,7 @@ function findSandboxRuntimeBinding(state, phaseId) {
28557
28593
  function defaultSandboxSessionId(state, phase) {
28558
28594
  const workflowSlug = sanitizeWorkflowId(state.workflowId, "workflow").slice(0, 24);
28559
28595
  const phaseSlug = sanitizeWorkflowId(phase.id, "phase").slice(0, 24);
28560
- const digest = (0, import_node_crypto10.createHash)("sha1").update(`${state.workflowId}:${phase.id}`).digest("hex").slice(0, 10);
28596
+ const digest = (0, import_node_crypto11.createHash)("sha1").update(`${state.workflowId}:${phase.id}`).digest("hex").slice(0, 10);
28561
28597
  return `sandbox-${workflowSlug}-${phaseSlug}-${digest}`.slice(0, 96);
28562
28598
  }
28563
28599
  function ensureSandboxRuntimeBinding(state, phase, now) {
@@ -35262,7 +35298,7 @@ async function sourceWatchCommand(options = {}) {
35262
35298
  var import_fs5 = __toESM(require("fs"));
35263
35299
  var import_path5 = __toESM(require("path"));
35264
35300
  var import_node_child_process14 = require("child_process");
35265
- var import_node_crypto11 = require("crypto");
35301
+ var import_node_crypto12 = require("crypto");
35266
35302
  var import_chalk11 = __toESM(require("chalk"));
35267
35303
  var CONTROLLED_WORKER_EXECUTIONS_DIR = import_path5.default.join(".snipara", "worker-executions");
35268
35304
  var UNIFIED_RECEIPTS_DIR = import_path5.default.join(".snipara", "unified-receipts");
@@ -35530,7 +35566,7 @@ function pathFingerprint(workspaceRoot2, relativePath2) {
35530
35566
  const stat = import_fs5.default.lstatSync(candidate);
35531
35567
  if (stat.isSymbolicLink()) return `symlink:${import_fs5.default.readlinkSync(candidate)}`;
35532
35568
  if (!stat.isFile()) return `mode:${stat.mode}:size:${stat.size}`;
35533
- return `file:${stat.mode}:${(0, import_node_crypto11.createHash)("sha256").update(import_fs5.default.readFileSync(candidate)).digest("hex")}`;
35569
+ return `file:${stat.mode}:${(0, import_node_crypto12.createHash)("sha256").update(import_fs5.default.readFileSync(candidate)).digest("hex")}`;
35534
35570
  } catch {
35535
35571
  return "missing";
35536
35572
  }
@@ -37829,7 +37865,7 @@ async function leadPlanCommand(options) {
37829
37865
  // src/commands/outcome-capture.ts
37830
37866
  var fs33 = __toESM(require("fs"));
37831
37867
  var path32 = __toESM(require("path"));
37832
- var import_node_crypto12 = require("crypto");
37868
+ var import_node_crypto13 = require("crypto");
37833
37869
  var WHY_OUTCOME_CAPTURE_VERSION = "snipara.why_outcome_capture.v1";
37834
37870
  var DEFAULT_MAX_CANDIDATES = 20;
37835
37871
  var MAX_EVENTS = 50;
@@ -38358,7 +38394,7 @@ function readEventsFromFile(filePath) {
38358
38394
  return [];
38359
38395
  }
38360
38396
  function stableHash2(parts) {
38361
- return (0, import_node_crypto12.createHash)("sha256").update(parts.join("\0")).digest("hex");
38397
+ return (0, import_node_crypto13.createHash)("sha256").update(parts.join("\0")).digest("hex");
38362
38398
  }
38363
38399
  function uniqueStrings22(values) {
38364
38400
  return Array.from(new Set(values.filter(Boolean)));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "snipara-companion",
3
- "version": "3.6.3",
3
+ "version": "3.6.4",
4
4
  "description": "Local-first CLI that asks your repo what breaks before an AI coding agent edits it.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {