# Owner-return pickup preparation STATE-WP-0094-T03 selects the existing Activity Core ActivityDefinition → ops_run → admitted owner harness path for recurring pickup. State Hub does not claim ops runs and its workplan launch queue is retired. This selection is a source integration boundary, not evidence that a definition or owner harness is admitted. `scripts/owner_return_handoff.py` consumes the existing consistency checker's C-25 JSON. It produces deterministic event identities from repository, task record ID and message UUID. Duplicate findings and reordered scans yield the same candidates. Eligible candidates are reviewable owner returns, not unblocked tasks. The event is suitable for TaskSpec.triggering_event_id; the existing Activity Core idempotency key also includes the admitted definition and source IDs. Supply the approved ActivityDefinition UUID explicitly. Before any future dispatch, obtain fresh Activity Core `/ops-runs` rows for the configured definition/repository. The planner correlates definition, repository and event: open/claimed remain pending, succeeded is completed pickup, and failed/expired require owner reconciliation. Duplicate correlated rows fail closed. Completed pickup does not imply the task's blocker is resolved or its file status should change. Malformed identities and checker collection errors fail closed. The module never opens a socket, schedules, dispatches, persists a receipt or changes a task. It does not invent a competing receipt ledger. ## Remaining T03 integration The Activity Core owner must identify an admitted definition, pinned harness profile and repository authority for the pickup; accept event/source binding; and supply the callable submission/receipt adapter. Use the existing ops-run unique key, lease and exact-repeat terminal close semantics. A list snapshot alone is not atomic dispatch: actual insertion must retain that server-side uniqueness. Message results must be paginated upstream: C-25 currently fetches at most 200 replies per counterpart, so a planner cannot claim complete coverage. An owner-approved review must precede live activation. No schedule was changed. References: Activity Core `docs/execution-queue-boundary.md`, `docs/ops-run-queue.md`, `src/activity_core/ops_run_queue.py` (TaskSpec key and row projection); State Hub `api/services/execution_queue.py` and `api/routers/ops_runs.py` (read-only summary). ## T05 graph freshness assessment The authorized receiving rollout and immutable qualifier/null-clear parity are recorded separately in `docs/evidence/2026-10-04-receiving-rollout.json`. They do not establish task-edge or scheduled freshness coverage. Current `api/services/forge_projection.py` neither derives `depends_on` edges nor reconciles WorkplanDependency rows. The snapshot returns existing edges, which is not evidence that normal Forge receiving maintains them. In contrast, `scripts/consistency_check.py` C-20 indexes frontmatter and task-block edges, using `from_task_id`; its fix path calls the dependency API. C-40 independently reads authoritative source target status. Task-level dependency schema support therefore exists while the normal receiving gap remains real. A bounded next receiving design must define full source edge ownership, cross-repository target resolution, missing/ambiguous targets, edge removal, transactional failure and repeat noop; it must preserve externally authored relations instead of deleting every dependency row. Adding graph receiving without that contract would create another destructive projection risk. Current chart values disable legacy sweep; workstation checkout traversal is excluded by ADR-002. Activity Core owns scheduling and Repo Manager owns the C-rule engine. No source reading or one successful normal sync establishes actual live schedule coverage, freshness SLA or full repository coverage. Retain T05 progress until accepted edge receiving and bounded freshness evidence include exact runner revision, active definition, per-repository source commit, last successful receipt, failed/queued receipts and measured freshness window. Historical registrar failures remain explicit coverage holes. Do not revive legacy --all --remote sweeping or collapse T03 pickup into T05 index freshness. ## Validation The staged offline module and regression suite passed 13 tests on 2026-10-04. The tests cover pair identity and replay, existing pending/success/failure rows, wrong-definition/repository/event receipts, ambiguous duplicate receipts, malformed message identity, collection error and legacy workplan-only warnings. This proves source planning behavior, not deployed pickup or owner acceptance. ## Current eligibility guard (review refinement) C-25 alone also reports owner replies on tasks that still require a human. The first 13-test preparation did not model this independent gate. Review found that omission before commit/activation; the refinement requires `current_tasks` and an explicit `observed_on` date. Its 30 offline tests pass. No automated pickup was dispatched by either preparation. Callers must build the mapping from fresh authoritative source, keyed by task record ID, and bind it to the same repository/source revision used for the scan. Each row explicitly includes `target_repo`, `task_record_id`, task `status`, `workplan_status`, `workplan_flavor`, boolean `needs_human`, `blocked_on`, `depends_on`, `predecessor_statuses`, `wait_until`, `decision_id` and `decision_status`. Resolve every task/workplan predecessor and the decision from the authoritative current graph; missing targets remain unknown. The offline module cannot authenticate a supplied source snapshot, so acquisition/binding is a mandatory part of the pending adapter contract. Never manufacture an empty predecessor list to compensate for the existing Forge dependency-edge gap. Missing eligibility fields refuse planning. Human-needed work, unresolved or unknown decisions, residual flavor, closed workplans, non-wait tasks, mismatched repo/task/owner marker, nonterminal or unknown predecessors and future windows produce `stopped`. Even matching successful ops-run history cannot override a current safety stop. Residual promotion means an authoritative flavor change; a comment or receipt does not promote it. Terminal predecessors/resolved non-human decisions and elapsed windows can leave an owner-return wait `reviewable`; that disposition permits review preparation only and never clears the wait marker, task status, human gate or any other field. ## Scanned source revision The checker JSON (`--json`) states the commit it scanned, per repository: `repo_slug`, `source_revision` (full 40-hex lowercase HEAD SHA) and `source_revision_reason`. Every C-25 finding repeats the same three fields so a consumer of the findings alone can bind. The revision is claimed only when `workplans/` has no modified, staged, untracked or ignored change and the tree did not move while the files were read and C-25 ran; otherwise `source_revision` is `null` with a reason (`not_a_git_tree`, `no_head_commit`, `unsupported_object_format`, `dirty_workplans`, `git_status_failed`, `changed_during_scan`, `not_scanned`). It is never a branch name or a guess. `plan_owner_returns` validates it (40-hex or null), refuses findings bound to a different repository/revision and copies it into every candidate; the deduplication event identity stays revision-independent. Activity Core's eligibility builder compares it to its `scan_revision`, so `null` refuses.