snipara-companion 2.2.0 → 2.3.0

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/README.md CHANGED
@@ -56,6 +56,7 @@ npx -y snipara-companion workflow start --goal "ship auth hardening"
56
56
  npx -y snipara-companion workflow phase-start audit
57
57
  npx -y snipara-companion lead-plan --task "ship auth hardening" --changed-files src/auth/session.ts --proof "pnpm test auth" --acceptance "auth tests pass"
58
58
  npx -y snipara-companion lead-plan --from-plan ./project-health-lead-plan.json --reconcile --changed-files src/auth/session.ts
59
+ npx -y snipara-companion lead-plan --from-plan ./project-health-lead-plan.json --json | jq '.engineeringLeadPlan.executionReceipts'
59
60
  npx -y snipara-companion workflow phase-commit audit --summary "mapped auth impact"
60
61
  npx -y snipara-companion handoff --summary "auth impact mapped" --next "run auth tests"
61
62
  ```
package/dist/index.d.ts CHANGED
@@ -2159,6 +2159,8 @@ declare const ENGINEERING_LEAD_WORKER_ROLES: readonly ["main_agent", "coding_wor
2159
2159
  declare const ENGINEERING_LEAD_ROUTING_MODES: readonly ["hold", "main_agent_execute", "explicit_handoff_ready", "needs_contract"];
2160
2160
  declare const ENGINEERING_LEAD_WORK_PACKAGE_STATUSES: readonly ["contracting", "ready_for_handoff", "executing", "verifying", "blocked", "closed", "unknown"];
2161
2161
  declare const ENGINEERING_LEAD_SUPERVISION_STATUSES: readonly ["on_track", "needs_review", "needs_replan", "blocked", "cold_start", "unknown"];
2162
+ declare const ENGINEERING_LEAD_EXECUTION_RECEIPT_STATUSES: readonly ["pending_handoff", "handoff_ready", "executing", "verification_required", "blocked", "closed", "unknown"];
2163
+ declare const ENGINEERING_LEAD_EXECUTION_RECEIPT_STAGES: readonly ["handoff", "claim", "approval", "proof", "outcome", "brain_update"];
2162
2164
  type EngineeringLeadPlanSummary = ProjectIntelligenceEngineeringLeadPlanSummary;
2163
2165
  interface CompanionEngineeringLeadReconciliation {
2164
2166
  status: "on_track" | "needs_review" | "needs_replan" | "blocked";
@@ -3519,4 +3521,4 @@ declare function buildOrchestratorHandoff(options: OrchestratorHandoffOptions):
3519
3521
  declare function buildAdaptiveWorkRoutingRecommendation(options: AdaptiveWorkRoutingOptions): AdaptiveWorkRoutingRecommendation;
3520
3522
  declare function writeOrchestratorHandoff(options: OrchestratorHandoffOptions): WrittenOrchestratorHandoff;
3521
3523
 
3522
- export { AUTOMATION_MANIFEST_RELATIVE_PATH, AutomationInstallConflictError, AutomationUnsupportedHookBundleError, COLLABORATION_STATE_RELATIVE_PATH, ENGINEERING_LEAD_POSTURES, ENGINEERING_LEAD_ROUTING_MODES, ENGINEERING_LEAD_STATUSES, ENGINEERING_LEAD_SUPERVISION_STATUSES, ENGINEERING_LEAD_WORKER_ROLES, ENGINEERING_LEAD_WORK_PACKAGE_STATUSES, ORCHESTRATOR_HANDOFF_RELATIVE_PATH, TEAM_SYNC_STATE_RELATIVE_PATH, WORKFLOW_PLANS_RELATIVE_DIR, WORKFLOW_STATE_RELATIVE_PATH, agentReadinessAuditCommand, archiveInactiveTeamSyncWork, attachLocalContextPackReceipts, autoArchiveTeamSyncState, buildAdaptiveWorkRoutingRecommendation, buildAgentReadinessAuditReport, buildAgenticHandoffMarkdown, buildAgenticTimeline, buildAgenticWorkStatus, buildAutomationInstallPlan, buildCanonicalEvent, buildCodeHooksInstallPlan, buildCodePromotionResult, buildCodeStatusResult, buildCodeSyncResult, buildCollaborationActor, buildCollaborationGuardActionCards, buildCollaborationHooksInstallPlan, buildCompanionEngineeringLeadPlanReport, buildContextPackStats, buildEvalCaseArtifact, buildGeneratedWorkflowPlanDocument, buildHostedCodeOverlayUploadPayload, buildHostedGuardPayload, buildJournalCheckpointEntry, buildLocalCallersResult, buildLocalCodeOverlay, buildLocalContextPackReceipt, buildLocalContextPackReceipts, buildLocalImpactResult, buildLocalImportsResult, buildLocalNeighborsResult, buildLocalShortestPathResult, buildMemoryAudit, buildOnboardFolderManifest, buildOrchestratorHandoff, buildProjectIntelligenceBrief, buildProjectIntelligenceRun, buildProjectJudgmentCard, buildSessionBootstrapQuality, buildSyncDocumentsDryRun, buildTeamSyncHandoffRecord, buildTeamSyncStartWorkRecord, buildTeamSyncSummary, buildToolCallPayload, buildToolResultPayload, buildVerificationPlan, buildWorkflowImpactGate, buildWorkflowPhaseCommitSummary, buildWorkflowPlanScaffold, categoryFromGuardTag, classifyToolResult, cleanContextPacks, collaborationIdeStatusCommand, collectAgentReadinessLocalSignals, collectSyncDocuments, collectSyncDocumentsInput, compactHostedGuardResources, completeTeamSyncStateFromEvidence, completeTeamSyncWorkFromEvidence, contextPackCleanCommand, contextPackPackCommand, contextPackRetrieveCommand, contextPackStatsCommand, createClient, createEmptyCollaborationState, createEmptyTeamSyncState, createLocalQueryCache, deriveLocalCollaborationResourcesFromFiles, detectReleaseSurfacesFromFiles, detectRuntimeEnvironment, evalExportCommand, evalRunCommand, evaluateProjectPolicyGates, extractCommandFromToolInput, extractFilesFromToolInput, formatAgentReadinessAuditReport, formatCompanionEngineeringLeadPlanReport, formatOrchestratorRecommendationReason, formatPolicyGateDecision, formatProjectJudgmentCard, formatStuckGuardDecision, getAutomationManifestPath, getAutomationStatus, getCollaborationStatePath, getConfigPath, getContextPackStoragePaths, getLocalCodeOverlayCachePath, getLocalCodePromotionStatePath, getOrchestratorRecommendation, getPlanStepDisplayTitle, getStagedFiles, getStuckGuardInjection, getTeamSyncStatePath, ingestReferences, installAutomationBundle, leadPlanCommand, listProjectsForApiKey, loadAutomationManifest, loadCollaborationState, loadConfig, loadTeamSyncState, memoryAuditCommand, memoryCleanCandidatesCommand, memoryCompactCommand, memoryHealthCommand, memoryLocalCommand, normalizeCollaborationFiles, normalizeGuardTag, normalizeWorkflowPlanInput, packContext, parseCollaborationResources, projectIntelligenceBriefCommand, projectIntelligenceRunCommand, readLocalCodeOverlayCache, readLocalCodePromotionState, referencesIngestCommand, referencesScanCommand, resolveContextPackRecord, resolveFullWorkflowTokenBudget, resolveQueryFromToolInput, retrieveContextPack, runMemoryGuardCheck, saveCollaborationState, saveConfig, saveTeamSyncState, scanReferences, shouldSuggestOrchestratorForWorkflow, shouldSuggestRuntimeForWorkflow, summarizeLocalCodeOverlay, teamSyncSweepCommand, validatePlanResult, verifyCommand, writeLocalCodeOverlayCache, writeLocalCodePromotionState, writeOrchestratorHandoff };
3524
+ export { AUTOMATION_MANIFEST_RELATIVE_PATH, AutomationInstallConflictError, AutomationUnsupportedHookBundleError, COLLABORATION_STATE_RELATIVE_PATH, ENGINEERING_LEAD_EXECUTION_RECEIPT_STAGES, ENGINEERING_LEAD_EXECUTION_RECEIPT_STATUSES, ENGINEERING_LEAD_POSTURES, ENGINEERING_LEAD_ROUTING_MODES, ENGINEERING_LEAD_STATUSES, ENGINEERING_LEAD_SUPERVISION_STATUSES, ENGINEERING_LEAD_WORKER_ROLES, ENGINEERING_LEAD_WORK_PACKAGE_STATUSES, ORCHESTRATOR_HANDOFF_RELATIVE_PATH, TEAM_SYNC_STATE_RELATIVE_PATH, WORKFLOW_PLANS_RELATIVE_DIR, WORKFLOW_STATE_RELATIVE_PATH, agentReadinessAuditCommand, archiveInactiveTeamSyncWork, attachLocalContextPackReceipts, autoArchiveTeamSyncState, buildAdaptiveWorkRoutingRecommendation, buildAgentReadinessAuditReport, buildAgenticHandoffMarkdown, buildAgenticTimeline, buildAgenticWorkStatus, buildAutomationInstallPlan, buildCanonicalEvent, buildCodeHooksInstallPlan, buildCodePromotionResult, buildCodeStatusResult, buildCodeSyncResult, buildCollaborationActor, buildCollaborationGuardActionCards, buildCollaborationHooksInstallPlan, buildCompanionEngineeringLeadPlanReport, buildContextPackStats, buildEvalCaseArtifact, buildGeneratedWorkflowPlanDocument, buildHostedCodeOverlayUploadPayload, buildHostedGuardPayload, buildJournalCheckpointEntry, buildLocalCallersResult, buildLocalCodeOverlay, buildLocalContextPackReceipt, buildLocalContextPackReceipts, buildLocalImpactResult, buildLocalImportsResult, buildLocalNeighborsResult, buildLocalShortestPathResult, buildMemoryAudit, buildOnboardFolderManifest, buildOrchestratorHandoff, buildProjectIntelligenceBrief, buildProjectIntelligenceRun, buildProjectJudgmentCard, buildSessionBootstrapQuality, buildSyncDocumentsDryRun, buildTeamSyncHandoffRecord, buildTeamSyncStartWorkRecord, buildTeamSyncSummary, buildToolCallPayload, buildToolResultPayload, buildVerificationPlan, buildWorkflowImpactGate, buildWorkflowPhaseCommitSummary, buildWorkflowPlanScaffold, categoryFromGuardTag, classifyToolResult, cleanContextPacks, collaborationIdeStatusCommand, collectAgentReadinessLocalSignals, collectSyncDocuments, collectSyncDocumentsInput, compactHostedGuardResources, completeTeamSyncStateFromEvidence, completeTeamSyncWorkFromEvidence, contextPackCleanCommand, contextPackPackCommand, contextPackRetrieveCommand, contextPackStatsCommand, createClient, createEmptyCollaborationState, createEmptyTeamSyncState, createLocalQueryCache, deriveLocalCollaborationResourcesFromFiles, detectReleaseSurfacesFromFiles, detectRuntimeEnvironment, evalExportCommand, evalRunCommand, evaluateProjectPolicyGates, extractCommandFromToolInput, extractFilesFromToolInput, formatAgentReadinessAuditReport, formatCompanionEngineeringLeadPlanReport, formatOrchestratorRecommendationReason, formatPolicyGateDecision, formatProjectJudgmentCard, formatStuckGuardDecision, getAutomationManifestPath, getAutomationStatus, getCollaborationStatePath, getConfigPath, getContextPackStoragePaths, getLocalCodeOverlayCachePath, getLocalCodePromotionStatePath, getOrchestratorRecommendation, getPlanStepDisplayTitle, getStagedFiles, getStuckGuardInjection, getTeamSyncStatePath, ingestReferences, installAutomationBundle, leadPlanCommand, listProjectsForApiKey, loadAutomationManifest, loadCollaborationState, loadConfig, loadTeamSyncState, memoryAuditCommand, memoryCleanCandidatesCommand, memoryCompactCommand, memoryHealthCommand, memoryLocalCommand, normalizeCollaborationFiles, normalizeGuardTag, normalizeWorkflowPlanInput, packContext, parseCollaborationResources, projectIntelligenceBriefCommand, projectIntelligenceRunCommand, readLocalCodeOverlayCache, readLocalCodePromotionState, referencesIngestCommand, referencesScanCommand, resolveContextPackRecord, resolveFullWorkflowTokenBudget, resolveQueryFromToolInput, retrieveContextPack, runMemoryGuardCheck, saveCollaborationState, saveConfig, saveTeamSyncState, scanReferences, shouldSuggestOrchestratorForWorkflow, shouldSuggestRuntimeForWorkflow, summarizeLocalCodeOverlay, teamSyncSweepCommand, validatePlanResult, verifyCommand, writeLocalCodeOverlayCache, writeLocalCodePromotionState, writeOrchestratorHandoff };
package/dist/index.js CHANGED
@@ -35,6 +35,8 @@ __export(index_exports, {
35
35
  AutomationInstallConflictError: () => AutomationInstallConflictError,
36
36
  AutomationUnsupportedHookBundleError: () => AutomationUnsupportedHookBundleError,
37
37
  COLLABORATION_STATE_RELATIVE_PATH: () => COLLABORATION_STATE_RELATIVE_PATH,
38
+ ENGINEERING_LEAD_EXECUTION_RECEIPT_STAGES: () => ENGINEERING_LEAD_EXECUTION_RECEIPT_STAGES,
39
+ ENGINEERING_LEAD_EXECUTION_RECEIPT_STATUSES: () => ENGINEERING_LEAD_EXECUTION_RECEIPT_STATUSES,
38
40
  ENGINEERING_LEAD_POSTURES: () => ENGINEERING_LEAD_POSTURES,
39
41
  ENGINEERING_LEAD_ROUTING_MODES: () => ENGINEERING_LEAD_ROUTING_MODES,
40
42
  ENGINEERING_LEAD_STATUSES: () => ENGINEERING_LEAD_STATUSES,
@@ -10499,6 +10501,23 @@ var PROJECT_INTELLIGENCE_ENGINEERING_LEAD_SUPERVISION_STATUSES = [
10499
10501
  "cold_start",
10500
10502
  "unknown"
10501
10503
  ];
10504
+ var PROJECT_INTELLIGENCE_ENGINEERING_LEAD_EXECUTION_RECEIPT_STATUSES = [
10505
+ "pending_handoff",
10506
+ "handoff_ready",
10507
+ "executing",
10508
+ "verification_required",
10509
+ "blocked",
10510
+ "closed",
10511
+ "unknown"
10512
+ ];
10513
+ var PROJECT_INTELLIGENCE_ENGINEERING_LEAD_EXECUTION_RECEIPT_STAGES = [
10514
+ "handoff",
10515
+ "claim",
10516
+ "approval",
10517
+ "proof",
10518
+ "outcome",
10519
+ "brain_update"
10520
+ ];
10502
10521
 
10503
10522
  // src/commands/lead-plan.ts
10504
10523
  var ENGINEERING_LEAD_STATUSES = PROJECT_HEALTH_COCKPIT_STATUSES;
@@ -10507,6 +10526,8 @@ var ENGINEERING_LEAD_WORKER_ROLES = PROJECT_INTELLIGENCE_ENGINEERING_LEAD_WORKER
10507
10526
  var ENGINEERING_LEAD_ROUTING_MODES = PROJECT_INTELLIGENCE_ENGINEERING_LEAD_ROUTING_MODES;
10508
10527
  var ENGINEERING_LEAD_WORK_PACKAGE_STATUSES = PROJECT_INTELLIGENCE_ENGINEERING_LEAD_WORK_PACKAGE_STATUSES;
10509
10528
  var ENGINEERING_LEAD_SUPERVISION_STATUSES = PROJECT_INTELLIGENCE_ENGINEERING_LEAD_SUPERVISION_STATUSES;
10529
+ var ENGINEERING_LEAD_EXECUTION_RECEIPT_STATUSES = PROJECT_INTELLIGENCE_ENGINEERING_LEAD_EXECUTION_RECEIPT_STATUSES;
10530
+ var ENGINEERING_LEAD_EXECUTION_RECEIPT_STAGES = PROJECT_INTELLIGENCE_ENGINEERING_LEAD_EXECUTION_RECEIPT_STAGES;
10510
10531
  var TARGET_LABELS = {
10511
10532
  codex: "Codex",
10512
10533
  "claude-code": "Claude Code",
@@ -10851,6 +10872,133 @@ function buildLocalSupervision(input) {
10851
10872
  ]
10852
10873
  };
10853
10874
  }
10875
+ function executionReceiptRequiredStagesForRecommendation(recommendation) {
10876
+ const stages = /* @__PURE__ */ new Set(["handoff", "proof", "outcome"]);
10877
+ if (recommendation && recommendation.role !== "main_agent") {
10878
+ stages.add("claim");
10879
+ }
10880
+ if (recommendation?.contract.approvalRequired) {
10881
+ stages.add("approval");
10882
+ }
10883
+ if ((recommendation?.brainUpdateCandidates.length ?? 0) > 0) {
10884
+ stages.add("brain_update");
10885
+ }
10886
+ return ENGINEERING_LEAD_EXECUTION_RECEIPT_STAGES.filter((stage) => stages.has(stage));
10887
+ }
10888
+ function missingRequirementsForExecutionReceipt(input) {
10889
+ const completed = new Set(input.completedStages);
10890
+ const missing = /* @__PURE__ */ new Set();
10891
+ if (!input.workPackage.owner) missing.add("owner");
10892
+ if (input.workPackage.writeScope.length === 0) missing.add("write_scope");
10893
+ if (input.workPackage.acceptanceCriteria.length === 0) missing.add("acceptance_criteria");
10894
+ if (input.workPackage.proofRequired.length === 0) missing.add("proof_gate");
10895
+ if (input.requiredStages.includes("handoff") && !completed.has("handoff")) {
10896
+ missing.add("handoff_receipt");
10897
+ }
10898
+ if (input.requiredStages.includes("claim") && !completed.has("claim")) {
10899
+ missing.add("claim_id");
10900
+ }
10901
+ if (input.requiredStages.includes("approval") && !completed.has("approval")) {
10902
+ missing.add("approval_receipt");
10903
+ }
10904
+ if (input.requiredStages.includes("proof") && !completed.has("proof")) {
10905
+ missing.add("proof_receipt");
10906
+ }
10907
+ if (input.requiredStages.includes("outcome") && !completed.has("outcome")) {
10908
+ missing.add("outcome_receipt");
10909
+ }
10910
+ if (input.brainUpdateCandidates.length > 0 && input.requiredStages.includes("brain_update") && !completed.has("brain_update")) {
10911
+ missing.add("brain_update_receipt");
10912
+ }
10913
+ return Array.from(missing).sort();
10914
+ }
10915
+ function executionReceiptStatusFromWorkPackage(input) {
10916
+ if (input.workPackage.status === "blocked") return "blocked";
10917
+ if (input.workPackage.status === "closed" && input.requiredStages.every((stage) => input.completedStages.includes(stage))) {
10918
+ return "closed";
10919
+ }
10920
+ if (input.workPackage.status === "executing") return "executing";
10921
+ if (input.workPackage.status === "verifying") return "verification_required";
10922
+ if (input.workPackage.status === "ready_for_handoff") return "handoff_ready";
10923
+ if (input.missingRequirements.length > 0) return "pending_handoff";
10924
+ return "handoff_ready";
10925
+ }
10926
+ function executionReceiptNextAction(input) {
10927
+ if (input.status === "blocked") {
10928
+ return "Resolve the blocking receipt or proof issue before delegated execution.";
10929
+ }
10930
+ if (input.missingRequirements.includes("handoff_receipt")) {
10931
+ return "Create or attach the handoff receipt before treating this package as delegated.";
10932
+ }
10933
+ if (input.missingRequirements.includes("approval_receipt")) {
10934
+ return "Capture approval before delegated execution can proceed.";
10935
+ }
10936
+ if (input.missingRequirements.includes("proof_receipt")) {
10937
+ return "Attach proof receipts before closure.";
10938
+ }
10939
+ if (input.missingRequirements.includes("outcome_receipt")) {
10940
+ return "Attach an outcome or closure receipt before Brain promotion.";
10941
+ }
10942
+ if (input.missingRequirements.includes("brain_update_receipt")) {
10943
+ return "Record the reviewed Project Brain update receipt.";
10944
+ }
10945
+ if (input.status === "closed") {
10946
+ return "Keep the closed receipt linked for future routing calibration.";
10947
+ }
10948
+ if (input.status === "executing") {
10949
+ return "Monitor liveness and collect proof, outcome, and Brain-update receipts.";
10950
+ }
10951
+ if (input.status === "verification_required") {
10952
+ return "Verify proof and outcome receipts before closure.";
10953
+ }
10954
+ return "Issue the explicit handoff package and collect the required receipts.";
10955
+ }
10956
+ function buildExpectedExecutionReceipts(input) {
10957
+ const recommendationsByWorkPackageId = new Map(
10958
+ input.workerRecommendations.filter((recommendation) => recommendation.workPackageId).map((recommendation) => [recommendation.workPackageId, recommendation])
10959
+ );
10960
+ return input.workPackages.map((workPackage) => {
10961
+ const recommendation = recommendationsByWorkPackageId.get(workPackage.id);
10962
+ const requiredStages = executionReceiptRequiredStagesForRecommendation(recommendation);
10963
+ const completedStages = [];
10964
+ const brainUpdateCandidates2 = recommendation?.brainUpdateCandidates ?? [];
10965
+ const missingRequirements = missingRequirementsForExecutionReceipt({
10966
+ workPackage,
10967
+ requiredStages,
10968
+ completedStages,
10969
+ brainUpdateCandidates: brainUpdateCandidates2
10970
+ });
10971
+ const status = executionReceiptStatusFromWorkPackage({
10972
+ workPackage,
10973
+ requiredStages,
10974
+ completedStages,
10975
+ missingRequirements
10976
+ });
10977
+ return {
10978
+ id: `engineering-lead-receipt:${workPackage.id}`,
10979
+ workPackageId: workPackage.id,
10980
+ workPackageTitle: workPackage.title,
10981
+ status,
10982
+ requiredStages,
10983
+ completedStages,
10984
+ handoffReceiptId: null,
10985
+ claimId: null,
10986
+ htaskId: null,
10987
+ approvalReceiptId: null,
10988
+ proofReceiptIds: [],
10989
+ outcomeReceiptId: null,
10990
+ brainUpdateReceiptId: null,
10991
+ proofRequired: workPackage.proofRequired,
10992
+ proofExecuted: [],
10993
+ missingRequirements,
10994
+ nextAction: executionReceiptNextAction({ status, missingRequirements }),
10995
+ replanTriggers: workPackage.replanTriggers,
10996
+ brainUpdateCandidates: brainUpdateCandidates2,
10997
+ evidence: workPackage.evidence,
10998
+ reasonCodes: [`engineering_lead_execution_receipt_${status}`, ...workPackage.reasonCodes]
10999
+ };
11000
+ });
11001
+ }
10854
11002
  function buildLocalEngineeringLeadPlan(input) {
10855
11003
  const score = computeScore(input);
10856
11004
  const posture = postureForLocalPlan({ ...input, score });
@@ -10919,6 +11067,10 @@ function buildLocalEngineeringLeadPlan(input) {
10919
11067
  workPackages,
10920
11068
  localSignals: input.localSignals
10921
11069
  });
11070
+ const executionReceipts = buildExpectedExecutionReceipts({
11071
+ workPackages,
11072
+ workerRecommendations: [worker]
11073
+ });
10922
11074
  return {
10923
11075
  version: PROJECT_INTELLIGENCE_ENGINEERING_LEAD_PLAN_VERSION,
10924
11076
  contractVersion: PROJECT_INTELLIGENCE_ENGINEERING_LEAD_CONTRACT_VERSION,
@@ -10932,6 +11084,7 @@ function buildLocalEngineeringLeadPlan(input) {
10932
11084
  failClosedFallback: "main_agent",
10933
11085
  workPackages,
10934
11086
  supervision,
11087
+ executionReceipts,
10935
11088
  workerRecommendations: [worker],
10936
11089
  proofGates: input.proofGates,
10937
11090
  brainUpdateActions: brainCandidates,
@@ -11048,6 +11201,93 @@ function normalizeWorkPackage(value, index) {
11048
11201
  reasonCodes
11049
11202
  };
11050
11203
  }
11204
+ function normalizeReceiptStages(field, value) {
11205
+ if (!Array.isArray(value)) {
11206
+ return { stages: [], reasonCodes: [] };
11207
+ }
11208
+ const stages = [];
11209
+ const reasonCodes = /* @__PURE__ */ new Set();
11210
+ for (const item of value) {
11211
+ const stage = cockpitEnumValue(
11212
+ field,
11213
+ ENGINEERING_LEAD_EXECUTION_RECEIPT_STAGES,
11214
+ item,
11215
+ "handoff"
11216
+ );
11217
+ if (stage.droppedReasonCode) {
11218
+ reasonCodes.add(stage.droppedReasonCode);
11219
+ continue;
11220
+ }
11221
+ if (!stages.includes(stage.value)) {
11222
+ stages.push(stage.value);
11223
+ }
11224
+ }
11225
+ return { stages, reasonCodes: Array.from(reasonCodes) };
11226
+ }
11227
+ function normalizeExecutionReceipt(value, index, workPackages, workerRecommendations) {
11228
+ const workPackageId = stringValue3(value.workPackageId) ?? workPackages[index]?.id ?? `work-package:${index + 1}`;
11229
+ const workPackage = workPackages.find((candidate) => candidate.id === workPackageId);
11230
+ const recommendation = workerRecommendations.find(
11231
+ (candidate) => candidate.workPackageId === workPackageId
11232
+ );
11233
+ const fallbackRequiredStages = executionReceiptRequiredStagesForRecommendation(recommendation);
11234
+ const requiredStages = normalizeReceiptStages("execution_receipt_stage", value.requiredStages);
11235
+ const completedStages = normalizeReceiptStages("execution_receipt_stage", value.completedStages);
11236
+ const normalizedRequiredStages = requiredStages.stages.length > 0 ? requiredStages.stages : fallbackRequiredStages;
11237
+ const normalizedCompletedStages = completedStages.stages.filter(
11238
+ (stage) => normalizedRequiredStages.includes(stage)
11239
+ );
11240
+ const brainUpdateCandidates2 = stringList(value.brainUpdateCandidates).length > 0 ? stringList(value.brainUpdateCandidates) : recommendation?.brainUpdateCandidates ?? [];
11241
+ const derivedMissing = workPackage && missingRequirementsForExecutionReceipt({
11242
+ workPackage,
11243
+ requiredStages: normalizedRequiredStages,
11244
+ completedStages: normalizedCompletedStages,
11245
+ brainUpdateCandidates: brainUpdateCandidates2
11246
+ });
11247
+ const missingRequirements = stringList(value.missingRequirements).length > 0 ? stringList(value.missingRequirements) : derivedMissing ?? [];
11248
+ const fallbackStatus = workPackage ? executionReceiptStatusFromWorkPackage({
11249
+ workPackage,
11250
+ requiredStages: normalizedRequiredStages,
11251
+ completedStages: normalizedCompletedStages,
11252
+ missingRequirements
11253
+ }) : "pending_handoff";
11254
+ const status = cockpitEnumValue(
11255
+ "execution_receipt_status",
11256
+ ENGINEERING_LEAD_EXECUTION_RECEIPT_STATUSES,
11257
+ value.status,
11258
+ fallbackStatus
11259
+ );
11260
+ return {
11261
+ id: stringValue3(value.id) ?? `engineering-lead-receipt:${workPackageId}`,
11262
+ workPackageId,
11263
+ workPackageTitle: stringValue3(value.workPackageTitle) ?? workPackage?.title ?? `Imported work package ${index + 1}`,
11264
+ status: status.value,
11265
+ requiredStages: normalizedRequiredStages,
11266
+ completedStages: normalizedCompletedStages,
11267
+ handoffReceiptId: stringValue3(value.handoffReceiptId) ?? null,
11268
+ claimId: stringValue3(value.claimId) ?? null,
11269
+ htaskId: stringValue3(value.htaskId) ?? null,
11270
+ approvalReceiptId: stringValue3(value.approvalReceiptId) ?? null,
11271
+ proofReceiptIds: stringList(value.proofReceiptIds),
11272
+ outcomeReceiptId: stringValue3(value.outcomeReceiptId) ?? null,
11273
+ brainUpdateReceiptId: stringValue3(value.brainUpdateReceiptId) ?? null,
11274
+ proofRequired: stringList(value.proofRequired).length > 0 ? stringList(value.proofRequired) : workPackage?.proofRequired ?? [],
11275
+ proofExecuted: stringList(value.proofExecuted),
11276
+ missingRequirements,
11277
+ nextAction: stringValue3(value.nextAction) ?? executionReceiptNextAction({ status: status.value, missingRequirements }),
11278
+ replanTriggers: stringList(value.replanTriggers).length > 0 ? stringList(value.replanTriggers) : workPackage?.replanTriggers ?? [],
11279
+ brainUpdateCandidates: brainUpdateCandidates2,
11280
+ evidence: normalizeEvidence(value.evidence).length > 0 ? normalizeEvidence(value.evidence) : workPackage?.evidence ?? [],
11281
+ reasonCodes: [
11282
+ .../* @__PURE__ */ new Set([
11283
+ ...stringList(value.reasonCodes),
11284
+ ...compactReasonCodes([status.droppedReasonCode]),
11285
+ ...requiredStages.reasonCodes,
11286
+ ...completedStages.reasonCodes
11287
+ ])
11288
+ ]
11289
+ };
11290
+ }
11051
11291
  function summarizeSupervisionFromWorkPackages(workPackages) {
11052
11292
  const blockedWorkPackages = workPackages.filter(
11053
11293
  (workPackage) => workPackage.status === "blocked"
@@ -11150,6 +11390,10 @@ function normalizeCockpitPlan(cockpit) {
11150
11390
  );
11151
11391
  const workPackages = recordList2(rawPlan.workPackages).map(normalizeWorkPackage);
11152
11392
  const supervision = normalizeSupervision(rawPlan.supervision, workPackages);
11393
+ const rawExecutionReceipts = recordList2(rawPlan.executionReceipts);
11394
+ const executionReceipts = rawExecutionReceipts.length > 0 ? rawExecutionReceipts.map(
11395
+ (receipt, index) => normalizeExecutionReceipt(receipt, index, workPackages, workerRecommendations)
11396
+ ) : buildExpectedExecutionReceipts({ workPackages, workerRecommendations });
11153
11397
  const posture = cockpitEnumValue(
11154
11398
  "posture",
11155
11399
  ENGINEERING_LEAD_POSTURES,
@@ -11171,6 +11415,9 @@ function normalizeCockpitPlan(cockpit) {
11171
11415
  const supervisionDroppedReasonCodes = supervision.reasonCodes.filter(
11172
11416
  (code2) => code2.startsWith("companion_dropped_unknown_")
11173
11417
  );
11418
+ const executionReceiptDroppedReasonCodes = executionReceipts.flatMap(
11419
+ (receipt) => receipt.reasonCodes.filter((code2) => code2.startsWith("companion_dropped_unknown_"))
11420
+ );
11174
11421
  return {
11175
11422
  version: PROJECT_INTELLIGENCE_ENGINEERING_LEAD_PLAN_VERSION,
11176
11423
  contractVersion: PROJECT_INTELLIGENCE_ENGINEERING_LEAD_CONTRACT_VERSION,
@@ -11184,6 +11431,7 @@ function normalizeCockpitPlan(cockpit) {
11184
11431
  failClosedFallback: "main_agent",
11185
11432
  workPackages,
11186
11433
  supervision,
11434
+ executionReceipts,
11187
11435
  workerRecommendations,
11188
11436
  proofGates: stringList(rawPlan.proofGates),
11189
11437
  brainUpdateActions: stringList(rawPlan.brainUpdateActions),
@@ -11206,7 +11454,8 @@ function normalizeCockpitPlan(cockpit) {
11206
11454
  ...stringList(rawPlan.reasonCodes),
11207
11455
  ...workerDroppedReasonCodes,
11208
11456
  ...workPackageDroppedReasonCodes,
11209
- ...supervisionDroppedReasonCodes
11457
+ ...supervisionDroppedReasonCodes,
11458
+ ...executionReceiptDroppedReasonCodes
11210
11459
  ])
11211
11460
  ]
11212
11461
  };
@@ -11223,6 +11472,7 @@ function reconcileEngineeringLeadPlan(input) {
11223
11472
  const reasonCodes = /* @__PURE__ */ new Set(["companion_lead_plan_reconciled"]);
11224
11473
  const plannedScope = scopeSetForPlan(input.plan);
11225
11474
  const outOfScopeFiles = input.changedFiles.filter((file) => !plannedScope.has(file));
11475
+ const executionReceipts = input.plan.executionReceipts ?? [];
11226
11476
  if (input.plan.workPackages.length === 0) {
11227
11477
  changedSignals.add("no_imported_work_packages");
11228
11478
  recommendedActions.add("Create or import bounded work packages before delegation.");
@@ -11270,9 +11520,25 @@ function reconcileEngineeringLeadPlan(input) {
11270
11520
  for (const trigger of input.plan.supervision.replanTriggers) {
11271
11521
  recommendedActions.add(trigger);
11272
11522
  }
11273
- const blocked = input.plan.supervision.status === "blocked" || input.plan.workPackages.some((workPackage) => workPackage.status === "blocked");
11523
+ for (const receipt of executionReceipts) {
11524
+ if (receipt.status === "blocked") {
11525
+ changedSignals.add(`blocked_execution_receipt:${receipt.workPackageId}`);
11526
+ recommendedActions.add(receipt.nextAction);
11527
+ reasonCodes.add("companion_reconcile_execution_receipt_blocked");
11528
+ }
11529
+ if (receipt.missingRequirements.length > 0) {
11530
+ changedSignals.add(
11531
+ `execution_receipt_missing:${receipt.workPackageId}:${receipt.missingRequirements.join(",")}`
11532
+ );
11533
+ recommendedActions.add(
11534
+ `Attach missing execution receipt requirement(s) for ${receipt.workPackageTitle}: ${receipt.missingRequirements.join(", ")}.`
11535
+ );
11536
+ reasonCodes.add("companion_reconcile_execution_receipt_missing_requirements");
11537
+ }
11538
+ }
11539
+ const blocked = input.plan.supervision.status === "blocked" || input.plan.workPackages.some((workPackage) => workPackage.status === "blocked") || executionReceipts.some((receipt) => receipt.status === "blocked");
11274
11540
  const replanRequired = blocked || input.plan.supervision.replanRequired || outOfScopeFiles.length > 0 || !input.localSignals.workflow.present || input.localSignals.workflow.status !== "active";
11275
- const reviewRequired = replanRequired || input.plan.supervision.reviewRequired || !input.localSignals.teamSync.present || input.declaredRisks.length > 0;
11541
+ const reviewRequired = replanRequired || input.plan.supervision.reviewRequired || executionReceipts.some((receipt) => receipt.missingRequirements.length > 0) || !input.localSignals.teamSync.present || input.declaredRisks.length > 0;
11276
11542
  const status = blocked ? "blocked" : replanRequired ? "needs_replan" : reviewRequired ? "needs_review" : "on_track";
11277
11543
  return {
11278
11544
  status,
@@ -11390,6 +11656,7 @@ function formatList2(values, empty = "none") {
11390
11656
  }
11391
11657
  function formatCompanionEngineeringLeadPlanReport(report) {
11392
11658
  const plan = report.engineeringLeadPlan;
11659
+ const executionReceipts = plan.executionReceipts ?? [];
11393
11660
  const lines = [];
11394
11661
  lines.push("Companion Engineering Lead Plan");
11395
11662
  lines.push(`Generated: ${report.generatedAt}`);
@@ -11437,6 +11704,25 @@ function formatCompanionEngineeringLeadPlanReport(report) {
11437
11704
  }
11438
11705
  }
11439
11706
  lines.push("");
11707
+ lines.push("Execution Receipts");
11708
+ if (executionReceipts.length === 0) {
11709
+ lines.push("- none");
11710
+ } else {
11711
+ for (const receipt of executionReceipts) {
11712
+ lines.push(`- [${receipt.status}] ${receipt.workPackageTitle}`);
11713
+ lines.push(` package: ${receipt.workPackageId}`);
11714
+ lines.push(` required stages: ${formatList2(receipt.requiredStages)}`);
11715
+ lines.push(` completed stages: ${formatList2(receipt.completedStages)}`);
11716
+ lines.push(` handoff receipt: ${receipt.handoffReceiptId ?? "missing"}`);
11717
+ lines.push(` claim: ${receipt.claimId ?? "missing"}`);
11718
+ lines.push(` approval receipt: ${receipt.approvalReceiptId ?? "missing"}`);
11719
+ lines.push(` outcome receipt: ${receipt.outcomeReceiptId ?? "missing"}`);
11720
+ lines.push(` brain update receipt: ${receipt.brainUpdateReceiptId ?? "missing"}`);
11721
+ lines.push(` missing: ${formatList2(receipt.missingRequirements)}`);
11722
+ lines.push(` next: ${receipt.nextAction}`);
11723
+ }
11724
+ }
11725
+ lines.push("");
11440
11726
  lines.push("Worker Recommendations");
11441
11727
  for (const worker of plan.workerRecommendations) {
11442
11728
  lines.push(`- [${worker.status}] ${worker.label} (${worker.role}, ${worker.routingMode})`);
@@ -25326,6 +25612,8 @@ if (require.main === module) {
25326
25612
  AutomationInstallConflictError,
25327
25613
  AutomationUnsupportedHookBundleError,
25328
25614
  COLLABORATION_STATE_RELATIVE_PATH,
25615
+ ENGINEERING_LEAD_EXECUTION_RECEIPT_STAGES,
25616
+ ENGINEERING_LEAD_EXECUTION_RECEIPT_STATUSES,
25329
25617
  ENGINEERING_LEAD_POSTURES,
25330
25618
  ENGINEERING_LEAD_ROUTING_MODES,
25331
25619
  ENGINEERING_LEAD_STATUSES,
@@ -313,6 +313,12 @@ Health: posture, score, routing mode, bounded worker contract, supervised work
313
313
  packages, supervision/replan status, proof gates, candidate Project Brain
314
314
  updates, `workersSpawned: 0`, and `main_agent` fallback.
315
315
 
316
+ Engineering Lead Execution Receipts V1 adds `executionReceipts` to that plan.
317
+ Each receipt records the expected handoff, claim, approval, proof, outcome, and
318
+ Project Brain update stages for a work package, plus missing requirements and
319
+ next actions. Unknown future receipt enum values fail closed with
320
+ `companion_dropped_unknown_execution_receipt_*` reason codes.
321
+
316
322
  Use `--from-cockpit <file>` or `--from-plan <file>` when Project Health has
317
323
  exported a cockpit/lead-plan JSON artifact and Companion only needs to normalize
318
324
  it into Markdown or JSON for handoff. Add `--reconcile` to compare the imported
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "snipara-companion",
3
- "version": "2.2.0",
3
+ "version": "2.3.0",
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": {