Skip to content

audit-pass: cross-epoch carry-forward, and audit-instructions needs a scope that suppresses the conflict pass #1430

Description

@kyle-sexton

Two defects found by cross-vendor review against #1318 are real, but neither can be settled by the run contract that PR ships. Both need either an implementation to constrain them or a change to a delegated interface, so they are recorded here rather than specified in prose against an artifact nobody has written.

1. Cross-epoch carry-forward on lease adoption

reference/run-contract.md §3 makes the partial artifact epoch-scoped — findings.partial.<owner_epoch>.jsonl — so a fenced writer cannot interleave into its adopter's file, and §7 has assembly read only the highest epoch present.

§5 independently says a completed, detection-qualified lane whose input digest is unchanged is skipped on resume and its findings carried forward.

Those two compose badly. When a stale run is adopted after some lanes completed, those lanes' records exist only in the superseded epoch file, and "assembly reads only the highest epoch" drops them — so the carried-forward lanes silently vanish from the final report.

Two candidate resolutions, and the choice depends on the artifact:

  • Adoption copies the superseded epoch's terminated, uninvalidated attempts into the new epoch file before the adopter writes anything. Simple assembly, a copy cost proportional to work already done, and the copy is itself a write that must be crash-safe.
  • Assembly merges across epochs, taking per lane the highest-ordinal terminated attempt in the highest epoch that contains one. No copy, but assembly stops being a single-file read and needs its own fencing story against a writer still appending to a lower epoch.

The property that must hold either way: a lane completed before adoption appears exactly once in the assembled report, and a lane invalidated before adoption does not appear at all.

2. audit-instructions has no scope that suppresses Phase B2

#1318 dispatches the cross-surface conflict pass exactly once, through audit-instructions' conflicts scope, so that each conflict pair belongs to one lane. That fix requires the per-class lanes (skills, agents, …) to not also return conflict pairs.

They currently do. audit-instructions offers only the surface-class scopes and conflicts, and Phase B2 runs for scoped invocations, reporting a pair whenever at least one anchor falls in the requested scope. So a conflict spanning a skill body and an agent definition still comes back from the skills lane and the agents lane, with the same identity, and the partial-log contract has no cross-lane ownership rule to dedupe it.

This is a change to the delegated interface, not to audit-pass — the same boundary that keeps the pass from reading inside another plugin. Options:

  • A scope modifier that runs the per-surface catalog without Phase B2 (skills --no-conflicts, or a surfaces scope meaning "every class, no pair pass").
  • Phase B2 reporting a pair only when every anchor is in the requested scope, which makes the per-class lanes naturally disjoint but changes what a bare scoped invocation returns for a human caller.

Until one lands, audit-pass cannot implement the single-conflict-lane rule from its side, and the duplicate is only avoidable by dispatching conflicts alone and accepting that the per-class lanes carry redundant pairs.

Why these are here and not in #1318

#1318 ships a design record and a skill body; it ships no executable implementation. Specifying a cross-epoch merge protocol or a delegate scope modifier in prose, with nothing to test either against, is how a contract accumulates detail that the eventual implementation then contradicts. Both are recorded with the property that must hold and the owner that must hold it.

Raised by chatgpt-codex-connector on #1318 (threads on run-contract.md:304 and SKILL.md:196).

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.priority: mediumReal value, no hard deadline; normal backlog flow.status: readyTriaged, unblocked, and fully specified; eligible to pick up.work-class: structuralRefactors, migrations, contract changes; cross-cutting and hard to reverse.

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions