snipara-companion 3.5.3 → 3.5.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,17 @@
2
2
 
3
3
  Release notes for `snipara-companion`, newest first.
4
4
 
5
+ ## New In 3.5.4
6
+
7
+ - Makes `reality-check` auto-link bounded reviewed Team Sync decisions, keyword
8
+ document context, managed workflow receipts, and current verification
9
+ evidence while preserving explicit CLI inputs and failing open when hosted
10
+ context is unavailable.
11
+ - Keeps the evidence used by Reality Check inspectable in JSON and Markdown
12
+ findings instead of using verification only as a hidden severity signal.
13
+ - Gives `query` a 30-second default timeout plus explicit search-mode,
14
+ Answer Pack, decomposition, and shared-context controls for fast recovery.
15
+
5
16
  ## New In 3.5.3
6
17
 
7
18
  - 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[];
@@ -2183,12 +2196,24 @@ interface RealityCheckCommandOptions {
2183
2196
  decision?: string[];
2184
2197
  document?: string[];
2185
2198
  verification?: string[];
2199
+ autoContext?: boolean;
2200
+ autoContextTimeoutMs?: number;
2186
2201
  includeDirty?: boolean;
2187
2202
  enforce?: boolean;
2188
2203
  dir?: string;
2189
2204
  json?: boolean;
2190
2205
  }
2206
+ interface RealityCheckAutoContextClient {
2207
+ queryContext(query: string, maxTokens?: number, options?: ContextQueryOptions): Promise<ContextQueryResult>;
2208
+ getTeamSyncWhatChanged(args: {
2209
+ limit?: number;
2210
+ branch?: string;
2211
+ paths?: string[];
2212
+ recentFiles?: string[];
2213
+ }): Promise<TeamSyncChangesResponse>;
2214
+ }
2191
2215
  declare function buildLocalProjectRealityCheck(options: RealityCheckCommandOptions): ProjectRealityCheckResult;
2216
+ declare function buildLocalProjectRealityCheckWithAutoContext(options: RealityCheckCommandOptions, clientOverride?: RealityCheckAutoContextClient): Promise<ProjectRealityCheckResult>;
2192
2217
  declare function realityCheckCommand(options: RealityCheckCommandOptions): Promise<void>;
2193
2218
 
2194
2219
  interface DecisionRequestWriteResult {
@@ -4906,4 +4931,4 @@ declare function installAutomationBundle(args: {
4906
4931
  }): Promise<AutomationInstallResult>;
4907
4932
  declare function getAutomationStatus(projectDir?: string): AutomationStatusResult;
4908
4933
 
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 };
4934
+ 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, 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
@@ -99,6 +99,7 @@ __export(index_exports, {
99
99
  buildLocalProjectContextValidationReport: () => buildLocalProjectContextValidationReport,
100
100
  buildLocalProjectDriftReport: () => buildLocalProjectDriftReport,
101
101
  buildLocalProjectRealityCheck: () => buildLocalProjectRealityCheck,
102
+ buildLocalProjectRealityCheckWithAutoContext: () => buildLocalProjectRealityCheckWithAutoContext,
102
103
  buildLocalShortestPathResult: () => buildLocalShortestPathResult,
103
104
  buildLocalSourceSnapshot: () => buildLocalSourceSnapshot,
104
105
  buildLocalSourceStatus: () => buildLocalSourceStatus,
@@ -805,13 +806,17 @@ var RLMClient = class {
805
806
  /**
806
807
  * Query for optimized context using snipara_context_query
807
808
  */
808
- async queryContext(query, maxTokens = 8e3) {
809
+ async queryContext(query, maxTokens = 8e3, options = {}) {
809
810
  const result = await this.mcpCall("snipara_context_query", {
810
811
  query,
811
812
  max_tokens: maxTokens,
812
- search_mode: "hybrid",
813
- include_metadata: true,
814
- include_answer_pack: true
813
+ search_mode: options.searchMode ?? "hybrid",
814
+ include_metadata: options.includeMetadata ?? true,
815
+ include_answer_pack: options.includeAnswerPack ?? true,
816
+ auto_decompose: options.autoDecompose,
817
+ include_shared_context: options.includeSharedContext,
818
+ include_all_tiers: options.includeAllTiers,
819
+ return_references: options.returnReferences
815
820
  });
816
821
  return {
817
822
  sections: (result.sections || []).map((s) => ({
@@ -840,7 +845,10 @@ var RLMClient = class {
840
845
  recommended_tool_arguments: result.recommended_tool_arguments || {},
841
846
  graph_hybrid_used: result.graph_hybrid_used,
842
847
  graph_context_tool: result.graph_context_tool,
843
- graph_context_summary: result.graph_context_summary
848
+ graph_context_summary: result.graph_context_summary,
849
+ search_mode: result.search_mode,
850
+ timing: result.timing,
851
+ retrieval_diagnostics: result.retrieval_diagnostics
844
852
  };
845
853
  }
846
854
  async sharedContext(options = {}) {
@@ -9541,6 +9549,9 @@ function buildDocumentIntentEntry(doc, policy) {
9541
9549
  doc.intent?.freshnessHorizonDays ?? doc.freshnessHorizonDays ?? sectionIntent.freshnessHorizonDays,
9542
9550
  policy
9543
9551
  );
9552
+ const affectedAnchors = uniqueStrings3(
9553
+ doc.affectedAnchors && doc.affectedAnchors.length > 0 ? doc.affectedAnchors : [doc.path]
9554
+ );
9544
9555
  return {
9545
9556
  id: `intent:doc:${doc.path}`,
9546
9557
  title: doc.title || doc.path,
@@ -9568,7 +9579,7 @@ function buildDocumentIntentEntry(doc, policy) {
9568
9579
  structuredSections: sectionIntent,
9569
9580
  fallbackUsed: goal === doc.path || goal === doc.title
9570
9581
  }),
9571
- affectedAnchors: [doc.path],
9582
+ affectedAnchors,
9572
9583
  owner: doc.intent?.owner ?? sectionIntent.owner ?? doc.owner ?? null,
9573
9584
  evidence: [
9574
9585
  {
@@ -10196,6 +10207,23 @@ function decisionEvidence(decisions) {
10196
10207
  strength: decision.confidenceScore ?? 0.8
10197
10208
  }));
10198
10209
  }
10210
+ function verificationEvidence(input) {
10211
+ return (input.verificationChecklist ?? []).slice(0, 8).map((item, index) => ({
10212
+ kind: /test|spec|vitest|pytest|e2e|smoke|lint|type.?check|build|health|ready|migration|schema|pack/i.test(
10213
+ item
10214
+ ) ? "test" : "manual",
10215
+ label: item,
10216
+ sourceRef: `verification:${index + 1}`,
10217
+ strength: 0.75
10218
+ }));
10219
+ }
10220
+ function uniqueEvidence(evidence) {
10221
+ return [
10222
+ ...new Map(
10223
+ evidence.map((item) => [`${item.kind}:${item.sourceRef ?? item.label}`, item])
10224
+ ).values()
10225
+ ];
10226
+ }
10199
10227
  function buildProjectRealityCheck(input) {
10200
10228
  const changedFiles = uniqueStrings3(input.changedFiles);
10201
10229
  const dirtyFiles = uniqueStrings3(input.dirtyFiles ?? []);
@@ -10203,7 +10231,17 @@ function buildProjectRealityCheck(input) {
10203
10231
  const tests = testFiles(changedFiles);
10204
10232
  const findings = [];
10205
10233
  const decisions = input.decisions ?? [];
10206
- const contextEvidence2 = [...docEvidence(input), ...symbolEvidence(input)];
10234
+ const verificationRefs = verificationEvidence(input);
10235
+ const contextEvidence2 = uniqueEvidence([
10236
+ ...docEvidence(input),
10237
+ ...symbolEvidence(input),
10238
+ ...input.evidence ?? []
10239
+ ]);
10240
+ const allEvidence = uniqueEvidence([
10241
+ ...decisionEvidence(decisions),
10242
+ ...verificationRefs,
10243
+ ...contextEvidence2
10244
+ ]).slice(0, 20);
10207
10245
  const intentLedger = buildProjectIntentLedger(input, changedFiles);
10208
10246
  for (const surface of SENSITIVE_SURFACES) {
10209
10247
  const files = surfaceFiles(surface, changedFiles);
@@ -10232,7 +10270,11 @@ function buildProjectRealityCheck(input) {
10232
10270
  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
10271
  changedFiles: files.slice(0, 12),
10234
10272
  decisionIds: relatedDecisions.map((decision) => decision.id).slice(0, 8),
10235
- evidence: [...decisionEvidence(relatedDecisions), ...contextEvidence2].slice(0, 8),
10273
+ evidence: uniqueEvidence([
10274
+ ...decisionEvidence(relatedDecisions),
10275
+ ...verificationRefs,
10276
+ ...contextEvidence2
10277
+ ]).slice(0, 8),
10236
10278
  reasonCodes: reasonCodes2,
10237
10279
  recommendedActions,
10238
10280
  caveats: [
@@ -10254,7 +10296,7 @@ function buildProjectRealityCheck(input) {
10254
10296
  summary: "This change spans architectural boundaries. Verify that the dependency direction and runtime ownership still match the intended architecture.",
10255
10297
  changedFiles: files.slice(0, 12),
10256
10298
  decisionIds: [],
10257
- evidence: contextEvidence2.slice(0, 6),
10299
+ evidence: uniqueEvidence([...verificationRefs, ...contextEvidence2]).slice(0, 8),
10258
10300
  reasonCodes: [rule.key, "cross_boundary_change"],
10259
10301
  recommendedActions: [
10260
10302
  "Check that the changed modules do not introduce a forbidden runtime dependency.",
@@ -10353,6 +10395,7 @@ function buildProjectRealityCheck(input) {
10353
10395
  findings,
10354
10396
  intentLedger,
10355
10397
  unknownRegistry,
10398
+ evidence: allEvidence,
10356
10399
  requiredActions,
10357
10400
  watchItems,
10358
10401
  reasonCodes: uniqueStrings3([
@@ -10421,11 +10464,24 @@ function renderProjectRealityCheckMarkdown(result) {
10421
10464
  if (finding.decisionIds.length > 0) {
10422
10465
  lines.push(` Decisions: ${finding.decisionIds.join(", ")}`);
10423
10466
  }
10467
+ if (finding.evidence.length > 0) {
10468
+ lines.push(
10469
+ ` Evidence: ${finding.evidence.slice(0, 4).map((item) => `${item.kind}:${item.label}`).join("; ")}`
10470
+ );
10471
+ }
10424
10472
  if (finding.recommendedActions.length > 0) {
10425
10473
  lines.push(` Action: ${finding.recommendedActions[0]}`);
10426
10474
  }
10427
10475
  }
10428
10476
  }
10477
+ if (result.evidence.length > 0) {
10478
+ lines.push("", "Evidence:");
10479
+ lines.push(
10480
+ ...result.evidence.slice(0, 10).map(
10481
+ (item) => `- ${item.kind}: ${item.label}${item.sourceRef ? ` (${item.sourceRef})` : ""}`
10482
+ )
10483
+ );
10484
+ }
10429
10485
  if (result.requiredActions.length > 0) {
10430
10486
  lines.push("", "Required actions:");
10431
10487
  lines.push(...result.requiredActions.map((action) => `- ${action}`));
@@ -26118,8 +26174,18 @@ function printRecallResult(result) {
26118
26174
  }
26119
26175
  async function queryCommand(options) {
26120
26176
  ensureConfigured();
26121
- const client = createClient(15e3);
26122
- const result = await client.queryContext(options.query, options.maxTokens || 8e3);
26177
+ const searchMode = options.searchMode ?? "hybrid";
26178
+ if (!["keyword", "semantic", "hybrid"].includes(searchMode)) {
26179
+ throw new Error("--search-mode must be keyword, semantic, or hybrid");
26180
+ }
26181
+ const timeoutMs = Math.max(1e3, Math.min(options.timeoutMs ?? 3e4, 12e4));
26182
+ const client = createClient(timeoutMs);
26183
+ const result = await client.queryContext(options.query, options.maxTokens || 8e3, {
26184
+ searchMode,
26185
+ includeAnswerPack: options.includeAnswerPack,
26186
+ autoDecompose: options.autoDecompose,
26187
+ includeSharedContext: options.includeSharedContext
26188
+ });
26123
26189
  const recommendedExecution = options.followRecommendation && result.recommended_tool ? await runRecommendedTool(result) : null;
26124
26190
  if (options.json) {
26125
26191
  printJson2(
@@ -34850,6 +34916,7 @@ async function projectIntelligenceBriefCommand(options) {
34850
34916
 
34851
34917
  // src/commands/reality-check.ts
34852
34918
  var import_node_child_process14 = require("child_process");
34919
+ var import_node_fs2 = __toESM(require("fs"));
34853
34920
  var import_node_path2 = __toESM(require("path"));
34854
34921
  var import_chalk12 = __toESM(require("chalk"));
34855
34922
  function runGit2(args, cwd, options = {}) {
@@ -34944,8 +35011,263 @@ function parseDocument(value) {
34944
35011
  contentPreview: rest.join(":").trim() || null
34945
35012
  };
34946
35013
  }
34947
- function buildLocalProjectRealityCheck(options) {
34948
- const scope = buildLocalGitScope(options);
35014
+ function emptyAutoContext() {
35015
+ return {
35016
+ decisions: [],
35017
+ documents: [],
35018
+ evidence: [],
35019
+ verification: [],
35020
+ caveats: []
35021
+ };
35022
+ }
35023
+ function isRecord19(value) {
35024
+ return typeof value === "object" && value !== null && !Array.isArray(value);
35025
+ }
35026
+ function stringValue14(value) {
35027
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
35028
+ }
35029
+ function stringList3(value) {
35030
+ return Array.isArray(value) ? unique5(value.map((item) => typeof item === "string" ? item : void 0)) : [];
35031
+ }
35032
+ function readJsonRecord3(filePath) {
35033
+ try {
35034
+ const parsed = JSON.parse(import_node_fs2.default.readFileSync(filePath, "utf8"));
35035
+ return isRecord19(parsed) ? parsed : void 0;
35036
+ } catch {
35037
+ return void 0;
35038
+ }
35039
+ }
35040
+ var GENERIC_SCOPE_TOKENS = /* @__PURE__ */ new Set([
35041
+ "apps",
35042
+ "packages",
35043
+ "src",
35044
+ "test",
35045
+ "tests",
35046
+ "index",
35047
+ "server",
35048
+ "project",
35049
+ "snipara",
35050
+ "file",
35051
+ "files",
35052
+ "change",
35053
+ "changed"
35054
+ ]);
35055
+ function scopeTokens(value) {
35056
+ const tokens = new Set(
35057
+ (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))
35058
+ );
35059
+ if (/packages\/cli\//i.test(value)) {
35060
+ tokens.add("cli");
35061
+ tokens.add("companion");
35062
+ }
35063
+ if (/project-intelligence-contracts/i.test(value)) {
35064
+ tokens.add("intelligence");
35065
+ tokens.add("intent");
35066
+ tokens.add("reality");
35067
+ }
35068
+ if (/mcp-server/i.test(value)) {
35069
+ tokens.add("mcp");
35070
+ tokens.add("context");
35071
+ tokens.add("retrieval");
35072
+ }
35073
+ if (/prisma|migration|document_chunks/i.test(value)) {
35074
+ tokens.add("database");
35075
+ tokens.add("schema");
35076
+ tokens.add("pgvector");
35077
+ }
35078
+ return tokens;
35079
+ }
35080
+ function matchingAnchors(text, changedFiles) {
35081
+ const textTokens = scopeTokens(text);
35082
+ return changedFiles.filter((file) => {
35083
+ const fileTokens = scopeTokens(file);
35084
+ return [...fileTokens].some((token) => textTokens.has(token));
35085
+ });
35086
+ }
35087
+ function hasFileOverlap(left, right) {
35088
+ const rightSet = new Set(right);
35089
+ return left.some((item) => rightSet.has(item));
35090
+ }
35091
+ function collectLocalReceiptContext(scope) {
35092
+ const context = emptyAutoContext();
35093
+ const workflowRef = ".snipara/workflow/current.json";
35094
+ const workflow2 = readJsonRecord3(import_node_path2.default.join(scope.root, workflowRef));
35095
+ if (workflow2) {
35096
+ const workflowId = stringValue14(workflow2.workflowId) ?? "managed workflow";
35097
+ const phases = Array.isArray(workflow2.phases) ? workflow2.phases.filter(isRecord19) : [];
35098
+ for (const phase of phases) {
35099
+ const phaseFiles = stringList3(phase.files);
35100
+ if (!hasFileOverlap(phaseFiles, scope.changedFiles)) continue;
35101
+ const title = stringValue14(phase.title) ?? stringValue14(phase.id) ?? "workflow phase";
35102
+ const status = stringValue14(phase.status) ?? "unknown";
35103
+ context.evidence.push({
35104
+ kind: "workflow",
35105
+ label: `${workflowId}: ${title} (${status})`,
35106
+ sourceRef: workflowRef,
35107
+ strength: status === "completed" ? 0.78 : 0.62
35108
+ });
35109
+ }
35110
+ }
35111
+ const finalReportRef = ".snipara/workflow/final-report.json";
35112
+ const finalReport = readJsonRecord3(import_node_path2.default.join(scope.root, finalReportRef));
35113
+ const changed = isRecord19(finalReport?.changed) ? finalReport.changed : void 0;
35114
+ const reportFiles = stringList3(changed?.files);
35115
+ const overlappingFiles = reportFiles.filter((file) => scope.changedFiles.includes(file));
35116
+ if (finalReport && overlappingFiles.length > 0) {
35117
+ const workflowId = stringValue14(finalReport.workflowId) ?? "completed workflow";
35118
+ const outcome = stringValue14(finalReport.outcome) ?? "unknown";
35119
+ context.evidence.push({
35120
+ kind: "workflow",
35121
+ label: `${workflowId}: final report (${outcome})`,
35122
+ sourceRef: finalReportRef,
35123
+ strength: outcome === "completed" ? 0.82 : 0.6
35124
+ });
35125
+ const repository = isRecord19(changed?.repository) ? changed.repository : void 0;
35126
+ const reportHead = stringValue14(repository?.head);
35127
+ const dirtyOverlap = hasFileOverlap(scope.dirtyFiles, overlappingFiles);
35128
+ const receiptMatchesCurrentHead = Boolean(reportHead && reportHead === scope.headRef);
35129
+ const evidence = isRecord19(finalReport.evidence) ? finalReport.evidence : void 0;
35130
+ const items = Array.isArray(evidence?.items) ? evidence.items.filter(isRecord19) : [];
35131
+ if (receiptMatchesCurrentHead && !dirtyOverlap) {
35132
+ for (const [index, item] of items.entries()) {
35133
+ if (stringValue14(item.status)?.toLowerCase() !== "passed") continue;
35134
+ const label = stringValue14(item.text);
35135
+ if (!label) continue;
35136
+ context.verification.push(label);
35137
+ context.evidence.push({
35138
+ kind: "test",
35139
+ label,
35140
+ sourceRef: `${finalReportRef}#evidence-${index + 1}`,
35141
+ strength: 0.88
35142
+ });
35143
+ }
35144
+ } else if (items.length > 0) {
35145
+ context.caveats.push(
35146
+ "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."
35147
+ );
35148
+ }
35149
+ }
35150
+ return context;
35151
+ }
35152
+ function isReviewedDecisionSignal(signal) {
35153
+ const status = signal.status.toUpperCase();
35154
+ if (!["ACTIVE", "APPROVED", "ACCEPTED", "CONFIRMED"].includes(status)) return false;
35155
+ const tags = signal.tags.map((tag) => tag.toLowerCase());
35156
+ if (tags.some(
35157
+ (tag) => tag === "workflow-phase" || tag === "release" || tag === "auto-captured" || tag === "review-pending" || tag.startsWith("journal:")
35158
+ )) {
35159
+ return false;
35160
+ }
35161
+ return /decision/i.test(signal.recommendedAction);
35162
+ }
35163
+ function decisionsFromTeamSync(response, changedFiles) {
35164
+ const decisions = [];
35165
+ for (const signal of response.whatChanged.decisions.filter(isReviewedDecisionSignal)) {
35166
+ const affectedAnchors = matchingAnchors(
35167
+ [signal.title, signal.summary, ...signal.tags].join(" "),
35168
+ changedFiles
35169
+ );
35170
+ if (affectedAnchors.length === 0) continue;
35171
+ decisions.push({
35172
+ id: signal.id,
35173
+ title: signal.title,
35174
+ decision: signal.summary,
35175
+ status: "approved",
35176
+ confidenceScore: signal.impact?.toUpperCase() === "HIGH" ? 0.9 : 0.84,
35177
+ affectedAnchors,
35178
+ evidence: [
35179
+ {
35180
+ kind: "decision",
35181
+ label: `${signal.id}: ${signal.title}`,
35182
+ sourceRef: signal.id,
35183
+ strength: signal.impact?.toUpperCase() === "HIGH" ? 0.9 : 0.84
35184
+ }
35185
+ ]
35186
+ });
35187
+ }
35188
+ return decisions.slice(0, 8);
35189
+ }
35190
+ function contextQueryText(options, scope) {
35191
+ const task = options.task?.trim() || "Project Reality Check governing intent";
35192
+ const tokens = unique5([
35193
+ ...scopeTokens(task),
35194
+ ...scope.changedFiles.slice(0, 12).flatMap((file) => [...scopeTokens(file)]),
35195
+ "decision",
35196
+ "constraint"
35197
+ ]).slice(0, 8);
35198
+ return tokens.join(" ");
35199
+ }
35200
+ function documentsFromContext(result, changedFiles) {
35201
+ return result.sections.filter((section) => section.file && section.file !== "(unknown)").map((section) => ({
35202
+ path: section.file,
35203
+ title: section.title,
35204
+ contentPreview: section.content.slice(0, 1600),
35205
+ kind: /adr|decision/i.test(`${section.file} ${section.title}`) ? "ADR" : "DOC",
35206
+ sourceRef: `${section.file}#L${section.lines[0]}-L${section.lines[1]}`,
35207
+ affectedAnchors: matchingAnchors(
35208
+ `${section.file} ${section.title} ${section.content.slice(0, 800)}`,
35209
+ changedFiles
35210
+ )
35211
+ })).slice(0, 8);
35212
+ }
35213
+ async function collectHostedAutoContext(client, options, scope) {
35214
+ const context = emptyAutoContext();
35215
+ const [teamSync2, documents] = await Promise.allSettled([
35216
+ client.getTeamSyncWhatChanged({
35217
+ limit: 50,
35218
+ branch: scope.branch,
35219
+ paths: scope.changedFiles.slice(0, 20),
35220
+ recentFiles: scope.changedFiles.slice(0, 10)
35221
+ }),
35222
+ client.queryContext(contextQueryText(options, scope), 1200, {
35223
+ searchMode: "keyword",
35224
+ includeMetadata: true,
35225
+ includeAnswerPack: false,
35226
+ autoDecompose: false,
35227
+ includeSharedContext: false,
35228
+ includeAllTiers: false
35229
+ })
35230
+ ]);
35231
+ if (teamSync2.status === "fulfilled") {
35232
+ context.decisions = decisionsFromTeamSync(teamSync2.value, scope.changedFiles);
35233
+ } else {
35234
+ context.caveats.push(
35235
+ "Hosted reviewed-decision auto-linking was unavailable; explicit --decision inputs remain authoritative."
35236
+ );
35237
+ }
35238
+ if (documents.status === "fulfilled") {
35239
+ context.documents = documentsFromContext(documents.value, scope.changedFiles);
35240
+ } else {
35241
+ context.caveats.push(
35242
+ "Hosted document auto-context was unavailable; Reality Check continued with local and explicit evidence."
35243
+ );
35244
+ }
35245
+ return context;
35246
+ }
35247
+ function mergeAutoContext(local, hosted) {
35248
+ return {
35249
+ decisions: [...local.decisions, ...hosted.decisions],
35250
+ documents: [...local.documents, ...hosted.documents],
35251
+ evidence: [...local.evidence, ...hosted.evidence],
35252
+ verification: unique5([...local.verification, ...hosted.verification]),
35253
+ caveats: unique5([...local.caveats, ...hosted.caveats])
35254
+ };
35255
+ }
35256
+ function buildProjectRealityCheckForScope(options, scope, autoContext = emptyAutoContext()) {
35257
+ const decisionsById = new Map(
35258
+ autoContext.decisions.map((decision) => [decision.id, decision])
35259
+ );
35260
+ for (const [index, value] of (options.decision ?? []).entries()) {
35261
+ const decision = parseDecision(value, index);
35262
+ decisionsById.set(decision.id, decision);
35263
+ }
35264
+ const documentsByPath = new Map(
35265
+ autoContext.documents.map((document) => [document.path, document])
35266
+ );
35267
+ for (const value of options.document ?? []) {
35268
+ const document = parseDocument(value);
35269
+ documentsByPath.set(document.path, document);
35270
+ }
34949
35271
  const result = buildProjectRealityCheck({
34950
35272
  source: "local",
34951
35273
  task: options.task,
@@ -34955,17 +35277,35 @@ function buildLocalProjectRealityCheck(options) {
34955
35277
  changedFiles: scope.changedFiles,
34956
35278
  dirtyFiles: scope.dirtyFiles,
34957
35279
  diffSummary: scope.diffSummary,
34958
- decisions: (options.decision ?? []).map(parseDecision),
34959
- documents: (options.document ?? []).map(parseDocument),
34960
- verificationChecklist: options.verification ?? []
35280
+ decisions: [...decisionsById.values()],
35281
+ documents: [...documentsByPath.values()],
35282
+ evidence: autoContext.evidence,
35283
+ verificationChecklist: unique5([...autoContext.verification, ...options.verification ?? []])
34961
35284
  });
34962
- if (scope.caveats.length === 0) {
34963
- return result;
35285
+ const caveats = unique5([...result.caveats, ...scope.caveats, ...autoContext.caveats]);
35286
+ return { ...result, caveats };
35287
+ }
35288
+ function buildLocalProjectRealityCheck(options) {
35289
+ const scope = buildLocalGitScope(options);
35290
+ return buildProjectRealityCheckForScope(options, scope);
35291
+ }
35292
+ async function buildLocalProjectRealityCheckWithAutoContext(options, clientOverride) {
35293
+ const scope = buildLocalGitScope(options);
35294
+ let autoContext = collectLocalReceiptContext(scope);
35295
+ const configured = Boolean(clientOverride) || isConfigured({ cwd: scope.root });
35296
+ if (configured) {
35297
+ const timeoutMs = Math.max(1e3, Math.min(options.autoContextTimeoutMs ?? 12e3, 3e4));
35298
+ const client = clientOverride ?? createClient(timeoutMs, { cwd: scope.root });
35299
+ autoContext = mergeAutoContext(
35300
+ autoContext,
35301
+ await collectHostedAutoContext(client, options, scope)
35302
+ );
35303
+ } else {
35304
+ autoContext.caveats.push(
35305
+ "Hosted auto-context was skipped because this workspace is not configured; use --decision, --document, and --verification for explicit evidence."
35306
+ );
34964
35307
  }
34965
- return {
34966
- ...result,
34967
- caveats: [...result.caveats, ...scope.caveats]
34968
- };
35308
+ return buildProjectRealityCheckForScope(options, scope, autoContext);
34969
35309
  }
34970
35310
  function printRealityCheck(result) {
34971
35311
  console.log(import_chalk12.default.bold("Project Reality Check"));
@@ -34977,7 +35317,7 @@ function printRealityCheck(result) {
34977
35317
  console.log(renderProjectRealityCheckMarkdown(result));
34978
35318
  }
34979
35319
  async function realityCheckCommand(options) {
34980
- const result = buildLocalProjectRealityCheck(options);
35320
+ const result = options.autoContext === false ? buildLocalProjectRealityCheck(options) : await buildLocalProjectRealityCheckWithAutoContext(options);
34981
35321
  if (options.json) {
34982
35322
  console.log(JSON.stringify(result, null, 2));
34983
35323
  } else {
@@ -34989,7 +35329,7 @@ async function realityCheckCommand(options) {
34989
35329
  }
34990
35330
 
34991
35331
  // src/commands/context-control.ts
34992
- var fs33 = __toESM(require("fs"));
35332
+ var fs34 = __toESM(require("fs"));
34993
35333
  var path33 = __toESM(require("path"));
34994
35334
  var import_node_child_process15 = require("child_process");
34995
35335
  var import_chalk13 = __toESM(require("chalk"));
@@ -35040,7 +35380,7 @@ function resolveGitDriftScopePaths(cwd) {
35040
35380
  path33.join(".snipara", "decisions")
35041
35381
  ];
35042
35382
  const manifestPath = resolveManifestPath(cwd);
35043
- if (!fs33.existsSync(manifestPath)) {
35383
+ if (!fs34.existsSync(manifestPath)) {
35044
35384
  return normalizeScopePaths(scopePaths, cwd);
35045
35385
  }
35046
35386
  const manifestRead = readJsonFileSafe(manifestPath);
@@ -35090,12 +35430,12 @@ function receiptPathFor(receipt, cwd) {
35090
35430
  return path33.resolve(cwd, CONTEXT_CONTROL_APPLIED_RELATIVE_DIR, `${receipt.receiptId}.json`);
35091
35431
  }
35092
35432
  function writeStableJsonFile(filePath, value) {
35093
- fs33.mkdirSync(path33.dirname(filePath), { recursive: true });
35094
- fs33.writeFileSync(filePath, `${stableDecisionJsonStringify(value)}
35433
+ fs34.mkdirSync(path33.dirname(filePath), { recursive: true });
35434
+ fs34.writeFileSync(filePath, `${stableDecisionJsonStringify(value)}
35095
35435
  `, "utf8");
35096
35436
  }
35097
35437
  function readJsonFile4(filePath) {
35098
- return JSON.parse(fs33.readFileSync(filePath, "utf8"));
35438
+ return JSON.parse(fs34.readFileSync(filePath, "utf8"));
35099
35439
  }
35100
35440
  function buildStateOperation(options) {
35101
35441
  const target = assertContextControlTarget(
@@ -35287,7 +35627,7 @@ function applyLocalContextMutationPlan(options) {
35287
35627
  baseRevisionAtApply: currentRevision
35288
35628
  });
35289
35629
  const receiptPath = receiptPathFor(pendingReceipt, cwd);
35290
- if (fs33.existsSync(receiptPath)) {
35630
+ if (fs34.existsSync(receiptPath)) {
35291
35631
  const receipt2 = buildContextMutationApplyReceipt({
35292
35632
  plan,
35293
35633
  appliedAt: options.now,
@@ -35325,7 +35665,7 @@ function applyLocalContextMutationPlan(options) {
35325
35665
  continue;
35326
35666
  }
35327
35667
  const absoluteTarget = path33.resolve(cwd, target);
35328
- if (operation.mode === "create" && fs33.existsSync(absoluteTarget)) {
35668
+ if (operation.mode === "create" && fs34.existsSync(absoluteTarget)) {
35329
35669
  throw new Error(`Refusing to overwrite existing context-control file: ${target}`);
35330
35670
  }
35331
35671
  writeStableJsonFile(absoluteTarget, operation.content ?? {});
@@ -35359,8 +35699,8 @@ function applyLocalContextMutationPlan(options) {
35359
35699
  };
35360
35700
  }
35361
35701
  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));
35702
+ if (!fs34.existsSync(dir)) return [];
35703
+ return fs34.readdirSync(dir).filter((name) => name.endsWith(".json")).map((name) => path33.join(dir, name)).sort((left, right) => left.localeCompare(right));
35364
35704
  }
35365
35705
  function readJsonFileSafe(filePath) {
35366
35706
  try {
@@ -35439,7 +35779,7 @@ function collectGitDriftSignals(cwd) {
35439
35779
  }
35440
35780
  function collectWorkflowDriftSignals(cwd) {
35441
35781
  const workflowPath = path33.join(cwd, ".snipara", "workflow", "current.json");
35442
- if (!fs33.existsSync(workflowPath)) {
35782
+ if (!fs34.existsSync(workflowPath)) {
35443
35783
  return [
35444
35784
  {
35445
35785
  id: "workflow-state-missing",
@@ -35582,7 +35922,7 @@ function collectContextControlDriftSignals(cwd) {
35582
35922
  function collectProjectContextManifestDriftSignals(cwd) {
35583
35923
  const manifestPath = resolveManifestPath(cwd);
35584
35924
  const relative11 = toProjectRelativePath4(manifestPath, cwd);
35585
- if (!fs33.existsSync(manifestPath)) {
35925
+ if (!fs34.existsSync(manifestPath)) {
35586
35926
  return [
35587
35927
  {
35588
35928
  id: "project-context-manifest-missing",
@@ -35785,23 +36125,23 @@ function resolveHostedContextSources(cwd, manifestPath, report) {
35785
36125
  if (!report.manifest || report.status === "invalid") {
35786
36126
  throw new Error("ProjectContext manifest is invalid; run context-control validate first.");
35787
36127
  }
35788
- const workspaceRoot2 = fs33.realpathSync(cwd);
36128
+ const workspaceRoot2 = fs34.realpathSync(cwd);
35789
36129
  return report.manifest.sources.map((source2) => {
35790
36130
  const candidate = path33.resolve(cwd, source2.path);
35791
- if (!fs33.existsSync(candidate)) {
36131
+ if (!fs34.existsSync(candidate)) {
35792
36132
  throw new Error(`ProjectContext source is missing: ${source2.path}`);
35793
36133
  }
35794
- if (fs33.lstatSync(candidate).isSymbolicLink()) {
36134
+ if (fs34.lstatSync(candidate).isSymbolicLink()) {
35795
36135
  throw new Error(`ProjectContext source symlinks are not allowed: ${source2.path}`);
35796
36136
  }
35797
- const canonical = fs33.realpathSync(candidate);
36137
+ const canonical = fs34.realpathSync(candidate);
35798
36138
  if (canonical !== workspaceRoot2 && !canonical.startsWith(`${workspaceRoot2}${path33.sep}`)) {
35799
36139
  throw new Error(`ProjectContext source escapes the workspace: ${source2.path}`);
35800
36140
  }
35801
- if (!fs33.statSync(canonical).isFile()) {
36141
+ if (!fs34.statSync(canonical).isFile()) {
35802
36142
  throw new Error(`ProjectContext source must be a file: ${source2.path}`);
35803
36143
  }
35804
- const content = fs33.readFileSync(canonical, "utf8");
36144
+ const content = fs34.readFileSync(canonical, "utf8");
35805
36145
  if (Buffer.byteLength(content, "utf8") > 1e6) {
35806
36146
  throw new Error(`ProjectContext source exceeds 1 MB: ${source2.path}`);
35807
36147
  }
@@ -35936,7 +36276,7 @@ function uniqueStrings22(values) {
35936
36276
 
35937
36277
  // src/commands/references.ts
35938
36278
  var crypto6 = __toESM(require("crypto"));
35939
- var fs34 = __toESM(require("fs"));
36279
+ var fs35 = __toESM(require("fs"));
35940
36280
  var path34 = __toESM(require("path"));
35941
36281
  var import_chalk14 = __toESM(require("chalk"));
35942
36282
  var MANIFEST_VERSION2 = "snipara.references.v1";
@@ -36020,13 +36360,13 @@ function toRelative(root, file) {
36020
36360
  return path34.relative(root, file).split(path34.sep).join("/");
36021
36361
  }
36022
36362
  function ensureParentDir(file) {
36023
- fs34.mkdirSync(path34.dirname(file), { recursive: true });
36363
+ fs35.mkdirSync(path34.dirname(file), { recursive: true });
36024
36364
  }
36025
36365
  function walkFiles(root, extensions, maxFiles, files = []) {
36026
36366
  if (files.length >= maxFiles) {
36027
36367
  return files;
36028
36368
  }
36029
- for (const entry of fs34.readdirSync(root, { withFileTypes: true })) {
36369
+ for (const entry of fs35.readdirSync(root, { withFileTypes: true })) {
36030
36370
  if (files.length >= maxFiles) {
36031
36371
  break;
36032
36372
  }
@@ -36047,7 +36387,7 @@ function collectReferenceItems(root, files, allowDomains, denyDomains) {
36047
36387
  const byUrl = /* @__PURE__ */ new Map();
36048
36388
  const discoveredAt = (/* @__PURE__ */ new Date()).toISOString();
36049
36389
  for (const file of files) {
36050
- const content = fs34.readFileSync(file, "utf-8");
36390
+ const content = fs35.readFileSync(file, "utf-8");
36051
36391
  const lines = content.split(/\r?\n/);
36052
36392
  const markdownLink = /\[([^\]]+)\]\((https?:\/\/[^)\s]+)\)/g;
36053
36393
  const bareUrl = /https?:\/\/[^\s<>"'`]+/g;
@@ -36113,7 +36453,7 @@ function scanReferences(options = {}) {
36113
36453
  items
36114
36454
  };
36115
36455
  ensureParentDir(outputPath);
36116
- fs34.writeFileSync(outputPath, `${JSON.stringify(manifest, null, 2)}
36456
+ fs35.writeFileSync(outputPath, `${JSON.stringify(manifest, null, 2)}
36117
36457
  `, "utf-8");
36118
36458
  return {
36119
36459
  manifest,
@@ -36127,7 +36467,7 @@ function scanReferences(options = {}) {
36127
36467
  };
36128
36468
  }
36129
36469
  function readManifest2(file) {
36130
- const manifest = JSON.parse(fs34.readFileSync(file, "utf-8"));
36470
+ const manifest = JSON.parse(fs35.readFileSync(file, "utf-8"));
36131
36471
  if (manifest.version !== MANIFEST_VERSION2 || !Array.isArray(manifest.items)) {
36132
36472
  throw new Error(`${file} is not a ${MANIFEST_VERSION2} manifest`);
36133
36473
  }
@@ -36212,7 +36552,7 @@ async function fetchReference(item, outputDir, destinationPrefix, timeoutMs, max
36212
36552
  bodyHash: hash
36213
36553
  });
36214
36554
  ensureParentDir(snapshotPath);
36215
- fs34.writeFileSync(snapshotPath, markdown, "utf-8");
36555
+ fs35.writeFileSync(snapshotPath, markdown, "utf-8");
36216
36556
  return {
36217
36557
  item,
36218
36558
  fetchedAt,
@@ -36322,7 +36662,7 @@ async function ingestReferences(options = {}) {
36322
36662
  });
36323
36663
  }
36324
36664
  }
36325
- fs34.writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}
36665
+ fs35.writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}
36326
36666
  `, "utf-8");
36327
36667
  if (options.reindex && client) {
36328
36668
  await client.reindex({ kind: "doc", mode: "incremental" });
@@ -36376,7 +36716,7 @@ async function referencesIngestCommand(options) {
36376
36716
  // src/commands/run.ts
36377
36717
  var import_node_child_process16 = require("child_process");
36378
36718
  var import_node_crypto12 = require("crypto");
36379
- var fs35 = __toESM(require("fs"));
36719
+ var fs36 = __toESM(require("fs"));
36380
36720
  var path35 = __toESM(require("path"));
36381
36721
  var import_chalk15 = __toESM(require("chalk"));
36382
36722
 
@@ -36385,21 +36725,21 @@ var REGISTRY_VERSION = "project-intelligence.policy-gates.registry.v1";
36385
36725
  function normalizeChangedFiles(changedFiles) {
36386
36726
  return [...new Set((changedFiles ?? []).map((file) => file.trim()).filter(Boolean))];
36387
36727
  }
36388
- function isRecord19(value) {
36728
+ function isRecord20(value) {
36389
36729
  return typeof value === "object" && value !== null && !Array.isArray(value);
36390
36730
  }
36391
- function stringValue14(value) {
36731
+ function stringValue15(value) {
36392
36732
  return typeof value === "string" && value.trim() ? value.trim() : void 0;
36393
36733
  }
36394
36734
  function nestedRecord3(root, keys) {
36395
36735
  let current = root;
36396
36736
  for (const key of keys) {
36397
- if (!isRecord19(current) || !isRecord19(current[key])) {
36737
+ if (!isRecord20(current) || !isRecord20(current[key])) {
36398
36738
  return {};
36399
36739
  }
36400
36740
  current = current[key];
36401
36741
  }
36402
- return isRecord19(current) ? current : {};
36742
+ return isRecord20(current) ? current : {};
36403
36743
  }
36404
36744
  function combinedText(input) {
36405
36745
  return [input.task, input.diffSummary, ...input.changedFiles ?? []].filter(Boolean).join("\n").toLowerCase();
@@ -36569,7 +36909,7 @@ function evaluateProjectPolicyGates(input) {
36569
36909
  );
36570
36910
  }
36571
36911
  const guardEval = guardEvaluation2(input.guard?.payload);
36572
- const guardDecision = stringValue14(guardEval.decision)?.toUpperCase();
36912
+ const guardDecision = stringValue15(guardEval.decision)?.toUpperCase();
36573
36913
  if (guardDecision === "BLOCKED" || input.release && input.guard?.status !== void 0 && input.guard.status !== 0) {
36574
36914
  gates.push(
36575
36915
  gate({
@@ -36807,8 +37147,8 @@ var GUARD_MAX_BUFFER_BYTES = 16 * 1024 * 1024;
36807
37147
  var RAW_OUTPUT_PREVIEW_BYTES = 64e3;
36808
37148
  var ADVISOR_RECEIPT_WRITE_LIMIT = 6;
36809
37149
  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);
37150
+ const sniparaSessionId = stringValue16(process.env.SNIPARA_SESSION_ID)?.slice(0, 200);
37151
+ const codexSessionId = stringValue16(process.env.CODEX_SESSION_ID)?.slice(0, 200);
36812
37152
  return {
36813
37153
  version: "project-intelligence.judgment-run-envelope.v1",
36814
37154
  runId: sniparaSessionId ?? codexSessionId ?? `judgment-run:${(0, import_node_crypto12.randomUUID)()}`,
@@ -36822,7 +37162,7 @@ function normalizeStringList6(values) {
36822
37162
  function uniqueStrings23(values) {
36823
37163
  return [...new Set(values.map((value) => value.trim()).filter(Boolean))];
36824
37164
  }
36825
- function isRecord20(value) {
37165
+ function isRecord21(value) {
36826
37166
  return typeof value === "object" && value !== null && !Array.isArray(value);
36827
37167
  }
36828
37168
  function guardPayload(guard) {
@@ -36835,7 +37175,7 @@ function readOutcomeReceipts(files) {
36835
37175
  const receipts = [];
36836
37176
  for (const file of normalizeStringList6(files)) {
36837
37177
  const resolved = path35.resolve(process.cwd(), file);
36838
- const parsed = JSON.parse(fs35.readFileSync(resolved, "utf8"));
37178
+ const parsed = JSON.parse(fs36.readFileSync(resolved, "utf8"));
36839
37179
  receipts.push(...outcomeReceiptsFromUnknown(parsed));
36840
37180
  }
36841
37181
  return receipts;
@@ -36844,13 +37184,13 @@ function outcomeReceiptsFromUnknown(value) {
36844
37184
  if (Array.isArray(value)) {
36845
37185
  return value.flatMap(outcomeReceiptsFromUnknown);
36846
37186
  }
36847
- if (!isRecord20(value)) {
37187
+ if (!isRecord21(value)) {
36848
37188
  return [];
36849
37189
  }
36850
37190
  if (value.version === "snipara.outcome_intelligence.receipt.v0") {
36851
37191
  return [value];
36852
37192
  }
36853
- if (isRecord20(value.outcomeReceipt)) {
37193
+ if (isRecord21(value.outcomeReceipt)) {
36854
37194
  return outcomeReceiptsFromUnknown(value.outcomeReceipt);
36855
37195
  }
36856
37196
  if (Array.isArray(value.outcomeReceipts)) {
@@ -36868,11 +37208,11 @@ function outputPreview(value) {
36868
37208
  return `${value.slice(0, RAW_OUTPUT_PREVIEW_BYTES)}
36869
37209
  ...[truncated]`;
36870
37210
  }
36871
- function stringValue15(value) {
37211
+ function stringValue16(value) {
36872
37212
  return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
36873
37213
  }
36874
37214
  function servedJudgmentIdForRun(options, brief) {
36875
- return stringValue15(options.servedJudgmentId) ?? stringValue15(brief.servedJudgmentId) ?? servedJudgmentIdFromContext(brief.resumeContext) ?? servedJudgmentIdFromContext(brief.verificationPlan);
37215
+ return stringValue16(options.servedJudgmentId) ?? stringValue16(brief.servedJudgmentId) ?? servedJudgmentIdFromContext(brief.resumeContext) ?? servedJudgmentIdFromContext(brief.verificationPlan);
36876
37216
  }
36877
37217
  function advisorMeasurementState(args) {
36878
37218
  if (args.agentDecision === "blocked") return "blocked";
@@ -36949,7 +37289,7 @@ function boundedLifecycleText(value, maxChars) {
36949
37289
  return value.trim().replace(/\s+/g, " ").slice(0, maxChars);
36950
37290
  }
36951
37291
  function advisorRecommendationPlanScope(args) {
36952
- const requestedRecommendationId = stringValue15(args.options.advisorRecommendationId) ?? null;
37292
+ const requestedRecommendationId = stringValue16(args.options.advisorRecommendationId) ?? null;
36953
37293
  if (requestedRecommendationId) {
36954
37294
  const targeted = requestedRecommendationId === args.recommendationId;
36955
37295
  return {
@@ -37257,7 +37597,7 @@ async function recordFirstPartyAdvisorReceipts(args) {
37257
37597
  };
37258
37598
  }
37259
37599
  const client = createClient(1e4);
37260
- const verificationEvidence = args.verificationEvidence ?? [];
37600
+ const verificationEvidence2 = args.verificationEvidence ?? [];
37261
37601
  const outcomeReceipts = args.outcomeReceipts ?? [];
37262
37602
  const selectedRecommendations = allRecommendations.slice(0, ADVISOR_RECEIPT_WRITE_LIMIT);
37263
37603
  const overflowWrites = allRecommendations.slice(ADVISOR_RECEIPT_WRITE_LIMIT).map((recommendation) => skippedAdvisorReceiptWrite(recommendation, "write_limit_exceeded"));
@@ -37315,7 +37655,7 @@ async function recordFirstPartyAdvisorReceipts(args) {
37315
37655
  recommendation,
37316
37656
  recommendationIndex,
37317
37657
  totalRecommendations: allRecommendations.length,
37318
- verificationEvidence,
37658
+ verificationEvidence: verificationEvidence2,
37319
37659
  lifecycle,
37320
37660
  planScope,
37321
37661
  measurementState,
@@ -37401,7 +37741,7 @@ function runGuard(options, changedFiles) {
37401
37741
  let payload;
37402
37742
  try {
37403
37743
  const parsed = JSON.parse(result.stdout);
37404
- if (isRecord20(parsed)) {
37744
+ if (isRecord21(parsed)) {
37405
37745
  payload = parsed;
37406
37746
  }
37407
37747
  } catch {
@@ -37522,7 +37862,7 @@ async function buildProjectIntelligenceRun(options) {
37522
37862
  decision: brief.projectPolicyDecision
37523
37863
  } : void 0
37524
37864
  });
37525
- const verificationEvidence = verificationEvidenceFromRun({
37865
+ const verificationEvidence2 = verificationEvidenceFromRun({
37526
37866
  guard,
37527
37867
  packageReview,
37528
37868
  policyGates
@@ -37531,7 +37871,7 @@ async function buildProjectIntelligenceRun(options) {
37531
37871
  options,
37532
37872
  brief,
37533
37873
  judgmentCard,
37534
- verificationEvidence,
37874
+ verificationEvidence: verificationEvidence2,
37535
37875
  outcomeReceipts,
37536
37876
  runEnvelope
37537
37877
  });
@@ -37594,10 +37934,10 @@ async function projectIntelligenceRunCommand(options) {
37594
37934
  if (result.guard) {
37595
37935
  console.log(import_chalk15.default.bold("Guard"));
37596
37936
  console.log(`Status: ${result.guard.status}`);
37597
- const actionCards = isRecord20(result.guard.payload) ? result.guard.payload.actionCards : [];
37937
+ const actionCards = isRecord21(result.guard.payload) ? result.guard.payload.actionCards : [];
37598
37938
  if (Array.isArray(actionCards) && actionCards.length > 0) {
37599
37939
  for (const card of actionCards.slice(0, 6)) {
37600
- if (!isRecord20(card)) continue;
37940
+ if (!isRecord21(card)) continue;
37601
37941
  console.log(`- ${card.kind}: ${card.title ?? card.reason ?? "guard action"}`);
37602
37942
  }
37603
37943
  }
@@ -37662,7 +38002,7 @@ async function projectIntelligenceRunCommand(options) {
37662
38002
  }
37663
38003
 
37664
38004
  // src/commands/policy-ledger-sync.ts
37665
- var fs36 = __toESM(require("fs"));
38005
+ var fs37 = __toESM(require("fs"));
37666
38006
  var path36 = __toESM(require("path"));
37667
38007
  var POLICY_LEDGER_SYNC_REPORT_VERSION = "snipara.workflow_policy_ledger_sync.v0";
37668
38008
  function buildPolicyLedgerSyncReport(options = {}) {
@@ -37810,12 +38150,12 @@ function statusForChoiceClass(choiceClass) {
37810
38150
  return "modified";
37811
38151
  }
37812
38152
  function readJsonFiles(directory, cwd) {
37813
- if (!fs36.existsSync(directory)) {
38153
+ if (!fs37.existsSync(directory)) {
37814
38154
  return [];
37815
38155
  }
37816
- return fs36.readdirSync(directory).filter((fileName) => fileName.endsWith(".json")).sort().map((fileName) => {
38156
+ return fs37.readdirSync(directory).filter((fileName) => fileName.endsWith(".json")).sort().map((fileName) => {
37817
38157
  const filePath = path36.join(directory, fileName);
37818
- const parsed = JSON.parse(fs36.readFileSync(filePath, "utf8"));
38158
+ const parsed = JSON.parse(fs37.readFileSync(filePath, "utf8"));
37819
38159
  return { parsed, relativePath: toProjectRelativePath5(filePath, cwd) };
37820
38160
  });
37821
38161
  }
@@ -38020,7 +38360,11 @@ function collectOption(value, previous = []) {
38020
38360
  return [...previous, value];
38021
38361
  }
38022
38362
  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) => {
38363
+ 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(
38364
+ "--auto-context-timeout-ms <number>",
38365
+ "Timeout for each hosted auto-context source",
38366
+ "12000"
38367
+ ).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
38368
  await realityCheckCommand({
38025
38369
  task: options.task,
38026
38370
  branch: options.branch,
@@ -38030,6 +38374,8 @@ function configureRealityCheckCommand(command) {
38030
38374
  decision: options.decision,
38031
38375
  document: options.document,
38032
38376
  verification: options.verification,
38377
+ autoContext: options.autoContext !== false,
38378
+ autoContextTimeoutMs: Number.parseInt(options.autoContextTimeoutMs, 10),
38033
38379
  includeDirty: options.includeDirty,
38034
38380
  enforce: Boolean(options.enforce),
38035
38381
  dir: options.dir,
@@ -38509,13 +38855,18 @@ program.command("memory-guard").description(
38509
38855
  );
38510
38856
  program.command("query").description(
38511
38857
  "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(
38858
+ ).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
38859
  "--follow-recommendation",
38514
38860
  "Automatically execute the recommended structural tool when Snipara returns one"
38515
38861
  ).option("--json", "Print raw JSON").action(async (options) => {
38516
38862
  await queryCommand({
38517
38863
  query: options.query,
38518
38864
  maxTokens: parseInt(options.maxTokens, 10),
38865
+ searchMode: options.searchMode,
38866
+ timeoutMs: parseInt(options.timeoutMs, 10),
38867
+ includeAnswerPack: options.answerPack !== false,
38868
+ autoDecompose: options.autoDecompose !== false,
38869
+ includeSharedContext: options.sharedContext !== false,
38519
38870
  followRecommendation: Boolean(options.followRecommendation),
38520
38871
  json: options.json
38521
38872
  });
@@ -40284,6 +40635,7 @@ if (require.main === module) {
40284
40635
  buildLocalProjectContextValidationReport,
40285
40636
  buildLocalProjectDriftReport,
40286
40637
  buildLocalProjectRealityCheck,
40638
+ buildLocalProjectRealityCheckWithAutoContext,
40287
40639
  buildLocalShortestPathResult,
40288
40640
  buildLocalSourceSnapshot,
40289
40641
  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.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": {