Plectis
This page

Paper module

Bridge Campaign DAG Validation

The bridge campaign DAG validation component surfaces the public bridge_campaign_dag bundle and checks, over bounded public fixtures, that a fan-in campaign graph is well formed: unique labels, existing dependency edges, acyclicity, exactly one synthesis reaching a probe, barrier alignment, and a worker count within the provider safe-parallelism ceiling.

Contains 18 sections · 1 diagram · 2 references

The write-up

Bridge campaign fans

A bridge campaign fans parallel reads into one synthesis step, and this component recomputes the plan's structure to accept or reject it before anything runs, never dispatching or executing. A bridge campaign is a small plan that fans several parallel reads into one synthesis step. This component reads such a plan and decides whether it is well formed before anything runs. It does not dispatch agents and it does not execute the campaign. It reads the plan, recomputes its structure, and returns an accept or reject decision with the rule id that fired.

Result is metadata-only

The result is a metadata-only record of status, per-case rows, and rejecting rule ids, accepting two clean plans and rejecting two broken ones over the shipped fixtures. The result is a metadata-only record: a status, per-case rows, and the rule ids that rejected each malformed plan. Over the shipped fixtures it accepts two clean plans and rejects two broken ones.

Purpose

Late structural faults waste a whole run

A structurally broken campaign is expensive to discover late, so the honest question is which rule fired rather than trusting an ok field that can lie. A structurally broken campaign is expensive to discover late. A dependency loop, two synthesis steps, or a step that depends on a name that does not exist will each waste a whole run before the fault surfaces. Trusting a plan because it carries an "ok" field does not help: the field can lie. The honest question is "which rule fired," not "is the plan valid."

Recomputing the graph from the plan

The check recomputes the graph from the plan itself, deriving cycles, single-synthesis, and reaches-a-probe from node roles rather than a summary, so passing requires every recomputed rule to hold. So the check recomputes the graph from the plan itself. Cycle detection runs over the declared edges. Single-synthesis and reaches-a-probe are derived from the node roles and dependencies, not read from a summary. A malformed plan cannot pass, because passing requires every recomputed rule to hold.

How it works

Validator bundle and component runner

Two source files carry the mechanism: the engine bundle bridge_campaign_dag.py is the validator, and the component runner drives it over the fixtures and writes the records. Two source files carry the mechanism. The engine bundle src/microcosm_core/engine_room/bridge_campaign_dag.py is the validator. The component runner src/microcosm_core/organs/bridge_campaign_dag_validation.py drives it over the fixtures and writes the records.

validate_campaign conjoins every rule outcome

validate_campaign builds a ValidationResult and adds each rule's outcome, where any reject flips ok false, so the final ok is the conjunction of every CR/VR rule. validate_campaign takes one plan, a provider name, and a worker count. It builds a ValidationResult and calls result.add(rule_id, outcome, target, message) for each rule. An outcome of reject flips ok to false and appends the formatted decision to the error list, so the final ok is the conjunction of every rule. The rule families mirror the private source CR/VR ids over a subset:

RuleCheck
CR001 to CR005schema version, kind, kebab-case campaign_id, intent, and a public plan_path
CR017node labels are unique and non-empty
CR015, CR016, CR020known input_mode, a rationale when the mode is not result records-only, a valid role
CR010, CR011every depends_on names a real node; reducer and synthesis nodes depend on something
CR012the node graph is acyclic
CR013, CR006, CR014exactly one synthesis node; the barrier names it; it transitively reaches a probe
CR007 to CR009barrier description, continuation packet schema, bounded next action
VR005requested workers stay within the provider ceiling

Cycle detection, reachability, and worker caps

_cycle_labels marks cycles with a depth-first back-edge check, _reachable_dependencies walks the closure from the synthesis node for CR014, and VR005 caps workers per provider via SAFE_PARALLELISM. Cycle detection lives in _cycle_labels. It runs a depth-first walk with a visiting set and a visited set; a back-edge into a node still on the stack marks a cycle. _reachable_dependencies walks the dependency closure from the single synthesis node so CR014 can ask whether any reachable node is a probe. VR005 reads SAFE_PARALLELISM, which caps workers per provider: chatgpt 8, claude 2, gemini 3, local 4.

The runner turns fixtures into records

The runner loads each fixture, evaluates it against validate_campaign, and aggregates a pass only when every positive validated, every negative was rejected as expected, and both planted ids fired. The runner turns fixtures into records. _fixture_cases loads every JSON file under the input directory. _evaluate_case calls validate_campaign for one case, reads the reject rule ids with _reject_codes, and decides observed_ok. A positive case passes when the plan validated and matched its expected_ok. A negative case passes only when the plan was rejected and its expected rule ids from EXPECTED_NEGATIVE_CASES are among the firing rejections. build_result aggregates the rows: the overall status is pass only if there is at least one positive and one negative case, all positive cases validated, all negative cases were rejected as expected, and both planted negative ids are present. run writes the result, a compact card from result_card, and a validation record, each with body_in_receipt set to false.

Diagram of the mechanism (7 steps).
Campaign plannodes, deps, barrier,provider, workersCampaign plan nodes, deps, barrier, provider, workersIdentity and schemaCR001 to CR005Identity and schema CR001 to CR005Unique labels, roles,real dependency edgesUnique labels, roles, real dependency edgesAcyclicityCR012 depth-firstAcyclicity CR012 depth-firstOne synthesis reachesa probe, CR013 CR014One synthesis reaches a probe, CR013 CR014Worker ceilingVR005Worker ceiling VR005Accept or rejectwith the rule idAccept or reject with the rule id
Diagram source & refs
flowchart TD Spec["Campaign plan nodes, deps, barrier, provider, workers"] Identity["Identity and schema CR001 to CR005"] Labels["Unique labels, roles, real dependency edges"] Cycle["Acyclicity CR012 depth-first"] Synth["One synthesis reaches a probe, CR013 CR014"] Ceiling["Worker ceiling VR005"] Verdict["Accept or reject with the rule id"] Spec --> Identity --> Labels --> Cycle --> Synth --> Ceiling --> Verdict

Negative cases

Two planted rejections and two clean plans

The fixtures plant cycle_rejected firing CR012 and two_synthesis_rejected firing CR013 against two clean plans, and a rejection counts only when it names the exact rule it broke. The fixtures plant two malformed plans, both rejected by recomputation. cycle_rejected has a dependency loop and must fire CR012. two_synthesis_rejected declares two synthesis nodes and must fire CR013. The two accepted plans are linear_chain_ok, a probe to reducer to synthesis chain, and fan_in_ok, three probes into one reducer into one synthesis. A negative case counts as handled only when the plan was rejected and its named rule id appears in the rejections, so a rejection always names the rule it broke.

Prior Art Grounding

Ordinary graph engineering and the coverage contract

The engine bundle is a source-faithful refactor of ordinary graph engineering, claiming no external citation, its local prior art being the Plectis coverage contract requiring a scope limit and result record path. The engine bundle is a source-faithful public refactor of the private bridge campaign contract layer and its provider ceiling rule. The lineage is ordinary software engineering: schema validation, depth-first cycle detection on a directed graph, reachability over a dependency closure, and fixture-scoped regression cases. No external citation is claimed. The local prior art is the Plectis coverage contract, which requires each reader page to publish a scope limit, a grounding note, and a result record path rather than letting a generated structured source record stand in for the source.

Validation Result record Path

Run the component over its fixtures and write the records:

What a pass means and how to confirm

A pass means both clean plans validated and both broken plans were rejected with their expected rule ids, confirmed against the bundle by the coverage contract and corpus check. A pass means both clean plans validated and both broken plans were rejected with their expected rule ids. From the repository root, the coverage contract and the paper-module corpus check confirm this page against its bundle:

PYTHONPATH=src ./repo-pytest tests/test_plectis_paper_module_coverage_contract.py -q --tb=short
PYTHONPATH=src ./repo-python scripts/build_doctrine_projection.py --check-paper-module-corpus

Scope boundary

Scope limit

Proof boundary and scope limit

A green run shows well-formed plans validated and malformed ones rejected with the rule they broke over bounded fixtures, while the component neither dispatches, executes, nor authorizes launch. A green run shows that well-formed plans validated and malformed ones were rejected, each with the rule it broke, over the bounded public fixtures in this checkout. That is the strongest claim here, and it is the proof boundary. The scope limit: this component does not dispatch agents, execute campaigns, prove provider correctness or safety, or claim whole-system equivalence. It excludes launch, public sharing, external model access, or source-file changes. It reads a plan and returns a decision.

Context & evidence

In short Bridge Campaign DAG Validation is the public agent-orchestration replay for a fan-in campaign graph. It validates each campaign spec against a subset of the source CR/VR rule families: schema and identity, unique node labels, dependency edges that reference existing nodes, DFS acyclicity, exactly one synthesis node that reaches a probe, a barrier naming that synthesis, and a requested worker count within the provider safe-parallelism ceiling. It accepts a linear chain and a three-way fan-in, and self-falsifies: a cyclic campaign is rejected with CR012 and a two-synthesis campaign with CR013. It writes metadata-only result records and surfaces microcosm_core.engine_room.bridge_campaign_dag without dispatching agents or calling providers.

Scope limit Public fixture and result record evidence only; it validates campaign DAG structure and does not dispatch agents, execute campaigns, prove provider correctness or safety, and is not launch-scope decision or publishing-scope decision.

Source

Source Source module: src/microcosm_core/organs/bridge_campaign_dag_validation.py · Source module: src/microcosm_core/engine_room/bridge_campaign_dag.py · Design note · Source registry