snipara-companion 2.1.0 → 2.2.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
@@ -55,6 +55,7 @@ After the first impact check, keep the work resumable:
55
55
  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
+ npx -y snipara-companion lead-plan --from-plan ./project-health-lead-plan.json --reconcile --changed-files src/auth/session.ts
58
59
  npx -y snipara-companion workflow phase-commit audit --summary "mapped auth impact"
59
60
  npx -y snipara-companion handoff --summary "auth impact mapped" --next "run auth tests"
60
61
  ```
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env node
2
+ import { ProjectIntelligenceEngineeringLeadPlanSummary } from '@snipara/project-intelligence-contracts';
3
+
2
4
  declare function resolveQueryFromToolInput(toolInput?: string, tool?: string): string | null;
3
5
 
4
6
  declare function extractFilesFromToolInput(toolInput?: string): string[];
@@ -2151,63 +2153,20 @@ declare function buildAgentReadinessAuditReport(options?: BuildAgentReadinessAud
2151
2153
  declare function formatAgentReadinessAuditReport(report: AgentReadinessAuditReport): string;
2152
2154
  declare function agentReadinessAuditCommand(options: AgentReadinessAuditCommandOptions): Promise<void>;
2153
2155
 
2154
- type EngineeringLeadPosture = "lead_ready" | "lead_watch" | "lead_blocked" | "lead_cold_start";
2155
- type EngineeringLeadStatus = "healthy" | "watch" | "risk" | "unknown";
2156
- type EngineeringLeadWorkerRole = "main_agent" | "coding_worker" | "test_worker" | "reviewer" | "documentation_worker" | "human_approver";
2157
- type EngineeringLeadRoutingMode = "hold" | "main_agent_execute" | "explicit_handoff_ready" | "needs_contract";
2158
- interface EngineeringLeadEvidenceRef {
2159
- id: string;
2160
- kind: "memory" | "project_decision" | "shadow_signal" | "context_graph" | "outcome_signal" | "retrieval_event" | "workflow" | "repository" | "manual";
2161
- label: string;
2162
- sourceRef?: string | null;
2163
- strength?: number | null;
2164
- reviewStatus?: string | null;
2165
- authorityStatus?: string | null;
2166
- freshness?: string | null;
2167
- }
2168
- interface EngineeringLeadWorkerContract {
2169
- writeScope: string[];
2170
- contextRefs: EngineeringLeadEvidenceRef[];
2171
- acceptanceCriteria: string[];
2172
- proofRequired: string[];
2173
- approvalRequired: boolean;
2174
- fallback: "main_agent";
2175
- }
2176
- interface EngineeringLeadWorkerRecommendation {
2177
- id: string;
2178
- role: EngineeringLeadWorkerRole;
2179
- label: string;
2180
- status: EngineeringLeadStatus;
2181
- routingMode: EngineeringLeadRoutingMode;
2182
- workPackageId: string | null;
2183
- workPackageTitle: string | null;
2184
- owner: string | null;
2185
- rationale: string;
2186
- contract: EngineeringLeadWorkerContract;
2187
- proofGates: string[];
2188
- brainUpdateCandidates: string[];
2189
- evidence: EngineeringLeadEvidenceRef[];
2190
- reasonCodes: string[];
2191
- }
2192
- interface EngineeringLeadPlanSummary {
2193
- version: "project-intelligence-engineering-lead-plan-v0";
2194
- posture: EngineeringLeadPosture;
2195
- status: EngineeringLeadStatus;
2196
- score: number;
2197
- headline: string;
2198
- operatingMode: "advisory_fail_closed";
2199
- nextAction: string;
2200
- workersSpawned: 0;
2201
- failClosedFallback: "main_agent";
2202
- workerRecommendations: EngineeringLeadWorkerRecommendation[];
2203
- proofGates: string[];
2204
- brainUpdateActions: string[];
2205
- metrics: Array<{
2206
- label: string;
2207
- value: string | number;
2208
- }>;
2209
- evidence: EngineeringLeadEvidenceRef[];
2210
- caveats: string[];
2156
+ declare const ENGINEERING_LEAD_STATUSES: readonly ["healthy", "watch", "risk", "unknown"];
2157
+ declare const ENGINEERING_LEAD_POSTURES: readonly ["lead_ready", "lead_watch", "lead_blocked", "lead_cold_start"];
2158
+ declare const ENGINEERING_LEAD_WORKER_ROLES: readonly ["main_agent", "coding_worker", "test_worker", "reviewer", "documentation_worker", "human_approver"];
2159
+ declare const ENGINEERING_LEAD_ROUTING_MODES: readonly ["hold", "main_agent_execute", "explicit_handoff_ready", "needs_contract"];
2160
+ declare const ENGINEERING_LEAD_WORK_PACKAGE_STATUSES: readonly ["contracting", "ready_for_handoff", "executing", "verifying", "blocked", "closed", "unknown"];
2161
+ declare const ENGINEERING_LEAD_SUPERVISION_STATUSES: readonly ["on_track", "needs_review", "needs_replan", "blocked", "cold_start", "unknown"];
2162
+ type EngineeringLeadPlanSummary = ProjectIntelligenceEngineeringLeadPlanSummary;
2163
+ interface CompanionEngineeringLeadReconciliation {
2164
+ status: "on_track" | "needs_review" | "needs_replan" | "blocked";
2165
+ summary: string;
2166
+ replanRequired: boolean;
2167
+ reviewRequired: boolean;
2168
+ changedSignals: string[];
2169
+ recommendedActions: string[];
2211
2170
  reasonCodes: string[];
2212
2171
  }
2213
2172
  interface CompanionEngineeringLeadPlanReport {
@@ -2228,6 +2187,7 @@ interface CompanionEngineeringLeadPlanReport {
2228
2187
  declaredRisks: string[];
2229
2188
  };
2230
2189
  localSignals: AgentReadinessLocalSignals;
2190
+ reconciliation?: CompanionEngineeringLeadReconciliation;
2231
2191
  suggestedCommands: string[];
2232
2192
  caveats: string[];
2233
2193
  }
@@ -2240,6 +2200,8 @@ interface LeadPlanCommandOptions {
2240
2200
  acceptance?: string[];
2241
2201
  risk?: string[];
2242
2202
  fromCockpit?: string;
2203
+ fromPlan?: string;
2204
+ reconcile?: boolean;
2243
2205
  dir?: string;
2244
2206
  output?: string;
2245
2207
  json?: boolean;
@@ -3557,4 +3519,4 @@ declare function buildOrchestratorHandoff(options: OrchestratorHandoffOptions):
3557
3519
  declare function buildAdaptiveWorkRoutingRecommendation(options: AdaptiveWorkRoutingOptions): AdaptiveWorkRoutingRecommendation;
3558
3520
  declare function writeOrchestratorHandoff(options: OrchestratorHandoffOptions): WrittenOrchestratorHandoff;
3559
3521
 
3560
- export { AUTOMATION_MANIFEST_RELATIVE_PATH, AutomationInstallConflictError, AutomationUnsupportedHookBundleError, COLLABORATION_STATE_RELATIVE_PATH, 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 };
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 };
package/dist/index.js CHANGED
@@ -35,6 +35,12 @@ __export(index_exports, {
35
35
  AutomationInstallConflictError: () => AutomationInstallConflictError,
36
36
  AutomationUnsupportedHookBundleError: () => AutomationUnsupportedHookBundleError,
37
37
  COLLABORATION_STATE_RELATIVE_PATH: () => COLLABORATION_STATE_RELATIVE_PATH,
38
+ ENGINEERING_LEAD_POSTURES: () => ENGINEERING_LEAD_POSTURES,
39
+ ENGINEERING_LEAD_ROUTING_MODES: () => ENGINEERING_LEAD_ROUTING_MODES,
40
+ ENGINEERING_LEAD_STATUSES: () => ENGINEERING_LEAD_STATUSES,
41
+ ENGINEERING_LEAD_SUPERVISION_STATUSES: () => ENGINEERING_LEAD_SUPERVISION_STATUSES,
42
+ ENGINEERING_LEAD_WORKER_ROLES: () => ENGINEERING_LEAD_WORKER_ROLES,
43
+ ENGINEERING_LEAD_WORK_PACKAGE_STATUSES: () => ENGINEERING_LEAD_WORK_PACKAGE_STATUSES,
38
44
  ORCHESTRATOR_HANDOFF_RELATIVE_PATH: () => ORCHESTRATOR_HANDOFF_RELATIVE_PATH,
39
45
  TEAM_SYNC_STATE_RELATIVE_PATH: () => TEAM_SYNC_STATE_RELATIVE_PATH,
40
46
  WORKFLOW_PLANS_RELATIVE_DIR: () => WORKFLOW_PLANS_RELATIVE_DIR,
@@ -10451,6 +10457,56 @@ async function agentReadinessAuditCommand(options) {
10451
10457
  // src/commands/lead-plan.ts
10452
10458
  var fs16 = __toESM(require("fs"));
10453
10459
  var path15 = __toESM(require("path"));
10460
+
10461
+ // ../project-intelligence-contracts/src/index.ts
10462
+ var PROJECT_HEALTH_COCKPIT_STATUSES = ["healthy", "watch", "risk", "unknown"];
10463
+ var PROJECT_INTELLIGENCE_ENGINEERING_LEAD_PLAN_VERSION = "project-intelligence-engineering-lead-plan-v0";
10464
+ var PROJECT_INTELLIGENCE_ENGINEERING_LEAD_CONTRACT_VERSION = "engineering-lead-contract-v1";
10465
+ var PROJECT_INTELLIGENCE_ENGINEERING_LEAD_POSTURES = [
10466
+ "lead_ready",
10467
+ "lead_watch",
10468
+ "lead_blocked",
10469
+ "lead_cold_start"
10470
+ ];
10471
+ var PROJECT_INTELLIGENCE_ENGINEERING_LEAD_WORKER_ROLES = [
10472
+ "main_agent",
10473
+ "coding_worker",
10474
+ "test_worker",
10475
+ "reviewer",
10476
+ "documentation_worker",
10477
+ "human_approver"
10478
+ ];
10479
+ var PROJECT_INTELLIGENCE_ENGINEERING_LEAD_ROUTING_MODES = [
10480
+ "hold",
10481
+ "main_agent_execute",
10482
+ "explicit_handoff_ready",
10483
+ "needs_contract"
10484
+ ];
10485
+ var PROJECT_INTELLIGENCE_ENGINEERING_LEAD_WORK_PACKAGE_STATUSES = [
10486
+ "contracting",
10487
+ "ready_for_handoff",
10488
+ "executing",
10489
+ "verifying",
10490
+ "blocked",
10491
+ "closed",
10492
+ "unknown"
10493
+ ];
10494
+ var PROJECT_INTELLIGENCE_ENGINEERING_LEAD_SUPERVISION_STATUSES = [
10495
+ "on_track",
10496
+ "needs_review",
10497
+ "needs_replan",
10498
+ "blocked",
10499
+ "cold_start",
10500
+ "unknown"
10501
+ ];
10502
+
10503
+ // src/commands/lead-plan.ts
10504
+ var ENGINEERING_LEAD_STATUSES = PROJECT_HEALTH_COCKPIT_STATUSES;
10505
+ var ENGINEERING_LEAD_POSTURES = PROJECT_INTELLIGENCE_ENGINEERING_LEAD_POSTURES;
10506
+ var ENGINEERING_LEAD_WORKER_ROLES = PROJECT_INTELLIGENCE_ENGINEERING_LEAD_WORKER_ROLES;
10507
+ var ENGINEERING_LEAD_ROUTING_MODES = PROJECT_INTELLIGENCE_ENGINEERING_LEAD_ROUTING_MODES;
10508
+ var ENGINEERING_LEAD_WORK_PACKAGE_STATUSES = PROJECT_INTELLIGENCE_ENGINEERING_LEAD_WORK_PACKAGE_STATUSES;
10509
+ var ENGINEERING_LEAD_SUPERVISION_STATUSES = PROJECT_INTELLIGENCE_ENGINEERING_LEAD_SUPERVISION_STATUSES;
10454
10510
  var TARGET_LABELS = {
10455
10511
  codex: "Codex",
10456
10512
  "claude-code": "Claude Code",
@@ -10504,17 +10560,17 @@ function numberValue2(value, fallback) {
10504
10560
  function booleanValue(value, fallback) {
10505
10561
  return typeof value === "boolean" ? value : fallback;
10506
10562
  }
10507
- function statusValue(value, fallback) {
10508
- return value === "healthy" || value === "watch" || value === "risk" || value === "unknown" ? value : fallback;
10509
- }
10510
- function postureValue(value, fallback) {
10511
- return value === "lead_ready" || value === "lead_watch" || value === "lead_blocked" || value === "lead_cold_start" ? value : fallback;
10512
- }
10513
- function roleValue(value, fallback) {
10514
- return value === "main_agent" || value === "coding_worker" || value === "test_worker" || value === "reviewer" || value === "documentation_worker" || value === "human_approver" ? value : fallback;
10563
+ function cockpitEnumValue(field, values, value, fallback) {
10564
+ if (typeof value === "string" && values.includes(value)) {
10565
+ return { value, droppedReasonCode: null };
10566
+ }
10567
+ return {
10568
+ value: fallback,
10569
+ droppedReasonCode: typeof value === "string" && value.trim() ? `companion_dropped_unknown_${field}` : null
10570
+ };
10515
10571
  }
10516
- function routingModeValue(value, fallback) {
10517
- return value === "hold" || value === "main_agent_execute" || value === "explicit_handoff_ready" || value === "needs_contract" ? value : fallback;
10572
+ function compactReasonCodes(values) {
10573
+ return values.filter((value) => Boolean(value));
10518
10574
  }
10519
10575
  function slug(value, fallback) {
10520
10576
  const normalized = value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48);
@@ -10690,6 +10746,111 @@ function suggestedCommands2(input) {
10690
10746
  }
10691
10747
  return commands;
10692
10748
  }
10749
+ function localWorkPackageStatus(input) {
10750
+ if (input.posture === "lead_cold_start") return "unknown";
10751
+ if (input.posture === "lead_blocked") return "blocked";
10752
+ if (input.routingMode === "explicit_handoff_ready") return "ready_for_handoff";
10753
+ return "contracting";
10754
+ }
10755
+ function localWorkPackageReplanTriggers(input) {
10756
+ const triggers = /* @__PURE__ */ new Set();
10757
+ if (!input.task) {
10758
+ triggers.add("Define the task before treating this as a work package.");
10759
+ }
10760
+ if (input.changedFiles.length === 0) {
10761
+ triggers.add("Declare the write scope before delegation.");
10762
+ }
10763
+ if (input.acceptanceCriteria.length === 0) {
10764
+ triggers.add("Add acceptance criteria before worker handoff.");
10765
+ }
10766
+ if (input.proofGates.length === 0) {
10767
+ triggers.add("Add proof gates before worker handoff.");
10768
+ }
10769
+ if (!input.localSignals.workflow.present || input.localSignals.workflow.status !== "active") {
10770
+ triggers.add("Start or resume a Companion workflow before delegated execution.");
10771
+ }
10772
+ if (!input.localSignals.teamSync.present) {
10773
+ triggers.add("Record a Team Sync breadcrumb before handing work to another agent.");
10774
+ }
10775
+ if (input.declaredRisks.length > 0) {
10776
+ triggers.add("Review declared risks before promoting Brain update candidates.");
10777
+ }
10778
+ return Array.from(triggers);
10779
+ }
10780
+ function buildLocalWorkPackages(input) {
10781
+ if (!input.workPackageId) {
10782
+ return [];
10783
+ }
10784
+ const workPackageStatus = localWorkPackageStatus({
10785
+ posture: input.posture,
10786
+ routingMode: input.routingMode
10787
+ });
10788
+ const replanTriggers = localWorkPackageReplanTriggers(input);
10789
+ return [
10790
+ {
10791
+ id: input.workPackageId,
10792
+ title: input.workPackageTitle,
10793
+ status: workPackageStatus,
10794
+ health: input.status,
10795
+ owner: input.owner,
10796
+ dependencies: [],
10797
+ writeScope: input.changedFiles,
10798
+ acceptanceCriteria: input.acceptanceCriteria,
10799
+ proofRequired: input.proofGates,
10800
+ resultExpectation: input.routingMode === "explicit_handoff_ready" ? "Return changed files, proof receipts, residual risks, and candidate Project Brain updates." : "Return a bounded implementation summary only after the contract is complete.",
10801
+ nextAction: workPackageStatus === "ready_for_handoff" ? "Generate a handoff or adapter pack, then collect proof receipts before closure." : replanTriggers[0] ?? "Tighten the work package contract before handoff.",
10802
+ replanTriggers,
10803
+ evidence: input.evidence,
10804
+ reasonCodes: [
10805
+ `engineering_lead_work_package_${workPackageStatus}`,
10806
+ `engineering_lead_${input.posture}`,
10807
+ `routing_${input.routingMode}`
10808
+ ]
10809
+ }
10810
+ ];
10811
+ }
10812
+ function buildLocalSupervision(input) {
10813
+ const replanTriggers = Array.from(
10814
+ new Set(input.workPackages.flatMap((workPackage) => workPackage.replanTriggers))
10815
+ );
10816
+ const reviewRequired = input.posture === "lead_watch" || input.routingMode === "main_agent_execute" || input.workPackages.some((workPackage) => workPackage.replanTriggers.length > 0);
10817
+ const replanRequired = input.posture === "lead_blocked" || input.workPackages.some((workPackage) => workPackage.status === "blocked");
10818
+ const status = input.workPackages.length === 0 ? "cold_start" : replanRequired ? "blocked" : reviewRequired ? "needs_review" : "on_track";
10819
+ const readyWorkPackages = input.workPackages.filter(
10820
+ (workPackage) => workPackage.status === "ready_for_handoff"
10821
+ ).length;
10822
+ const blockedWorkPackages = input.workPackages.filter(
10823
+ (workPackage) => workPackage.status === "blocked"
10824
+ ).length;
10825
+ const receiptsRequired = /* @__PURE__ */ new Set();
10826
+ if (input.routingMode === "explicit_handoff_ready") {
10827
+ receiptsRequired.add("handoff_receipt");
10828
+ receiptsRequired.add("proof_receipt");
10829
+ }
10830
+ if (!input.localSignals.teamSync.present) {
10831
+ receiptsRequired.add("team_sync_handoff");
10832
+ }
10833
+ return {
10834
+ status,
10835
+ summary: status === "cold_start" ? "No local work package is available for supervision yet." : status === "blocked" ? "Local delegation is blocked until the worker contract has scope, acceptance, and proof." : status === "needs_review" ? "Local work is scoped, but workflow continuity or handoff readiness still needs review." : "Local work package is ready for advisory handoff supervision.",
10836
+ openWorkPackages: input.workPackages.length,
10837
+ blockedWorkPackages,
10838
+ readyWorkPackages,
10839
+ executingWorkPackages: 0,
10840
+ verifyingWorkPackages: 0,
10841
+ closedWorkPackages: 0,
10842
+ reviewRequired,
10843
+ replanRequired,
10844
+ nextCheck: status === "cold_start" ? "Define task scope, files, context refs, and proof gates." : status === "blocked" ? "Close contract gaps before delegated execution." : status === "needs_review" ? "Review workflow, Team Sync, risks, and proof gates before handoff." : "Collect proof and outcome receipts after handoff.",
10845
+ replanTriggers,
10846
+ receiptsRequired: Array.from(receiptsRequired),
10847
+ reasonCodes: [
10848
+ "engineering_lead_contract_v1_supervision",
10849
+ `engineering_lead_supervision_${status}`,
10850
+ `routing_${input.routingMode}`
10851
+ ]
10852
+ };
10853
+ }
10693
10854
  function buildLocalEngineeringLeadPlan(input) {
10694
10855
  const score = computeScore(input);
10695
10856
  const posture = postureForLocalPlan({ ...input, score });
@@ -10709,6 +10870,7 @@ function buildLocalEngineeringLeadPlan(input) {
10709
10870
  ].slice(0, 10);
10710
10871
  const brainCandidates = brainUpdateCandidates(input);
10711
10872
  const workPackageId = posture === "lead_cold_start" ? null : `lead-plan:${slug(workPackageTitle, "work-package")}`;
10873
+ const owner = posture === "lead_cold_start" ? "main_agent" : TARGET_LABELS[input.target];
10712
10874
  const worker = {
10713
10875
  id: workPackageId ?? "engineering-lead:cold-start",
10714
10876
  role,
@@ -10717,7 +10879,7 @@ function buildLocalEngineeringLeadPlan(input) {
10717
10879
  routingMode,
10718
10880
  workPackageId,
10719
10881
  workPackageTitle: posture === "lead_cold_start" ? null : workPackageTitle,
10720
- owner: posture === "lead_cold_start" ? "main_agent" : TARGET_LABELS[input.target],
10882
+ owner,
10721
10883
  rationale: routingMode === "explicit_handoff_ready" ? "Local scope, workflow continuity, acceptance, and proof gates are present for an explicit handoff." : routingMode === "main_agent_execute" ? "The contract is usable, but no active Companion workflow is present; keep execution with the main agent." : routingMode === "needs_contract" ? "Proof gates or acceptance criteria are incomplete; hold worker launch until the contract is explicit." : "No bounded work package exists yet; the main agent must define scope before delegation.",
10722
10884
  contract: {
10723
10885
  writeScope: input.changedFiles,
@@ -10736,8 +10898,30 @@ function buildLocalEngineeringLeadPlan(input) {
10736
10898
  `routing_${routingMode}`
10737
10899
  ]
10738
10900
  };
10901
+ const workPackages = buildLocalWorkPackages({
10902
+ workPackageId,
10903
+ workPackageTitle,
10904
+ status,
10905
+ posture,
10906
+ routingMode,
10907
+ owner,
10908
+ changedFiles: input.changedFiles,
10909
+ acceptanceCriteria: input.acceptanceCriteria,
10910
+ proofGates: input.proofGates,
10911
+ evidence,
10912
+ declaredRisks: input.declaredRisks,
10913
+ localSignals: input.localSignals,
10914
+ task: input.task
10915
+ });
10916
+ const supervision = buildLocalSupervision({
10917
+ posture,
10918
+ routingMode,
10919
+ workPackages,
10920
+ localSignals: input.localSignals
10921
+ });
10739
10922
  return {
10740
- version: "project-intelligence-engineering-lead-plan-v0",
10923
+ version: PROJECT_INTELLIGENCE_ENGINEERING_LEAD_PLAN_VERSION,
10924
+ contractVersion: PROJECT_INTELLIGENCE_ENGINEERING_LEAD_CONTRACT_VERSION,
10741
10925
  posture,
10742
10926
  status,
10743
10927
  score,
@@ -10746,6 +10930,8 @@ function buildLocalEngineeringLeadPlan(input) {
10746
10930
  nextAction: routingMode === "explicit_handoff_ready" ? "Generate a handoff or adapter pack, then require proof receipts before closure." : routingMode === "main_agent_execute" ? "Start or resume a Companion workflow before assigning this to another worker." : routingMode === "needs_contract" ? "Define proof gates and acceptance criteria before worker handoff." : "Define task scope, files, context refs, and proof gates.",
10747
10931
  workersSpawned: 0,
10748
10932
  failClosedFallback: "main_agent",
10933
+ workPackages,
10934
+ supervision,
10749
10935
  workerRecommendations: [worker],
10750
10936
  proofGates: input.proofGates,
10751
10937
  brainUpdateActions: brainCandidates,
@@ -10753,6 +10939,7 @@ function buildLocalEngineeringLeadPlan(input) {
10753
10939
  { label: "Work packages", value: workPackageId ? 1 : 0 },
10754
10940
  { label: "Ready packages", value: routingMode === "explicit_handoff_ready" ? 1 : 0 },
10755
10941
  { label: "Blocked packages", value: posture === "lead_blocked" ? 1 : 0 },
10942
+ { label: "Supervision", value: supervision.status },
10756
10943
  { label: "Context refs", value: input.contextRefs.length },
10757
10944
  { label: "Proof gates", value: input.proofGates.length },
10758
10945
  { label: "Acceptance criteria", value: input.acceptanceCriteria.length },
@@ -10774,12 +10961,30 @@ function buildLocalEngineeringLeadPlan(input) {
10774
10961
  }
10775
10962
  function normalizeWorkerRecommendation(value, index) {
10776
10963
  const contract = isRecord5(value.contract) ? value.contract : {};
10964
+ const role = cockpitEnumValue(
10965
+ "worker_role",
10966
+ ENGINEERING_LEAD_WORKER_ROLES,
10967
+ value.role,
10968
+ "main_agent"
10969
+ );
10970
+ const status = cockpitEnumValue(
10971
+ "worker_status",
10972
+ ENGINEERING_LEAD_STATUSES,
10973
+ value.status,
10974
+ "unknown"
10975
+ );
10976
+ const routingMode = cockpitEnumValue(
10977
+ "routing_mode",
10978
+ ENGINEERING_LEAD_ROUTING_MODES,
10979
+ value.routingMode,
10980
+ "hold"
10981
+ );
10777
10982
  return {
10778
10983
  id: stringValue3(value.id) ?? `worker:${index + 1}`,
10779
- role: roleValue(value.role, "main_agent"),
10780
- label: stringValue3(value.label) ?? workerLabel(roleValue(value.role, "main_agent")),
10781
- status: statusValue(value.status, "unknown"),
10782
- routingMode: routingModeValue(value.routingMode, "hold"),
10984
+ role: role.value,
10985
+ label: stringValue3(value.label) ?? workerLabel(role.value),
10986
+ status: status.value,
10987
+ routingMode: routingMode.value,
10783
10988
  workPackageId: stringValue3(value.workPackageId) ?? null,
10784
10989
  workPackageTitle: stringValue3(value.workPackageTitle) ?? null,
10785
10990
  owner: stringValue3(value.owner) ?? null,
@@ -10795,7 +11000,146 @@ function normalizeWorkerRecommendation(value, index) {
10795
11000
  proofGates: stringList(value.proofGates),
10796
11001
  brainUpdateCandidates: stringList(value.brainUpdateCandidates),
10797
11002
  evidence: normalizeEvidence(value.evidence),
10798
- reasonCodes: stringList(value.reasonCodes)
11003
+ reasonCodes: [
11004
+ .../* @__PURE__ */ new Set([
11005
+ ...stringList(value.reasonCodes),
11006
+ ...compactReasonCodes([
11007
+ role.droppedReasonCode,
11008
+ status.droppedReasonCode,
11009
+ routingMode.droppedReasonCode
11010
+ ])
11011
+ ])
11012
+ ]
11013
+ };
11014
+ }
11015
+ function normalizeWorkPackage(value, index) {
11016
+ const status = cockpitEnumValue(
11017
+ "work_package_status",
11018
+ ENGINEERING_LEAD_WORK_PACKAGE_STATUSES,
11019
+ value.status,
11020
+ "unknown"
11021
+ );
11022
+ const health = cockpitEnumValue(
11023
+ "work_package_health",
11024
+ ENGINEERING_LEAD_STATUSES,
11025
+ value.health,
11026
+ "unknown"
11027
+ );
11028
+ const reasonCodes = [
11029
+ .../* @__PURE__ */ new Set([
11030
+ ...stringList(value.reasonCodes),
11031
+ ...compactReasonCodes([status.droppedReasonCode, health.droppedReasonCode])
11032
+ ])
11033
+ ];
11034
+ return {
11035
+ id: stringValue3(value.id) ?? `work-package:${index + 1}`,
11036
+ title: stringValue3(value.title) ?? `Imported work package ${index + 1}`,
11037
+ status: status.value,
11038
+ health: health.value,
11039
+ owner: stringValue3(value.owner) ?? null,
11040
+ dependencies: stringList(value.dependencies),
11041
+ writeScope: stringList(value.writeScope),
11042
+ acceptanceCriteria: stringList(value.acceptanceCriteria),
11043
+ proofRequired: stringList(value.proofRequired),
11044
+ resultExpectation: stringValue3(value.resultExpectation) ?? "Return proof receipts, residual risks, and candidate Project Brain updates.",
11045
+ nextAction: stringValue3(value.nextAction) ?? "Review imported work package before creating handoffs.",
11046
+ replanTriggers: stringList(value.replanTriggers),
11047
+ evidence: normalizeEvidence(value.evidence),
11048
+ reasonCodes
11049
+ };
11050
+ }
11051
+ function summarizeSupervisionFromWorkPackages(workPackages) {
11052
+ const blockedWorkPackages = workPackages.filter(
11053
+ (workPackage) => workPackage.status === "blocked"
11054
+ ).length;
11055
+ const readyWorkPackages = workPackages.filter(
11056
+ (workPackage) => workPackage.status === "ready_for_handoff"
11057
+ ).length;
11058
+ const executingWorkPackages = workPackages.filter(
11059
+ (workPackage) => workPackage.status === "executing"
11060
+ ).length;
11061
+ const verifyingWorkPackages = workPackages.filter(
11062
+ (workPackage) => workPackage.status === "verifying"
11063
+ ).length;
11064
+ const closedWorkPackages = workPackages.filter(
11065
+ (workPackage) => workPackage.status === "closed"
11066
+ ).length;
11067
+ const replanTriggers = Array.from(
11068
+ new Set(workPackages.flatMap((workPackage) => workPackage.replanTriggers))
11069
+ );
11070
+ const reviewRequired = workPackages.some((workPackage) => workPackage.health === "watch") || workPackages.some((workPackage) => workPackage.replanTriggers.length > 0);
11071
+ const replanRequired = blockedWorkPackages > 0;
11072
+ const status = workPackages.length === 0 ? "cold_start" : replanRequired ? "needs_replan" : reviewRequired ? "needs_review" : "on_track";
11073
+ return {
11074
+ status,
11075
+ summary: workPackages.length === 0 ? "No imported work packages are available for supervision." : replanRequired ? `${blockedWorkPackages} imported work package(s) require replan.` : reviewRequired ? "Imported work packages need review before delegated execution." : "Imported work packages are on track for advisory supervision.",
11076
+ openWorkPackages: Math.max(0, workPackages.length - closedWorkPackages),
11077
+ blockedWorkPackages,
11078
+ readyWorkPackages,
11079
+ executingWorkPackages,
11080
+ verifyingWorkPackages,
11081
+ closedWorkPackages,
11082
+ reviewRequired,
11083
+ replanRequired,
11084
+ nextCheck: status === "cold_start" ? "Import or create bounded work packages." : status === "needs_replan" ? "Replan blocked imported packages before handoff." : status === "needs_review" ? "Review imported package contracts and receipts." : "Collect proof and outcome receipts after handoff.",
11085
+ replanTriggers,
11086
+ receiptsRequired: [],
11087
+ reasonCodes: [
11088
+ "engineering_lead_contract_v1_supervision",
11089
+ `engineering_lead_supervision_${status}`
11090
+ ]
11091
+ };
11092
+ }
11093
+ function normalizeSupervision(value, workPackages) {
11094
+ if (!isRecord5(value)) {
11095
+ return summarizeSupervisionFromWorkPackages(workPackages);
11096
+ }
11097
+ const fallback = summarizeSupervisionFromWorkPackages(workPackages);
11098
+ const fallbackStatus = fallback.status === "on_track" ? "needs_review" : fallback.status;
11099
+ const status = cockpitEnumValue(
11100
+ "supervision_status",
11101
+ ENGINEERING_LEAD_SUPERVISION_STATUSES,
11102
+ value.status,
11103
+ fallbackStatus
11104
+ );
11105
+ return {
11106
+ status: status.value,
11107
+ summary: stringValue3(value.summary) ?? fallback.summary,
11108
+ openWorkPackages: Math.max(
11109
+ 0,
11110
+ Math.round(numberValue2(value.openWorkPackages, fallback.openWorkPackages))
11111
+ ),
11112
+ blockedWorkPackages: Math.max(
11113
+ 0,
11114
+ Math.round(numberValue2(value.blockedWorkPackages, fallback.blockedWorkPackages))
11115
+ ),
11116
+ readyWorkPackages: Math.max(
11117
+ 0,
11118
+ Math.round(numberValue2(value.readyWorkPackages, fallback.readyWorkPackages))
11119
+ ),
11120
+ executingWorkPackages: Math.max(
11121
+ 0,
11122
+ Math.round(numberValue2(value.executingWorkPackages, fallback.executingWorkPackages))
11123
+ ),
11124
+ verifyingWorkPackages: Math.max(
11125
+ 0,
11126
+ Math.round(numberValue2(value.verifyingWorkPackages, fallback.verifyingWorkPackages))
11127
+ ),
11128
+ closedWorkPackages: Math.max(
11129
+ 0,
11130
+ Math.round(numberValue2(value.closedWorkPackages, fallback.closedWorkPackages))
11131
+ ),
11132
+ reviewRequired: booleanValue(value.reviewRequired, fallback.reviewRequired),
11133
+ replanRequired: booleanValue(value.replanRequired, fallback.replanRequired),
11134
+ nextCheck: stringValue3(value.nextCheck) ?? fallback.nextCheck,
11135
+ replanTriggers: stringList(value.replanTriggers),
11136
+ receiptsRequired: stringList(value.receiptsRequired),
11137
+ reasonCodes: [
11138
+ .../* @__PURE__ */ new Set([
11139
+ ...stringList(value.reasonCodes),
11140
+ ...compactReasonCodes([status.droppedReasonCode])
11141
+ ])
11142
+ ]
10799
11143
  };
10800
11144
  }
10801
11145
  function normalizeCockpitPlan(cockpit) {
@@ -10804,16 +11148,42 @@ function normalizeCockpitPlan(cockpit) {
10804
11148
  const workerRecommendations = recordList2(rawPlan.workerRecommendations).map(
10805
11149
  normalizeWorkerRecommendation
10806
11150
  );
11151
+ const workPackages = recordList2(rawPlan.workPackages).map(normalizeWorkPackage);
11152
+ const supervision = normalizeSupervision(rawPlan.supervision, workPackages);
11153
+ const posture = cockpitEnumValue(
11154
+ "posture",
11155
+ ENGINEERING_LEAD_POSTURES,
11156
+ rawPlan.posture,
11157
+ "lead_cold_start"
11158
+ );
11159
+ const status = cockpitEnumValue(
11160
+ "status",
11161
+ ENGINEERING_LEAD_STATUSES,
11162
+ rawPlan.status,
11163
+ statusForScore(score)
11164
+ );
11165
+ const workerDroppedReasonCodes = workerRecommendations.flatMap(
11166
+ (worker) => worker.reasonCodes.filter((code2) => code2.startsWith("companion_dropped_unknown_"))
11167
+ );
11168
+ const workPackageDroppedReasonCodes = workPackages.flatMap(
11169
+ (workPackage) => workPackage.reasonCodes.filter((code2) => code2.startsWith("companion_dropped_unknown_"))
11170
+ );
11171
+ const supervisionDroppedReasonCodes = supervision.reasonCodes.filter(
11172
+ (code2) => code2.startsWith("companion_dropped_unknown_")
11173
+ );
10807
11174
  return {
10808
- version: "project-intelligence-engineering-lead-plan-v0",
10809
- posture: postureValue(rawPlan.posture, "lead_cold_start"),
10810
- status: statusValue(rawPlan.status, statusForScore(score)),
11175
+ version: PROJECT_INTELLIGENCE_ENGINEERING_LEAD_PLAN_VERSION,
11176
+ contractVersion: PROJECT_INTELLIGENCE_ENGINEERING_LEAD_CONTRACT_VERSION,
11177
+ posture: posture.value,
11178
+ status: status.value,
10811
11179
  score,
10812
11180
  headline: stringValue3(rawPlan.headline) ?? "Imported Project Health Engineering Lead Plan.",
10813
11181
  operatingMode: "advisory_fail_closed",
10814
11182
  nextAction: stringValue3(rawPlan.nextAction) ?? "Review the imported cockpit plan before creating worker handoffs.",
10815
11183
  workersSpawned: 0,
10816
11184
  failClosedFallback: "main_agent",
11185
+ workPackages,
11186
+ supervision,
10817
11187
  workerRecommendations,
10818
11188
  proofGates: stringList(rawPlan.proofGates),
10819
11189
  brainUpdateActions: stringList(rawPlan.brainUpdateActions),
@@ -10832,11 +11202,119 @@ function normalizeCockpitPlan(cockpit) {
10832
11202
  reasonCodes: [
10833
11203
  .../* @__PURE__ */ new Set([
10834
11204
  "companion_imported_project_health_lead_plan",
10835
- ...stringList(rawPlan.reasonCodes)
11205
+ ...compactReasonCodes([posture.droppedReasonCode, status.droppedReasonCode]),
11206
+ ...stringList(rawPlan.reasonCodes),
11207
+ ...workerDroppedReasonCodes,
11208
+ ...workPackageDroppedReasonCodes,
11209
+ ...supervisionDroppedReasonCodes
10836
11210
  ])
10837
11211
  ]
10838
11212
  };
10839
11213
  }
11214
+ function scopeSetForPlan(plan) {
11215
+ return /* @__PURE__ */ new Set([
11216
+ ...plan.workPackages.flatMap((workPackage) => workPackage.writeScope),
11217
+ ...plan.workerRecommendations.flatMap((worker) => worker.contract.writeScope)
11218
+ ]);
11219
+ }
11220
+ function reconcileEngineeringLeadPlan(input) {
11221
+ const changedSignals = /* @__PURE__ */ new Set();
11222
+ const recommendedActions = /* @__PURE__ */ new Set();
11223
+ const reasonCodes = /* @__PURE__ */ new Set(["companion_lead_plan_reconciled"]);
11224
+ const plannedScope = scopeSetForPlan(input.plan);
11225
+ const outOfScopeFiles = input.changedFiles.filter((file) => !plannedScope.has(file));
11226
+ if (input.plan.workPackages.length === 0) {
11227
+ changedSignals.add("no_imported_work_packages");
11228
+ recommendedActions.add("Create or import bounded work packages before delegation.");
11229
+ reasonCodes.add("companion_reconcile_no_work_packages");
11230
+ }
11231
+ if (outOfScopeFiles.length > 0) {
11232
+ changedSignals.add(`out_of_scope_files:${outOfScopeFiles.join(",")}`);
11233
+ recommendedActions.add(
11234
+ "Replan because current changed files are outside the imported write scope."
11235
+ );
11236
+ reasonCodes.add("companion_reconcile_scope_changed");
11237
+ }
11238
+ if (!input.localSignals.workflow.present || input.localSignals.workflow.status !== "active") {
11239
+ changedSignals.add("workflow_not_active");
11240
+ recommendedActions.add("Start or resume a Companion workflow before delegated execution.");
11241
+ reasonCodes.add("companion_reconcile_workflow_not_active");
11242
+ }
11243
+ if (!input.localSignals.teamSync.present) {
11244
+ changedSignals.add("team_sync_missing");
11245
+ recommendedActions.add(
11246
+ "Record Team Sync start-work or handoff before assigning work to another agent."
11247
+ );
11248
+ reasonCodes.add("companion_reconcile_team_sync_missing");
11249
+ }
11250
+ if (input.proofGates.length === 0 && input.plan.proofGates.length === 0) {
11251
+ changedSignals.add("proof_gates_missing");
11252
+ recommendedActions.add("Define proof gates before worker handoff.");
11253
+ reasonCodes.add("companion_reconcile_missing_proof");
11254
+ }
11255
+ if (input.acceptanceCriteria.length === 0) {
11256
+ const importedAcceptance = input.plan.workPackages.some(
11257
+ (workPackage) => workPackage.acceptanceCriteria.length > 0
11258
+ );
11259
+ if (!importedAcceptance) {
11260
+ changedSignals.add("acceptance_criteria_missing");
11261
+ recommendedActions.add("Define acceptance criteria before worker handoff.");
11262
+ reasonCodes.add("companion_reconcile_missing_acceptance");
11263
+ }
11264
+ }
11265
+ if (input.declaredRisks.length > 0) {
11266
+ changedSignals.add("declared_risks_present");
11267
+ recommendedActions.add("Review declared risks before promoting Brain update candidates.");
11268
+ reasonCodes.add("companion_reconcile_declared_risks");
11269
+ }
11270
+ for (const trigger of input.plan.supervision.replanTriggers) {
11271
+ recommendedActions.add(trigger);
11272
+ }
11273
+ const blocked = input.plan.supervision.status === "blocked" || input.plan.workPackages.some((workPackage) => workPackage.status === "blocked");
11274
+ 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;
11276
+ const status = blocked ? "blocked" : replanRequired ? "needs_replan" : reviewRequired ? "needs_review" : "on_track";
11277
+ return {
11278
+ status,
11279
+ summary: status === "blocked" ? "Imported lead plan has blocked work or blocked supervision signals." : status === "needs_replan" ? "Imported lead plan no longer matches current local execution signals." : status === "needs_review" ? "Imported lead plan is usable, but local continuity or risk review is required." : "Imported lead plan matches current local execution signals.",
11280
+ replanRequired,
11281
+ reviewRequired,
11282
+ changedSignals: Array.from(changedSignals),
11283
+ recommendedActions: Array.from(recommendedActions),
11284
+ reasonCodes: Array.from(reasonCodes)
11285
+ };
11286
+ }
11287
+ function applyReconciliationToPlan(plan, reconciliation) {
11288
+ if (!reconciliation.replanRequired && !reconciliation.reviewRequired) {
11289
+ return {
11290
+ ...plan,
11291
+ reasonCodes: [.../* @__PURE__ */ new Set([...plan.reasonCodes, ...reconciliation.reasonCodes])]
11292
+ };
11293
+ }
11294
+ const supervisionStatus = reconciliation.status === "blocked" ? "blocked" : reconciliation.status === "needs_replan" ? "needs_replan" : "needs_review";
11295
+ return {
11296
+ ...plan,
11297
+ nextAction: reconciliation.recommendedActions[0] ?? plan.nextAction,
11298
+ supervision: {
11299
+ ...plan.supervision,
11300
+ status: supervisionStatus,
11301
+ summary: reconciliation.summary,
11302
+ reviewRequired: reconciliation.reviewRequired,
11303
+ replanRequired: reconciliation.replanRequired,
11304
+ replanTriggers: [
11305
+ .../* @__PURE__ */ new Set([...plan.supervision.replanTriggers, ...reconciliation.recommendedActions])
11306
+ ],
11307
+ reasonCodes: [.../* @__PURE__ */ new Set([...plan.supervision.reasonCodes, ...reconciliation.reasonCodes])]
11308
+ },
11309
+ caveats: [
11310
+ .../* @__PURE__ */ new Set([
11311
+ ...plan.caveats,
11312
+ "This plan was reconciled against current local Companion signals; replan signals are advisory and fail-closed."
11313
+ ])
11314
+ ],
11315
+ reasonCodes: [.../* @__PURE__ */ new Set([...plan.reasonCodes, ...reconciliation.reasonCodes])]
11316
+ };
11317
+ }
10840
11318
  function readJsonFile3(filePath) {
10841
11319
  const parsed = JSON.parse(fs16.readFileSync(path15.resolve(filePath), "utf8"));
10842
11320
  if (!isRecord5(parsed)) {
@@ -10854,8 +11332,8 @@ function buildCompanionEngineeringLeadPlanReport(options = {}) {
10854
11332
  const proofGates = unique3(options.proof);
10855
11333
  const acceptanceCriteria = unique3(options.acceptance);
10856
11334
  const declaredRisks = unique3(options.risk);
10857
- const cockpit = options.cockpit ?? (options.fromCockpit ? readJsonFile3(options.fromCockpit) : void 0);
10858
- const engineeringLeadPlan = cockpit ? normalizeCockpitPlan(cockpit) : buildLocalEngineeringLeadPlan({
11335
+ const cockpit = options.cockpit ?? (options.fromCockpit || options.fromPlan ? readJsonFile3(options.fromCockpit ?? options.fromPlan ?? "") : void 0);
11336
+ const importedPlan = cockpit ? normalizeCockpitPlan(cockpit) : buildLocalEngineeringLeadPlan({
10859
11337
  target,
10860
11338
  task,
10861
11339
  changedFiles,
@@ -10865,6 +11343,15 @@ function buildCompanionEngineeringLeadPlanReport(options = {}) {
10865
11343
  declaredRisks,
10866
11344
  localSignals
10867
11345
  });
11346
+ const reconciliation = options.reconcile && cockpit ? reconcileEngineeringLeadPlan({
11347
+ plan: importedPlan,
11348
+ changedFiles,
11349
+ proofGates,
11350
+ acceptanceCriteria,
11351
+ declaredRisks,
11352
+ localSignals
11353
+ }) : void 0;
11354
+ const engineeringLeadPlan = reconciliation ? applyReconciliationToPlan(importedPlan, reconciliation) : importedPlan;
10868
11355
  return {
10869
11356
  version: "snipara.companion_engineering_lead_plan.v1",
10870
11357
  generatedAt: (options.now ?? /* @__PURE__ */ new Date()).toISOString(),
@@ -10883,6 +11370,7 @@ function buildCompanionEngineeringLeadPlanReport(options = {}) {
10883
11370
  declaredRisks
10884
11371
  },
10885
11372
  localSignals,
11373
+ ...reconciliation ? { reconciliation } : {},
10886
11374
  suggestedCommands: suggestedCommands2({
10887
11375
  target,
10888
11376
  task,
@@ -10918,6 +11406,37 @@ function formatCompanionEngineeringLeadPlanReport(report) {
10918
11406
  lines.push(`Headline: ${plan.headline}`);
10919
11407
  lines.push(`Next action: ${plan.nextAction}`);
10920
11408
  lines.push("");
11409
+ lines.push("Supervision");
11410
+ lines.push(`Status: ${plan.supervision.status}`);
11411
+ lines.push(`Summary: ${plan.supervision.summary}`);
11412
+ lines.push(`Review required: ${plan.supervision.reviewRequired}`);
11413
+ lines.push(`Replan required: ${plan.supervision.replanRequired}`);
11414
+ lines.push(`Next check: ${plan.supervision.nextCheck}`);
11415
+ lines.push(`Replan triggers: ${formatList2(plan.supervision.replanTriggers)}`);
11416
+ lines.push("");
11417
+ if (report.reconciliation) {
11418
+ lines.push("Reconciliation");
11419
+ lines.push(`Status: ${report.reconciliation.status}`);
11420
+ lines.push(`Summary: ${report.reconciliation.summary}`);
11421
+ lines.push(`Changed signals: ${formatList2(report.reconciliation.changedSignals)}`);
11422
+ lines.push(`Recommended actions: ${formatList2(report.reconciliation.recommendedActions)}`);
11423
+ lines.push("");
11424
+ }
11425
+ lines.push("Work Packages");
11426
+ if (plan.workPackages.length === 0) {
11427
+ lines.push("- none");
11428
+ } else {
11429
+ for (const workPackage of plan.workPackages) {
11430
+ lines.push(`- [${workPackage.health}] ${workPackage.title} (${workPackage.status})`);
11431
+ if (workPackage.owner) {
11432
+ lines.push(` owner: ${workPackage.owner}`);
11433
+ }
11434
+ lines.push(` next: ${workPackage.nextAction}`);
11435
+ lines.push(` scope: ${formatList2(workPackage.writeScope)}`);
11436
+ lines.push(` proof: ${formatList2(workPackage.proofRequired)}`);
11437
+ }
11438
+ }
11439
+ lines.push("");
10921
11440
  lines.push("Worker Recommendations");
10922
11441
  for (const worker of plan.workerRecommendations) {
10923
11442
  lines.push(`- [${worker.status}] ${worker.label} (${worker.role}, ${worker.routingMode})`);
@@ -23287,7 +23806,7 @@ program.command("agent-readiness").description("Audit whether a repo/task is rea
23287
23806
  program.command("lead-plan").description("Create a fail-closed Companion Engineering Lead Plan").option("--task <task>", "Current task or work package summary").option(
23288
23807
  "--target <target>",
23289
23808
  "Target agent or ADE (codex|claude-code|cursor|orca|windsurf|custom)"
23290
- ).option("--changed-files <files...>", "Changed or relevant files").option("--context <refs...>", "Context references, decisions, docs, or source facts").option("--proof <proof...>", "Required proof gates or verification evidence").option("--acceptance <criteria...>", "Acceptance criteria for the delegated work").option("--risk <risks...>", "Known risks or caveats").option("--from-cockpit <file>", "Read a Project Health cockpit JSON export").option("-d, --dir <directory>", "Project directory (default: current)").option("-o, --output <file>", "Write Markdown or JSON report").option("--json", "Print raw JSON").action(async (options) => {
23809
+ ).option("--changed-files <files...>", "Changed or relevant files").option("--context <refs...>", "Context references, decisions, docs, or source facts").option("--proof <proof...>", "Required proof gates or verification evidence").option("--acceptance <criteria...>", "Acceptance criteria for the delegated work").option("--risk <risks...>", "Known risks or caveats").option("--from-cockpit <file>", "Read a Project Health cockpit JSON export").option("--from-plan <file>", "Read a Companion or Project Health Engineering Lead Plan JSON").option("--reconcile", "Reconcile an imported lead plan against current local Companion signals").option("-d, --dir <directory>", "Project directory (default: current)").option("-o, --output <file>", "Write Markdown or JSON report").option("--json", "Print raw JSON").action(async (options) => {
23291
23810
  await leadPlanCommand({
23292
23811
  task: options.task,
23293
23812
  target: options.target,
@@ -23297,6 +23816,8 @@ program.command("lead-plan").description("Create a fail-closed Companion Enginee
23297
23816
  acceptance: options.acceptance,
23298
23817
  risk: options.risk,
23299
23818
  fromCockpit: options.fromCockpit,
23819
+ fromPlan: options.fromPlan,
23820
+ reconcile: Boolean(options.reconcile),
23300
23821
  dir: options.dir,
23301
23822
  output: options.output,
23302
23823
  json: Boolean(options.json)
@@ -24805,6 +25326,12 @@ if (require.main === module) {
24805
25326
  AutomationInstallConflictError,
24806
25327
  AutomationUnsupportedHookBundleError,
24807
25328
  COLLABORATION_STATE_RELATIVE_PATH,
25329
+ ENGINEERING_LEAD_POSTURES,
25330
+ ENGINEERING_LEAD_ROUTING_MODES,
25331
+ ENGINEERING_LEAD_STATUSES,
25332
+ ENGINEERING_LEAD_SUPERVISION_STATUSES,
25333
+ ENGINEERING_LEAD_WORKER_ROLES,
25334
+ ENGINEERING_LEAD_WORK_PACKAGE_STATUSES,
24808
25335
  ORCHESTRATOR_HANDOFF_RELATIVE_PATH,
24809
25336
  TEAM_SYNC_STATE_RELATIVE_PATH,
24810
25337
  WORKFLOW_PLANS_RELATIVE_DIR,
@@ -309,13 +309,16 @@ snipara-companion lead-plan \
309
309
 
310
310
  The command reads local workflow state, Team Sync, project instructions, and
311
311
  explicit inputs. The output uses the same lead-plan vocabulary as Project
312
- Health: posture, score, routing mode, bounded worker contract, proof gates,
313
- candidate Project Brain updates, `workersSpawned: 0`, and `main_agent` fallback.
314
-
315
- Use `--from-cockpit <file>` when Project Health has exported a cockpit JSON
316
- artifact and Companion only needs to normalize it into Markdown or JSON for
317
- handoff. This is still advisory and fail-closed: the command does not approve
318
- work, execute proof gates, or spawn workers.
312
+ Health: posture, score, routing mode, bounded worker contract, supervised work
313
+ packages, supervision/replan status, proof gates, candidate Project Brain
314
+ updates, `workersSpawned: 0`, and `main_agent` fallback.
315
+
316
+ Use `--from-cockpit <file>` or `--from-plan <file>` when Project Health has
317
+ exported a cockpit/lead-plan JSON artifact and Companion only needs to normalize
318
+ it into Markdown or JSON for handoff. Add `--reconcile` to compare the imported
319
+ plan against current local workflow, Team Sync, proof, acceptance, and file
320
+ scope signals. This is still advisory and fail-closed: the command does not
321
+ approve work, execute proof gates, or spawn workers.
319
322
 
320
323
  ## Verification Plans
321
324
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "snipara-companion",
3
- "version": "2.1.0",
3
+ "version": "2.2.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": {
@@ -57,6 +57,7 @@
57
57
  "conf": "^12.0.0"
58
58
  },
59
59
  "devDependencies": {
60
+ "@snipara/project-intelligence-contracts": "workspace:*",
60
61
  "@eslint/js": "^9.39.3",
61
62
  "@types/node": "^20.19.31",
62
63
  "@typescript-eslint/eslint-plugin": "^8.56.0",