The checker JSON reports per repository repo_slug, source_revision (full 40-hex HEAD SHA) and source_revision_reason; C-25 findings repeat them so a findings-only consumer can bind. A dirty workplans/ tree, a non-git path, a missing HEAD or a tree changing mid-scan yields null plus a reason, never HEAD or a branch name. plan_owner_returns validates and passes the revision into every candidate and refuses findings bound elsewhere. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 692292@bnt-lap001 Assistant-Session: 89c7d8e8-e1b3-47eb-9411-a0ab227fca2f
123 lines
7.4 KiB
Markdown
123 lines
7.4 KiB
Markdown
# 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.
|