4.5 KiB
Axiom Relation Resolver Bug: Parent-Child BINDS_TO
Summary
The relation resolver fails to resolve @RELATION BINDS_TO -> [ParentContractId] when the target is a parent #region in the same file and the children are nested inside it. The parent contract exists in the index (read_outline shows it), but search_contracts does not return it — suggesting the parent fails to register in the graph, causing all child BINDS_TO edges to become unresolved_relation.
Impact: ~550 of 638 unresolved_relation warnings (~86%).
Reproduction
File: backend/src/api/routes/__tests__/test_assistant_api.py
# #region AssistantApiTests [TYPE Module] [C:3] [SEMANTICS tests, assistant, api]
# @BRIEF Validate assistant API endpoint logic via direct async handler invocation.
# @RELATION DEPENDS_ON -> [AssistantApi]
import asyncio
...
# #region _run_async [TYPE Function]
# @RELATION BINDS_TO -> [AssistantApiTests] ← unresolved_relation
def _run_async(coro):
return asyncio.run(coro)
# #endregion _run_async
# #region test_unknown_command_returns_needs_clarification [TYPE Function]
# @RELATION BINDS_TO -> [AssistantApiTests] ← unresolved_relation
def test_unknown_command_returns_needs_clarification(monkeypatch):
...
# #endregion test_unknown_command_returns_needs_clarification
... (17 children total, all BINDS_TO flagged)
# #endregion AssistantApiTests
Observations
read_outlineon the file returns the parentAssistantApiTestscorrectly — it exists structurally.search_contracts query="AssistantApiTests"returns ONLY the 8 children — the parent is NOT in results.- All 17 children have
@RELATION BINDS_TO -> [AssistantApiTests]— all markedunresolved_relation. - The parent
#region AssistantApiTestswraps the entire file, opens at line 4, closes at the last line.
Checked hypotheses (ruled out)
| Hypothesis | Ruled out by |
|---|---|
@TAG: colon format breaks registration |
Colon was there, but even after fixing 2216 colon instances across the codebase, the parent still doesn't register in the graph |
Brackets vs no-brackets in BINDS_TO syntax |
Both -> AssistantApiTests (no brackets) and -> [AssistantApiTests] (with brackets) fail identically |
@INVARIANT: tag parsing failure |
The colon in tags was normalized, but other parents without that tag also fail |
| Duplicate relation edges | Removed duplicates from auth.py; test files have no duplicates |
| Tag forbidden by complexity | Config now allows ALL tags at ALL tiers (C1-C5) |
Likely root cause
The relation graph builder processes the parent #region at file-open time but the children's BINDS_TO references are resolved before the parent node is fully registered in the graph. This is a timing/order-of-operations issue in the Rust parser.
Alternatively: when the parent contract's body contains code (imports, helper functions) mixed with metadata, the parser may consider the parent "not a valid contract" and skip it, making all child references dangling.
Affected files (same pattern)
backend/src/api/routes/__tests__/test_assistant_api.py — 17 children → AssistantApiTests
backend/src/api/routes/__tests__/test_assistant_authz.py — 3 children → TestAssistantAuthz
backend/src/api/routes/__tests__/test_clean_release_api.py — 4 children → TestCleanReleaseApi
backend/src/api/routes/__tests__/test_clean_release_legacy_compat.py — 2 children
backend/src/api/routes/__tests__/test_clean_release_source_policy.py — 2 children
backend/src/api/routes/__tests__/test_clean_release_v2_api.py — 3 children
backend/src/api/routes/__tests__/test_clean_release_v2_release_api.py — 3 children
backend/src/api/routes/__tests__/test_dashboards.py — 25 children → DashboardsApiTests
backend/tests/core/test_defensive_guards.py — 2 children → UnknownModule
... and more across the codebase (~550 total)
Expected behavior
If a child contract is nested inside a parent #region/#endregion pair and the child has @RELATION BINDS_TO -> [ParentId], the resolver should:
- Register the parent contract
ParentIdin the graph - Resolve
BINDS_TO -> [ParentId]as a valid edge pointing toParentId
Fix suggestion
In the Rust relation resolver (axiom-mcp-server-rs):
- When processing a file, register parent contracts before resolving their children's relation edges
- Ensure the parent node is added to the graph even if it contains code blocks between its opening anchor and first metadata tag