Skip to content

0.4.0: one vocabulary break, three renames landing together #32

Description

@borisdev

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).

2. about → subject + subject_kind, with :: paths

Proposal and measurements in docs/naming-potential-incoherence.md.

  • 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions