Skip to content

Declare module layers as a family; CI writes the layer report - #3184

Merged
trissim merged 8 commits into
mainfrom
ratchet/layer-family
Oct 25, 2026
Merged

trissim merged 8 commits into
mainfrom
ratchet/layer-family

Conversation

@trissim

@trissim trissim commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #3170 (ratchet/repair); retarget to main once it lands.

What was slop. tools/module_layers.py kept the layer order as hand-written name lists and an index table: a roster restating the layers (MEMB-1), with may_import decided by comparing positions in that roster. And docs/layout/MODULE_LAYERS.md was a committed copy of the tool's output that had drifted 886 lines from the tree it claimed to describe, and nothing read it.

What replaces it.

  • class Layer(DeclaredFamily): each layer is a class built on the layers it may import (Wire ← Registry ← Coordination ← Context ← Turns ← Runtime; UiModel, Cli and Commander on Runtime). may_import is issubclass. Each layer declares its module prefixes; the longest claim wins. An unclaimed unit rises to the highest layer it imports.
  • The report is written by CI to the job summary (--check --report "$GITHUB_STEP_SUMMARY"), so it always describes the tree it ran on. The committed copy is deleted.
  • Reachability now reads the packages console scripts start in (agent_comms_hooks, derived from [project.scripts], never named). Before, agent_comms.pattern_sources (imported by agent_comms_hooks/reread.py) was listed as a deletion candidate.

Evidence.

  • Violations 1,293 before and after, with identical layers and unit edges (snapshot hash compared).
  • Deletion candidates lose pattern_sources and nothing else.
  • --check: 813 client imports of 119 units, 0 missing.
  • Runtime 0.016 s (was 0.014 s).
  • tests/test_module_layers_{clients,loads}.py: 3 pass. The new hook-reachability case fails on the old tool.

Merged onto main (after #3170)

  • main replaced --previous/InstallerZip with --base/OutgoingWire; the CI step now runs --check --base "$BASE" --report "$GITHUB_STEP_SUMMARY", both flags kept.
  • main's new OutgoingWire fixture (wire_base in tests/test_module_layers_clients.py) wrote an empty pyproject.toml. Package.modules now reads [project.scripts] and raises on a tree with none, as no real Core revision is; the fixture declares ac = "agent_comms.cli:main". 5 layer tests pass.
  • the usage line regenerating docs/layout/MODULE_LAYERS.md is gone with the committed copy.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Q8rVa3cPyXzpCKyR8XvM8W

trissim and others added 3 commits October 24, 2026 21:54
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q8rVa3cPyXzpCKyR8XvM8W
LAYERS held each layer's identity as a name string, its order as tuple
position and "nothing imports it" as a top flag. Layer is now a
DeclaredFamily: each layer is a class built on the layers it may import,
so an import is legal exactly when the importing layer subclasses its
target, a top layer is one nothing is built on, and names come from the
classes. The longest prefix claims a unit instead of the first in the
tuple. Unclaimed units still take the highest layer they import, by
declaration order. The report is byte-identical but for the sentence
naming the layer classes.

docs/layout/MODULE_LAYERS.md drifted 886 lines within hours of its last
regeneration, and nothing reads it. It is deleted; the merge queue's
--check step writes the report to its job summary with --report.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q8rVa3cPyXzpCKyR8XvM8W
Hook console scripts (agent_comms_hooks.*) rooted the walk, but their
files were never parsed, so a module only a hook imports was listed as
a deletion candidate: agent_comms.pattern_sources, which
agent_comms_hooks/reread.py imports. The script packages now come from
the same [project.scripts] table and are read for reachability only,
never as layer units. Violations (1,293), layers and unit edges are
unchanged; unreached loses pattern_sources.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q8rVa3cPyXzpCKyR8XvM8W
@trissim trissim changed the title Module layers as a declared family: order and legality from inheritance Declare module layers as a family; CI writes the layer report Oct 25, 2026
trissim and others added 4 commits October 25, 2026 00:13
…er-family

# Conflicts:
#	.github/workflows/debt-ratchet.yml
#	tools/module_layers.py
# Conflicts:
#	.github/workflows/debt-ratchet.yml
#	tools/module_layers.py
The merge of main brought back `> docs/layout/MODULE_LAYERS.md` in the usage
lines; this branch deleted that committed copy because --check --report writes
the report to the job summary of the tree it ran on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q8rVa3cPyXzpCKyR8XvM8W
@trissim
trissim marked this pull request as ready for review October 25, 2026 04:19
Copilot AI balanced review requested due to automatic review settings October 25, 2026 04:19

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@github-actions

Copy link
Copy Markdown

debt-tools at 774f082, every finding:

grew TypeErrors:tools/module_layers.py +5

@trissim
trissim enabled auto-merge October 25, 2026 04:20
…is no fact

Each override assigned a fixed-length tuple, so mypy typed every layer built on
another as a conflicting tuple length (debt-tools: grew TypeErrors:
tools/module_layers.py +5). A frozenset declares what claim reads, a set of
prefixes, and mypy now reports no error in the file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q8rVa3cPyXzpCKyR8XvM8W
@trissim
trissim merged commit 0d5b973 into main Oct 25, 2026
8 checks passed
trissim added a commit that referenced this pull request Oct 25, 2026
…e base job

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013ejYrMLnLWah8wCDDcb57V
trissim added a commit that referenced this pull request Oct 25, 2026
The probe was declared at module level in tests/test_install_worker_holds.py,
so it stayed in RuntimeProbe.__registry__ for every later test in the worker
and OutgoingWire read it as an installer probe outside the package. Declare it
inside the one test that uses it and pop it from the registry in finally.

test_repairs' tree() fixture now writes the pyproject.toml scripts entry
Package needs since #3184.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q8rVa3cPyXzpCKyR8XvM8W
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants