snipara-companion 3.5.3 → 3.5.5

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,25 @@
2
2
 
3
3
  Release notes for `snipara-companion`, newest first.
4
4
 
5
+ ## New In 3.5.5
6
+
7
+ - Gives Memory Guard source-context retrieval its own bounded 30-second window
8
+ while keeping ordinary memory recalls at 15 seconds.
9
+ - Skips Answer Pack generation and automatic decomposition for guard context so
10
+ pre-commit and pre-final checks consume raw source sections without needless
11
+ latency.
12
+
13
+ ## New In 3.5.4
14
+
15
+ - Makes `reality-check` auto-link bounded reviewed Team Sync decisions, keyword
16
+ document context, managed workflow receipts, and current verification
17
+ evidence while preserving explicit CLI inputs and failing open when hosted
18
+ context is unavailable.
19
+ - Keeps the evidence used by Reality Check inspectable in JSON and Markdown
20
+ findings instead of using verification only as a hidden severity signal.
21
+ - Gives `query` a 30-second default timeout plus explicit search-mode,
22
+ Answer Pack, decomposition, and shared-context controls for fast recovery.
23
+
5
24
  ## New In 3.5.3
6
25
 
7
26
  - Propagates the configured Companion `sessionId` as
package/README.md CHANGED
@@ -94,7 +94,7 @@ These commands are useful without hosted Snipara:
94
94
  | ------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
95
95
  | `source init` / `source sync` / `source status` | Local source snapshot, document preview, and code overlay |
96
96
  | `impact` / `code impact` | File-level blast-radius from the local code overlay |
97
- | `reality-check` | Intent Ledger, Unknown Registry, and verification checks |
97
+ | `reality-check` | Intent Ledger, Unknown Registry, auto-linked context, and inspectable proof |
98
98
  | `code callers` / `imports` / `neighbors` / `shortest-path` | Structural repo questions from local files |
99
99
  | `workflow start` / `phase-start` / `phase-commit` / `resume` | Agent continuity that survives compaction |
100
100
  | `workflow timeline` / `workflow session` | Append-only local activity log and Session Snapshot V0 |
package/dist/index.d.ts CHANGED
@@ -269,6 +269,19 @@ interface ContextQueryResult {
269
269
  graph_hybrid_used?: boolean;
270
270
  graph_context_tool?: string;
271
271
  graph_context_summary?: string;
272
+ search_mode?: ContextQuerySearchMode;
273
+ timing?: Record<string, number>;
274
+ retrieval_diagnostics?: Record<string, unknown>;
275
+ }
276
+ type ContextQuerySearchMode = "keyword" | "semantic" | "hybrid";
277
+ interface ContextQueryOptions {
278
+ searchMode?: ContextQuerySearchMode;
279
+ includeMetadata?: boolean;
280
+ includeAnswerPack?: boolean;
281
+ autoDecompose?: boolean;
282
+ includeSharedContext?: boolean;
283
+ includeAllTiers?: boolean;
284
+ returnReferences?: boolean;
272
285
  }
273
286
  interface AnswerPackSource {
274
287
  title?: string;
@@ -1222,7 +1235,7 @@ declare class RLMClient {
1222
1235
  /**
1223
1236
  * Query for optimized context using snipara_context_query
1224
1237
  */
1225
- queryContext(query: string, maxTokens?: number): Promise<ContextQueryResult>;
1238
+ queryContext(query: string, maxTokens?: number, options?: ContextQueryOptions): Promise<ContextQueryResult>;
1226
1239
  sharedContext(options?: {
1227
1240
  maxTokens?: number;
1228
1241
  categories?: string[];
@@ -1533,6 +1546,8 @@ interface MemoryGuardFinding {
1533
1546
  code: "recent_failure" | "release_surface" | "manual" | "destructive_intent" | "contradiction";
1534
1547
  message: string;
1535
1548
  }
1549
+ declare const MEMORY_GUARD_RECALL_TIMEOUT_MS = 15000;
1550
+ declare const MEMORY_GUARD_CONTEXT_TIMEOUT_MS = 30000;
1536
1551
  type MemoryGuardBlockReason = "confirmation_required" | "guidance_unavailable";
1537
1552
  interface MemoryGuardContradiction {
1538
1553
  source: "memory" | "context";
@@ -2183,12 +2198,24 @@ interface RealityCheckCommandOptions {
2183
2198
  decision?: string[];
2184
2199
  document?: string[];
2185
2200
  verification?: string[];
2201
+ autoContext?: boolean;
2202
+ autoContextTimeoutMs?: number;
2186
2203
  includeDirty?: boolean;
2187
2204
  enforce?: boolean;
2188
2205
  dir?: string;
2189
2206
  json?: boolean;
2190
2207
  }
2208
+ interface RealityCheckAutoContextClient {
2209
+ queryContext(query: string, maxTokens?: number, options?: ContextQueryOptions): Promise<ContextQueryResult>;
2210
+ getTeamSyncWhatChanged(args: {
2211
+ limit?: number;
2212
+ branch?: string;
2213
+ paths?: string[];
2214
+ recentFiles?: string[];
2215
+ }): Promise<TeamSyncChangesResponse>;
2216
+ }
2191
2217
  declare function buildLocalProjectRealityCheck(options: RealityCheckCommandOptions): ProjectRealityCheckResult;
2218
+ declare function buildLocalProjectRealityCheckWithAutoContext(options: RealityCheckCommandOptions, clientOverride?: RealityCheckAutoContextClient): Promise<ProjectRealityCheckResult>;
2192
2219
  declare function realityCheckCommand(options: RealityCheckCommandOptions): Promise<void>;
2193
2220
 
2194
2221
  interface DecisionRequestWriteResult {
@@ -4906,4 +4933,4 @@ declare function installAutomationBundle(args: {
4906
4933
  }): Promise<AutomationInstallResult>;
4907
4934
  declare function getAutomationStatus(projectDir?: string): AutomationStatusResult;
4908
4935
 
4909
- export { AUTOMATION_MANIFEST_RELATIVE_PATH, AutomationInstallConflictError, AutomationUnsupportedHookBundleError, CODING_INTELLIGENCE_LEDGER_VERSION, COLLABORATION_STATE_RELATIVE_PATH, ENGINEERING_LEAD_EXECUTION_RECEIPT_STAGES, ENGINEERING_LEAD_EXECUTION_RECEIPT_STATUSES, ENGINEERING_LEAD_POSTURES, ENGINEERING_LEAD_PROOF_VERIFICATION_SOURCES, ENGINEERING_LEAD_PROOF_VERIFICATION_STATUSES, ENGINEERING_LEAD_ROUTING_MODES, ENGINEERING_LEAD_STATUSES, ENGINEERING_LEAD_SUPERVISION_STATUSES, ENGINEERING_LEAD_WORKER_ROLES, ENGINEERING_LEAD_WORK_PACKAGE_STATUSES, FINAL_COMMIT_REPORT_RELATIVE_PATH, FINAL_COMMIT_REPORT_VERSION, ORCHESTRATOR_HANDOFF_RELATIVE_PATH, POLICY_LEDGER_SYNC_REPORT_VERSION, PRODUCER_LOOP_ARTIFACT_VERSION, PRODUCER_LOOP_RELATIVE_DIR, PRODUCER_LOOP_REPORT_VERSION, TEAM_SYNC_STATE_RELATIVE_PATH, WHY_OUTCOME_CAPTURE_VERSION, WORKFLOW_PLANS_RELATIVE_DIR, WORKFLOW_STATE_RELATIVE_PATH, addLocalWorker, agentReadinessAuditCommand, appendActivityEvent, applyLocalContextMutationPlan, archiveInactiveTeamSyncWork, attachLocalContextPackReceipts, autoArchiveTeamSyncState, buildAdaptiveWorkRoutingRecommendation, buildAgentReadinessAuditReport, buildAgenticHandoffMarkdown, buildAgenticTimeline, buildAgenticWorkStatus, buildAutomationInstallPlan, buildCanonicalEvent, buildCodeHooksInstallPlan, buildCodePromotionResult, buildCodeStatusResult, buildCodeSyncResult, buildCodingIntelligenceLedger, buildCollaborationActor, buildCollaborationGuardActionCards, buildCollaborationHooksInstallPlan, buildCommitResultMetadata, buildCompanionEngineeringLeadPlanReport, buildContextPackStats, buildEvalCaseArtifact, buildFinalCommitReport, buildGeneratedWorkflowPlanDocument, buildHostedCodeOverlayUploadPayload, buildHostedGuardPayload, buildJournalCheckpointEntry, buildLocalCallersResult, buildLocalCodeOverlay, buildLocalContextMutationPlan, buildLocalContextPackReceipt, buildLocalContextPackReceipts, buildLocalImpactResult, buildLocalImportsResult, buildLocalNeighborsResult, buildLocalProjectContextValidationReport, buildLocalProjectDriftReport, buildLocalProjectRealityCheck, buildLocalShortestPathResult, buildLocalSourceSnapshot, buildLocalSourceStatus, buildLocalSourceSyncResult, buildMemoryAudit, buildOnboardFolderManifest, buildOrchestratorHandoff, buildPolicyLedgerSyncReport, buildProducerLoopReport, buildProjectIntelligenceBrief, buildProjectIntelligenceRun, buildProjectJudgmentCard, buildSessionBootstrapBrief, buildSessionBootstrapQuality, buildSessionSnapshot, buildSyncDocumentsDryRun, buildTeamSyncHandoffRecord, buildTeamSyncStartWorkRecord, buildTeamSyncSummary, buildToolCallPayload, buildToolResultPayload, buildVerificationPlan, buildWhyOutcomeCaptureReport, buildWorkerTrustCandidates, buildWorkflowImpactGate, buildWorkflowPhaseCommitReceipt, buildWorkflowPhaseCommitSummary, buildWorkflowPlanScaffold, categoryFromGuardTag, classifyToolResult, cleanContextPacks, codingLedgerExportCommand, collaborationIdeStatusCommand, collectAgentReadinessLocalSignals, collectPolicyLedgerSyncArtifacts, collectSyncDocuments, collectSyncDocumentsInput, compactHostedGuardResources, compareLocalSourceSnapshots, completeTeamSyncStateFromEvidence, completeTeamSyncWorkFromEvidence, contextControlApplyCommand, contextControlDriftCommand, contextControlHostedApplyCommand, contextControlHostedDiffCommand, contextControlPlanCommand, contextControlValidateCommand, contextPackCleanCommand, contextPackPackCommand, contextPackRetrieveCommand, contextPackStatsCommand, controlledWorkerExecuteCommand, createClient, createEmptyCollaborationState, createEmptyTeamSyncState, createLocalQueryCache, deriveLocalCollaborationResourcesFromFiles, detectReleaseSurfacesFromFiles, detectRuntimeEnvironment, evalExportCommand, evalRunCommand, evaluateProjectPolicyGates, extractCommandFromToolInput, extractFilesFromToolInput, formatAgentReadinessAuditReport, formatCompanionEngineeringLeadPlanReport, formatFinalCommitReport, formatOrchestratorRecommendationReason, formatPolicyGateDecision, formatProjectJudgmentCard, formatStuckGuardDecision, getAutomationManifestPath, getAutomationStatus, getCollaborationStatePath, getConfigPath, getContextPackStoragePaths, getLocalCodeOverlayCachePath, getLocalCodePromotionStatePath, getLocalSourceSnapshotPath, getOrchestratorRecommendation, getPlanStepDisplayTitle, getStagedFiles, getStuckGuardInjection, getTeamSyncStatePath, hashWorkerProfile, ingestReferences, installAutomationBundle, leadPlanCommand, listProjectsForApiKey, loadAutomationManifest, loadCollaborationState, loadConfig, loadTeamSyncState, memoryAuditCommand, memoryCleanCandidatesCommand, memoryCompactCommand, memoryHealthCommand, memoryLocalCommand, memoryReviewsCommand, normalizeCollaborationFiles, normalizeGuardTag, normalizeWorkflowPlanInput, outcomeCapturePreviewCommand, packContext, parseCollaborationResources, projectIntelligenceBriefCommand, projectIntelligenceRunCommand, readActivityTimeline, readLocalCodeOverlayCache, readLocalCodePromotionState, readLocalSourceSnapshot, readLocalWorkersConfig, readSessionSnapshot, readWorkerTrustEvent, realityCheckCommand, referencesIngestCommand, referencesScanCommand, resolveAutoWorkflowMode, resolveContextPackRecord, resolveFullWorkflowTokenBudget, resolveLocalWorkerRoutingDefaults, resolveQueryFromToolInput, retrieveContextPack, runMemoryGuardCheck, saveCollaborationState, saveConfig, saveTeamSyncState, scanReferences, shouldFailCollaborationGuard, shouldSuggestOrchestratorForWorkflow, shouldSuggestRuntimeForWorkflow, summarizeLocalCodeOverlay, teamSyncSweepCommand, validatePlanResult, verifyCommand, workerTrustCandidateCommand, workerTrustReviewCommand, workerTrustStatusCommand, workersLocalAddCommand, workersLocalListCommand, workersLocalProbePrintCommand, workersLocalRemoveCommand, workersLocalStatusCommand, workflowSyncPolicyLedgerCommand, writeFinalCommitReport, writeLocalCodeOverlayCache, writeLocalCodePromotionState, writeLocalSourceSnapshot, writeOrchestratorHandoff, writeProducerLoopArtifact, writeSessionSnapshot };
4936
+ export { AUTOMATION_MANIFEST_RELATIVE_PATH, AutomationInstallConflictError, AutomationUnsupportedHookBundleError, CODING_INTELLIGENCE_LEDGER_VERSION, COLLABORATION_STATE_RELATIVE_PATH, ENGINEERING_LEAD_EXECUTION_RECEIPT_STAGES, ENGINEERING_LEAD_EXECUTION_RECEIPT_STATUSES, ENGINEERING_LEAD_POSTURES, ENGINEERING_LEAD_PROOF_VERIFICATION_SOURCES, ENGINEERING_LEAD_PROOF_VERIFICATION_STATUSES, ENGINEERING_LEAD_ROUTING_MODES, ENGINEERING_LEAD_STATUSES, ENGINEERING_LEAD_SUPERVISION_STATUSES, ENGINEERING_LEAD_WORKER_ROLES, ENGINEERING_LEAD_WORK_PACKAGE_STATUSES, FINAL_COMMIT_REPORT_RELATIVE_PATH, FINAL_COMMIT_REPORT_VERSION, MEMORY_GUARD_CONTEXT_TIMEOUT_MS, MEMORY_GUARD_RECALL_TIMEOUT_MS, ORCHESTRATOR_HANDOFF_RELATIVE_PATH, POLICY_LEDGER_SYNC_REPORT_VERSION, PRODUCER_LOOP_ARTIFACT_VERSION, PRODUCER_LOOP_RELATIVE_DIR, PRODUCER_LOOP_REPORT_VERSION, TEAM_SYNC_STATE_RELATIVE_PATH, WHY_OUTCOME_CAPTURE_VERSION, WORKFLOW_PLANS_RELATIVE_DIR, WORKFLOW_STATE_RELATIVE_PATH, addLocalWorker, agentReadinessAuditCommand, appendActivityEvent, applyLocalContextMutationPlan, archiveInactiveTeamSyncWork, attachLocalContextPackReceipts, autoArchiveTeamSyncState, buildAdaptiveWorkRoutingRecommendation, buildAgentReadinessAuditReport, buildAgenticHandoffMarkdown, buildAgenticTimeline, buildAgenticWorkStatus, buildAutomationInstallPlan, buildCanonicalEvent, buildCodeHooksInstallPlan, buildCodePromotionResult, buildCodeStatusResult, buildCodeSyncResult, buildCodingIntelligenceLedger, buildCollaborationActor, buildCollaborationGuardActionCards, buildCollaborationHooksInstallPlan, buildCommitResultMetadata, buildCompanionEngineeringLeadPlanReport, buildContextPackStats, buildEvalCaseArtifact, buildFinalCommitReport, buildGeneratedWorkflowPlanDocument, buildHostedCodeOverlayUploadPayload, buildHostedGuardPayload, buildJournalCheckpointEntry, buildLocalCallersResult, buildLocalCodeOverlay, buildLocalContextMutationPlan, buildLocalContextPackReceipt, buildLocalContextPackReceipts, buildLocalImpactResult, buildLocalImportsResult, buildLocalNeighborsResult, buildLocalProjectContextValidationReport, buildLocalProjectDriftReport, buildLocalProjectRealityCheck, buildLocalProjectRealityCheckWithAutoContext, buildLocalShortestPathResult, buildLocalSourceSnapshot, buildLocalSourceStatus, buildLocalSourceSyncResult, buildMemoryAudit, buildOnboardFolderManifest, buildOrchestratorHandoff, buildPolicyLedgerSyncReport, buildProducerLoopReport, buildProjectIntelligenceBrief, buildProjectIntelligenceRun, buildProjectJudgmentCard, buildSessionBootstrapBrief, buildSessionBootstrapQuality, buildSessionSnapshot, buildSyncDocumentsDryRun, buildTeamSyncHandoffRecord, buildTeamSyncStartWorkRecord, buildTeamSyncSummary, buildToolCallPayload, buildToolResultPayload, buildVerificationPlan, buildWhyOutcomeCaptureReport, buildWorkerTrustCandidates, buildWorkflowImpactGate, buildWorkflowPhaseCommitReceipt, buildWorkflowPhaseCommitSummary, buildWorkflowPlanScaffold, categoryFromGuardTag, classifyToolResult, cleanContextPacks, codingLedgerExportCommand, collaborationIdeStatusCommand, collectAgentReadinessLocalSignals, collectPolicyLedgerSyncArtifacts, collectSyncDocuments, collectSyncDocumentsInput, compactHostedGuardResources, compareLocalSourceSnapshots, completeTeamSyncStateFromEvidence, completeTeamSyncWorkFromEvidence, contextControlApplyCommand, contextControlDriftCommand, contextControlHostedApplyCommand, contextControlHostedDiffCommand, contextControlPlanCommand, contextControlValidateCommand, contextPackCleanCommand, contextPackPackCommand, contextPackRetrieveCommand, contextPackStatsCommand, controlledWorkerExecuteCommand, createClient, createEmptyCollaborationState, createEmptyTeamSyncState, createLocalQueryCache, deriveLocalCollaborationResourcesFromFiles, detectReleaseSurfacesFromFiles, detectRuntimeEnvironment, evalExportCommand, evalRunCommand, evaluateProjectPolicyGates, extractCommandFromToolInput, extractFilesFromToolInput, formatAgentReadinessAuditReport, formatCompanionEngineeringLeadPlanReport, formatFinalCommitReport, formatOrchestratorRecommendationReason, formatPolicyGateDecision, formatProjectJudgmentCard, formatStuckGuardDecision, getAutomationManifestPath, getAutomationStatus, getCollaborationStatePath, getConfigPath, getContextPackStoragePaths, getLocalCodeOverlayCachePath, getLocalCodePromotionStatePath, getLocalSourceSnapshotPath, getOrchestratorRecommendation, getPlanStepDisplayTitle, getStagedFiles, getStuckGuardInjection, getTeamSyncStatePath, hashWorkerProfile, ingestReferences, installAutomationBundle, leadPlanCommand, listProjectsForApiKey, loadAutomationManifest, loadCollaborationState, loadConfig, loadTeamSyncState, memoryAuditCommand, memoryCleanCandidatesCommand, memoryCompactCommand, memoryHealthCommand, memoryLocalCommand, memoryReviewsCommand, normalizeCollaborationFiles, normalizeGuardTag, normalizeWorkflowPlanInput, outcomeCapturePreviewCommand, packContext, parseCollaborationResources, projectIntelligenceBriefCommand, projectIntelligenceRunCommand, readActivityTimeline, readLocalCodeOverlayCache, readLocalCodePromotionState, readLocalSourceSnapshot, readLocalWorkersConfig, readSessionSnapshot, readWorkerTrustEvent, realityCheckCommand, referencesIngestCommand, referencesScanCommand, resolveAutoWorkflowMode, resolveContextPackRecord, resolveFullWorkflowTokenBudget, resolveLocalWorkerRoutingDefaults, resolveQueryFromToolInput, retrieveContextPack, runMemoryGuardCheck, saveCollaborationState, saveConfig, saveTeamSyncState, scanReferences, shouldFailCollaborationGuard, shouldSuggestOrchestratorForWorkflow, shouldSuggestRuntimeForWorkflow, summarizeLocalCodeOverlay, teamSyncSweepCommand, validatePlanResult, verifyCommand, workerTrustCandidateCommand, workerTrustReviewCommand, workerTrustStatusCommand, workersLocalAddCommand, workersLocalListCommand, workersLocalProbePrintCommand, workersLocalRemoveCommand, workersLocalStatusCommand, workflowSyncPolicyLedgerCommand, writeFinalCommitReport, writeLocalCodeOverlayCache, writeLocalCodePromotionState, writeLocalSourceSnapshot, writeOrchestratorHandoff, writeProducerLoopArtifact, writeSessionSnapshot };
package/dist/index.js CHANGED
@@ -48,6 +48,8 @@ __export(index_exports, {
48
48
  ENGINEERING_LEAD_WORK_PACKAGE_STATUSES: () => ENGINEERING_LEAD_WORK_PACKAGE_STATUSES,
49
49
  FINAL_COMMIT_REPORT_RELATIVE_PATH: () => FINAL_COMMIT_REPORT_RELATIVE_PATH,
50
50
  FINAL_COMMIT_REPORT_VERSION: () => FINAL_COMMIT_REPORT_VERSION,
51
+ MEMORY_GUARD_CONTEXT_TIMEOUT_MS: () => MEMORY_GUARD_CONTEXT_TIMEOUT_MS,
52
+ MEMORY_GUARD_RECALL_TIMEOUT_MS: () => MEMORY_GUARD_RECALL_TIMEOUT_MS,
51
53
  ORCHESTRATOR_HANDOFF_RELATIVE_PATH: () => ORCHESTRATOR_HANDOFF_RELATIVE_PATH,
52
54
  POLICY_LEDGER_SYNC_REPORT_VERSION: () => POLICY_LEDGER_SYNC_REPORT_VERSION,
53
55
  PRODUCER_LOOP_ARTIFACT_VERSION: () => PRODUCER_LOOP_ARTIFACT_VERSION,
@@ -99,6 +101,7 @@ __export(index_exports, {
99
101
  buildLocalProjectContextValidationReport: () => buildLocalProjectContextValidationReport,
100
102
  buildLocalProjectDriftReport: () => buildLocalProjectDriftReport,
101
103
  buildLocalProjectRealityCheck: () => buildLocalProjectRealityCheck,
104
+ buildLocalProjectRealityCheckWithAutoContext: () => buildLocalProjectRealityCheckWithAutoContext,
102
105
  buildLocalShortestPathResult: () => buildLocalShortestPathResult,
103
106
  buildLocalSourceSnapshot: () => buildLocalSourceSnapshot,
104
107
  buildLocalSourceStatus: () => buildLocalSourceStatus,
@@ -805,13 +808,17 @@ var RLMClient = class {
805
808
  /**
806
809
  * Query for optimized context using snipara_context_query
807
810
  */
808
- async queryContext(query, maxTokens = 8e3) {
811
+ async queryContext(query, maxTokens = 8e3, options = {}) {
809
812
  const result = await this.mcpCall("snipara_context_query", {
810
813
  query,
811
814
  max_tokens: maxTokens,
812
- search_mode: "hybrid",
813
- include_metadata: true,
814
- include_answer_pack: true
815
+ search_mode: options.searchMode ?? "hybrid",
816
+ include_metadata: options.includeMetadata ?? true,
817
+ include_answer_pack: options.includeAnswerPack ?? true,
818
+ auto_decompose: options.autoDecompose,
819
+ include_shared_context: options.includeSharedContext,
820
+ include_all_tiers: options.includeAllTiers,
821
+ return_references: options.returnReferences
815
822
  });
816
823
  return {
817
824
  sections: (result.sections || []).map((s) => ({
@@ -840,7 +847,10 @@ var RLMClient = class {
840
847
  recommended_tool_arguments: result.recommended_tool_arguments || {},
841
848
  graph_hybrid_used: result.graph_hybrid_used,
842
849
  graph_context_tool: result.graph_context_tool,
843
- graph_context_summary: result.graph_context_summary
850
+ graph_context_summary: result.graph_context_summary,
851
+ search_mode: result.search_mode,
852
+ timing: result.timing,
853
+ retrieval_diagnostics: result.retrieval_diagnostics
844
854
  };
845
855
  }
846
856
  async sharedContext(options = {}) {
@@ -8052,6 +8062,8 @@ var MEMORY_GUARD_EXIT_CODES = {
8052
8062
  guidanceUnavailable: 21,
8053
8063
  validationError: 22
8054
8064
  };
8065
+ var MEMORY_GUARD_RECALL_TIMEOUT_MS = 15e3;
8066
+ var MEMORY_GUARD_CONTEXT_TIMEOUT_MS = 3e4;
8055
8067
  var DEFAULT_GUARD_CATEGORIES_BY_TRIGGER = {
8056
8068
  failure: ["failure", "debug", "stuck", "retry", "workflow-policy", "guard:failure"],
8057
8069
  "pre-commit": [
@@ -8494,7 +8506,9 @@ async function runMemoryGuardCheck(options = {}) {
8494
8506
  message: "The proposed action is destructive, irreversible, or publish/deploy-like."
8495
8507
  });
8496
8508
  }
8497
- const client = isConfigured() ? createClient(15e3) : null;
8509
+ const configured = isConfigured();
8510
+ const client = configured ? createClient(MEMORY_GUARD_RECALL_TIMEOUT_MS) : null;
8511
+ const contextClient = configured ? createClient(MEMORY_GUARD_CONTEXT_TIMEOUT_MS) : null;
8498
8512
  let recentFailures = [];
8499
8513
  if (client && options.recentFailures !== false && ["pre-commit", "commit", "pre-final"].includes(trigger)) {
8500
8514
  try {
@@ -8573,7 +8587,10 @@ async function runMemoryGuardCheck(options = {}) {
8573
8587
  }
8574
8588
  if (options.includeContext !== false) {
8575
8589
  try {
8576
- contextResult = await client.queryContext(query, 1600);
8590
+ contextResult = await (contextClient ?? client).queryContext(query, 1600, {
8591
+ includeAnswerPack: false,
8592
+ autoDecompose: false
8593
+ });
8577
8594
  contextAvailable = (contextResult.sections || []).length > 0;
8578
8595
  } catch (error) {
8579
8596
  warnings.push(
@@ -9541,6 +9558,9 @@ function buildDocumentIntentEntry(doc, policy) {
9541
9558
  doc.intent?.freshnessHorizonDays ?? doc.freshnessHorizonDays ?? sectionIntent.freshnessHorizonDays,
9542
9559
  policy
9543
9560
  );
9561
+ const affectedAnchors = uniqueStrings3(
9562
+ doc.affectedAnchors && doc.affectedAnchors.length > 0 ? doc.affectedAnchors : [doc.path]
9563
+ );
9544
9564
  return {
9545
9565
  id: `intent:doc:${doc.path}`,
9546
9566
  title: doc.title || doc.path,
@@ -9568,7 +9588,7 @@ function buildDocumentIntentEntry(doc, policy) {
9568
9588
  structuredSections: sectionIntent,
9569
9589
  fallbackUsed: goal === doc.path || goal === doc.title
9570
9590
  }),
9571
- affectedAnchors: [doc.path],
9591
+ affectedAnchors,
9572
9592
  owner: doc.intent?.owner ?? sectionIntent.owner ?? doc.owner ?? null,
9573
9593
  evidence: [
9574
9594
  {
@@ -10196,6 +10216,23 @@ function decisionEvidence(decisions) {
10196
10216
  strength: decision.confidenceScore ?? 0.8
10197
10217
  }));
10198
10218
  }
10219
+ function verificationEvidence(input) {
10220
+ return (input.verificationChecklist ?? []).slice(0, 8).map((item, index) => ({
10221
+ kind: /test|spec|vitest|pytest|e2e|smoke|lint|type.?check|build|health|ready|migration|schema|pack/i.test(
10222
+ item
10223
+ ) ? "test" : "manual",
10224
+ label: item,
10225
+ sourceRef: `verification:${index + 1}`,
10226
+ strength: 0.75
10227
+ }));
10228
+ }
10229
+ function uniqueEvidence(evidence) {
10230
+ return [
10231
+ ...new Map(
10232
+ evidence.map((item) => [`${item.kind}:${item.sourceRef ?? item.label}`, item])
10233
+ ).values()
10234
+ ];
10235
+ }
10199
10236
  function buildProjectRealityCheck(input) {
10200
10237
  const changedFiles = uniqueStrings3(input.changedFiles);
10201
10238
  const dirtyFiles = uniqueStrings3(input.dirtyFiles ?? []);
@@ -10203,7 +10240,17 @@ function buildProjectRealityCheck(input) {
10203
10240
  const tests = testFiles(changedFiles);
10204
10241
  const findings = [];
10205
10242
  const decisions = input.decisions ?? [];
10206
- const contextEvidence2 = [...docEvidence(input), ...symbolEvidence(input)];
10243
+ const verificationRefs = verificationEvidence(input);
10244
+ const contextEvidence2 = uniqueEvidence([
10245
+ ...docEvidence(input),
10246
+ ...symbolEvidence(input),
10247
+ ...input.evidence ?? []
10248
+ ]);
10249
+ const allEvidence = uniqueEvidence([
10250
+ ...decisionEvidence(decisions),
10251
+ ...verificationRefs,
10252
+ ...contextEvidence2
10253
+ ]).slice(0, 20);
10207
10254
  const intentLedger = buildProjectIntentLedger(input, changedFiles);
10208
10255
  for (const surface of SENSITIVE_SURFACES) {
10209
10256
  const files = surfaceFiles(surface, changedFiles);
@@ -10232,7 +10279,11 @@ function buildProjectRealityCheck(input) {
10232
10279
  summary: `${files.length} changed file(s) touch ${surface.label.toLowerCase()} with ${relatedDecisions.length > 0 ? `${relatedDecisions.length} linked decision(s)` : "no linked decision"} and ${hasVerification ? "some verification evidence" : "no obvious verification evidence"}.`,
10233
10280
  changedFiles: files.slice(0, 12),
10234
10281
  decisionIds: relatedDecisions.map((decision) => decision.id).slice(0, 8),
10235
- evidence: [...decisionEvidence(relatedDecisions), ...contextEvidence2].slice(0, 8),
10282
+ evidence: uniqueEvidence([
10283
+ ...decisionEvidence(relatedDecisions),
10284
+ ...verificationRefs,
10285
+ ...contextEvidence2
10286
+ ]).slice(0, 8),
10236
10287
  reasonCodes: reasonCodes2,
10237
10288
  recommendedActions,
10238
10289
  caveats: [
@@ -10254,7 +10305,7 @@ function buildProjectRealityCheck(input) {
10254
10305
  summary: "This change spans architectural boundaries. Verify that the dependency direction and runtime ownership still match the intended architecture.",
10255
10306
  changedFiles: files.slice(0, 12),
10256
10307
  decisionIds: [],
10257
- evidence: contextEvidence2.slice(0, 6),
10308
+ evidence: uniqueEvidence([...verificationRefs, ...contextEvidence2]).slice(0, 8),
10258
10309
  reasonCodes: [rule.key, "cross_boundary_change"],
10259
10310
  recommendedActions: [
10260
10311
  "Check that the changed modules do not introduce a forbidden runtime dependency.",
@@ -10353,6 +10404,7 @@ function buildProjectRealityCheck(input) {
10353
10404
  findings,
10354
10405
  intentLedger,
10355
10406
  unknownRegistry,
10407
+ evidence: allEvidence,
10356
10408
  requiredActions,
10357
10409
  watchItems,
10358
10410
  reasonCodes: uniqueStrings3([
@@ -10421,11 +10473,24 @@ function renderProjectRealityCheckMarkdown(result) {
10421
10473
  if (finding.decisionIds.length > 0) {
10422
10474
  lines.push(` Decisions: ${finding.decisionIds.join(", ")}`);
10423
10475
  }
10476
+ if (finding.evidence.length > 0) {
10477
+ lines.push(
10478
+ ` Evidence: ${finding.evidence.slice(0, 4).map((item) => `${item.kind}:${item.label}`).join("; ")}`
10479
+ );
10480
+ }
10424
10481
  if (finding.recommendedActions.length > 0) {
10425
10482
  lines.push(` Action: ${finding.recommendedActions[0]}`);
10426
10483
  }
10427
10484
  }
10428
10485
  }
10486
+ if (result.evidence.length > 0) {
10487
+ lines.push("", "Evidence:");
10488
+ lines.push(
10489
+ ...result.evidence.slice(0, 10).map(
10490
+ (item) => `- ${item.kind}: ${item.label}${item.sourceRef ? ` (${item.sourceRef})` : ""}`
10491
+ )
10492
+ );
10493
+ }
10429
10494
  if (result.requiredActions.length > 0) {
10430
10495
  lines.push("", "Required actions:");
10431
10496
  lines.push(...result.requiredActions.map((action) => `- ${action}`));
@@ -26118,8 +26183,18 @@ function printRecallResult(result) {
26118
26183
  }
26119
26184
  async function queryCommand(options) {
26120
26185
  ensureConfigured();
26121
- const client = createClient(15e3);
26122
- const result = await client.queryContext(options.query, options.maxTokens || 8e3);
26186
+ const searchMode = options.searchMode ?? "hybrid";
26187
+ if (!["keyword", "semantic", "hybrid"].includes(searchMode)) {
26188
+ throw new Error("--search-mode must be keyword, semantic, or hybrid");
26189
+ }
26190
+ const timeoutMs = Math.max(1e3, Math.min(options.timeoutMs ?? 3e4, 12e4));
26191
+ const client = createClient(timeoutMs);
26192
+ const result = await client.queryContext(options.query, options.maxTokens || 8e3, {
26193
+ searchMode,
26194
+ includeAnswerPack: options.includeAnswerPack,
26195
+ autoDecompose: options.autoDecompose,
26196
+ includeSharedContext: options.includeSharedContext
26197
+ });
26123
26198
  const recommendedExecution = options.followRecommendation && result.recommended_tool ? await runRecommendedTool(result) : null;
26124
26199
  if (options.json) {
26125
26200
  printJson2(
@@ -34850,6 +34925,7 @@ async function projectIntelligenceBriefCommand(options) {
34850
34925
 
34851
34926
  // src/commands/reality-check.ts
34852
34927
  var import_node_child_process14 = require("child_process");
34928
+ var import_node_fs2 = __toESM(require("fs"));
34853
34929
  var import_node_path2 = __toESM(require("path"));
34854
34930
  var import_chalk12 = __toESM(require("chalk"));
34855
34931
  function runGit2(args, cwd, options = {}) {
@@ -34944,8 +35020,263 @@ function parseDocument(value) {
34944
35020
  contentPreview: rest.join(":").trim() || null
34945
35021
  };
34946
35022
  }
34947
- function buildLocalProjectRealityCheck(options) {
34948
- const scope = buildLocalGitScope(options);
35023
+ function emptyAutoContext() {
35024
+ return {
35025
+ decisions: [],
35026
+ documents: [],
35027
+ evidence: [],
35028
+ verification: [],
35029
+ caveats: []
35030
+ };
35031
+ }
35032
+ function isRecord19(value) {
35033
+ return typeof value === "object" && value !== null && !Array.isArray(value);
35034
+ }
35035
+ function stringValue14(value) {
35036
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
35037
+ }
35038
+ function stringList3(value) {
35039
+ return Array.isArray(value) ? unique5(value.map((item) => typeof item === "string" ? item : void 0)) : [];
35040
+ }
35041
+ function readJsonRecord3(filePath) {
35042
+ try {
35043
+ const parsed = JSON.parse(import_node_fs2.default.readFileSync(filePath, "utf8"));
35044
+ return isRecord19(parsed) ? parsed : void 0;
35045
+ } catch {
35046
+ return void 0;
35047
+ }
35048
+ }
35049
+ var GENERIC_SCOPE_TOKENS = /* @__PURE__ */ new Set([
35050
+ "apps",
35051
+ "packages",
35052
+ "src",
35053
+ "test",
35054
+ "tests",
35055
+ "index",
35056
+ "server",
35057
+ "project",
35058
+ "snipara",
35059
+ "file",
35060
+ "files",
35061
+ "change",
35062
+ "changed"
35063
+ ]);
35064
+ function scopeTokens(value) {
35065
+ const tokens = new Set(
35066
+ (value.toLowerCase().match(/[a-z0-9][a-z0-9_-]{2,}/g) ?? []).flatMap((token) => token.split(/[-_]/g)).filter((token) => token.length >= 3 && !GENERIC_SCOPE_TOKENS.has(token))
35067
+ );
35068
+ if (/packages\/cli\//i.test(value)) {
35069
+ tokens.add("cli");
35070
+ tokens.add("companion");
35071
+ }
35072
+ if (/project-intelligence-contracts/i.test(value)) {
35073
+ tokens.add("intelligence");
35074
+ tokens.add("intent");
35075
+ tokens.add("reality");
35076
+ }
35077
+ if (/mcp-server/i.test(value)) {
35078
+ tokens.add("mcp");
35079
+ tokens.add("context");
35080
+ tokens.add("retrieval");
35081
+ }
35082
+ if (/prisma|migration|document_chunks/i.test(value)) {
35083
+ tokens.add("database");
35084
+ tokens.add("schema");
35085
+ tokens.add("pgvector");
35086
+ }
35087
+ return tokens;
35088
+ }
35089
+ function matchingAnchors(text, changedFiles) {
35090
+ const textTokens = scopeTokens(text);
35091
+ return changedFiles.filter((file) => {
35092
+ const fileTokens = scopeTokens(file);
35093
+ return [...fileTokens].some((token) => textTokens.has(token));
35094
+ });
35095
+ }
35096
+ function hasFileOverlap(left, right) {
35097
+ const rightSet = new Set(right);
35098
+ return left.some((item) => rightSet.has(item));
35099
+ }
35100
+ function collectLocalReceiptContext(scope) {
35101
+ const context = emptyAutoContext();
35102
+ const workflowRef = ".snipara/workflow/current.json";
35103
+ const workflow2 = readJsonRecord3(import_node_path2.default.join(scope.root, workflowRef));
35104
+ if (workflow2) {
35105
+ const workflowId = stringValue14(workflow2.workflowId) ?? "managed workflow";
35106
+ const phases = Array.isArray(workflow2.phases) ? workflow2.phases.filter(isRecord19) : [];
35107
+ for (const phase of phases) {
35108
+ const phaseFiles = stringList3(phase.files);
35109
+ if (!hasFileOverlap(phaseFiles, scope.changedFiles)) continue;
35110
+ const title = stringValue14(phase.title) ?? stringValue14(phase.id) ?? "workflow phase";
35111
+ const status = stringValue14(phase.status) ?? "unknown";
35112
+ context.evidence.push({
35113
+ kind: "workflow",
35114
+ label: `${workflowId}: ${title} (${status})`,
35115
+ sourceRef: workflowRef,
35116
+ strength: status === "completed" ? 0.78 : 0.62
35117
+ });
35118
+ }
35119
+ }
35120
+ const finalReportRef = ".snipara/workflow/final-report.json";
35121
+ const finalReport = readJsonRecord3(import_node_path2.default.join(scope.root, finalReportRef));
35122
+ const changed = isRecord19(finalReport?.changed) ? finalReport.changed : void 0;
35123
+ const reportFiles = stringList3(changed?.files);
35124
+ const overlappingFiles = reportFiles.filter((file) => scope.changedFiles.includes(file));
35125
+ if (finalReport && overlappingFiles.length > 0) {
35126
+ const workflowId = stringValue14(finalReport.workflowId) ?? "completed workflow";
35127
+ const outcome = stringValue14(finalReport.outcome) ?? "unknown";
35128
+ context.evidence.push({
35129
+ kind: "workflow",
35130
+ label: `${workflowId}: final report (${outcome})`,
35131
+ sourceRef: finalReportRef,
35132
+ strength: outcome === "completed" ? 0.82 : 0.6
35133
+ });
35134
+ const repository = isRecord19(changed?.repository) ? changed.repository : void 0;
35135
+ const reportHead = stringValue14(repository?.head);
35136
+ const dirtyOverlap = hasFileOverlap(scope.dirtyFiles, overlappingFiles);
35137
+ const receiptMatchesCurrentHead = Boolean(reportHead && reportHead === scope.headRef);
35138
+ const evidence = isRecord19(finalReport.evidence) ? finalReport.evidence : void 0;
35139
+ const items = Array.isArray(evidence?.items) ? evidence.items.filter(isRecord19) : [];
35140
+ if (receiptMatchesCurrentHead && !dirtyOverlap) {
35141
+ for (const [index, item] of items.entries()) {
35142
+ if (stringValue14(item.status)?.toLowerCase() !== "passed") continue;
35143
+ const label = stringValue14(item.text);
35144
+ if (!label) continue;
35145
+ context.verification.push(label);
35146
+ context.evidence.push({
35147
+ kind: "test",
35148
+ label,
35149
+ sourceRef: `${finalReportRef}#evidence-${index + 1}`,
35150
+ strength: 0.88
35151
+ });
35152
+ }
35153
+ } else if (items.length > 0) {
35154
+ context.caveats.push(
35155
+ "A prior workflow report overlaps this scope, but its passed checks were not counted as current verification because the receipt does not cover the current dirty/HEAD state."
35156
+ );
35157
+ }
35158
+ }
35159
+ return context;
35160
+ }
35161
+ function isReviewedDecisionSignal(signal) {
35162
+ const status = signal.status.toUpperCase();
35163
+ if (!["ACTIVE", "APPROVED", "ACCEPTED", "CONFIRMED"].includes(status)) return false;
35164
+ const tags = signal.tags.map((tag) => tag.toLowerCase());
35165
+ if (tags.some(
35166
+ (tag) => tag === "workflow-phase" || tag === "release" || tag === "auto-captured" || tag === "review-pending" || tag.startsWith("journal:")
35167
+ )) {
35168
+ return false;
35169
+ }
35170
+ return /decision/i.test(signal.recommendedAction);
35171
+ }
35172
+ function decisionsFromTeamSync(response, changedFiles) {
35173
+ const decisions = [];
35174
+ for (const signal of response.whatChanged.decisions.filter(isReviewedDecisionSignal)) {
35175
+ const affectedAnchors = matchingAnchors(
35176
+ [signal.title, signal.summary, ...signal.tags].join(" "),
35177
+ changedFiles
35178
+ );
35179
+ if (affectedAnchors.length === 0) continue;
35180
+ decisions.push({
35181
+ id: signal.id,
35182
+ title: signal.title,
35183
+ decision: signal.summary,
35184
+ status: "approved",
35185
+ confidenceScore: signal.impact?.toUpperCase() === "HIGH" ? 0.9 : 0.84,
35186
+ affectedAnchors,
35187
+ evidence: [
35188
+ {
35189
+ kind: "decision",
35190
+ label: `${signal.id}: ${signal.title}`,
35191
+ sourceRef: signal.id,
35192
+ strength: signal.impact?.toUpperCase() === "HIGH" ? 0.9 : 0.84
35193
+ }
35194
+ ]
35195
+ });
35196
+ }
35197
+ return decisions.slice(0, 8);
35198
+ }
35199
+ function contextQueryText(options, scope) {
35200
+ const task = options.task?.trim() || "Project Reality Check governing intent";
35201
+ const tokens = unique5([
35202
+ ...scopeTokens(task),
35203
+ ...scope.changedFiles.slice(0, 12).flatMap((file) => [...scopeTokens(file)]),
35204
+ "decision",
35205
+ "constraint"
35206
+ ]).slice(0, 8);
35207
+ return tokens.join(" ");
35208
+ }
35209
+ function documentsFromContext(result, changedFiles) {
35210
+ return result.sections.filter((section) => section.file && section.file !== "(unknown)").map((section) => ({
35211
+ path: section.file,
35212
+ title: section.title,
35213
+ contentPreview: section.content.slice(0, 1600),
35214
+ kind: /adr|decision/i.test(`${section.file} ${section.title}`) ? "ADR" : "DOC",
35215
+ sourceRef: `${section.file}#L${section.lines[0]}-L${section.lines[1]}`,
35216
+ affectedAnchors: matchingAnchors(
35217
+ `${section.file} ${section.title} ${section.content.slice(0, 800)}`,
35218
+ changedFiles
35219
+ )
35220
+ })).slice(0, 8);
35221
+ }
35222
+ async function collectHostedAutoContext(client, options, scope) {
35223
+ const context = emptyAutoContext();
35224
+ const [teamSync2, documents] = await Promise.allSettled([
35225
+ client.getTeamSyncWhatChanged({
35226
+ limit: 50,
35227
+ branch: scope.branch,
35228
+ paths: scope.changedFiles.slice(0, 20),
35229
+ recentFiles: scope.changedFiles.slice(0, 10)
35230
+ }),
35231
+ client.queryContext(contextQueryText(options, scope), 1200, {
35232
+ searchMode: "keyword",
35233
+ includeMetadata: true,
35234
+ includeAnswerPack: false,
35235
+ autoDecompose: false,
35236
+ includeSharedContext: false,
35237
+ includeAllTiers: false
35238
+ })
35239
+ ]);
35240
+ if (teamSync2.status === "fulfilled") {
35241
+ context.decisions = decisionsFromTeamSync(teamSync2.value, scope.changedFiles);
35242
+ } else {
35243
+ context.caveats.push(
35244
+ "Hosted reviewed-decision auto-linking was unavailable; explicit --decision inputs remain authoritative."
35245
+ );
35246
+ }
35247
+ if (documents.status === "fulfilled") {
35248
+ context.documents = documentsFromContext(documents.value, scope.changedFiles);
35249
+ } else {
35250
+ context.caveats.push(
35251
+ "Hosted document auto-context was unavailable; Reality Check continued with local and explicit evidence."
35252
+ );
35253
+ }
35254
+ return context;
35255
+ }
35256
+ function mergeAutoContext(local, hosted) {
35257
+ return {
35258
+ decisions: [...local.decisions, ...hosted.decisions],
35259
+ documents: [...local.documents, ...hosted.documents],
35260
+ evidence: [...local.evidence, ...hosted.evidence],
35261
+ verification: unique5([...local.verification, ...hosted.verification]),
35262
+ caveats: unique5([...local.caveats, ...hosted.caveats])
35263
+ };
35264
+ }
35265
+ function buildProjectRealityCheckForScope(options, scope, autoContext = emptyAutoContext()) {
35266
+ const decisionsById = new Map(
35267
+ autoContext.decisions.map((decision) => [decision.id, decision])
35268
+ );
35269
+ for (const [index, value] of (options.decision ?? []).entries()) {
35270
+ const decision = parseDecision(value, index);
35271
+ decisionsById.set(decision.id, decision);
35272
+ }
35273
+ const documentsByPath = new Map(
35274
+ autoContext.documents.map((document) => [document.path, document])
35275
+ );
35276
+ for (const value of options.document ?? []) {
35277
+ const document = parseDocument(value);
35278
+ documentsByPath.set(document.path, document);
35279
+ }
34949
35280
  const result = buildProjectRealityCheck({
34950
35281
  source: "local",
34951
35282
  task: options.task,
@@ -34955,17 +35286,35 @@ function buildLocalProjectRealityCheck(options) {
34955
35286
  changedFiles: scope.changedFiles,
34956
35287
  dirtyFiles: scope.dirtyFiles,
34957
35288
  diffSummary: scope.diffSummary,
34958
- decisions: (options.decision ?? []).map(parseDecision),
34959
- documents: (options.document ?? []).map(parseDocument),
34960
- verificationChecklist: options.verification ?? []
35289
+ decisions: [...decisionsById.values()],
35290
+ documents: [...documentsByPath.values()],
35291
+ evidence: autoContext.evidence,
35292
+ verificationChecklist: unique5([...autoContext.verification, ...options.verification ?? []])
34961
35293
  });
34962
- if (scope.caveats.length === 0) {
34963
- return result;
35294
+ const caveats = unique5([...result.caveats, ...scope.caveats, ...autoContext.caveats]);
35295
+ return { ...result, caveats };
35296
+ }
35297
+ function buildLocalProjectRealityCheck(options) {
35298
+ const scope = buildLocalGitScope(options);
35299
+ return buildProjectRealityCheckForScope(options, scope);
35300
+ }
35301
+ async function buildLocalProjectRealityCheckWithAutoContext(options, clientOverride) {
35302
+ const scope = buildLocalGitScope(options);
35303
+ let autoContext = collectLocalReceiptContext(scope);
35304
+ const configured = Boolean(clientOverride) || isConfigured({ cwd: scope.root });
35305
+ if (configured) {
35306
+ const timeoutMs = Math.max(1e3, Math.min(options.autoContextTimeoutMs ?? 12e3, 3e4));
35307
+ const client = clientOverride ?? createClient(timeoutMs, { cwd: scope.root });
35308
+ autoContext = mergeAutoContext(
35309
+ autoContext,
35310
+ await collectHostedAutoContext(client, options, scope)
35311
+ );
35312
+ } else {
35313
+ autoContext.caveats.push(
35314
+ "Hosted auto-context was skipped because this workspace is not configured; use --decision, --document, and --verification for explicit evidence."
35315
+ );
34964
35316
  }
34965
- return {
34966
- ...result,
34967
- caveats: [...result.caveats, ...scope.caveats]
34968
- };
35317
+ return buildProjectRealityCheckForScope(options, scope, autoContext);
34969
35318
  }
34970
35319
  function printRealityCheck(result) {
34971
35320
  console.log(import_chalk12.default.bold("Project Reality Check"));
@@ -34977,7 +35326,7 @@ function printRealityCheck(result) {
34977
35326
  console.log(renderProjectRealityCheckMarkdown(result));
34978
35327
  }
34979
35328
  async function realityCheckCommand(options) {
34980
- const result = buildLocalProjectRealityCheck(options);
35329
+ const result = options.autoContext === false ? buildLocalProjectRealityCheck(options) : await buildLocalProjectRealityCheckWithAutoContext(options);
34981
35330
  if (options.json) {
34982
35331
  console.log(JSON.stringify(result, null, 2));
34983
35332
  } else {
@@ -34989,7 +35338,7 @@ async function realityCheckCommand(options) {
34989
35338
  }
34990
35339
 
34991
35340
  // src/commands/context-control.ts
34992
- var fs33 = __toESM(require("fs"));
35341
+ var fs34 = __toESM(require("fs"));
34993
35342
  var path33 = __toESM(require("path"));
34994
35343
  var import_node_child_process15 = require("child_process");
34995
35344
  var import_chalk13 = __toESM(require("chalk"));
@@ -35040,7 +35389,7 @@ function resolveGitDriftScopePaths(cwd) {
35040
35389
  path33.join(".snipara", "decisions")
35041
35390
  ];
35042
35391
  const manifestPath = resolveManifestPath(cwd);
35043
- if (!fs33.existsSync(manifestPath)) {
35392
+ if (!fs34.existsSync(manifestPath)) {
35044
35393
  return normalizeScopePaths(scopePaths, cwd);
35045
35394
  }
35046
35395
  const manifestRead = readJsonFileSafe(manifestPath);
@@ -35090,12 +35439,12 @@ function receiptPathFor(receipt, cwd) {
35090
35439
  return path33.resolve(cwd, CONTEXT_CONTROL_APPLIED_RELATIVE_DIR, `${receipt.receiptId}.json`);
35091
35440
  }
35092
35441
  function writeStableJsonFile(filePath, value) {
35093
- fs33.mkdirSync(path33.dirname(filePath), { recursive: true });
35094
- fs33.writeFileSync(filePath, `${stableDecisionJsonStringify(value)}
35442
+ fs34.mkdirSync(path33.dirname(filePath), { recursive: true });
35443
+ fs34.writeFileSync(filePath, `${stableDecisionJsonStringify(value)}
35095
35444
  `, "utf8");
35096
35445
  }
35097
35446
  function readJsonFile4(filePath) {
35098
- return JSON.parse(fs33.readFileSync(filePath, "utf8"));
35447
+ return JSON.parse(fs34.readFileSync(filePath, "utf8"));
35099
35448
  }
35100
35449
  function buildStateOperation(options) {
35101
35450
  const target = assertContextControlTarget(
@@ -35287,7 +35636,7 @@ function applyLocalContextMutationPlan(options) {
35287
35636
  baseRevisionAtApply: currentRevision
35288
35637
  });
35289
35638
  const receiptPath = receiptPathFor(pendingReceipt, cwd);
35290
- if (fs33.existsSync(receiptPath)) {
35639
+ if (fs34.existsSync(receiptPath)) {
35291
35640
  const receipt2 = buildContextMutationApplyReceipt({
35292
35641
  plan,
35293
35642
  appliedAt: options.now,
@@ -35325,7 +35674,7 @@ function applyLocalContextMutationPlan(options) {
35325
35674
  continue;
35326
35675
  }
35327
35676
  const absoluteTarget = path33.resolve(cwd, target);
35328
- if (operation.mode === "create" && fs33.existsSync(absoluteTarget)) {
35677
+ if (operation.mode === "create" && fs34.existsSync(absoluteTarget)) {
35329
35678
  throw new Error(`Refusing to overwrite existing context-control file: ${target}`);
35330
35679
  }
35331
35680
  writeStableJsonFile(absoluteTarget, operation.content ?? {});
@@ -35359,8 +35708,8 @@ function applyLocalContextMutationPlan(options) {
35359
35708
  };
35360
35709
  }
35361
35710
  function listJsonFiles2(dir) {
35362
- if (!fs33.existsSync(dir)) return [];
35363
- return fs33.readdirSync(dir).filter((name) => name.endsWith(".json")).map((name) => path33.join(dir, name)).sort((left, right) => left.localeCompare(right));
35711
+ if (!fs34.existsSync(dir)) return [];
35712
+ return fs34.readdirSync(dir).filter((name) => name.endsWith(".json")).map((name) => path33.join(dir, name)).sort((left, right) => left.localeCompare(right));
35364
35713
  }
35365
35714
  function readJsonFileSafe(filePath) {
35366
35715
  try {
@@ -35439,7 +35788,7 @@ function collectGitDriftSignals(cwd) {
35439
35788
  }
35440
35789
  function collectWorkflowDriftSignals(cwd) {
35441
35790
  const workflowPath = path33.join(cwd, ".snipara", "workflow", "current.json");
35442
- if (!fs33.existsSync(workflowPath)) {
35791
+ if (!fs34.existsSync(workflowPath)) {
35443
35792
  return [
35444
35793
  {
35445
35794
  id: "workflow-state-missing",
@@ -35582,7 +35931,7 @@ function collectContextControlDriftSignals(cwd) {
35582
35931
  function collectProjectContextManifestDriftSignals(cwd) {
35583
35932
  const manifestPath = resolveManifestPath(cwd);
35584
35933
  const relative11 = toProjectRelativePath4(manifestPath, cwd);
35585
- if (!fs33.existsSync(manifestPath)) {
35934
+ if (!fs34.existsSync(manifestPath)) {
35586
35935
  return [
35587
35936
  {
35588
35937
  id: "project-context-manifest-missing",
@@ -35785,23 +36134,23 @@ function resolveHostedContextSources(cwd, manifestPath, report) {
35785
36134
  if (!report.manifest || report.status === "invalid") {
35786
36135
  throw new Error("ProjectContext manifest is invalid; run context-control validate first.");
35787
36136
  }
35788
- const workspaceRoot2 = fs33.realpathSync(cwd);
36137
+ const workspaceRoot2 = fs34.realpathSync(cwd);
35789
36138
  return report.manifest.sources.map((source2) => {
35790
36139
  const candidate = path33.resolve(cwd, source2.path);
35791
- if (!fs33.existsSync(candidate)) {
36140
+ if (!fs34.existsSync(candidate)) {
35792
36141
  throw new Error(`ProjectContext source is missing: ${source2.path}`);
35793
36142
  }
35794
- if (fs33.lstatSync(candidate).isSymbolicLink()) {
36143
+ if (fs34.lstatSync(candidate).isSymbolicLink()) {
35795
36144
  throw new Error(`ProjectContext source symlinks are not allowed: ${source2.path}`);
35796
36145
  }
35797
- const canonical = fs33.realpathSync(candidate);
36146
+ const canonical = fs34.realpathSync(candidate);
35798
36147
  if (canonical !== workspaceRoot2 && !canonical.startsWith(`${workspaceRoot2}${path33.sep}`)) {
35799
36148
  throw new Error(`ProjectContext source escapes the workspace: ${source2.path}`);
35800
36149
  }
35801
- if (!fs33.statSync(canonical).isFile()) {
36150
+ if (!fs34.statSync(canonical).isFile()) {
35802
36151
  throw new Error(`ProjectContext source must be a file: ${source2.path}`);
35803
36152
  }
35804
- const content = fs33.readFileSync(canonical, "utf8");
36153
+ const content = fs34.readFileSync(canonical, "utf8");
35805
36154
  if (Buffer.byteLength(content, "utf8") > 1e6) {
35806
36155
  throw new Error(`ProjectContext source exceeds 1 MB: ${source2.path}`);
35807
36156
  }
@@ -35936,7 +36285,7 @@ function uniqueStrings22(values) {
35936
36285
 
35937
36286
  // src/commands/references.ts
35938
36287
  var crypto6 = __toESM(require("crypto"));
35939
- var fs34 = __toESM(require("fs"));
36288
+ var fs35 = __toESM(require("fs"));
35940
36289
  var path34 = __toESM(require("path"));
35941
36290
  var import_chalk14 = __toESM(require("chalk"));
35942
36291
  var MANIFEST_VERSION2 = "snipara.references.v1";
@@ -36020,13 +36369,13 @@ function toRelative(root, file) {
36020
36369
  return path34.relative(root, file).split(path34.sep).join("/");
36021
36370
  }
36022
36371
  function ensureParentDir(file) {
36023
- fs34.mkdirSync(path34.dirname(file), { recursive: true });
36372
+ fs35.mkdirSync(path34.dirname(file), { recursive: true });
36024
36373
  }
36025
36374
  function walkFiles(root, extensions, maxFiles, files = []) {
36026
36375
  if (files.length >= maxFiles) {
36027
36376
  return files;
36028
36377
  }
36029
- for (const entry of fs34.readdirSync(root, { withFileTypes: true })) {
36378
+ for (const entry of fs35.readdirSync(root, { withFileTypes: true })) {
36030
36379
  if (files.length >= maxFiles) {
36031
36380
  break;
36032
36381
  }
@@ -36047,7 +36396,7 @@ function collectReferenceItems(root, files, allowDomains, denyDomains) {
36047
36396
  const byUrl = /* @__PURE__ */ new Map();
36048
36397
  const discoveredAt = (/* @__PURE__ */ new Date()).toISOString();
36049
36398
  for (const file of files) {
36050
- const content = fs34.readFileSync(file, "utf-8");
36399
+ const content = fs35.readFileSync(file, "utf-8");
36051
36400
  const lines = content.split(/\r?\n/);
36052
36401
  const markdownLink = /\[([^\]]+)\]\((https?:\/\/[^)\s]+)\)/g;
36053
36402
  const bareUrl = /https?:\/\/[^\s<>"'`]+/g;
@@ -36113,7 +36462,7 @@ function scanReferences(options = {}) {
36113
36462
  items
36114
36463
  };
36115
36464
  ensureParentDir(outputPath);
36116
- fs34.writeFileSync(outputPath, `${JSON.stringify(manifest, null, 2)}
36465
+ fs35.writeFileSync(outputPath, `${JSON.stringify(manifest, null, 2)}
36117
36466
  `, "utf-8");
36118
36467
  return {
36119
36468
  manifest,
@@ -36127,7 +36476,7 @@ function scanReferences(options = {}) {
36127
36476
  };
36128
36477
  }
36129
36478
  function readManifest2(file) {
36130
- const manifest = JSON.parse(fs34.readFileSync(file, "utf-8"));
36479
+ const manifest = JSON.parse(fs35.readFileSync(file, "utf-8"));
36131
36480
  if (manifest.version !== MANIFEST_VERSION2 || !Array.isArray(manifest.items)) {
36132
36481
  throw new Error(`${file} is not a ${MANIFEST_VERSION2} manifest`);
36133
36482
  }
@@ -36212,7 +36561,7 @@ async function fetchReference(item, outputDir, destinationPrefix, timeoutMs, max
36212
36561
  bodyHash: hash
36213
36562
  });
36214
36563
  ensureParentDir(snapshotPath);
36215
- fs34.writeFileSync(snapshotPath, markdown, "utf-8");
36564
+ fs35.writeFileSync(snapshotPath, markdown, "utf-8");
36216
36565
  return {
36217
36566
  item,
36218
36567
  fetchedAt,
@@ -36322,7 +36671,7 @@ async function ingestReferences(options = {}) {
36322
36671
  });
36323
36672
  }
36324
36673
  }
36325
- fs34.writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}
36674
+ fs35.writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}
36326
36675
  `, "utf-8");
36327
36676
  if (options.reindex && client) {
36328
36677
  await client.reindex({ kind: "doc", mode: "incremental" });
@@ -36376,7 +36725,7 @@ async function referencesIngestCommand(options) {
36376
36725
  // src/commands/run.ts
36377
36726
  var import_node_child_process16 = require("child_process");
36378
36727
  var import_node_crypto12 = require("crypto");
36379
- var fs35 = __toESM(require("fs"));
36728
+ var fs36 = __toESM(require("fs"));
36380
36729
  var path35 = __toESM(require("path"));
36381
36730
  var import_chalk15 = __toESM(require("chalk"));
36382
36731
 
@@ -36385,21 +36734,21 @@ var REGISTRY_VERSION = "project-intelligence.policy-gates.registry.v1";
36385
36734
  function normalizeChangedFiles(changedFiles) {
36386
36735
  return [...new Set((changedFiles ?? []).map((file) => file.trim()).filter(Boolean))];
36387
36736
  }
36388
- function isRecord19(value) {
36737
+ function isRecord20(value) {
36389
36738
  return typeof value === "object" && value !== null && !Array.isArray(value);
36390
36739
  }
36391
- function stringValue14(value) {
36740
+ function stringValue15(value) {
36392
36741
  return typeof value === "string" && value.trim() ? value.trim() : void 0;
36393
36742
  }
36394
36743
  function nestedRecord3(root, keys) {
36395
36744
  let current = root;
36396
36745
  for (const key of keys) {
36397
- if (!isRecord19(current) || !isRecord19(current[key])) {
36746
+ if (!isRecord20(current) || !isRecord20(current[key])) {
36398
36747
  return {};
36399
36748
  }
36400
36749
  current = current[key];
36401
36750
  }
36402
- return isRecord19(current) ? current : {};
36751
+ return isRecord20(current) ? current : {};
36403
36752
  }
36404
36753
  function combinedText(input) {
36405
36754
  return [input.task, input.diffSummary, ...input.changedFiles ?? []].filter(Boolean).join("\n").toLowerCase();
@@ -36569,7 +36918,7 @@ function evaluateProjectPolicyGates(input) {
36569
36918
  );
36570
36919
  }
36571
36920
  const guardEval = guardEvaluation2(input.guard?.payload);
36572
- const guardDecision = stringValue14(guardEval.decision)?.toUpperCase();
36921
+ const guardDecision = stringValue15(guardEval.decision)?.toUpperCase();
36573
36922
  if (guardDecision === "BLOCKED" || input.release && input.guard?.status !== void 0 && input.guard.status !== 0) {
36574
36923
  gates.push(
36575
36924
  gate({
@@ -36807,8 +37156,8 @@ var GUARD_MAX_BUFFER_BYTES = 16 * 1024 * 1024;
36807
37156
  var RAW_OUTPUT_PREVIEW_BYTES = 64e3;
36808
37157
  var ADVISOR_RECEIPT_WRITE_LIMIT = 6;
36809
37158
  function buildProjectIntelligenceRunEnvelope(startedAt = /* @__PURE__ */ new Date()) {
36810
- const sniparaSessionId = stringValue15(process.env.SNIPARA_SESSION_ID)?.slice(0, 200);
36811
- const codexSessionId = stringValue15(process.env.CODEX_SESSION_ID)?.slice(0, 200);
37159
+ const sniparaSessionId = stringValue16(process.env.SNIPARA_SESSION_ID)?.slice(0, 200);
37160
+ const codexSessionId = stringValue16(process.env.CODEX_SESSION_ID)?.slice(0, 200);
36812
37161
  return {
36813
37162
  version: "project-intelligence.judgment-run-envelope.v1",
36814
37163
  runId: sniparaSessionId ?? codexSessionId ?? `judgment-run:${(0, import_node_crypto12.randomUUID)()}`,
@@ -36822,7 +37171,7 @@ function normalizeStringList6(values) {
36822
37171
  function uniqueStrings23(values) {
36823
37172
  return [...new Set(values.map((value) => value.trim()).filter(Boolean))];
36824
37173
  }
36825
- function isRecord20(value) {
37174
+ function isRecord21(value) {
36826
37175
  return typeof value === "object" && value !== null && !Array.isArray(value);
36827
37176
  }
36828
37177
  function guardPayload(guard) {
@@ -36835,7 +37184,7 @@ function readOutcomeReceipts(files) {
36835
37184
  const receipts = [];
36836
37185
  for (const file of normalizeStringList6(files)) {
36837
37186
  const resolved = path35.resolve(process.cwd(), file);
36838
- const parsed = JSON.parse(fs35.readFileSync(resolved, "utf8"));
37187
+ const parsed = JSON.parse(fs36.readFileSync(resolved, "utf8"));
36839
37188
  receipts.push(...outcomeReceiptsFromUnknown(parsed));
36840
37189
  }
36841
37190
  return receipts;
@@ -36844,13 +37193,13 @@ function outcomeReceiptsFromUnknown(value) {
36844
37193
  if (Array.isArray(value)) {
36845
37194
  return value.flatMap(outcomeReceiptsFromUnknown);
36846
37195
  }
36847
- if (!isRecord20(value)) {
37196
+ if (!isRecord21(value)) {
36848
37197
  return [];
36849
37198
  }
36850
37199
  if (value.version === "snipara.outcome_intelligence.receipt.v0") {
36851
37200
  return [value];
36852
37201
  }
36853
- if (isRecord20(value.outcomeReceipt)) {
37202
+ if (isRecord21(value.outcomeReceipt)) {
36854
37203
  return outcomeReceiptsFromUnknown(value.outcomeReceipt);
36855
37204
  }
36856
37205
  if (Array.isArray(value.outcomeReceipts)) {
@@ -36868,11 +37217,11 @@ function outputPreview(value) {
36868
37217
  return `${value.slice(0, RAW_OUTPUT_PREVIEW_BYTES)}
36869
37218
  ...[truncated]`;
36870
37219
  }
36871
- function stringValue15(value) {
37220
+ function stringValue16(value) {
36872
37221
  return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
36873
37222
  }
36874
37223
  function servedJudgmentIdForRun(options, brief) {
36875
- return stringValue15(options.servedJudgmentId) ?? stringValue15(brief.servedJudgmentId) ?? servedJudgmentIdFromContext(brief.resumeContext) ?? servedJudgmentIdFromContext(brief.verificationPlan);
37224
+ return stringValue16(options.servedJudgmentId) ?? stringValue16(brief.servedJudgmentId) ?? servedJudgmentIdFromContext(brief.resumeContext) ?? servedJudgmentIdFromContext(brief.verificationPlan);
36876
37225
  }
36877
37226
  function advisorMeasurementState(args) {
36878
37227
  if (args.agentDecision === "blocked") return "blocked";
@@ -36949,7 +37298,7 @@ function boundedLifecycleText(value, maxChars) {
36949
37298
  return value.trim().replace(/\s+/g, " ").slice(0, maxChars);
36950
37299
  }
36951
37300
  function advisorRecommendationPlanScope(args) {
36952
- const requestedRecommendationId = stringValue15(args.options.advisorRecommendationId) ?? null;
37301
+ const requestedRecommendationId = stringValue16(args.options.advisorRecommendationId) ?? null;
36953
37302
  if (requestedRecommendationId) {
36954
37303
  const targeted = requestedRecommendationId === args.recommendationId;
36955
37304
  return {
@@ -37257,7 +37606,7 @@ async function recordFirstPartyAdvisorReceipts(args) {
37257
37606
  };
37258
37607
  }
37259
37608
  const client = createClient(1e4);
37260
- const verificationEvidence = args.verificationEvidence ?? [];
37609
+ const verificationEvidence2 = args.verificationEvidence ?? [];
37261
37610
  const outcomeReceipts = args.outcomeReceipts ?? [];
37262
37611
  const selectedRecommendations = allRecommendations.slice(0, ADVISOR_RECEIPT_WRITE_LIMIT);
37263
37612
  const overflowWrites = allRecommendations.slice(ADVISOR_RECEIPT_WRITE_LIMIT).map((recommendation) => skippedAdvisorReceiptWrite(recommendation, "write_limit_exceeded"));
@@ -37315,7 +37664,7 @@ async function recordFirstPartyAdvisorReceipts(args) {
37315
37664
  recommendation,
37316
37665
  recommendationIndex,
37317
37666
  totalRecommendations: allRecommendations.length,
37318
- verificationEvidence,
37667
+ verificationEvidence: verificationEvidence2,
37319
37668
  lifecycle,
37320
37669
  planScope,
37321
37670
  measurementState,
@@ -37401,7 +37750,7 @@ function runGuard(options, changedFiles) {
37401
37750
  let payload;
37402
37751
  try {
37403
37752
  const parsed = JSON.parse(result.stdout);
37404
- if (isRecord20(parsed)) {
37753
+ if (isRecord21(parsed)) {
37405
37754
  payload = parsed;
37406
37755
  }
37407
37756
  } catch {
@@ -37522,7 +37871,7 @@ async function buildProjectIntelligenceRun(options) {
37522
37871
  decision: brief.projectPolicyDecision
37523
37872
  } : void 0
37524
37873
  });
37525
- const verificationEvidence = verificationEvidenceFromRun({
37874
+ const verificationEvidence2 = verificationEvidenceFromRun({
37526
37875
  guard,
37527
37876
  packageReview,
37528
37877
  policyGates
@@ -37531,7 +37880,7 @@ async function buildProjectIntelligenceRun(options) {
37531
37880
  options,
37532
37881
  brief,
37533
37882
  judgmentCard,
37534
- verificationEvidence,
37883
+ verificationEvidence: verificationEvidence2,
37535
37884
  outcomeReceipts,
37536
37885
  runEnvelope
37537
37886
  });
@@ -37594,10 +37943,10 @@ async function projectIntelligenceRunCommand(options) {
37594
37943
  if (result.guard) {
37595
37944
  console.log(import_chalk15.default.bold("Guard"));
37596
37945
  console.log(`Status: ${result.guard.status}`);
37597
- const actionCards = isRecord20(result.guard.payload) ? result.guard.payload.actionCards : [];
37946
+ const actionCards = isRecord21(result.guard.payload) ? result.guard.payload.actionCards : [];
37598
37947
  if (Array.isArray(actionCards) && actionCards.length > 0) {
37599
37948
  for (const card of actionCards.slice(0, 6)) {
37600
- if (!isRecord20(card)) continue;
37949
+ if (!isRecord21(card)) continue;
37601
37950
  console.log(`- ${card.kind}: ${card.title ?? card.reason ?? "guard action"}`);
37602
37951
  }
37603
37952
  }
@@ -37662,7 +38011,7 @@ async function projectIntelligenceRunCommand(options) {
37662
38011
  }
37663
38012
 
37664
38013
  // src/commands/policy-ledger-sync.ts
37665
- var fs36 = __toESM(require("fs"));
38014
+ var fs37 = __toESM(require("fs"));
37666
38015
  var path36 = __toESM(require("path"));
37667
38016
  var POLICY_LEDGER_SYNC_REPORT_VERSION = "snipara.workflow_policy_ledger_sync.v0";
37668
38017
  function buildPolicyLedgerSyncReport(options = {}) {
@@ -37810,12 +38159,12 @@ function statusForChoiceClass(choiceClass) {
37810
38159
  return "modified";
37811
38160
  }
37812
38161
  function readJsonFiles(directory, cwd) {
37813
- if (!fs36.existsSync(directory)) {
38162
+ if (!fs37.existsSync(directory)) {
37814
38163
  return [];
37815
38164
  }
37816
- return fs36.readdirSync(directory).filter((fileName) => fileName.endsWith(".json")).sort().map((fileName) => {
38165
+ return fs37.readdirSync(directory).filter((fileName) => fileName.endsWith(".json")).sort().map((fileName) => {
37817
38166
  const filePath = path36.join(directory, fileName);
37818
- const parsed = JSON.parse(fs36.readFileSync(filePath, "utf8"));
38167
+ const parsed = JSON.parse(fs37.readFileSync(filePath, "utf8"));
37819
38168
  return { parsed, relativePath: toProjectRelativePath5(filePath, cwd) };
37820
38169
  });
37821
38170
  }
@@ -38020,7 +38369,11 @@ function collectOption(value, previous = []) {
38020
38369
  return [...previous, value];
38021
38370
  }
38022
38371
  function configureRealityCheckCommand(command) {
38023
- return command.description("Run a Project Reality Check against local or supplied change scope").option("--task <task>", "Task or change summary").option("--branch <branch>", "Branch to scope the check").option("--base <ref>", "Base ref for committed local changes (default: upstream)").option("--changed-files <files...>", "Changed files to analyze").option("--diff-summary <summary>", "Natural-language diff summary").option("--decision <decision...>", "Decision or intent in ID: text form").option("--document <document...>", "Document/context hint in path: preview form").option("--verification <item...>", "Verification evidence or checklist item").option("--no-include-dirty", "Exclude dirty working-tree files from local scope").option("--enforce", "Exit non-zero for review-required or blocking findings").option("-d, --dir <directory>", "Project directory (default: current)").option("--json", "Print raw JSON").action(async (options) => {
38372
+ return command.description("Run a Project Reality Check against local or supplied change scope").option("--task <task>", "Task or change summary").option("--branch <branch>", "Branch to scope the check").option("--base <ref>", "Base ref for committed local changes (default: upstream)").option("--changed-files <files...>", "Changed files to analyze").option("--diff-summary <summary>", "Natural-language diff summary").option("--decision <decision...>", "Decision or intent in ID: text form").option("--document <document...>", "Document/context hint in path: preview form").option("--verification <item...>", "Verification evidence or checklist item").option("--no-auto-context", "Disable bounded hosted/local context auto-linking").option(
38373
+ "--auto-context-timeout-ms <number>",
38374
+ "Timeout for each hosted auto-context source",
38375
+ "12000"
38376
+ ).option("--no-include-dirty", "Exclude dirty working-tree files from local scope").option("--enforce", "Exit non-zero for review-required or blocking findings").option("-d, --dir <directory>", "Project directory (default: current)").option("--json", "Print raw JSON").action(async (options) => {
38024
38377
  await realityCheckCommand({
38025
38378
  task: options.task,
38026
38379
  branch: options.branch,
@@ -38030,6 +38383,8 @@ function configureRealityCheckCommand(command) {
38030
38383
  decision: options.decision,
38031
38384
  document: options.document,
38032
38385
  verification: options.verification,
38386
+ autoContext: options.autoContext !== false,
38387
+ autoContextTimeoutMs: Number.parseInt(options.autoContextTimeoutMs, 10),
38033
38388
  includeDirty: options.includeDirty,
38034
38389
  enforce: Boolean(options.enforce),
38035
38390
  dir: options.dir,
@@ -38509,13 +38864,18 @@ program.command("memory-guard").description(
38509
38864
  );
38510
38865
  program.command("query").description(
38511
38866
  "Search project documents, parsed files, and current truth through hosted Snipara context"
38512
- ).requiredOption("-q, --query <query>", "Search query").option("-m, --max-tokens <number>", "Maximum tokens", "8000").option(
38867
+ ).requiredOption("-q, --query <query>", "Search query").option("-m, --max-tokens <number>", "Maximum tokens", "8000").option("--search-mode <mode>", "Search mode: keyword|semantic|hybrid", "hybrid").option("--timeout-ms <number>", "Hosted context query timeout in milliseconds", "30000").option("--no-answer-pack", "Skip Answer Pack generation").option("--no-auto-decompose", "Disable automatic query decomposition").option("--no-shared-context", "Exclude linked shared context").option(
38513
38868
  "--follow-recommendation",
38514
38869
  "Automatically execute the recommended structural tool when Snipara returns one"
38515
38870
  ).option("--json", "Print raw JSON").action(async (options) => {
38516
38871
  await queryCommand({
38517
38872
  query: options.query,
38518
38873
  maxTokens: parseInt(options.maxTokens, 10),
38874
+ searchMode: options.searchMode,
38875
+ timeoutMs: parseInt(options.timeoutMs, 10),
38876
+ includeAnswerPack: options.answerPack !== false,
38877
+ autoDecompose: options.autoDecompose !== false,
38878
+ includeSharedContext: options.sharedContext !== false,
38519
38879
  followRecommendation: Boolean(options.followRecommendation),
38520
38880
  json: options.json
38521
38881
  });
@@ -40233,6 +40593,8 @@ if (require.main === module) {
40233
40593
  ENGINEERING_LEAD_WORK_PACKAGE_STATUSES,
40234
40594
  FINAL_COMMIT_REPORT_RELATIVE_PATH,
40235
40595
  FINAL_COMMIT_REPORT_VERSION,
40596
+ MEMORY_GUARD_CONTEXT_TIMEOUT_MS,
40597
+ MEMORY_GUARD_RECALL_TIMEOUT_MS,
40236
40598
  ORCHESTRATOR_HANDOFF_RELATIVE_PATH,
40237
40599
  POLICY_LEDGER_SYNC_REPORT_VERSION,
40238
40600
  PRODUCER_LOOP_ARTIFACT_VERSION,
@@ -40284,6 +40646,7 @@ if (require.main === module) {
40284
40646
  buildLocalProjectContextValidationReport,
40285
40647
  buildLocalProjectDriftReport,
40286
40648
  buildLocalProjectRealityCheck,
40649
+ buildLocalProjectRealityCheckWithAutoContext,
40287
40650
  buildLocalShortestPathResult,
40288
40651
  buildLocalSourceSnapshot,
40289
40652
  buildLocalSourceStatus,
@@ -1050,6 +1050,7 @@ npx -y snipara-companion@latest plan --query "plan the auth refactor" --write-pl
1050
1050
  npx -y snipara-companion@latest task-commit --summary "Shipped auth refactor" --files apps/web/src/lib/auth.ts
1051
1051
 
1052
1052
  snipara-companion query --query "auth middleware"
1053
+ snipara-companion query --query "auth middleware" --search-mode keyword --no-answer-pack --timeout-ms 30000
1053
1054
  snipara-companion query --query "who calls src.mcp_transport.handle_call_tool" --follow-recommendation
1054
1055
  snipara-companion status
1055
1056
  snipara-companion brief --task "ship auth hardening" --changed-files apps/web/src/lib/auth.ts tests/auth.test.ts --diff-summary "auth hardening"
@@ -1272,7 +1273,13 @@ snipara-companion reality-check \
1272
1273
 
1273
1274
  The command reads the local Git scope by default, includes dirty files unless
1274
1275
  `--no-include-dirty` is set, and also accepts explicit `--changed-files` for
1275
- hooks or CI collectors. `--enforce` exits non-zero for `review_required` or
1276
+ hooks or CI collectors. When the workspace is configured, bounded auto-context
1277
+ loads reviewed Team Sync decisions, a narrow keyword document query, and local
1278
+ workflow receipts in parallel. Explicit `--decision`, `--document`, and
1279
+ `--verification` values take precedence. Use `--no-auto-context` for a purely
1280
+ local/explicit run or `--auto-context-timeout-ms` to tighten the hosted budget.
1281
+ Verification and workflow sources are retained in each finding's `evidence`
1282
+ array and in the top-level evidence summary. `--enforce` exits non-zero for `review_required` or
1276
1283
  `blocking` findings, but should stay opt-in until the matched surfaces,
1277
1284
  verification signals, and project-specific thresholds have been calibrated.
1278
1285
  Intent can be supplied as structured sections inside `--decision` or
@@ -1461,7 +1468,7 @@ snipara-companion workflow scaffold \
1461
1468
 
1462
1469
  Semantics:
1463
1470
 
1464
- - `snipara-companion query --follow-recommendation` = execute the hosted recommended structural tool instead of only printing it
1471
+ - `snipara-companion query --follow-recommendation` = execute the hosted recommended structural tool instead of only printing it; context retrieval defaults to a 30-second timeout and supports `--search-mode keyword|semantic|hybrid`, `--no-answer-pack`, `--no-auto-decompose`, and `--no-shared-context`
1465
1472
  - `snipara-companion workflow run --mode lite` = zero mandatory hosted calls for small known-file work
1466
1473
  - `snipara-companion workflow run --mode standard` = context query plus automatic `snipara_code_*` follow-up when Snipara recommends one
1467
1474
  - `snipara-companion workflow run --mode auto` = routes to lite, standard, full, or orchestrate from task intent
@@ -1473,7 +1480,7 @@ Semantics:
1473
1480
  - `snipara-companion status` = top-level agentic work status across local workflow state, git dirtiness, and Team Sync carryover
1474
1481
  - `snipara-companion source init|sync|status|snapshot|watch` = automatic local source activation for folders with or without Git metadata; writes `.snipara/source/latest.json`, previews document sync, and refreshes the local code overlay cache
1475
1482
  - `snipara-companion brief` = short alias for `snipara-companion intelligence brief`
1476
- - `snipara-companion reality-check` = local Project Reality Check plus Intent Ledger and Unknown Registry coverage for supplied or Git-derived changed files; `--enforce` is an opt-in strict mode for calibrated hooks
1483
+ - `snipara-companion reality-check` = Project Reality Check plus Intent Ledger, Unknown Registry, bounded auto-context, and inspectable evidence for supplied or Git-derived changed files; `--no-auto-context` keeps it local/explicit and `--enforce` is an opt-in strict mode for calibrated hooks
1477
1484
  - `snipara-companion timeline` = local timeline of workflow starts, phase starts, phase commits, final commits, and Team Sync handoffs
1478
1485
  - `snipara-companion workflow timeline` = append-only activity timeline from `.snipara/activity/timeline.jsonl`, including workflow, Producer Loop, Decision Request, and Team Sync events emitted by Companion commands; add `--export md` for a redacted Markdown artifact
1479
1486
  - `snipara-companion workflow session` = writes and prints Session Snapshot V0 at `.snipara/activity/session.json` with latest activity, risk, touched files, next action, advisory Intent Detection V0 intent/confidence/signals/suggested mode, workflow/session counts, Producer Loop calibration, decision counts, Team Sync counts, and `hardRoutingAllowed=false`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "snipara-companion",
3
- "version": "3.5.3",
3
+ "version": "3.5.5",
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": {