You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
0.4.0: one vocabulary break, three renames landing together #32
Three renames are each agreed in principle and each breaking for both downstream consumers. They must land as ONE migration, not three — that is the only thing this issue adds over the three places they are currently recorded.
1. SubgraphBinding → GraphImplementation
Decided twice — the issue body and Boris, 2026-10-07: "YES GraphImplementation. Decided. already." Full argument in #9, including why "subgraph" is factually wrong (a subgraph of G is a subset of G's vertices; a child here is a separate graph whose result substitutes for one node).
subject, because the repo already uses that word — checks.py:547, and test_about_follows_the_subject_of_the_sentence_not_the_loop_variable. Reuse, not a coined synonym.
subject_kind as a stored enum, because the kinds are not distinguishable from the value: "normalize" (a node) and "trim_only" (a strategy) are both bare names. Only edges (a->b) and the whole design ("") can be told apart by inspection.
:: for nesting, pytest-style — Boris's suggestion. This is what A subgraph is just a Graph — SubgraphBinding → GraphImplementation (0.4.0) #9 actually needs: a child's finding currently returns about="orphan", which is not a node the caller holds, and two children each having an orphan produce findings spelled identically. Verified by running it — four findings, all 'orphan', none resolvable in the parent.
3. diff_diagram(a, b) → diagram(a, b)
Boris, 2026-10-08: "just curious ......why cant the interface be spec.diagram()"
It can, and it is nearly there: diagram() already takes strategy: StrategySpec | None, so diagram() and diagram(trim_only) both work today. Folding in the two-strategy case is a small signature change and a large vocabulary one — diff_diagram is in the README, the glossary, the generated reference table and both downstream repos.
⚠️upstream_diagram(strategy) stays separate. It returns their drawing, not ours, and its mandatory strategy argument is load-bearing documentation — see its docstring.
Why one migration
Both downstream repos (nobsmed-v2, ai_computer_use) track main, not a sha — so each break reaches them on their next uv sync. The 2026-10-07 rename cost two coordinated PRs plus a gh repo rename plus a lock refresh in each. Three separate breaks is that cost three times.
Precedent for no compat alias
0.2.0 (NodeSpec(...) → TypeError) and 0.3.0 (check() → coherence_check()) both broke cleanly with no alias, and #5's commit message gives the reason: "one concept had two names." An alias re-creates exactly that.
⛔ And the measured consequence of a no-alias break, so it is planned for rather than discovered: 0.3.0's check() removal broke 18 call sites in nobsmed-v2, which only worked because its lock pinned an older commit. The lock refresh was the moment they would have started raising AttributeError.
Three renames are each agreed in principle and each breaking for both downstream consumers. They must land as ONE migration, not three — that is the only thing this issue adds over the three places they are currently recorded.
1.
SubgraphBinding→GraphImplementationDecided twice — the issue body and Boris, 2026-10-07: "YES GraphImplementation. Decided. already." Full argument in #9, including why "subgraph" is factually wrong (a subgraph of G is a subset of G's vertices; a child here is a separate graph whose result substitutes for one node).
2.
about→subject+subject_kind, with::pathsProposal and measurements in
docs/naming-potential-incoherence.md.subject, because the repo already uses that word —checks.py:547, andtest_about_follows_the_subject_of_the_sentence_not_the_loop_variable. Reuse, not a coined synonym.subject_kindas a stored enum, because the kinds are not distinguishable from the value:"normalize"(a node) and"trim_only"(a strategy) are both bare names. Only edges (a->b) and the whole design ("") can be told apart by inspection.::for nesting, pytest-style — Boris's suggestion. This is what A subgraph is just a Graph — SubgraphBinding → GraphImplementation (0.4.0) #9 actually needs: a child's finding currently returnsabout="orphan", which is not a node the caller holds, and two children each having anorphanproduce findings spelled identically. Verified by running it — four findings, all'orphan', none resolvable in the parent.3.
diff_diagram(a, b)→diagram(a, b)Boris, 2026-10-08: "just curious ......why cant the interface be
spec.diagram()"It can, and it is nearly there:
diagram()already takesstrategy: StrategySpec | None, sodiagram()anddiagram(trim_only)both work today. Folding in the two-strategy case is a small signature change and a large vocabulary one —diff_diagramis in the README, the glossary, the generated reference table and both downstream repos.upstream_diagram(strategy)stays separate. It returns their drawing, not ours, and its mandatorystrategyargument is load-bearing documentation — see its docstring.Why one migration
Both downstream repos (
nobsmed-v2,ai_computer_use) trackmain, not a sha — so each break reaches them on their nextuv sync. The 2026-10-07 rename cost two coordinated PRs plus agh repo renameplus a lock refresh in each. Three separate breaks is that cost three times.Precedent for no compat alias
0.2.0 (
NodeSpec(...)→TypeError) and 0.3.0 (check()→coherence_check()) both broke cleanly with no alias, and #5's commit message gives the reason: "one concept had two names." An alias re-creates exactly that.⛔ And the measured consequence of a no-alias break, so it is planned for rather than discovered: 0.3.0's
check()removal broke 18 call sites in nobsmed-v2, which only worked because its lock pinned an older commit. The lock refresh was the moment they would have started raisingAttributeError.