snipara-companion 3.6.8 → 3.6.9

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,21 @@
2
2
 
3
3
  Release notes for `snipara-companion`, newest first.
4
4
 
5
+ ## New In 3.6.9
6
+
7
+ - Auto-accepts only `info` and `watch` Advisor recommendations in managed
8
+ workflows, with an auditable `policy_auto` source and stable reason codes;
9
+ `risk` and `block` recommendations still require explicit authority.
10
+ - Adds an evidence-derived Judgment Resolution V1 beside the immutable original
11
+ card. Verification-only warnings can become `ready` after a completed outcome
12
+ and matching passed evidence, while failed evidence, collaboration blockers,
13
+ `resolve_blocker` actions, and explicit blocked decisions remain hard blocks.
14
+ - Preserves superseded responses and refreshed cards in bounded local history,
15
+ and normalizes older Judgment V1 states without a migration or schema reset.
16
+ - Makes action-to-evidence matching explicit for tests, type checks, lint,
17
+ builds, package review, deployment/guard review, impact inspection, and Team
18
+ Sync handoffs.
19
+
5
20
  ## New In 3.6.8
6
21
 
7
22
  - Redacts macOS workspace paths consistently when the same temporary directory
package/README.md CHANGED
@@ -313,6 +313,7 @@ After the first impact check, keep the work resumable:
313
313
 
314
314
  ```bash
315
315
  npx -y snipara-companion workflow start --goal "ship auth hardening"
316
+ npx -y snipara-companion workflow judgment
316
317
  npx -y snipara-companion workflow phase-start audit
317
318
  npx -y snipara-companion lead-plan --task "ship auth hardening" --changed-files src/auth/session.ts --proof "pnpm test auth" --acceptance "auth tests pass"
318
319
  npx -y snipara-companion lead-plan --from-plan ./project-health-lead-plan.json --reconcile --changed-files src/auth/session.ts
@@ -332,6 +333,14 @@ npx -y snipara-companion workflow producer-review --latest --outcome useful --re
332
333
  npx -y snipara-companion handoff --summary "auth impact mapped" --next "run auth tests"
333
334
  ```
334
335
 
336
+ Managed workflow judgments use risk-based authority. `info` and `watch`
337
+ recommendations are accepted locally by policy and remain auditable; `risk` and
338
+ `block` recommendations still need `workflow judgment-respond`. The immutable
339
+ card is never rewritten. Companion appends an effective resolution and can lift
340
+ a verification-only `proof_required` state only after a completed outcome and
341
+ matching passed evidence. Failed evidence, a blocked collaboration guard, a
342
+ `resolve_blocker` action, or an explicit blocked response remains a hard stop.
343
+
335
344
  `snipara-companion` writes local state under `.snipara/` so a coding agent can
336
345
  resume with the current phase, recent handoffs, timeline, context packs, and
337
346
  verification hints.
@@ -489,8 +498,10 @@ Release notes live in [CHANGELOG.md](./CHANGELOG.md).
489
498
  When project auth is configured, `workflow phase-commit`, `final-commit`, and
490
499
  `team-sync handoff` also run reviewed Why Capture. The Companion first sends a
491
500
  read-only preview and confirms only when the server detects durable rationale.
492
- Confirmed candidates enter the pending review queue; capture failures remain
493
- visible but do not block the primary workflow command. No documentation prompt
494
- is shown. `final-commit` remains handoff-only: the report explains what was
495
- stored or proposed, but it does not approve pending candidates or write final
496
- summary text as durable memory.
501
+ Low-risk, directly confirmed and sufficiently evidenced captures can be
502
+ approved by the hosted memory policy; shared-scope, conflicting, weakly
503
+ supported, imported, or canonical decision-draft candidates remain reviewed.
504
+ Capture failures stay visible but do not block the primary workflow command. No
505
+ documentation prompt is shown. `final-commit` remains handoff-only: the report
506
+ explains what was stored or proposed, but it does not itself approve canonical
507
+ decision drafts or write final summary text as durable memory.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { AdvisorInfluenceLifecycle, HostedContextControlSource, HostedContextControlPlan, HostedContextControlApplyReceipt, ProjectIntentDetectionResult, ProjectPolicyDecision, ProjectRealityCheckResult, ContextMutationPlan, ContextMutationApplyReceipt, ProjectContextValidationReport, ProjectDriftReport, AgentContextResolution, AgentContextValidationReport, AgentContextEvidenceReceipt, AgentContextEvidenceReport, ProjectIntelligenceEngineeringLeadPlanSummary, ProjectPolicyRule, DecisionRequest, AdvisorInfluenceLifecycleState, OutcomeIntelligenceCalibration, OutcomeIntelligenceReceipt, ControlledWorkerExecutionMode, WorkerTrustCategory, ControlledWorkerExecutionReceipt, UnifiedReceiptEnvelope, WorkerTrustCandidate, WorkerProfile, WorkerTrustEvent } from '@snipara/project-intelligence-contracts';
2
+ import { AdvisorInfluenceLifecycle, HostedContextControlSource, HostedContextControlPlan, HostedContextControlApplyReceipt, ProjectIntentDetectionResult, ProjectPolicyDecision, ProjectRealityCheckResult, ContextMutationPlan, ContextMutationApplyReceipt, ProjectContextValidationReport, ProjectDriftReport, AgentContextResolution, AgentContextValidationReport, AgentContextEvidenceReceipt, AgentContextEvidenceReport, ProjectIntelligenceEngineeringLeadPlanSummary, ProjectPolicyRule, AdvisorInfluenceLifecycleState, DecisionRequest, OutcomeIntelligenceCalibration, OutcomeIntelligenceReceipt, OutcomeIntelligenceEvidence, ControlledWorkerExecutionMode, WorkerTrustCategory, ControlledWorkerExecutionReceipt, UnifiedReceiptEnvelope, WorkerTrustCandidate, WorkerProfile, WorkerTrustEvent } from '@snipara/project-intelligence-contracts';
3
3
 
4
4
  declare function resolveQueryFromToolInput(toolInput?: string, tool?: string): string | null;
5
5
 
@@ -4316,12 +4316,39 @@ interface ManagedWorkflowJudgmentResponse {
4316
4316
  recommendationId: string;
4317
4317
  decision: AdvisorInfluenceAgentDecision;
4318
4318
  respondedAt: string;
4319
+ source: "explicit" | "policy_auto";
4320
+ policyVersion?: "snipara.workflow.judgment-autonomy.v1";
4321
+ reasonCodes: string[];
4319
4322
  planBefore?: string;
4320
4323
  planAfter?: string;
4321
4324
  initialReceipt?: ProjectRunAdvisorReceiptCapture;
4322
4325
  closeoutReceipt?: ProjectRunAdvisorReceiptCapture;
4323
4326
  outcomeReceipts?: OutcomeIntelligenceReceipt[];
4324
4327
  }
4328
+ interface ManagedWorkflowJudgmentResolution {
4329
+ version: "snipara.workflow.judgment-resolution.v1";
4330
+ evaluatedAt: string;
4331
+ state: ProjectJudgmentState;
4332
+ canProceed: ProjectJudgmentCanProceed;
4333
+ originalCard: {
4334
+ generatedAt: string;
4335
+ state: ProjectJudgmentState;
4336
+ canProceed: ProjectJudgmentCanProceed;
4337
+ score: number;
4338
+ };
4339
+ reasonCodes: string[];
4340
+ hardBlockerCodes: string[];
4341
+ pendingExplicitRecommendationIds: string[];
4342
+ autoResponseCount: number;
4343
+ evidence: {
4344
+ passedCount: number;
4345
+ failedCount: number;
4346
+ skippedCount: number;
4347
+ requiredActionCount: number;
4348
+ satisfiedRequiredActionCount: number;
4349
+ unsatisfiedRequiredActions: string[];
4350
+ };
4351
+ }
4325
4352
  interface ManagedWorkflowJudgmentState {
4326
4353
  version: "snipara.workflow.judgment.v1";
4327
4354
  generatedAt: string;
@@ -4329,6 +4356,8 @@ interface ManagedWorkflowJudgmentState {
4329
4356
  brief: ManagedWorkflowJudgmentBrief;
4330
4357
  card: ProjectIntelligenceJudgmentCard;
4331
4358
  responses: ManagedWorkflowJudgmentResponse[];
4359
+ responseHistory?: ManagedWorkflowJudgmentResponse[];
4360
+ resolution?: ManagedWorkflowJudgmentResolution;
4332
4361
  }
4333
4362
  interface ManagedWorkflowState {
4334
4363
  schemaVersion: ManagedWorkflowSchemaVersion;
@@ -4344,6 +4373,7 @@ interface ManagedWorkflowState {
4344
4373
  runtime?: ManagedWorkflowRuntimeState;
4345
4374
  coordination?: ManagedWorkflowCoordinationState;
4346
4375
  judgment?: ManagedWorkflowJudgmentState;
4376
+ judgmentHistory?: ManagedWorkflowJudgmentState[];
4347
4377
  phaseCommitReceipts?: WorkflowPhaseCommitReceipt[];
4348
4378
  finalReport?: FinalCommitReportArtifact;
4349
4379
  lastCommit?: {
@@ -4743,6 +4773,12 @@ declare function buildSyncDocumentsDryRun(documents: SyncDocumentInput[], option
4743
4773
  reindexMode?: ReindexMode;
4744
4774
  now?: Date;
4745
4775
  }): SyncDocumentsDryRunSummary;
4776
+ declare function applyManagedWorkflowPolicyAutoResponses(judgment: ManagedWorkflowJudgmentState, respondedAt?: string): ManagedWorkflowJudgmentResponse[];
4777
+ declare function deriveManagedWorkflowJudgmentResolution(judgment: ManagedWorkflowJudgmentState, options?: {
4778
+ evidence?: OutcomeIntelligenceEvidence[];
4779
+ outcome?: TaskCommitOutcome;
4780
+ evaluatedAt?: string;
4781
+ }): ManagedWorkflowJudgmentResolution;
4746
4782
  declare function buildAgenticWorkStatus(cwd?: string): AgenticWorkStatus;
4747
4783
  declare function buildAgenticTimeline(options?: {
4748
4784
  limit?: number;
@@ -5232,4 +5268,4 @@ declare function installAutomationBundle(args: {
5232
5268
  }): Promise<AutomationInstallResult>;
5233
5269
  declare function getAutomationStatus(projectDir?: string): AutomationStatusResult;
5234
5270
 
5235
- export { AGENT_CONTEXT_EVIDENCE_DEFAULT_LEDGER, 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, agentContextEvidenceRecordCommand, agentContextEvidenceStatusCommand, agentContextEvidenceTemplateCommand, agentContextResolveCommand, agentContextValidateCommand, 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, buildLocalAgentContextValidationReport, 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, formatAgentContextResolution, 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, mergeHybridCodeResults, normalizeCollaborationFiles, normalizeGuardTag, normalizeWorkflowPlanInput, outcomeCapturePreviewCommand, packContext, parseCollaborationResources, projectIntelligenceBriefCommand, projectIntelligenceRunCommand, readActivityTimeline, readAgentContextEvidenceLedger, readLocalCodeOverlayCache, readLocalCodePromotionState, readLocalSourceSnapshot, readLocalWorkersConfig, readSessionSnapshot, readWorkerTrustEvent, realityCheckCommand, referencesIngestCommand, referencesScanCommand, resolveAutoWorkflowMode, resolveCodeGraphMode, 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 };
5271
+ export { AGENT_CONTEXT_EVIDENCE_DEFAULT_LEDGER, 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, agentContextEvidenceRecordCommand, agentContextEvidenceStatusCommand, agentContextEvidenceTemplateCommand, agentContextResolveCommand, agentContextValidateCommand, agentReadinessAuditCommand, appendActivityEvent, applyLocalContextMutationPlan, applyManagedWorkflowPolicyAutoResponses, 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, buildLocalAgentContextValidationReport, 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, deriveManagedWorkflowJudgmentResolution, detectReleaseSurfacesFromFiles, detectRuntimeEnvironment, evalExportCommand, evalRunCommand, evaluateProjectPolicyGates, extractCommandFromToolInput, extractFilesFromToolInput, formatAgentContextResolution, 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, mergeHybridCodeResults, normalizeCollaborationFiles, normalizeGuardTag, normalizeWorkflowPlanInput, outcomeCapturePreviewCommand, packContext, parseCollaborationResources, projectIntelligenceBriefCommand, projectIntelligenceRunCommand, readActivityTimeline, readAgentContextEvidenceLedger, readLocalCodeOverlayCache, readLocalCodePromotionState, readLocalSourceSnapshot, readLocalWorkersConfig, readSessionSnapshot, readWorkerTrustEvent, realityCheckCommand, referencesIngestCommand, referencesScanCommand, resolveAutoWorkflowMode, resolveCodeGraphMode, 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
@@ -69,6 +69,7 @@ __export(index_exports, {
69
69
  agentReadinessAuditCommand: () => agentReadinessAuditCommand,
70
70
  appendActivityEvent: () => appendActivityEvent,
71
71
  applyLocalContextMutationPlan: () => applyLocalContextMutationPlan,
72
+ applyManagedWorkflowPolicyAutoResponses: () => applyManagedWorkflowPolicyAutoResponses,
72
73
  archiveInactiveTeamSyncWork: () => archiveInactiveTeamSyncWork,
73
74
  attachLocalContextPackReceipts: () => attachLocalContextPackReceipts,
74
75
  autoArchiveTeamSyncState: () => autoArchiveTeamSyncState,
@@ -166,6 +167,7 @@ __export(index_exports, {
166
167
  createEmptyTeamSyncState: () => createEmptyTeamSyncState,
167
168
  createLocalQueryCache: () => createLocalQueryCache,
168
169
  deriveLocalCollaborationResourcesFromFiles: () => deriveLocalCollaborationResourcesFromFiles,
170
+ deriveManagedWorkflowJudgmentResolution: () => deriveManagedWorkflowJudgmentResolution,
169
171
  detectReleaseSurfacesFromFiles: () => detectReleaseSurfacesFromFiles,
170
172
  detectRuntimeEnvironment: () => detectRuntimeEnvironment,
171
173
  evalExportCommand: () => evalExportCommand,
@@ -28461,13 +28463,32 @@ function normalizeManagedWorkflowState(state) {
28461
28463
  if (state.schemaVersion !== "snipara.workflow.v1" && state.schemaVersion !== "snipara.workflow.v2") {
28462
28464
  throw new Error(`${WORKFLOW_STATE_RELATIVE_PATH} is not a valid Snipara workflow state file`);
28463
28465
  }
28466
+ const judgment = state.judgment ? {
28467
+ ...state.judgment,
28468
+ responses: (Array.isArray(state.judgment.responses) ? state.judgment.responses : []).map(
28469
+ (response) => ({
28470
+ ...response,
28471
+ source: response.source === "policy_auto" ? "policy_auto" : "explicit",
28472
+ reasonCodes: uniqueStringList(response.reasonCodes) ?? (response.source === "policy_auto" ? ["low_risk_advisory_auto_accepted"] : ["explicit_agent_response"])
28473
+ })
28474
+ ),
28475
+ responseHistory: (Array.isArray(state.judgment.responseHistory) ? state.judgment.responseHistory : []).map((response) => ({
28476
+ ...response,
28477
+ source: response.source === "policy_auto" ? "policy_auto" : "explicit",
28478
+ reasonCodes: uniqueStringList(response.reasonCodes) ?? (response.source === "policy_auto" ? ["low_risk_advisory_auto_accepted"] : ["explicit_agent_response"])
28479
+ }))
28480
+ } : void 0;
28481
+ if (judgment) {
28482
+ applyManagedWorkflowPolicyAutoResponses(judgment, judgment.generatedAt);
28483
+ judgment.resolution ??= deriveManagedWorkflowJudgmentResolution(judgment, {
28484
+ evaluatedAt: judgment.generatedAt
28485
+ });
28486
+ }
28464
28487
  return {
28465
28488
  ...state,
28466
28489
  runtime: normalizeManagedWorkflowRuntimeState(state.runtime),
28467
- judgment: state.judgment ? {
28468
- ...state.judgment,
28469
- responses: Array.isArray(state.judgment.responses) ? state.judgment.responses : []
28470
- } : void 0,
28490
+ judgment,
28491
+ judgmentHistory: Array.isArray(state.judgmentHistory) ? state.judgmentHistory : [],
28471
28492
  phaseCommitReceipts: Array.isArray(state.phaseCommitReceipts) ? state.phaseCommitReceipts : []
28472
28493
  };
28473
28494
  }
@@ -30145,14 +30166,19 @@ function printManagedWorkflowState(state) {
30145
30166
  }
30146
30167
  }
30147
30168
  if (state.judgment) {
30169
+ const resolution = state.judgment.resolution ?? deriveManagedWorkflowJudgmentResolution(state.judgment);
30148
30170
  printKeyValue2(
30149
30171
  "Judgment:",
30150
- `${state.judgment.card.state} (${state.judgment.responses.length}/${state.judgment.card.advisorRecommendations.length} response(s))`
30172
+ `${resolution.state} (original ${state.judgment.card.state}; ${state.judgment.responses.length}/${state.judgment.card.advisorRecommendations.length} response(s))`
30151
30173
  );
30174
+ printKeyValue2("Judgment authority:", resolution.canProceed);
30152
30175
  printKeyValue2(
30153
30176
  "Judgment identity:",
30154
30177
  state.judgment.brief.servedJudgmentId ? "linked" : "missing"
30155
30178
  );
30179
+ if ((state.judgmentHistory ?? []).length > 0) {
30180
+ printKeyValue2("Prior judgment cards:", String(state.judgmentHistory?.length ?? 0));
30181
+ }
30156
30182
  }
30157
30183
  console.log("");
30158
30184
  console.log(import_chalk9.default.bold("Phases"));
@@ -30172,7 +30198,20 @@ function printManagedWorkflowJudgmentNextCommands(state) {
30172
30198
  const judgment = state.judgment;
30173
30199
  if (!judgment) return;
30174
30200
  console.log("");
30175
- console.log(import_chalk9.default.bold("Explicit advisor responses"));
30201
+ const resolution = judgment.resolution ?? deriveManagedWorkflowJudgmentResolution(judgment);
30202
+ console.log(import_chalk9.default.bold("Effective judgment resolution"));
30203
+ printKeyValue2("State:", resolution.state);
30204
+ printKeyValue2("Can proceed:", resolution.canProceed);
30205
+ printKeyValue2("Original card:", `${resolution.originalCard.state}/${resolution.originalCard.canProceed}`);
30206
+ printKeyValue2("Reason codes:", resolution.reasonCodes.join(", "));
30207
+ if (resolution.evidence.unsatisfiedRequiredActions.length > 0) {
30208
+ printKeyValue2(
30209
+ "Unsatisfied actions:",
30210
+ resolution.evidence.unsatisfiedRequiredActions.join(" | ")
30211
+ );
30212
+ }
30213
+ console.log("");
30214
+ console.log(import_chalk9.default.bold("Advisor responses"));
30176
30215
  if (!judgment.brief.servedJudgmentId) {
30177
30216
  console.log(
30178
30217
  "No served judgment identity was returned. The card is inspectable, but hosted influence receipts cannot be linked yet."
@@ -30186,7 +30225,7 @@ function printManagedWorkflowJudgmentNextCommands(state) {
30186
30225
  for (const recommendation of judgment.card.advisorRecommendations) {
30187
30226
  const response = judgment.responses.find((item) => item.recommendationId === recommendation.id);
30188
30227
  console.log(
30189
- `- ${recommendation.id}: ${response ? `${response.decision} (${response.initialReceipt?.status ?? "local"})` : "pending explicit response"}`
30228
+ `- ${recommendation.id}: ${response ? `${response.decision} [${response.source}] (${response.initialReceipt?.status ?? "local"})` : "pending explicit response"}`
30190
30229
  );
30191
30230
  if (!response) {
30192
30231
  console.log(
@@ -30195,7 +30234,7 @@ function printManagedWorkflowJudgmentNextCommands(state) {
30195
30234
  }
30196
30235
  }
30197
30236
  console.log(
30198
- "Use --decision modified with distinct --plan-before/--plan-after snapshots when the judgment changed the plan; use ignored or blocked explicitly when applicable."
30237
+ "Info/watch recommendations are accepted locally by policy. Risk/block recommendations still require an explicit response. Use --decision modified with distinct --plan-before/--plan-after snapshots when the judgment changed the plan."
30199
30238
  );
30200
30239
  console.log("");
30201
30240
  }
@@ -34036,7 +34075,9 @@ function workflowOutcomeEvidence(values) {
34036
34075
  const detail = (matched?.[2] ?? text).trim();
34037
34076
  const status = rawStatus === "passed" || rawStatus === "pass" || rawStatus === "ok" || rawStatus === "success" ? "passed" : rawStatus === "failed" || rawStatus === "fail" || rawStatus === "error" ? "failed" : "skipped";
34038
34077
  const normalizedDetail = detail.toLowerCase();
34039
- const source2 = normalizedDetail.includes("typecheck") ? "typecheck" : normalizedDetail.includes("lint") ? "lint" : normalizedDetail.includes("build") ? "build" : normalizedDetail.includes("deploy") || normalizedDetail.includes("health") ? "deploy_health" : normalizedDetail.includes("publish") || normalizedDetail.includes("npm") ? "package_publish" : normalizedDetail.includes("guard") ? "guard" : normalizedDetail.includes("test") || normalizedDetail.includes("smoke") ? "test" : "manual";
34078
+ const source2 = /\b(type[-_ ]?check|tsc)\b/.test(
34079
+ normalizedDetail
34080
+ ) ? "typecheck" : /\b(lint|eslint|ruff|black)\b/.test(normalizedDetail) ? "lint" : /\b(build|compile)\b/.test(normalizedDetail) ? "build" : /\b(deploy|health)\b/.test(normalizedDetail) ? "deploy_health" : /\b(npm|package|publish|pack(?::|\b))\b/.test(normalizedDetail) ? "package_publish" : /\bguard\b/.test(normalizedDetail) ? "guard" : /\b(test|vitest|jest|pytest|smoke)\b/.test(normalizedDetail) ? "test" : "manual";
34040
34081
  return [
34041
34082
  {
34042
34083
  source: source2,
@@ -34047,6 +34088,242 @@ function workflowOutcomeEvidence(values) {
34047
34088
  ];
34048
34089
  });
34049
34090
  }
34091
+ var MANAGED_WORKFLOW_JUDGMENT_AUTONOMY_VERSION = "snipara.workflow.judgment-autonomy.v1";
34092
+ function isPolicyAutoEligibleRecommendation(recommendation) {
34093
+ return recommendation.severity === "info" || recommendation.severity === "watch";
34094
+ }
34095
+ function applyManagedWorkflowPolicyAutoResponses(judgment, respondedAt = (/* @__PURE__ */ new Date()).toISOString()) {
34096
+ const created = [];
34097
+ for (const recommendation of judgment.card.advisorRecommendations) {
34098
+ if (!isPolicyAutoEligibleRecommendation(recommendation) || judgment.responses.some((response) => response.recommendationId === recommendation.id)) {
34099
+ continue;
34100
+ }
34101
+ created.push({
34102
+ recommendationId: recommendation.id,
34103
+ decision: "accepted",
34104
+ respondedAt,
34105
+ source: "policy_auto",
34106
+ policyVersion: MANAGED_WORKFLOW_JUDGMENT_AUTONOMY_VERSION,
34107
+ reasonCodes: [
34108
+ "low_risk_advisory_auto_accepted",
34109
+ `advisor_severity_${recommendation.severity}`,
34110
+ "no_plan_mutation"
34111
+ ]
34112
+ });
34113
+ }
34114
+ if (created.length > 0) {
34115
+ judgment.responses = [...judgment.responses, ...created];
34116
+ }
34117
+ return created;
34118
+ }
34119
+ function judgmentResponseEvidence(judgment) {
34120
+ const receipts = [...judgment.responseHistory ?? [], ...judgment.responses].flatMap((response) => response.outcomeReceipts ?? []).sort((left, right) => left.generatedAt.localeCompare(right.generatedAt));
34121
+ return receipts.flatMap((receipt) => receipt.verification.evidence);
34122
+ }
34123
+ function effectiveJudgmentEvidence(judgment, currentEvidence) {
34124
+ const latestBySemanticKey = /* @__PURE__ */ new Map();
34125
+ for (const evidence of [...judgmentResponseEvidence(judgment), ...currentEvidence]) {
34126
+ const label = (evidence.command ?? evidence.label).toLowerCase().replace(/\s+/g, " ").trim();
34127
+ latestBySemanticKey.set(`${evidence.source}:${label}`, evidence);
34128
+ }
34129
+ return [...latestBySemanticKey.values()];
34130
+ }
34131
+ function completedJudgmentOutcomeRecorded(judgment) {
34132
+ return [...judgment.responseHistory ?? [], ...judgment.responses].some(
34133
+ (response) => (response.outcomeReceipts ?? []).some((receipt) => receipt.outcome.status === "success")
34134
+ );
34135
+ }
34136
+ function judgmentTextTokens(value) {
34137
+ const ignored = /* @__PURE__ */ new Set([
34138
+ "and",
34139
+ "before",
34140
+ "check",
34141
+ "close",
34142
+ "command",
34143
+ "for",
34144
+ "from",
34145
+ "into",
34146
+ "review",
34147
+ "run",
34148
+ "the",
34149
+ "this",
34150
+ "with"
34151
+ ]);
34152
+ return value.toLowerCase().match(/[a-z0-9][a-z0-9_-]{2,}/g)?.filter((token) => !ignored.has(token)) ?? [];
34153
+ }
34154
+ function judgmentEvidenceText(evidence) {
34155
+ return `${evidence.label} ${evidence.command ?? ""} ${evidence.detail ?? ""}`.toLowerCase();
34156
+ }
34157
+ function expectedEvidenceSourceForAction(action) {
34158
+ const text = `${action.title} ${action.command ?? ""}`.toLowerCase();
34159
+ if (/\b(type[-_ ]?check|tsc)\b/.test(text)) return "typecheck";
34160
+ if (/\b(lint|eslint|ruff|black)\b/.test(text)) return "lint";
34161
+ if (/\b(pre-?deploy guard|collaboration guard|guard)\b/.test(text)) return "guard";
34162
+ if (/\b(deploy|production health|health check)\b/.test(text)) return "deploy_health";
34163
+ if (/\b(npm|package|pack(?::|\b)|publish)\b/.test(text)) return "package_publish";
34164
+ if (/\b(test|vitest|jest|pytest|smoke)\b/.test(text)) return "test";
34165
+ if (/\b(build|compile)\b/.test(text)) return "build";
34166
+ return void 0;
34167
+ }
34168
+ function passedEvidenceSatisfiesAction(action, passedEvidence) {
34169
+ if (action.type === "resolve_blocker") return false;
34170
+ if (action.type === "acknowledge") {
34171
+ return passedEvidence.some((evidence) => evidence.source === "guard");
34172
+ }
34173
+ if (action.type === "package_review") {
34174
+ return passedEvidence.some((evidence) => evidence.source === "package_publish");
34175
+ }
34176
+ if (action.type === "deploy_review") {
34177
+ const expected2 = expectedEvidenceSourceForAction(action);
34178
+ return passedEvidence.some((evidence) => evidence.source === (expected2 ?? "deploy_health"));
34179
+ }
34180
+ if (action.type === "handoff") {
34181
+ return passedEvidence.some((evidence) => /\b(team sync|handoff)\b/i.test(judgmentEvidenceText(evidence)));
34182
+ }
34183
+ const actionText = `${action.title} ${action.command ?? ""}`;
34184
+ const expected = expectedEvidenceSourceForAction(action);
34185
+ if (action.type === "run_check" && expected) {
34186
+ return passedEvidence.some((evidence) => evidence.source === expected);
34187
+ }
34188
+ if (/\bcode impact\b/i.test(actionText)) {
34189
+ return passedEvidence.some((evidence) => /\bcode impact\b/i.test(judgmentEvidenceText(evidence)));
34190
+ }
34191
+ if (/\bverification gap\b/i.test(actionText)) {
34192
+ return passedEvidence.some(
34193
+ (evidence) => ["test", "typecheck", "lint", "build", "manual"].includes(evidence.source)
34194
+ );
34195
+ }
34196
+ if (expected) {
34197
+ return passedEvidence.some((evidence) => evidence.source === expected);
34198
+ }
34199
+ const tokens = judgmentTextTokens(actionText);
34200
+ return passedEvidence.some((evidence) => {
34201
+ const evidenceText = judgmentEvidenceText(evidence);
34202
+ return tokens.some((token) => evidenceText.includes(token));
34203
+ });
34204
+ }
34205
+ function unresolvedJudgmentReasonCodes(card, passedEvidence) {
34206
+ const passedText = passedEvidence.map(judgmentEvidenceText).join(" ");
34207
+ return card.reasons.flatMap((reason) => {
34208
+ if (reason.code.startsWith("surface_unavailable_")) return [reason.code];
34209
+ if (reason.code === "memory_health_low") return [reason.code];
34210
+ if (reason.code === "code_impact_degraded" && !/\b(local (read|inspection)|code impact)\b/.test(passedText)) {
34211
+ return [reason.code];
34212
+ }
34213
+ if (reason.code === "code_graph_stale" && !/\b(local (read|inspection)|code impact)\b/.test(passedText)) {
34214
+ return [reason.code];
34215
+ }
34216
+ if (reason.code === "team_sync_proof_required" && !/\b(team sync|handoff)\b/.test(passedText)) {
34217
+ return [reason.code];
34218
+ }
34219
+ return [];
34220
+ });
34221
+ }
34222
+ function deriveManagedWorkflowJudgmentResolution(judgment, options = {}) {
34223
+ const evidence = effectiveJudgmentEvidence(judgment, options.evidence ?? []);
34224
+ const passedEvidence = evidence.filter((item) => item.status === "passed");
34225
+ const failedEvidence = evidence.filter((item) => item.status === "failed");
34226
+ const skippedEvidence = evidence.filter(
34227
+ (item) => item.status === "skipped" || item.status === "warning"
34228
+ );
34229
+ const responsesByRecommendation = new Map(
34230
+ judgment.responses.map((response) => [response.recommendationId, response])
34231
+ );
34232
+ const pendingExplicitRecommendations = judgment.card.advisorRecommendations.filter(
34233
+ (recommendation) => !isPolicyAutoEligibleRecommendation(recommendation) && !responsesByRecommendation.has(recommendation.id)
34234
+ );
34235
+ const ignoredRiskRecommendations = judgment.card.advisorRecommendations.filter((recommendation) => {
34236
+ const response = responsesByRecommendation.get(recommendation.id);
34237
+ return recommendation.severity === "risk" && response?.decision === "ignored";
34238
+ });
34239
+ const ignoredBlockRecommendations = judgment.card.advisorRecommendations.filter(
34240
+ (recommendation) => {
34241
+ const response = responsesByRecommendation.get(recommendation.id);
34242
+ return recommendation.severity === "block" && response?.decision === "ignored";
34243
+ }
34244
+ );
34245
+ const unsatisfiedActions = judgment.card.requiredActions.filter(
34246
+ (action) => !passedEvidenceSatisfiesAction(action, passedEvidence)
34247
+ );
34248
+ const unresolvedSignals = unresolvedJudgmentReasonCodes(judgment.card, passedEvidence);
34249
+ const hardBlockerCodes = uniqueStrings23([
34250
+ ...judgment.card.reasons.filter((reason) => reason.code === "guard_blocked").map((reason) => reason.code),
34251
+ ...judgment.card.requiredActions.filter((action) => action.type === "resolve_blocker").map(() => "required_action_resolve_blocker"),
34252
+ ...judgment.responses.filter((response) => response.decision === "blocked").map(() => "explicit_blocked_decision"),
34253
+ ...pendingExplicitRecommendations.filter((recommendation) => recommendation.severity === "block").map(() => "pending_block_recommendation"),
34254
+ ...ignoredBlockRecommendations.map(() => "ignored_block_recommendation"),
34255
+ ...failedEvidence.length > 0 ? ["failed_verification_evidence"] : []
34256
+ ]);
34257
+ const reasonCodes = ["original_judgment_card_preserved"];
34258
+ const autoResponseCount = judgment.responses.filter(
34259
+ (response) => response.source === "policy_auto"
34260
+ ).length;
34261
+ if (autoResponseCount > 0) reasonCodes.push("low_risk_advisories_auto_accepted");
34262
+ let state;
34263
+ let canProceed;
34264
+ if (hardBlockerCodes.length > 0) {
34265
+ state = "blocked";
34266
+ canProceed = "block";
34267
+ reasonCodes.push(...hardBlockerCodes);
34268
+ } else if (pendingExplicitRecommendations.some((recommendation) => recommendation.severity === "risk") || ignoredRiskRecommendations.length > 0 || unresolvedSignals.length > 0) {
34269
+ state = "review";
34270
+ canProceed = "review";
34271
+ if (pendingExplicitRecommendations.some((item) => item.severity === "risk")) {
34272
+ reasonCodes.push("pending_risk_recommendation");
34273
+ }
34274
+ if (ignoredRiskRecommendations.length > 0) reasonCodes.push("ignored_risk_recommendation");
34275
+ if (unresolvedSignals.length > 0) reasonCodes.push("unresolved_review_signal");
34276
+ } else {
34277
+ const proofRequired = judgment.card.canProceed !== "yes" || judgment.card.requiredActions.length > 0;
34278
+ const completedOutcome = options.outcome === "completed" || completedJudgmentOutcomeRecorded(judgment);
34279
+ if (unsatisfiedActions.length > 0 || proofRequired && (!completedOutcome || passedEvidence.length === 0)) {
34280
+ state = "proof_required";
34281
+ canProceed = "review";
34282
+ if (unsatisfiedActions.length > 0) reasonCodes.push("required_action_unsatisfied");
34283
+ if (!completedOutcome) reasonCodes.push("workflow_outcome_incomplete");
34284
+ if (passedEvidence.length === 0) reasonCodes.push("verification_evidence_missing");
34285
+ } else if (judgment.card.state === "watch" || autoResponseCount > 0) {
34286
+ state = "watch";
34287
+ canProceed = "yes";
34288
+ reasonCodes.push("required_actions_verified");
34289
+ } else {
34290
+ state = "ready";
34291
+ canProceed = "yes";
34292
+ reasonCodes.push("required_actions_verified");
34293
+ }
34294
+ }
34295
+ return {
34296
+ version: "snipara.workflow.judgment-resolution.v1",
34297
+ evaluatedAt: options.evaluatedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
34298
+ state,
34299
+ canProceed,
34300
+ originalCard: {
34301
+ generatedAt: judgment.card.generatedAt,
34302
+ state: judgment.card.state,
34303
+ canProceed: judgment.card.canProceed,
34304
+ score: judgment.card.score
34305
+ },
34306
+ reasonCodes: uniqueStrings23(reasonCodes),
34307
+ hardBlockerCodes,
34308
+ pendingExplicitRecommendationIds: pendingExplicitRecommendations.map((item) => item.id),
34309
+ autoResponseCount,
34310
+ evidence: {
34311
+ passedCount: passedEvidence.length,
34312
+ failedCount: failedEvidence.length,
34313
+ skippedCount: skippedEvidence.length,
34314
+ requiredActionCount: judgment.card.requiredActions.length,
34315
+ satisfiedRequiredActionCount: judgment.card.requiredActions.length - unsatisfiedActions.length,
34316
+ unsatisfiedRequiredActions: unsatisfiedActions.map(
34317
+ (action) => action.command ?? action.title
34318
+ )
34319
+ }
34320
+ };
34321
+ }
34322
+ function updateManagedWorkflowJudgmentResolution(judgment, options = {}) {
34323
+ applyManagedWorkflowPolicyAutoResponses(judgment, options.evaluatedAt);
34324
+ judgment.resolution = deriveManagedWorkflowJudgmentResolution(judgment, options);
34325
+ return judgment.resolution;
34326
+ }
34050
34327
  function workflowOutcomeSurfaces(files) {
34051
34328
  const surfaces = /* @__PURE__ */ new Set(["workflow"]);
34052
34329
  for (const file of files) {
@@ -34097,8 +34374,10 @@ function buildManagedWorkflowOutcomeReceipt(args) {
34097
34374
  });
34098
34375
  }
34099
34376
  async function closeManagedWorkflowJudgment(args) {
34100
- if (!args.state?.judgment || args.state.judgment.responses.length === 0) return [];
34101
- if (args.requireEvidence && workflowOutcomeEvidence(args.evidence).length === 0) return [];
34377
+ if (!args.state?.judgment) return [];
34378
+ const parsedEvidence = workflowOutcomeEvidence(args.evidence);
34379
+ if (args.requireEvidence && parsedEvidence.length === 0) return [];
34380
+ applyManagedWorkflowPolicyAutoResponses(args.state.judgment);
34102
34381
  const captures = [];
34103
34382
  for (const response of args.state.judgment.responses) {
34104
34383
  const outcomeReceipt = buildManagedWorkflowOutcomeReceipt({
@@ -34127,7 +34406,13 @@ async function closeManagedWorkflowJudgment(args) {
34127
34406
  captures.push(capture);
34128
34407
  }
34129
34408
  }
34130
- args.state.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
34409
+ const evaluatedAt = (/* @__PURE__ */ new Date()).toISOString();
34410
+ updateManagedWorkflowJudgmentResolution(args.state.judgment, {
34411
+ evidence: parsedEvidence,
34412
+ outcome: args.outcome,
34413
+ evaluatedAt
34414
+ });
34415
+ args.state.updatedAt = evaluatedAt;
34131
34416
  writeWorkflowState(args.state);
34132
34417
  return captures;
34133
34418
  }
@@ -34243,11 +34528,6 @@ async function workflowJudgmentCommand(options) {
34243
34528
  printManagedWorkflowJudgmentNextCommands(state);
34244
34529
  return;
34245
34530
  }
34246
- if (state.judgment?.responses.length) {
34247
- throw new Error(
34248
- "Cannot refresh a managed judgment after responses were recorded; start a new workflow for a new served judgment."
34249
- );
34250
- }
34251
34531
  const result = await buildProjectIntelligenceRun({
34252
34532
  task: state.goal,
34253
34533
  changedFiles: managedWorkflowJudgmentFiles(state),
@@ -34255,7 +34535,10 @@ async function workflowJudgmentCommand(options) {
34255
34535
  skipGuard: true,
34256
34536
  skipAdvisorReceipts: true
34257
34537
  });
34258
- state.judgment = {
34538
+ if (state.judgment) {
34539
+ state.judgmentHistory = [...state.judgmentHistory ?? [], state.judgment].slice(-5);
34540
+ }
34541
+ const judgment = {
34259
34542
  version: "snipara.workflow.judgment.v1",
34260
34543
  generatedAt: result.generatedAt,
34261
34544
  runEnvelope: result.runEnvelope,
@@ -34263,13 +34546,18 @@ async function workflowJudgmentCommand(options) {
34263
34546
  card: result.judgmentCard,
34264
34547
  responses: []
34265
34548
  };
34549
+ const autoResponses = applyManagedWorkflowPolicyAutoResponses(judgment, result.generatedAt);
34550
+ const resolution = updateManagedWorkflowJudgmentResolution(judgment, {
34551
+ evaluatedAt: result.generatedAt
34552
+ });
34553
+ state.judgment = judgment;
34266
34554
  state.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
34267
34555
  writeWorkflowState(state);
34268
34556
  appendActivityEvent({
34269
34557
  source: "workflow",
34270
34558
  kind: "workflow-judgment",
34271
34559
  title: state.judgment.card.summary,
34272
- summary: `${state.judgment.card.advisorRecommendations.length} advisor recommendation(s) served for explicit response.`,
34560
+ summary: `${autoResponses.length} low-risk recommendation(s) accepted by policy; ${resolution.pendingExplicitRecommendationIds.length} recommendation(s) require explicit authority.`,
34273
34561
  workflowId: state.workflowId,
34274
34562
  files: state.judgment.brief.changedFiles,
34275
34563
  refs: [state.judgment.brief.servedJudgmentId].filter(Boolean),
@@ -34277,7 +34565,11 @@ async function workflowJudgmentCommand(options) {
34277
34565
  metadata: {
34278
34566
  state: state.judgment.card.state,
34279
34567
  canProceed: state.judgment.card.canProceed,
34568
+ effectiveState: resolution.state,
34569
+ effectiveCanProceed: resolution.canProceed,
34280
34570
  recommendationCount: state.judgment.card.advisorRecommendations.length,
34571
+ autoResponseCount: autoResponses.length,
34572
+ pendingExplicitRecommendationCount: resolution.pendingExplicitRecommendationIds.length,
34281
34573
  identityStatus: state.judgment.brief.servedJudgmentId ? "linked" : "missing"
34282
34574
  }
34283
34575
  });
@@ -34311,6 +34603,8 @@ async function workflowJudgmentRespondCommand(options) {
34311
34603
  recommendationId: recommendation.id,
34312
34604
  decision,
34313
34605
  respondedAt: (/* @__PURE__ */ new Date()).toISOString(),
34606
+ source: "explicit",
34607
+ reasonCodes: ["explicit_agent_response"],
34314
34608
  ...planBefore ? { planBefore } : {},
34315
34609
  ...planAfter ? { planAfter } : {}
34316
34610
  };
@@ -34319,23 +34613,35 @@ async function workflowJudgmentRespondCommand(options) {
34319
34613
  response,
34320
34614
  trigger: "snipara-companion workflow judgment-respond"
34321
34615
  });
34616
+ const supersededResponses = judgment.responses.filter(
34617
+ (item) => item.recommendationId === recommendation.id
34618
+ );
34619
+ if (supersededResponses.length > 0) {
34620
+ judgment.responseHistory = [...judgment.responseHistory ?? [], ...supersededResponses];
34621
+ }
34322
34622
  judgment.responses = [
34323
34623
  ...judgment.responses.filter((item) => item.recommendationId !== recommendation.id),
34324
34624
  response
34325
34625
  ];
34626
+ const resolution = updateManagedWorkflowJudgmentResolution(judgment, {
34627
+ evaluatedAt: response.respondedAt
34628
+ });
34326
34629
  state.updatedAt = response.respondedAt;
34327
34630
  writeWorkflowState(state);
34328
34631
  appendActivityEvent({
34329
34632
  source: "workflow",
34330
34633
  kind: "workflow-judgment-response",
34331
34634
  title: recommendation.title,
34332
- summary: `Agent explicitly ${decision} recommendation ${recommendation.id}.`,
34635
+ summary: `Agent explicitly ${decision} recommendation ${recommendation.id}; effective judgment is ${resolution.state}.`,
34333
34636
  workflowId: state.workflowId,
34334
34637
  files: judgment.brief.changedFiles,
34335
34638
  refs: [judgment.brief.servedJudgmentId, recommendation.id].filter(Boolean),
34336
34639
  timestamp: response.respondedAt,
34337
34640
  metadata: {
34338
34641
  decision,
34642
+ responseSource: response.source,
34643
+ effectiveState: resolution.state,
34644
+ effectiveCanProceed: resolution.canProceed,
34339
34645
  receiptStatus: response.initialReceipt?.status ?? "unavailable",
34340
34646
  recordedCount: response.initialReceipt?.recordedCount ?? 0
34341
34647
  }
@@ -34348,6 +34654,8 @@ async function workflowJudgmentRespondCommand(options) {
34348
34654
  console.log(import_chalk9.default.bold("Workflow judgment response"));
34349
34655
  printKeyValue2("Recommendation:", recommendation.id);
34350
34656
  printKeyValue2("Decision:", decision);
34657
+ printKeyValue2("Source:", response.source);
34658
+ printKeyValue2("Effective judgment:", `${resolution.state}/${resolution.canProceed}`);
34351
34659
  printKeyValue2("Receipt:", response.initialReceipt?.status ?? "unavailable");
34352
34660
  if (response.initialReceipt?.reason) {
34353
34661
  printKeyValue2("Reason:", response.initialReceipt.reason);
@@ -35599,22 +35907,27 @@ async function workflowPhaseCommitCommand(options) {
35599
35907
  }
35600
35908
  async function finalCommitCommand(options) {
35601
35909
  const state = readWorkflowState2();
35602
- const pendingJudgmentResponses = state?.judgment?.card.advisorRecommendations.filter(
35603
- (recommendation) => !state.judgment?.responses.some((response) => response.recommendationId === recommendation.id)
35604
- );
35605
- if (pendingJudgmentResponses && pendingJudgmentResponses.length > 0) {
35606
- throw new Error(
35607
- `Managed workflow judgment has ${pendingJudgmentResponses.length} unanswered recommendation(s): ${pendingJudgmentResponses.map((item) => item.id).join(
35608
- ", "
35609
- )}. Record accepted, modified, ignored, or blocked explicitly before final-commit.`
35610
- );
35910
+ const outcome = options.outcome ?? "completed";
35911
+ if (state?.judgment) {
35912
+ const evaluatedAt = (/* @__PURE__ */ new Date()).toISOString();
35913
+ const resolution = updateManagedWorkflowJudgmentResolution(state.judgment, {
35914
+ evidence: workflowOutcomeEvidence(options.evidence),
35915
+ outcome,
35916
+ evaluatedAt
35917
+ });
35918
+ state.updatedAt = evaluatedAt;
35919
+ writeWorkflowState(state);
35920
+ if (outcome === "completed" && resolution.canProceed !== "yes") {
35921
+ throw new Error(
35922
+ `Managed workflow judgment is ${resolution.state}/${resolution.canProceed}. Pending authority: ${resolution.pendingExplicitRecommendationIds.join(", ") || "none"}. Hard blockers: ${resolution.hardBlockerCodes.join(", ") || "none"}. Unsatisfied actions: ${resolution.evidence.unsatisfiedRequiredActions.join(" | ") || "none"}. Respond to risk/block recommendations explicitly, clear hard blockers with a refreshed judgment, and attach passed evidence before final-commit.`
35923
+ );
35924
+ }
35611
35925
  }
35612
35926
  await memoryGuardCheckCommand({
35613
35927
  trigger: "pre-final",
35614
35928
  files: options.files,
35615
35929
  strict: true
35616
35930
  });
35617
- const outcome = options.outcome ?? "completed";
35618
35931
  const category = normalizeFinalCommitCategory(options.category);
35619
35932
  const structuredWhy = structuredTaskCommitWhy(options);
35620
35933
  const result = await commitFinalTaskMemory({
@@ -44669,6 +44982,7 @@ if (require.main === module) {
44669
44982
  agentReadinessAuditCommand,
44670
44983
  appendActivityEvent,
44671
44984
  applyLocalContextMutationPlan,
44985
+ applyManagedWorkflowPolicyAutoResponses,
44672
44986
  archiveInactiveTeamSyncWork,
44673
44987
  attachLocalContextPackReceipts,
44674
44988
  autoArchiveTeamSyncState,
@@ -44766,6 +45080,7 @@ if (require.main === module) {
44766
45080
  createEmptyTeamSyncState,
44767
45081
  createLocalQueryCache,
44768
45082
  deriveLocalCollaborationResourcesFromFiles,
45083
+ deriveManagedWorkflowJudgmentResolution,
44769
45084
  detectReleaseSurfacesFromFiles,
44770
45085
  detectRuntimeEnvironment,
44771
45086
  evalExportCommand,
@@ -1433,7 +1433,9 @@ package-review, and policy-gate diagnostics remain available in compatibility
1433
1433
  metadata, but they do not advance this lifecycle by themselves.
1434
1434
 
1435
1435
  Managed FULL workflows expose the same contract directly. Serve one bounded
1436
- card before editing, then answer every recommendation explicitly:
1436
+ card before editing. Companion auto-accepts only `info` and `watch`
1437
+ recommendations with `source=policy_auto`; answer `risk` and `block`
1438
+ recommendations explicitly:
1437
1439
 
1438
1440
  ```bash
1439
1441
  snipara-companion workflow judgment
@@ -1450,9 +1452,25 @@ non-application decisions and cannot carry plan snapshots. Companion writes a
1450
1452
  targeted Advisor Influence receipt immediately, then idempotently replays that
1451
1453
  same `(served judgment, recommendation)` receipt when `workflow phase-commit`
1452
1454
  has explicit `--evidence` and again at `final-commit`. The backend preserves
1453
- monotone lifecycle progress and owns canonical OutcomeSignal linking. A final
1454
- commit fails closed while any served recommendation is unanswered; there is no
1455
- implicit ignored receipt.
1455
+ monotone lifecycle progress and owns canonical OutcomeSignal linking.
1456
+
1457
+ The stored card stays immutable. Companion appends
1458
+ `snipara.workflow.judgment-resolution.v1`, which reports the original state,
1459
+ effective state, reason codes, pending explicit recommendation ids, hard
1460
+ blockers, and per-action evidence coverage. A completed phase or final outcome
1461
+ can resolve verification-only warnings when passed evidence matches every
1462
+ required action. `run_check` matches its concrete test/typecheck/lint/build
1463
+ source; package and deployment reviews require package or guard/deploy proof;
1464
+ code-impact inspection and Team Sync handoff require matching labeled proof.
1465
+ Generic tests never resolve `resolve_blocker`. Failed evidence, `guard_blocked`,
1466
+ a `resolve_blocker` action, a pending `block` recommendation, or an explicit
1467
+ blocked decision remains non-proceedable. A completed final commit also fails
1468
+ closed while any `risk` or `block` recommendation lacks explicit authority.
1469
+
1470
+ `workflow judgment --refresh` archives the prior card and response history
1471
+ locally before serving a new immutable card. Older Judgment V1 state files are
1472
+ normalized additively: missing response sources are treated as explicit, while
1473
+ eligible low-risk recommendations receive policy responses on load.
1456
1474
 
1457
1475
  `run` can also consume Outcome Intelligence V0 receipts:
1458
1476
 
@@ -1698,7 +1716,7 @@ Use this when the user's LLM has already produced a plan and Snipara should enfo
1698
1716
 
1699
1717
  1. Generate or save a visible plan into a JSON file. `snipara-companion plan --query "<goal>" --write-plan-file ./plan.json` converts hosted `snipara_plan` output into a managed workflow plan; keep a Markdown/Text copy only when you also want a human-facing contract alongside the machine plan. Keep simple Q&A and single-source lookups on targeted `snipara_context_query`; for FULL-mode audits, comparisons, roadmap/implementation planning, release readiness, or package-surface reviews, preserve the axes with `snipara_decompose` and execute independent follow-up questions with `snipara_multi_query` when those tools are exposed.
1700
1718
  2. Run `snipara-companion workflow start --goal "<goal>" --plan-file ./plan.json`.
1701
- 3. Run `snipara-companion workflow judgment`, then answer every served Advisor recommendation with `workflow judgment-respond <recommendation-id> --decision accepted|modified|ignored|blocked`. Use distinct `--plan-before` and `--plan-after` snapshots only for `modified`.
1719
+ 3. Run `snipara-companion workflow judgment`. Companion handles `info`/`watch` recommendations with auditable policy responses; answer every `risk`/`block` recommendation with `workflow judgment-respond <recommendation-id> --decision accepted|modified|ignored|blocked`. Use distinct `--plan-before` and `--plan-after` snapshots only for `modified`.
1702
1720
  4. At each phase/chunk, run `snipara-companion workflow phase-start <phase_id>`, then `snipara-companion workflow run --mode full --query "<phase query>"`. Add `--include-session-context` after compaction, handoff, or another agent's work may matter.
1703
1721
  5. Before risky code changes, routes/services/jobs work, or any "what is missing" conclusion, run `snipara-companion code impact --changed-files <files...> --diff-summary "<change>"`. For an important symbol, run `snipara-companion code symbol-card --qualified-name <symbol>`.
1704
1722
  6. After compaction, first run `snipara-companion workflow resume --include-session-context`, then rerun `workflow judgment` to inspect the persisted card and `workflow phase-start <phase_id>` before editing again.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "snipara-companion",
3
- "version": "3.6.8",
3
+ "version": "3.6.9",
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": {