From 8f4fed0e11c5711e896733f5c9a22c2c54f53dec Mon Sep 17 00:00:00 2001 From: hhyykk <4408344+hhyykk@users.noreply.github.com> Date: Mon, 2 Nov 2026 19:12:33 +0800 Subject: [PATCH] refactor(control-plane): retire 19 effect runtime registrations with no caller No Python or TypeScript caller dispatches these 19 effect-runtime methods, so their registrations are removed (376 -> 357). The functions behind them stay where another production module still calls them. Four exports lose their last production caller and are deleted with their private decoders: evaluateTaskLeaseOwnerEligibility, governedCapabilitySettlementStatus, delegationTurnPlanDecision and the recordLocalAuthorityShadow tombstone. Their test cases now exercise the live shared helpers (leaseOwnerRejection, leaseOwnerConstraint) or the dispatcher's unsupported-method rejection. Handler tests assert every retired method name is rejected. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> Signed-off-by: hhyykk <4408344+hhyykk@users.noreply.github.com> --- .../control_plane/collaboration/delegation.ts | 20 ------- .../coordination/local_authority_shadow.ts | 8 --- .../control_plane/effect_runtime_handlers.ts | 58 ------------------- loopx/control_plane/governed_capability.ts | 6 -- .../work_items/task_lease_eligibility.ts | 34 ----------- tests/control_plane_ts/delegation.test.ts | 15 +---- .../effect_runtime_handlers.test.ts | 28 +++++++++ .../governed_capability.test.ts | 9 --- .../local_authority_shadow.test.ts | 11 ++-- .../task_lease_eligibility.test.ts | 19 +++--- 10 files changed, 42 insertions(+), 166 deletions(-) diff --git a/loopx/control_plane/collaboration/delegation.ts b/loopx/control_plane/collaboration/delegation.ts index 5c85989f07..3e5f76504e 100644 --- a/loopx/control_plane/collaboration/delegation.ts +++ b/loopx/control_plane/collaboration/delegation.ts @@ -346,26 +346,6 @@ function boundedReason(value: unknown, fallback: string): string { return reason.length > 0 ? reason.slice(0, 4096) : fallback; } -/** Preserve a rejected Turn plan as data before the host adapter reads its transaction. */ -export function delegationTurnPlanDecision(params: JsonObject): JsonObject { - const plan = requireJsonObject(params.plan, "Turn plan"); - if (plan.ok !== true) return { - schema_version: "loopx_delegation_turn_plan_decision_v0", - state: "rejected", - turn_key: null, - reason: boundedReason(plan.error ?? plan.reason, "Turn plan rejected without a reason"), - }; - const transaction = requireJsonObject(plan.transaction, "Turn plan transaction"); - requireThat(typeof transaction.turn_key === "string" - && ENVELOPED_SHA256_PATTERN.test(transaction.turn_key), "Turn plan transaction requires a valid turn_key"); - return { - schema_version: "loopx_delegation_turn_plan_decision_v0", - state: "planned", - turn_key: transaction.turn_key, - reason: null, - }; -} - /** Preserve the host owner's public diagnosis, not its private configuration. * Optional fields keep older host previews compatible; null means unprobed. */ export function delegationRuntimeFacts(executor: JsonObject): JsonObject { diff --git a/loopx/control_plane/coordination/local_authority_shadow.ts b/loopx/control_plane/coordination/local_authority_shadow.ts index 58ab672f87..05316f5a54 100644 --- a/loopx/control_plane/coordination/local_authority_shadow.ts +++ b/loopx/control_plane/coordination/local_authority_shadow.ts @@ -55,14 +55,6 @@ export { LOCAL_AUTHORITY_SHADOW_REQUEST_SCHEMA, }; -/** Compatibility tombstone for older clients: never open or mint a store. */ -export async function recordLocalAuthorityShadow(_value: unknown): Promise { - throw new EffectRuntimeRequestError( - "Post-commit observation is retired; configure runtime shadow and explicitly bootstrap its source lineage.", - "local_authority_shadow_retired", - ); -} - export interface LocalAuthorityShadowDependencies { openStore?: (directory: string, goalId: string) => AuthorityStore; } diff --git a/loopx/control_plane/effect_runtime_handlers.ts b/loopx/control_plane/effect_runtime_handlers.ts index 125e4caeef..f15535c98f 100644 --- a/loopx/control_plane/effect_runtime_handlers.ts +++ b/loopx/control_plane/effect_runtime_handlers.ts @@ -30,7 +30,6 @@ import { optionalNonEmptyString as optionalString, requireJsonObject as requiredObject, requireNonEmptyString as requiredString, - requireStringArray as stringArray, requireStringLiteral, requireInteger, } from "./runtime_decode.ts"; @@ -271,9 +270,7 @@ export function createEffectRuntimeHandlers( ["turn_journal.find_settlement", lazyHandler(() => import("./turn_driver/turn_journal_query.ts"), ({findTurnJournalBySettlement}) => findTurnJournalBySettlement)], ["turn_journal.observed_capabilities", lazyHandler(() => import("./turn_driver/turn_journal_query.ts"), ({readTurnJournalCapabilities}) => readTurnJournalCapabilities)], ["todo.completion_fence.evaluate", lazyHandler(() => import("./todos/completion_fence.ts"), ({evaluateTodoCompletionFence}) => evaluateTodoCompletionFence)], - ["todo.field_update.plan", lazyHandler(() => import("./todos/field_update.ts"), ({planTodoFieldUpdate}) => planTodoFieldUpdate)], ["todo.priority.plan", lazyHandler(() => import("./todos/priority.ts"), ({evaluateTodoPriority}) => evaluateTodoPriority)], - ["todo.public_update.plan", lazyHandler(() => import("./todos/public_update.ts"), ({planPublicTodoUpdate}) => planPublicTodoUpdate)], ["todo.standing_decision.project", lazyHandler(() => import("./todos/standing_decision.ts"), ({evaluateStandingDecisionProjection}) => evaluateStandingDecisionProjection)], ["todo.read", lazyHandler(() => import("./todos/read_transport.ts"), ({readTodoRuntime}) => readTodoRuntime)], ["capabilities.periodic_report.progress.select", lazyHandler(() => import("./capabilities/periodic_report_progress.ts"), ({selectPeriodicReportProgress}) => selectPeriodicReportProgress)], @@ -299,25 +296,6 @@ export function createEffectRuntimeHandlers( ["todo.creation_scope.plan", lazyHandler(() => import("./todos/creation_scope.ts"), ({planTodoCreationScope}) => planTodoCreationScope)], ["todo.authoring_scope.plan", lazyHandler(() => import("./todos/authoring_scope.ts"), ({planTodoAuthoringScope}) => planTodoAuthoringScope)], ["todo.contract_diagnostics.evaluate", lazyHandler(() => import("./todos/authoring_scope.ts"), ({evaluateTodoContractDiagnostics}) => evaluateTodoContractDiagnostics)], - [ - "todo.claim.decide", - lazyHandler(() => import("./coordination/todo_claim.ts"), ({evaluateCoordinationTodoClaimDecision}) => (params) => evaluateCoordinationTodoClaimDecision( - requiredObject(params.todo, "todo"), - { - goal_id: requiredString(params.goal_id, "goal_id"), - todo_id: requiredString(params.todo_id, "todo_id"), - claimed_by: requiredString(params.claimed_by, "claimed_by"), - actor_agent_id: params.actor_agent_id === null - ? null : requiredString(params.actor_agent_id, "actor_agent_id"), - expected_role: params.expected_role === null - ? null : requiredString(params.expected_role, "expected_role"), - registered_agents: stringArray(params.registered_agents, "registered_agents"), - operation_id: "decision-only", - dry_run: true, - now: new Date(0), - }, - )), - ], ["todo.terminal.decide", lazyHandler(() => import("./coordination/todo_lifecycle_decision.ts"), ({evaluateCoordinationTodoTerminalDecision}) => evaluateCoordinationTodoTerminalDecision)], ["todo.mutation.decide", lazyHandler(() => import("./coordination/todo_lifecycle_decision.ts"), ({evaluateCoordinationTodoMutationDecision}) => evaluateCoordinationTodoMutationDecision)], ["todo.ownership_gate.decide", lazyHandler(() => import("./coordination/todo_lifecycle_decision.ts"), ({evaluateTodoOwnershipGate}) => evaluateTodoOwnershipGate)], @@ -332,13 +310,11 @@ export function createEffectRuntimeHandlers( ["todo.quota_planning.project", lazyHandler(() => import("./todos/quota_selection.ts"), ({projectTodoQuotaPlanning}) => projectTodoQuotaPlanning)], ["todo.frontier_revision.project", lazyHandler(() => import("./todos/frontier_revision.ts"), ({projectAdvancementFrontier}) => projectAdvancementFrontier)], ["goal.long_todo_chain.evaluate", lazyHandler(() => import("./todos/frontier_revision.ts"), ({evaluateLongTodoChain}) => evaluateLongTodoChain)], - ["todo.external_wait.plan", lazyHandler(() => import("./todos/resume_condition.ts"), ({planTodoExternalWaitTransition}) => planTodoExternalWaitTransition)], ["scheduler.state_transition.evaluate", lazyHandler(() => import("./scheduler/state_transition_rules.ts"), ({evaluateSchedulerStateTransition}) => evaluateSchedulerStateTransition)], ["scheduler.hint.project", lazyHandler(() => import("./scheduler/hint.ts"), ({projectSchedulerHint}) => projectSchedulerHint)], ["quota.automation_cadence.manage", lazyHandler(() => import("./quota/automation_cadence.ts"), ({manageAutomationCadence}) => manageAutomationCadence)], ["quota.automation_cadence.admit", lazyHandler(() => import("./quota/automation_cadence.ts"), ({admitAutomationStart}) => admitAutomationStart)], ["quota.automation_cadence.confirm_start", lazyHandler(() => import("./quota/automation_cadence.ts"), ({confirmAutomationStart}) => confirmAutomationStart)], - ["quota.automation_cadence.schedule", lazyHandler(() => import("./quota/automation_cadence.ts"), ({projectCadenceSchedule}) => projectCadenceSchedule)], ["scheduler.state.evaluate", lazyHandler(() => import("./scheduler/state_store.ts"), ({evaluateSchedulerStateOperation}) => evaluateSchedulerStateOperation)], ["scheduler.state.load", lazyHandler(() => import("./scheduler/state_store.ts"), ({loadSchedulerState}) => loadSchedulerState)], ["scheduler.state.write", lazyHandler(() => import("./scheduler/state_store.ts"), ({writeSchedulerState}) => writeSchedulerState)], @@ -351,12 +327,9 @@ export function createEffectRuntimeHandlers( "work_item.action_selection.reconcile_retained", lazyHandler(() => import("./work_items/action_portfolio.ts"), ({reconcileRetainedActionSelection}) => reconcileRetainedActionSelection), ], - ["work_item.planning_horizon.project", lazyHandler(() => import("./work_items/planning_horizon.ts"), ({projectQuotaPlanningHorizon}) => projectQuotaPlanningHorizon)], ["todo.context.page", lazyHandler(() => import("./todos/context_projection.ts"), ({projectTodoContextPage}) => projectTodoContextPage)], ["work_item.task_graph.topology", lazyHandler(() => import("./work_items/task_graph.ts"), ({projectTaskGraphTopology}) => projectTaskGraphTopology)], ["work_item.task_graph.goal_topology", lazyHandler(() => import("./work_items/task_graph.ts"), ({projectGoalTaskMap}) => projectGoalTaskMap)], - ["work_item.planning_inventory.project", lazyHandler(() => import("./work_items/planning_inventory.ts"), ({projectTodoPlanningInventory}) => projectTodoPlanningInventory)], - ["work_item.planning_inventory.detail", lazyHandler(() => import("./work_items/planning_inventory.ts"), ({projectTodoPlanningInventoryDetail}) => projectTodoPlanningInventoryDetail)], ["work_item.refresh_recommendation.resolve", lazyHandler(() => import("./work_items/refresh_recommendation.ts"), ({resolveRefreshRecommendation}) => resolveRefreshRecommendation)], ["work_item.refresh_recommendation.lane", lazyHandler(() => import("./work_items/refresh_recommendation.ts"), ({resolveLaneRecommendation}) => resolveLaneRecommendation)], ["work_item.delivery_history.project", lazyHandler(() => import("./work_items/delivery_history.ts"), ({projectDeliveryHistory}) => projectDeliveryHistory)], @@ -366,7 +339,6 @@ export function createEffectRuntimeHandlers( ["goal.checkpoint_read_context.resolve", lazyHandler(() => import("./goals/checkpoint_authority.ts"), ({resolveCheckpointReadContext}) => resolveCheckpointReadContext)], ["goal.checkpoint_read_context.commit", lazyHandler(() => import("./goals/checkpoint_commit.ts"), ({commitCheckpoint}) => commitCheckpoint)], ["goal.checkpoint_read_context.inspect_replay", lazyHandler(() => import("./goals/checkpoint_commit.ts"), ({inspectCheckpointReplay}) => inspectCheckpointReplay)], - ["goal.vision_wait.coverage", lazyHandler(() => import("./goals/vision_wait_coverage.ts"), ({projectVisionWaitCoverage}) => projectVisionWaitCoverage)], ["goal.vision_wait.project", lazyHandler(() => import("./goals/vision_wait_coverage.ts"), ({projectGoalVisionWaitState}) => projectGoalVisionWaitState)], ["goal.shared_goal_alignment.project", lazyHandler(() => import("./goals/shared_goal_alignment.ts"), ({projectSharedGoalAlignment}) => projectSharedGoalAlignment)], ["goal.operator_actions.project", lazyHandler(() => import("./goals/operator_actions.ts"), ({projectGoalOperatorActions}) => projectGoalOperatorActions)], @@ -409,7 +381,6 @@ export function createEffectRuntimeHandlers( ["quota.turn_envelope.evaluate", lazyHandler(() => import("./quota/turn_envelope.ts"), ({evaluateTurnEnvelope}) => evaluateTurnEnvelope)], ["quota.run_decision", lazyHandler(() => import("./quota/run_decision.ts"), ({resolveQuotaRunDecision}) => resolveQuotaRunDecision)], ["quota.scoped_override.project", lazyHandler(() => import("./quota/scoped_override.ts"), ({projectScopedOverride}) => projectScopedOverride)], - ["task_lease.owner_eligibility", lazyHandler(() => import("./work_items/task_lease_eligibility.ts"), ({evaluateTaskLeaseOwnerEligibility}) => evaluateTaskLeaseOwnerEligibility)], ["task_lease.acquire.native", lazyHandler(() => import("./work_items/task_lease_acquire.ts"), ({executeTaskLeaseAcquire}) => executeTaskLeaseAcquire)], ["task_lease.inspect.native", lazyHandler(() => import("./work_items/task_lease_inspection.ts"), ({inspectTaskLease}) => inspectTaskLease)], ["task_lease.lifecycle.native", lazyHandler(() => import("./work_items/task_lease_lifecycle.ts"), ({executeTaskLeaseLifecycle}) => executeTaskLeaseLifecycle)], @@ -451,15 +422,10 @@ export function createEffectRuntimeHandlers( ["coordination.local_authority.todo_read", lazyHandler(() => import("./coordination/local_authority_read.ts"), ({readLocalCoordinationTodo}) => readLocalCoordinationTodo)], ["coordination.local_authority.operation_receipt", lazyHandler(() => import("./coordination/local_authority_read.ts"), ({readLocalCoordinationOperationReceipt}) => readLocalCoordinationOperationReceipt)], ["coordination.local_authority.todo_source", lazyHandler(() => import("./coordination/local_authority_read.ts"), ({readLocalCoordinationTodoSource}) => readLocalCoordinationTodoSource)], - ["coordination.ownership_observation", lazyHandler(() => import("./coordination/ownership_observation.ts"), ({projectOwnershipObservation}) => projectOwnershipObservation)], ["coordination.local_authority.ownership_observation", lazyHandler(() => import("./coordination/local_authority_runtime.ts"), ({observeLocalCoordinationOwnership}) => observeLocalCoordinationOwnership)], ["coordination.local_authority.todo_snapshot_page", lazyHandler(() => import("./coordination/canonical_snapshot_page.ts"), ({readCanonicalSnapshotPage}) => readCanonicalSnapshotPage)], ["coordination.local_authority.todo_snapshot", lazyHandler(() => import("./coordination/canonical_snapshot_page.ts"), ({readCanonicalSnapshot}) => readCanonicalSnapshot)], ["coordination.local_authority.todo_list", lazyHandler(() => import("./coordination/local_authority_read.ts"), ({listLocalCoordinationTodos}) => listLocalCoordinationTodos)], - [ - "coordination.local_authority.legacy_writer_fence.engage", - lazyHandler(() => import("./coordination/legacy_writer_fence.ts"), ({engageLegacyCoordinationWriterFence}) => engageLegacyCoordinationWriterFence), - ], [ "coordination.local_authority.legacy_write_check", lazyHandler(() => import("./coordination/legacy_writer_fence.ts"), ({checkLegacyCoordinationWriteAllowed}) => checkLegacyCoordinationWriteAllowed), @@ -487,7 +453,6 @@ export function createEffectRuntimeHandlers( ["operation.agent_handoff.actor", lazyHandler(() => import("./work_items/operation_agent_handoff.ts"), ({deriveAgentOperationActor}) => deriveAgentOperationActor)], ["operation.agent_handoff.plan", lazyHandler(() => import("./work_items/operation_agent_handoff.ts"), ({planAgentOperationHandoff}) => planAgentOperationHandoff)], ["operation.agent_handoff.inbox", lazyHandler(() => import("./work_items/operation_agent_handoff.ts"), ({projectAgentOperationInbox}) => projectAgentOperationInbox)], - ["scheduler.monitor_successor.plan", lazyHandler(() => import("./scheduler/monitor_successor.ts"), ({planMonitorSuccessor}) => planMonitorSuccessor)], ["scheduler.monitor_batch.replay", lazyHandler(() => import("./scheduler/monitor_batch.ts"), ({replayLegacyMonitorBatch}) => replayLegacyMonitorBatch)], ["scheduler.monitor_target.select", lazyHandler(() => import("./scheduler/monitor_successor.ts"), ({selectMonitorTodoRequest}) => selectMonitorTodoRequest)], ["capabilities.issue_fix.monitor_reconciliation.plan", lazyHandler(() => import("./capabilities/issue_fix_monitor_reconciliation.ts"), ({planIssueFixMonitorReconciliation}) => planIssueFixMonitorReconciliation)], @@ -496,8 +461,6 @@ export function createEffectRuntimeHandlers( ["capabilities.pr_review.conclusion.select", lazyHandler(() => import("./capabilities/pr_review_approval_closeout.ts"), ({selectPrReviewConclusion}) => selectPrReviewConclusion)], ["capabilities.pr_review.configuration", lazyHandler(() => import("./capabilities/pr_review_order.ts"), ({prReviewConfiguration}) => prReviewConfiguration)], ["capabilities.pr_review.order", lazyHandler(() => import("./capabilities/pr_review_order.ts"), ({orderPrReviewQueue}) => orderPrReviewQueue)], - ["coordination.local_authority_shadow.record", lazyHandler(() => import("./coordination/local_authority_shadow.ts"), ({recordLocalAuthorityShadow}) => recordLocalAuthorityShadow)], - ["coordination.runtime_shadow.commit_entry", lazyHandler(() => import("./coordination/shadow_entry_delivery.ts"), ({deliverShadowEntry}) => deliverShadowEntry)], ["coordination.runtime_shadow.outbox_read", lazyHandler(() => import("./coordination/local_authority_shadow.ts"), ({readLocalAuthorityShadow}) => readLocalAuthorityShadow)], ["coordination.runtime_shadow.drain", lazyHandler(() => import("./coordination/shadow_drain.ts"), ({drainShadowOutbox}) => drainShadowOutbox)], ["coordination.cold_source.import", lazyHandler(() => Promise.all([import("./coordination/cold_source_import.ts"), import("./coordination/source_transfer.ts")]), ([{executeColdSourceImport}, {withCoordinationSourceTransfer}]) => withCoordinationSourceTransfer("coordination.cold_source.import", executeColdSourceImport))], @@ -522,14 +485,6 @@ export function createEffectRuntimeHandlers( asObject(params.identity), ), ], - [ - "governed_capability.validate_admission", - lazyHandler(() => import("./governed_capability.ts"), ({validateGovernedCapabilityAdmission}) => (params) => validateGovernedCapabilityAdmission({ - admission: params.admission, - todo_id: requiredString(params.todo_id, "todo_id"), - todo_contract: params.todo_contract, - })), - ], [ "governed_capability.validate_result", lazyHandler(() => import("./governed_capability.ts"), ({validateGovernedCapabilityResult}) => (params) => validateGovernedCapabilityResult({ @@ -553,10 +508,6 @@ export function createEffectRuntimeHandlers( require_receipt_digest: params.require_receipt_digest === true, })), ], - [ - "governed_capability.settlement_status", - lazyHandler(() => import("./governed_capability.ts"), ({governedCapabilitySettlementStatus}) => (params) => governedCapabilitySettlementStatus(params.failure)), - ], [ "quota.peer_orchestration.project", lazyHandler(() => import("./quota/peer_orchestration.ts"), ({projectPeerOrchestration}) => (params) => projectPeerOrchestration(params)), @@ -621,7 +572,6 @@ export function createEffectRuntimeHandlers( ["collaboration.delegation.lane_readiness", lazyHandler(() => import("./collaboration/delegation.ts"), ({delegationLaneReadiness}) => delegationLaneReadiness)], ["collaboration.delegation.validation_plan", lazyHandler(() => import("./collaboration/delegation.ts"), ({delegationValidationPlan}) => delegationValidationPlan)], ["collaboration.delegation.checked_artifacts", lazyHandler(() => import("./collaboration/delegation.ts"), ({delegationCheckedArtifacts}) => delegationCheckedArtifacts)], - ["collaboration.delegation.turn_plan", lazyHandler(() => import("./collaboration/delegation.ts"), ({delegationTurnPlanDecision}) => delegationTurnPlanDecision)], ["collaboration.delegation.inventory_query", lazyHandler(() => import("./collaboration/delegation.ts"), ({delegationInventoryQuery}) => delegationInventoryQuery)], ["collaboration.delegation.inventory_page", lazyHandler(() => import("./collaboration/delegation.ts"), ({delegationInventoryPage}) => delegationInventoryPage)], ["collaboration.chat_mode", lazyHandler(() => import("./collaboration/chat_mode.ts"), ({planChatMode}) => planChatMode)], @@ -786,14 +736,6 @@ export function createEffectRuntimeHandlers( quota_spend_present: params.quota_spend_present === true, })), ], - [ - "settlement.receipt_bound_terminal_phase", - lazyHandler(() => import("./quota/settlement_phase.ts"), ({receiptBoundTerminalPhase}) => (params) => receiptBoundTerminalPhase({ - terminal_closeout_present: params.terminal_closeout_present === true, - durable_writeback_present: params.durable_writeback_present === true, - quota_spend_present: params.quota_spend_present === true, - })), - ], [ "settlement.receipt", (params) => settlementReceipt( diff --git a/loopx/control_plane/governed_capability.ts b/loopx/control_plane/governed_capability.ts index 86fc4359c2..bda8947b2e 100644 --- a/loopx/control_plane/governed_capability.ts +++ b/loopx/control_plane/governed_capability.ts @@ -945,9 +945,3 @@ export function validateGovernedCapabilitySettlementCallback(input: { } return payload; } - -export function governedCapabilitySettlementStatus( - failure: unknown, -): "settlement_failed" | "committed" { - return failure === null ? "committed" : "settlement_failed"; -} diff --git a/loopx/control_plane/work_items/task_lease_eligibility.ts b/loopx/control_plane/work_items/task_lease_eligibility.ts index 4dfc33cad7..4822084b19 100644 --- a/loopx/control_plane/work_items/task_lease_eligibility.ts +++ b/loopx/control_plane/work_items/task_lease_eligibility.ts @@ -1,7 +1,5 @@ /** Owner eligibility is shared by acquisition, renewal, transfer and observation. * It is not a lease grant: time, mode, proof, CAS and release remain with callers. */ -import {EffectRuntimeRequestError} from "../effect_runtime_errors.ts"; -import {requireJsonObject} from "../runtime_decode.ts"; export interface LeaseEligibilityTodo { readonly status: string; @@ -48,35 +46,3 @@ export function leaseOwnerConstraint(todo: LeaseEligibilityTodo | null | undefin default: return {effective: false as const, reason}; } } - -function strings(value: unknown, label: string): string[] { - if (!Array.isArray(value) || value.some(item => typeof item !== "string")) { - throw new EffectRuntimeRequestError(`${label} must be an array of strings`); - } - return value as string[]; -} - -function nullableString(value: unknown, label: string): string | null { - if (value == null) return null; - if (typeof value !== "string") throw new EffectRuntimeRequestError(`${label} must be a string or null`); - return value; -} - -/** A narrow adapter for the still-shipped Python coordination/inspection API. - * Inputs are normalized facts, not Markdown or a second authority snapshot. */ -export function evaluateTaskLeaseOwnerEligibility(value: unknown) { - const input = requireJsonObject(value, "task lease owner eligibility"); - const raw = input.todo == null ? null : requireJsonObject(input.todo, "todo"); - let todo: LeaseEligibilityTodo | null = null; - if (raw !== null) { - if (typeof raw.status !== "string") throw new EffectRuntimeRequestError("todo.status must be a string"); - todo = {status: raw.status, task_class: nullableString(raw.task_class, "todo.task_class"), - claimed_by: nullableString(raw.claimed_by, "todo.claimed_by"), - excluded_agents: strings(raw.excluded_agents, "todo.excluded_agents")}; - } - const constraint = leaseOwnerConstraint(todo, nullableString(input.owner, "owner"), - strings(input.registered_agents, "registered_agents")); - return {schema_version: "task_lease_owner_eligibility_v0", - outcome: constraint.effective ? "apply" : "rejected", - code: constraint.effective ? "lease_owner_allowed" : constraint.reason, constraint}; -} diff --git a/tests/control_plane_ts/delegation.test.ts b/tests/control_plane_ts/delegation.test.ts index 4aea31d7f2..e0c44e450f 100644 --- a/tests/control_plane_ts/delegation.test.ts +++ b/tests/control_plane_ts/delegation.test.ts @@ -1,6 +1,6 @@ import test from "node:test"; import assert from "node:assert/strict"; -import {recordDelegationAdoption, decideDelegationStop, decideDelegationWakeObservation, delegationCheckedArtifacts, delegationInventoryItem, delegationInventoryQuery, delegationPreflight, delegationTurnPlanDecision, delegationTurnWorkContext, delegationValidationPlan, recoverValidatedDelegationSettlement, selectDelegationBinding, transitionDelegationObservation, verifyDelegationSourceReplay} from "../../loopx/control_plane/collaboration/delegation.ts"; +import {recordDelegationAdoption, decideDelegationStop, decideDelegationWakeObservation, delegationCheckedArtifacts, delegationInventoryItem, delegationInventoryQuery, delegationPreflight, delegationTurnWorkContext, delegationValidationPlan, recoverValidatedDelegationSettlement, selectDelegationBinding, transitionDelegationObservation, verifyDelegationSourceReplay} from "../../loopx/control_plane/collaboration/delegation.ts"; import {canonicalAuthoritySha256} from "../../loopx/control_plane/coordination/authority_store_codec.ts"; import {projectTurnSelectionRejection} from "../../loopx/control_plane/turn_driver/selection_rejection.ts"; @@ -741,16 +741,3 @@ test("workspace faults are bounded observations, not authority or launch permits assert.deepEqual(delegationPreflight({...unavailable, workspace: {state: "available"}}), delegationPreflight(unavailable)); }); - -test("Turn plan decision preserves a rejection and validates a successful transaction", () => { - const rejected = delegationTurnPlanDecision({plan: {ok: false, - error: "Requested Turn Todo is not accepted by canonical authority"}}); - assert.deepEqual(rejected, { - schema_version: "loopx_delegation_turn_plan_decision_v0", state: "rejected", - turn_key: null, reason: "Requested Turn Todo is not accepted by canonical authority", - }); - const turnKey = `sha256:${"a".repeat(64)}`; - assert.equal(delegationTurnPlanDecision({plan: {ok: true, - transaction: {turn_key: turnKey}}}).turn_key, turnKey); - assert.throws(() => delegationTurnPlanDecision({plan: {ok: true, transaction: {}}})); -}); diff --git a/tests/control_plane_ts/effect_runtime_handlers.test.ts b/tests/control_plane_ts/effect_runtime_handlers.test.ts index 1de7f3e0cf..ffd49683a0 100644 --- a/tests/control_plane_ts/effect_runtime_handlers.test.ts +++ b/tests/control_plane_ts/effect_runtime_handlers.test.ts @@ -228,3 +228,31 @@ test("preauthorized lease fence has no standalone runtime handler", async () => /unsupported Effect runtime method/, ); }); + +for (const retired of [ + "todo.field_update.plan", + "todo.public_update.plan", + "todo.claim.decide", + "todo.external_wait.plan", + "quota.automation_cadence.schedule", + "work_item.planning_horizon.project", + "work_item.planning_inventory.project", + "work_item.planning_inventory.detail", + "goal.vision_wait.coverage", + "task_lease.owner_eligibility", + "coordination.ownership_observation", + "coordination.local_authority.legacy_writer_fence.engage", + "scheduler.monitor_successor.plan", + "coordination.local_authority_shadow.record", + "coordination.runtime_shadow.commit_entry", + "governed_capability.validate_admission", + "governed_capability.settlement_status", + "collaboration.delegation.turn_plan", + "settlement.receipt_bound_terminal_phase", +]) { + test(`unused leaf RPC ${retired} fails closed`, async () => { + assert.equal(handlers.has(retired), false); + await assert.rejects(dispatchEffectRuntimeMethod(handlers, retired, {}), + {code: "unsupported_method"}); + }); +} diff --git a/tests/control_plane_ts/governed_capability.test.ts b/tests/control_plane_ts/governed_capability.test.ts index 9f6ba7f64e..a469e8922f 100644 --- a/tests/control_plane_ts/governed_capability.test.ts +++ b/tests/control_plane_ts/governed_capability.test.ts @@ -2,7 +2,6 @@ import assert from "node:assert/strict"; import test from "node:test"; import { - governedCapabilitySettlementStatus, validateGovernedCapabilityAdmission, validateGovernedCapabilityResult, validateGovernedCapabilitySettlementCallback, @@ -435,14 +434,6 @@ test("writeback proves the effect receipt before settlement can spend", () => { assert.equal(committed.ok, true); }); -test("settlement terminal state is TS-owned", () => { - assert.equal(governedCapabilitySettlementStatus(null), "committed"); - assert.equal( - governedCapabilitySettlementStatus({ kind: "quota_spend_rejected" }), - "settlement_failed", - ); -}); - test("one lifecycle packet validates an observed provider result and projects its receipt", () => { const journal = lifecycleJournal("starting", result("succeeded")); const reduction = reduceLifecycle(journal, "observe_result"); diff --git a/tests/control_plane_ts/local_authority_shadow.test.ts b/tests/control_plane_ts/local_authority_shadow.test.ts index d6a93256f3..0be0b61d1f 100644 --- a/tests/control_plane_ts/local_authority_shadow.test.ts +++ b/tests/control_plane_ts/local_authority_shadow.test.ts @@ -3,10 +3,10 @@ import { mkdtemp, readdir, rm } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; import test from "node:test"; -import { EffectRuntimeRequestError } from "../../loopx/control_plane/effect_runtime_errors.ts"; +import {createEffectRuntimeHandlers, dispatchEffectRuntimeMethod} from "../../loopx/control_plane/effect_runtime_handlers.ts"; import { FileAuthorityStore } from "../../loopx/control_plane/coordination/file_authority_store.ts"; import {localAuthorityShadowHeadDigest, localAuthorityShadowPartitionDigest, - recordLocalAuthorityShadow, readLocalAuthorityShadow} from "../../loopx/control_plane/coordination/local_authority_shadow.ts"; + readLocalAuthorityShadow} from "../../loopx/control_plane/coordination/local_authority_shadow.ts"; test("runtime shadow parity ignores only the resume evaluation observation clock", () => { const head = { @@ -62,11 +62,12 @@ test("runtime shadow parity ignores only the resume evaluation observation clock test("retired record RPC rejects even a stale client without creating any storage", async t => { const root = await mkdtemp(join(tmpdir(), "loopx-retired-observer-")); t.after(() => rm(root, {recursive: true, force: true})); - for (const request of [null, {}, {schema_version: "loopx_local_authority_shadow_request_v0", + const handlers = createEffectRuntimeHandlers({fingerprint: "test", requestShutdown: () => undefined}); + for (const request of [{}, {schema_version: "loopx_local_authority_shadow_request_v0", mode: "file_one_way", runtime_root: root, goal_id: "goal-a", observation_id: "old-op", source_digest: `sha256:${"a".repeat(64)}`, observation_trigger: "todo_update", source_projection: {}}]) { - await assert.rejects(recordLocalAuthorityShadow(request), error => - error instanceof EffectRuntimeRequestError && error.code === "local_authority_shadow_retired"); + await assert.rejects(dispatchEffectRuntimeMethod(handlers, "coordination.local_authority_shadow.record", request), + {code: "unsupported_method"}); } assert.deepEqual(await readdir(root), []); }); diff --git a/tests/control_plane_ts/task_lease_eligibility.test.ts b/tests/control_plane_ts/task_lease_eligibility.test.ts index 41409f123f..adc2b0179b 100644 --- a/tests/control_plane_ts/task_lease_eligibility.test.ts +++ b/tests/control_plane_ts/task_lease_eligibility.test.ts @@ -2,7 +2,7 @@ import assert from "node:assert/strict"; import test from "node:test"; import {evaluateTaskLeaseAcquireDecision} from "../../loopx/control_plane/work_items/task_lease_acquire_decision.ts"; import {decideTaskLeaseLifecycle, evaluateTaskLeaseLifecycleDecision} from "../../loopx/control_plane/work_items/task_lease_lifecycle_decision.ts"; -import {evaluateTaskLeaseOwnerEligibility, leaseOwnerRejection, type LeaseEligibilityTodo} from +import {leaseOwnerConstraint, leaseOwnerRejection, type LeaseEligibilityTodo} from "../../loopx/control_plane/work_items/task_lease_eligibility.ts"; import {productionScaleCoordinationFixture} from "./production_scale_coordination_fixture.ts"; @@ -45,8 +45,7 @@ test("release remains a fenced cleanup operation after owner eligibility is lost test("User actions cannot acquire, renew or transfer execution but retained leases can be released", () => { const action = {...todo, task_class: "user_action", bound_agent: "agent-a"}; for (const owner of ["agent-a", "agent-b"]) { - assert.equal(evaluateTaskLeaseOwnerEligibility({todo: action, owner, - registered_agents: ["agent-a", "agent-b"]}).code, "todo_not_executable"); + assert.equal(leaseOwnerRejection(action, owner, ["agent-a", "agent-b"]), "todo_not_executable"); assert.equal(evaluateTaskLeaseAcquireDecision({...acquire(false), todo: action, command: {...acquire(false).command, owner}}).code, "todo_not_executable"); } @@ -73,8 +72,9 @@ test("owner eligibility has one precedence across adapters and renewal", () => { ]; for (const row of cases) { assert.equal(leaseOwnerRejection(row.todo, row.owner, row.agents), row.reason); - const adapted = evaluateTaskLeaseOwnerEligibility({todo: row.todo, owner: row.owner, registered_agents: row.agents}); - assert.equal(adapted.code, row.reason ?? "lease_owner_allowed"); + const constraint = leaseOwnerConstraint(row.todo, row.owner, row.agents); + assert.equal(constraint.effective, row.reason === null); + if (!constraint.effective) assert.equal(constraint.reason, row.reason); if (!row.owner) continue; const renewed = decideTaskLeaseLifecycle({handoff_mode: "hard_lease", registered_agents: row.agents, todo: row.todo && {...row.todo, todo_id: "todo_target"}, lease, @@ -101,14 +101,9 @@ test("production-scale history preserves independent claim, exclusion and termin } }); -test("eligibility decoder rejects malformed facts and does not infer authorisation from prose", () => { - for (const patch of [{registered_agents: "agent-a"}, {owner: 1}, - {todo: {...todo, status: true}}, {todo: {...todo, excluded_agents: "agent-a"}}]) { - assert.throws(() => evaluateTaskLeaseOwnerEligibility({todo, owner: "agent-a", registered_agents: ["agent-a"], ...patch})); - } +test("owner eligibility does not infer authorisation from prose", () => { const described = {...todo, text: "approved owner agent-a; safe to proceed", claimed_by: "agent-b"}; - assert.equal(evaluateTaskLeaseOwnerEligibility({todo: described, owner: "agent-a", registered_agents: ["agent-a"]}).code, - "owner_conflicts_with_claim"); + assert.equal(leaseOwnerRejection(described, "agent-a", ["agent-a"]), "owner_conflicts_with_claim"); }); for (const generation of ["version", "lease_epoch"] as const) {