Graph route with an edge to a non-existent target node executes partially then exits silently instead of failing config validation #89

Open
opened 2026-07-31 18:50:14 +00:00 by CoreRasurae · 0 comments
Member

Metadata

  • Commit Message: fix(graph): reject edges targeting unknown nodes during validation
  • Branch: bugfix/m1-graph-edge-target-validation

Background and context

The Actor Configuration Standard requires that a graph route be structurally
sane before it is allowed to run. Two normative requirements govern this:

  • §11 (Validation Rules), preamble: validation "MUST be enforced at
    configuration-load time, before any agent is instantiated or any message is
    processed
    . Violations MUST be reported as ConfigurationError."
  • §11.3 Route Validation, item 4 (graph routes): "Each edge's source and
    target MUST refer to existing nodes (after START/END normalization)."
  • §6.11 Graph Analysis, item 5 (Edge validation): "every edge MUST be
    verified to reference existing nodes (after START/END normalization)."

Today the implementation does not enforce this at load time. Instead, an edge
whose target names a node that is not present in the graph's nodes mapping
is accepted silently, and the defect only manifests at runtime.

Current behavior

Given a graph route containing an edge whose target (or source) references a
node name that does not exist in nodes (and is not start/end after
normalization):

  • Configuration loads without error — no ConfigurationError is raised.
  • The actor begins executing and processes nodes normally up to the node
    that precedes the dangling edge.
  • When execution reaches the point where it must transition to the missing
    target node, it stops and exits silently, right before the transition —
    returning whatever partial output had accumulated.

The result is a partially-executed graph and a silent, hard-to-diagnose failure
instead of an up-front, actionable validation error. This violates the
"fail before execution" guarantee of §11 and the edge-validation requirements of
§11.3.4 and §6.11.5.

Expected behavior

Edge target/source sanity MUST be validated at configuration-load time, before
any agent is instantiated or any message is processed:

  • Loading a graph route where any edge target or source names a node absent
    from nodes (after START/END/start/end normalization) MUST raise a
    ConfigurationError.
  • The error MUST identify the offending edge (its source and target) and the
    specific unknown node name.
  • No agent is created and no message is processed when validation fails — the
    actor never executes partially.
  • Valid graphs (every edge references an existing node) continue to load and
    execute exactly as before.

Acceptance criteria

  • Loading a config with a graph edge whose target is not a defined node
    raises ConfigurationError at load time (before agent instantiation /
    message processing).
  • Loading a config with a graph edge whose source is not a defined node
    raises ConfigurationError at load time.
  • The raised error message names the offending edge (sourcetarget)
    and the unknown node name.
  • Edges referencing start/START/end/END are NOT flagged, since these
    nodes are auto-injected and normalized per §6.2.1 and §6.4.
  • A fully valid graph route loads without error and executes to completion
    unchanged (no regression).
  • On validation failure, no partial graph execution occurs and no output is
    emitted.

Supporting information

  • Spec: docs/index.md — §11 preamble (load-time validation, ConfigurationError),
    §11.3.4 (graph edge source/target must reference existing nodes), §6.11.5
    (edge validation), §6.4 (edge schema and START/END normalization),
    §6.2.1 (start/end auto-injection).
  • This is a spec-conformance gap: the validation is mandated but not currently
    enforced, so a malformed graph is detected only by silent runtime truncation.

Subtasks

  • Add edge source/target existence validation to graph-route configuration
    validation, run at load time (after start/end auto-injection and
    START/END normalization), raising ConfigurationError with the
    offending edge and unknown node name.
  • Ensure validation runs before agent instantiation and message processing
    per the §12.1 lifecycle ordering.
  • Tests (Behave): scenarios for invalid target, invalid source,
    start/end normalization not being flagged, and a valid graph loading
    cleanly. Add the failing-first regression scenario referenced by the
    companion TDD issue.
  • Tests (Robot): integration scenario asserting the CLI/loader rejects a
    malformed graph config with a ConfigurationError and non-zero exit,
    performing no execution.
  • Update CHANGELOG with a user-facing entry.
  • Verify coverage >= 97% via nox -s coverage_report.
  • Run nox (all default sessions), fix any errors.

Definition of Done

This issue is complete when:

  • All subtasks above are completed and checked off.
  • A Git commit is created where the first line matches the Commit Message in
    Metadata exactly.
  • The commit is pushed to the branch matching the Branch in Metadata exactly.
  • The companion TDD regression test (@tdd_issue / @tdd_issue_N) passes with
    @tdd_expected_fail removed.
  • The commit is submitted as a PR to master, reviewed, and merged.
## Metadata - **Commit Message:** `fix(graph): reject edges targeting unknown nodes during validation` - **Branch:** `bugfix/m1-graph-edge-target-validation` ## Background and context The Actor Configuration Standard requires that a graph route be structurally sane *before* it is allowed to run. Two normative requirements govern this: - **§11 (Validation Rules), preamble:** validation "MUST be enforced at configuration-load time, **before any agent is instantiated or any message is processed**. Violations MUST be reported as `ConfigurationError`." - **§11.3 Route Validation, item 4 (graph routes):** "Each edge's `source` and `target` MUST refer to existing nodes (after `START`/`END` normalization)." - **§6.11 Graph Analysis, item 5 (Edge validation):** "every edge MUST be verified to reference existing nodes (after `START`/`END` normalization)." Today the implementation does not enforce this at load time. Instead, an edge whose `target` names a node that is not present in the graph's `nodes` mapping is accepted silently, and the defect only manifests at runtime. ## Current behavior Given a graph route containing an edge whose `target` (or `source`) references a node name that does not exist in `nodes` (and is not `start`/`end` after normalization): - Configuration loads without error — no `ConfigurationError` is raised. - The actor begins executing and processes nodes normally **up to** the node that precedes the dangling edge. - When execution reaches the point where it must transition to the missing target node, it **stops and exits silently**, right before the transition — returning whatever partial output had accumulated. The result is a partially-executed graph and a silent, hard-to-diagnose failure instead of an up-front, actionable validation error. This violates the "fail before execution" guarantee of §11 and the edge-validation requirements of §11.3.4 and §6.11.5. ## Expected behavior Edge target/source sanity MUST be validated at configuration-load time, before any agent is instantiated or any message is processed: - Loading a graph route where any edge `target` or `source` names a node absent from `nodes` (after `START`/`END`/`start`/`end` normalization) MUST raise a `ConfigurationError`. - The error MUST identify the offending edge (its `source` and `target`) and the specific unknown node name. - No agent is created and no message is processed when validation fails — the actor never executes partially. - Valid graphs (every edge references an existing node) continue to load and execute exactly as before. ## Acceptance criteria - [ ] Loading a config with a graph edge whose `target` is not a defined node raises `ConfigurationError` at load time (before agent instantiation / message processing). - [ ] Loading a config with a graph edge whose `source` is not a defined node raises `ConfigurationError` at load time. - [ ] The raised error message names the offending edge (`source` → `target`) and the unknown node name. - [ ] Edges referencing `start`/`START`/`end`/`END` are NOT flagged, since these nodes are auto-injected and normalized per §6.2.1 and §6.4. - [ ] A fully valid graph route loads without error and executes to completion unchanged (no regression). - [ ] On validation failure, no partial graph execution occurs and no output is emitted. ## Supporting information - Spec: `docs/index.md` — §11 preamble (load-time validation, `ConfigurationError`), §11.3.4 (graph edge source/target must reference existing nodes), §6.11.5 (edge validation), §6.4 (edge schema and `START`/`END` normalization), §6.2.1 (`start`/`end` auto-injection). - This is a spec-conformance gap: the validation is mandated but not currently enforced, so a malformed graph is detected only by silent runtime truncation. ## Subtasks - [ ] Add edge source/target existence validation to graph-route configuration validation, run at load time (after `start`/`end` auto-injection and `START`/`END` normalization), raising `ConfigurationError` with the offending edge and unknown node name. - [ ] Ensure validation runs before agent instantiation and message processing per the §12.1 lifecycle ordering. - [ ] Tests (Behave): scenarios for invalid `target`, invalid `source`, `start`/`end` normalization not being flagged, and a valid graph loading cleanly. Add the failing-first regression scenario referenced by the companion TDD issue. - [ ] Tests (Robot): integration scenario asserting the CLI/loader rejects a malformed graph config with a `ConfigurationError` and non-zero exit, performing no execution. - [ ] Update CHANGELOG with a user-facing entry. - [ ] Verify coverage >= 97% via `nox -s coverage_report`. - [ ] Run `nox` (all default sessions), fix any errors. ## Definition of Done This issue is complete when: - All subtasks above are completed and checked off. - A Git commit is created where the first line matches the Commit Message in Metadata exactly. - The commit is pushed to the branch matching the Branch in Metadata exactly. - The companion TDD regression test (`@tdd_issue` / `@tdd_issue_N`) passes with `@tdd_expected_fail` removed. - The commit is submitted as a PR to `master`, reviewed, and merged.
CoreRasurae added this to the v2.1.0 milestone 2026-07-31 18:50:15 +00:00
CoreRasurae added the
State
Unverified
Type
Bug
Priority
Critical
labels 2026-07-31 18:50:15 +00:00
CoreRasurae added
State
Verified
and removed
State
Unverified
labels 2026-07-31 19:25:08 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Reference: cleveragents/cleveractors-core#89