Skip to content

debt_ratchet.py is only the CI entry; the pinned audit owns every measure - #3606

Merged
trissim merged 24 commits into
mainfrom
refactor/audit-owns-ratchet-measures
Oct 30, 2026
Merged

trissim merged 24 commits into
mainfrom
refactor/audit-owns-ratchet-measures

Conversation

@trissim

@trissim trissim commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

P872, items C and D, plus agent-comms' half of E and F. tools/debt_ratchet.py is now only the CI entry. The engine, every measure, the comparison and the report moved to the refactor-audit this repository pins (OpenHCSDev/refactor-audit#7), and this PR moves the pin to that head.

ratchet that refuses restated facts
2,919 lines
its own Measure family, right next to the audit's Measure family
now 32 lines
the absolute state of the previous state

Summary in numbers

  • 5 commits / −4,597 across 14 files.
  • tools/debt_ratchet.py: 2,919 lines and 95 classes → 14 lines, 0 ClassDefs, 0 FunctionDefs: raise SystemExit(main(AgentCommsProject(Path.cwd()))).
  • tools/agent_comms_project.py (new, 241 lines): agent-comms' own facts and ClientTypeErrors, moved out of the pinned audit so they change here.
  • from audit import agent_comms_project side-effect imports: 6 → 0.
  • tools/typing_names.py: 151 lines → 0 (moved to audit.typing_names).
  • tests/guards/test_debt_ratchet.py: 1,512 lines → 0. The generic suite moved to the audit owner. What only agent-comms declares is tests/guards/test_agent_comms_ratchet.py, with 10 tests plus the broad-swallow budget.

The entry and its contract

from agent_comms_project import AgentCommsProject
from audit.ratchet import main

if __name__ == "__main__":
    raise SystemExit(main(AgentCommsProject(Path.cwd())))

The one fact the entry owns is which project it measures. audit.ratchet.main(project) owns the command line.

  • Flags --root/--base/--head/--workers are unchanged, and so are .github/workflows/debt-ratchet.yml and debt-ratchet-cache.yml.
  • stdout is the one JSON report with root, base_revision, head_revision, paths, base, head, introduced, found and delta, using the same keys (Measure[:path[::member]]) and shapes.
  • stderr ends with the grew / found / introduced lines. A found checker site reads path:line (message) (item F).
  • The exit status is int(failed). The cache stays at ~/.cache/agent-comms/debt-ratchet.

agent-comms' facts are AgentCommsProject(Project[PlanPhase]) in tools/agent_comms_project.py, an instance of this checkout passed to every measure. Each fact derives from its owner here.

  • Lock owners and functions come from store_files, locked_store and process_claim.
  • The absence decoder is boundary_decoder. The mechanism modules are field_codec, typed_table and coordination_schema, plus Toad's agent_schema.py and db.py.
  • The selecting call is DeclaredFamily.member_named. Guards are PlanPhase members, typed (no cast).
  • Stored formats come from tools/stored_formats.py and WheelStamp. A carry step is an added module under installer.carry.STEPS with a class whose base this module binds to the Carry family. The old stem.startswith("carry_") check is deleted.
  • ClientTypeErrors reads StackClient.
  • The pool and runner are ForkedProcessPool and SpawnedProcess.run, so pool workers, format probes and checkers still die with the ratchet. test_compare_timeout_retires_pool_probe_and_defiant_grandchild stays here to prove it.
  • repairs.py and the tests measure an AgentCommsProject instance. phase_evidence reads GodFunction.threshold(), which is LongFunction.lines.

Importing that module declares the project; with no declaration, the comparison refuses. pinned_audit never imports it, so there is no cycle.

Consumers migrated directly (no re-export)

Consumer Before After
tools/repairs.py:28 from debt_ratchet import FunctionLocalImport, LocatedSource, compare, production_paths audit.ratchet, audit.source_measures, audit.repository (Repository(repo).production_paths, compare(Repository(repo), ...))
tests/test_boundary_decoding.py:81 function-local from debt_ratchet import RawRecordShapes top-level from audit.source_measures import RawRecordShapes
tests/test_carry.py:14 from debt_ratchet import UncarriedRecordFormat, git audit.project_measures.UncarriedRecordFormat, audit.repository.Repository(...).read
tools/module_layers.py:42 from typing_names import ... from audit.typing_names import ...
src/agent_comms/pinned_audit.py audit.measures.ForeignAbsenceProbe audit.source_measures.ForeignAbsenceProbe
src/agent_comms/phase_evidence.py:671 ForeignAbsenceProbe.count(node) ForeignAbsenceProbe.occurrences(node) (the census capability)

Two done phases that would have broken silently

PlainStrIdRatchetPhase (plan_phases.py:554) and LockCensusPhase (:1022) were PatternPresent(r"^class X\(", ("tools/debt_ratchet.py",)). Those classes now live in the submodule, which is one gitlink in this tree. Both phases would have flipped to "no longer holds", and DonePhaseBroken would have blamed every change after this one.

Fixed at the evidence owner. MainTree.pinned(path) returns the tree of the submodule main pins, read at exactly the commit its gitlink names, from that repository's own objects. It still never reads a worktree. PinnedPatternPresent greps that tree, so both phases now read scripts/audit of the pinned refactor-audit.

A red test found on the way

test_store_lock_calls_skip_the_store_owners asserted two lock owners. Commit 1ab5bde (2026-10-25) added process_claim as a third and never updated it, so the test has been red for four days. It now asserts the three owners the declaration derives.

Tests here

tests/guards/test_agent_comms_ratchet.py covers:

  • store-lock counting and owners;
  • the pool/probe process-tree timeout;
  • the archived format probe and the done phase;
  • mechanism-module facades;
  • the boundary_decoder exemption;
  • the merged-log CLI contract;
  • the indirect-module cache key;
  • the agent_comms broad-swallow budget.

Not run by me: P872 forbids the author pytest and mypy. Verification is in-memory compilation of every changed module, an AST name check (the only hits are the side-effect imports that put the pinned audit on the path and declare the project) and the entry's ClassDef inventory.

Assumed

  • The pin is the audit PR head bbab9314 so CI can exercise it. It moves to the merged refactor-audit commit before this merges.
  • Audit's new declared dependencies (metaclass-registry, typing_extensions) are already in this environment through the existing pip install -e src/agent_comms/skills/refactor-audit.

Round 5 (19de7bc): absent reader and absent pin answer, git no longer crashes

claude-code ran the ratchet's own tests, which CI never runs:

  • stored_formats (tools/agent_comms_project.py) archived tools/stored_formats.py at every revision. Before the reader existed (164c80c) git archive died on the pathspec. That revision declares no stored format, so it answers {}. Main was red on the same crash in the 11 test_a_stored_record_format_* cases: their fixtures copied only src/agent_comms. Those fixtures now ship the reader.
  • AuditPatternPresent asked git for the submodule pin at a commit with no submodule. A commit that pins no audit holds none of its patterns.
  • Pin bumped to refactor-audit 342e2690: the census takes its mechanism owners.
  • Checked by script: no reader gives {}, with the reader the probe record reads version 7; no pin reads False, the real pin reads True. debt-src and debt-tools are green on 19de7bc (run 40929342095).

Review round 3 (claude-code e95b7b02ff80)

  • Explicit audit dependency: tools and tests import audit from agent_comms.pinned_audit and read every name as audit.<module>.<Name>. No module depends on another having put the pinned scripts dir on sys.path first, and module_layers' import is now one it reads.
  • AuditPatternPresent: it locates the skills dir from the loaded skills package, relative to agent_comms' source root. It no longer derives it by stripping .py from a module path.
  • Hoist repair: it builds its AgentCommsProject once instead of once per file.

Round 6 (f25539d): one stored-format record, fresh type counts (Codex 1a5fa2bdbb7a, claude-code 8bfa094055fd)

Pin 705ebb65 = refactor-audit #10 carrying #9.

  • StoredForm deleted. It restated the audit's StoredFormat (3 fields) to carry its own wire form, and only the top-level required was a set, so Acquire display identities and relationship inputs through their declared owners #3607's nested RegistryDocument reorder read as grew UncarriedRecordFormat +1. Now StoredFormat.declared is the one constructor and the one decoder, with required a set at every depth; :179 decodes as StoredFormat.declared(**form) with no subscripts.
  • PinnedAudit.has deleted. Its bare subprocess.run(["git", ...]) is gone in favour of Repository.has on the audit's one git runner.
  • Type counts measured fresh. ClientTypeErrors.findings returns side, cls.checked(...), and the audit's CheckedRevision.findings runs the checker. Only LintFindings memoizes. Mypy reads PEP 561 packages on PYTHONPATH that no content key names.
  • Controls carried: test_type_counts_follow_the_installed_dependency_not_a_stored_count (source + client), and the 12-case test_declared_decoder_boundary_is_shared_by_both_contextual_absence_measures for NoneAbsence + ForeignAbsenceProbe.
  • Probe (no tests run): all 4 versioned records round-trip; RegistryDocument and RelationshipDocument hold nested required as sets.

🤖 Generated with Claude Code

https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA

…sure

tools/debt_ratchet.py was 2,919 lines and 95 classes, a second audit engine
beside the refactor-audit this repository pins. The engine, its measures and its
report moved to refactor-audit (OpenHCSDev/refactor-audit#7). agent-comms' own
facts are that package's audit/agent_comms_project.py, derived from their owners
here, and the pool and runner stay ForkedProcessPool and SpawnedProcess. The
entry is now argparse for --root/--base/--head/--workers and one call to
audit.ratchet.ratchet(): 32 lines, 0 classes. The report, the stderr lines and
the exit status are unchanged, and both workflows run as before.

- The submodule pin moves to refactor-audit 45b7fc27 (the PR head; the pin moves
  to the reviewed commit before merge).
- tools/typing_names.py moved to audit.typing_names; module_layers imports it
  from there.
- repairs.py, test_boundary_decoding.py and test_carry.py import their measures
  from the audit owner directly.
- pinned_audit takes ForeignAbsenceProbe from audit.source_measures, and
  phase_evidence calls its occurrences(node).
- PlainStrIdRatchetPhase and LockCensusPhase kept grepping tools/debt_ratchet.py,
  which no longer holds those classes. The new PinnedPatternPresent reads the
  submodule tree main pins, at the commit its gitlink names (MainTree.pinned).
- tests/guards/test_debt_ratchet.py: the generic suite moved to refactor-audit.
  What only agent-comms declares stays here as test_agent_comms_ratchet.py: lock
  owners, the boundary decoder, codec modules, done phases, the stored-record
  probe, the pool's process tree and the CLI's merged log. The lock-owner test
  had asserted two owners since 1ab5bde added process_claim as a third; it
  now asserts the three the declaration derives.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

debt-tools at 8b20ff7, every finding:

concurrent.futures.process._RemoteTraceback: 
"""
Traceback (most recent call last):
  File "/opt/hostedtoolcache/Python/3.14.9/x64/lib/python3.14/concurrent/futures/process.py", line 255, in _process_worker
    r = call_item.fn(*call_item.args, **call_item.kwargs)
  File "/home/runner/work/agent-comms/agent-comms/src/agent_comms/child_process.py", line 2333, in _work
    return work()
  File "/home/runner/work/agent-comms/agent-comms/src/agent_comms/skills/refactor-audit/scripts/audit/project_measures.py", line 51, in counted
    carried = repo.carried(base, head)
  File "/home/runner/work/agent-comms/agent-comms/tools/agent_comms_project.py", line 182, in carried
    families = self.carry_family()
  File "/home/runner/work/agent-comms/agent-comms/tools/agent_comms_project.py", line 198, in carry_family
    base for member in Carry.members_with(Carry)
                       ~~~~~~~~~~~~~~~~~~^^^^^^^
  File "/home/runner/work/agent-comms/agent-comms/src/agent_comms/declared_family.py", line 262, in members_with
    for member in cls._member_declarations()
                  ~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/home/runner/work/agent-comms/agent-comms/src/agent_comms/declared_family.py", line 242, in _member_declarations
    return tuple(cls.__registry__.values())
                 ~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/home/runner/work/agent-comms/agent-comms/.venv/lib/python3.14/site-packages/metaclass_registry/core.py", line 422, in values
    self._discover()
    ~~~~~~~~~~~~~~^^
  File "/home/runner/work/agent-comms/agent-comms/.venv/lib/python3.14/site-packages/metaclass_registry/core.py", line 364, in _discover
    discover(paths, f"{config.discovery_package}.", cast(type, self._base_class))
    ~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/runner/work/agent-comms/agent-comms/.venv/lib/python3.14/site-packages/metaclass_registry/discovery.py", line 133, in discover_registry_classes
    module = import_module_preserving_root_logging(module_name)
  File "/home/runner/work/agent-comms/agent-comms/.venv/lib/python3.14/site-packages/metaclass_registry/discovery.py", line 56, in import_module_preserving_root_logging
    return importlib.import_module(module_name, package)
           ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/hostedtoolcache/Python/3.14.9/x64/lib/python3.14/importlib/__init__.py", line 88, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1406, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1371, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1342, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 938, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 763, in exec_module
  File "<frozen importlib._bootstrap>", line 491, in _call_with_frames_removed
  File "/home/runner/work/agent-comms/agent-comms/tools/cutover/carry_toad_arrow_keys.py", line 17, in <module>
    from cutover.carry_toad_key_mode import ToadSettingsCarry
  File "/home/runner/work/agent-comms/agent-comms/tools/cutover/carry_toad_key_mode.py", line 14, in <module>
    from toad.key_modes import KeyMode, Standard, VimNormal
  File "/home/runner/work/agent-comms/agent-comms/.venv/lib/python3.14/site-packages/toad/key_modes.py", line 5, in <module>
    from textual.document._editing import (
    ...<5 lines>...
    )
ImportError: cannot import name 'VimInsert' from 'textual.document._editing' (/home/runner/work/agent-comms/agent-comms/.venv/lib/python3.14/site-packages/textual/document/_editing.py)
"""

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/runner/work/agent-comms/agent-comms/tools/debt_ratchet.py", line 14, in <module>
    raise SystemExit(audit.ratchet.main(AgentCommsProject(Path.cwd())))
                     ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/runner/work/agent-comms/agent-comms/src/agent_comms/skills/refactor-audit/scripts/audit/ratchet.py", line 1039, in main
    return ratchet(project, args.base, args.head, args.root, args.workers)
  File "/home/runner/work/agent-comms/agent-comms/src/agent_comms/skills/refactor-audit/scripts/audit/ratchet.py", line 1012, in ratchet
    result = compare(repo, base, head, root, workers, Measure.members_with(Compared))
  File "/home/runner/work/agent-comms/agent-comms/src/agent_comms/skills/refactor-audit/scripts/audit/ratchet.py", line 979, in compare
    results[measure] = [part.result() for part in parts[measure]]
                        ~~~~~~~~~~~^^
  File "/opt/hostedtoolcache/Python/3.14.9/x64/lib/python3.14/concurrent/futures/_base.py", line 447, in result
    return self.__get_result()
           ~~~~~~~~~~~~~~~~~^^
  File "/opt/hostedtoolcache/Python/3.14.9/x64/lib/python3.14/concurrent/futures/_base.py", line 396, in __get_result
    raise self._exception
ImportError: cannot import name 'VimInsert' from 'textual.document._editing' (/home/runner/work/agent-comms/agent-comms/.venv/lib/python3.14/site-packages/textual/document/_editing.py)

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

debt-src at 8b20ff7, every finding:

concurrent.futures.process._RemoteTraceback: 
"""
Traceback (most recent call last):
  File "/opt/hostedtoolcache/Python/3.14.9/x64/lib/python3.14/concurrent/futures/process.py", line 255, in _process_worker
    r = call_item.fn(*call_item.args, **call_item.kwargs)
  File "/home/runner/work/agent-comms/agent-comms/src/agent_comms/child_process.py", line 2333, in _work
    return work()
  File "/home/runner/work/agent-comms/agent-comms/src/agent_comms/skills/refactor-audit/scripts/audit/project_measures.py", line 51, in counted
    carried = repo.carried(base, head)
  File "/home/runner/work/agent-comms/agent-comms/tools/agent_comms_project.py", line 182, in carried
    families = self.carry_family()
  File "/home/runner/work/agent-comms/agent-comms/tools/agent_comms_project.py", line 198, in carry_family
    base for member in Carry.members_with(Carry)
                       ~~~~~~~~~~~~~~~~~~^^^^^^^
  File "/home/runner/work/agent-comms/agent-comms/src/agent_comms/declared_family.py", line 262, in members_with
    for member in cls._member_declarations()
                  ~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/home/runner/work/agent-comms/agent-comms/src/agent_comms/declared_family.py", line 242, in _member_declarations
    return tuple(cls.__registry__.values())
                 ~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/home/runner/work/agent-comms/agent-comms/.venv/lib/python3.14/site-packages/metaclass_registry/core.py", line 422, in values
    self._discover()
    ~~~~~~~~~~~~~~^^
  File "/home/runner/work/agent-comms/agent-comms/.venv/lib/python3.14/site-packages/metaclass_registry/core.py", line 364, in _discover
    discover(paths, f"{config.discovery_package}.", cast(type, self._base_class))
    ~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/runner/work/agent-comms/agent-comms/.venv/lib/python3.14/site-packages/metaclass_registry/discovery.py", line 133, in discover_registry_classes
    module = import_module_preserving_root_logging(module_name)
  File "/home/runner/work/agent-comms/agent-comms/.venv/lib/python3.14/site-packages/metaclass_registry/discovery.py", line 56, in import_module_preserving_root_logging
    return importlib.import_module(module_name, package)
           ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/hostedtoolcache/Python/3.14.9/x64/lib/python3.14/importlib/__init__.py", line 88, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1406, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1371, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1342, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 938, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 763, in exec_module
  File "<frozen importlib._bootstrap>", line 491, in _call_with_frames_removed
  File "/home/runner/work/agent-comms/agent-comms/tools/cutover/carry_toad_arrow_keys.py", line 17, in <module>
    from cutover.carry_toad_key_mode import ToadSettingsCarry
  File "/home/runner/work/agent-comms/agent-comms/tools/cutover/carry_toad_key_mode.py", line 14, in <module>
    from toad.key_modes import KeyMode, Standard, VimNormal
  File "/home/runner/work/agent-comms/agent-comms/.venv/lib/python3.14/site-packages/toad/key_modes.py", line 5, in <module>
    from textual.document._editing import (
    ...<5 lines>...
    )
ImportError: cannot import name 'VimInsert' from 'textual.document._editing' (/home/runner/work/agent-comms/agent-comms/.venv/lib/python3.14/site-packages/textual/document/_editing.py)
"""

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/runner/work/agent-comms/agent-comms/tools/debt_ratchet.py", line 14, in <module>
    raise SystemExit(audit.ratchet.main(AgentCommsProject(Path.cwd())))
                     ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/runner/work/agent-comms/agent-comms/src/agent_comms/skills/refactor-audit/scripts/audit/ratchet.py", line 1039, in main
    return ratchet(project, args.base, args.head, args.root, args.workers)
  File "/home/runner/work/agent-comms/agent-comms/src/agent_comms/skills/refactor-audit/scripts/audit/ratchet.py", line 1012, in ratchet
    result = compare(repo, base, head, root, workers, Measure.members_with(Compared))
  File "/home/runner/work/agent-comms/agent-comms/src/agent_comms/skills/refactor-audit/scripts/audit/ratchet.py", line 979, in compare
    results[measure] = [part.result() for part in parts[measure]]
                        ~~~~~~~~~~~^^
  File "/opt/hostedtoolcache/Python/3.14.9/x64/lib/python3.14/concurrent/futures/_base.py", line 447, in result
    return self.__get_result()
           ~~~~~~~~~~~~~~~~~^^
  File "/opt/hostedtoolcache/Python/3.14.9/x64/lib/python3.14/concurrent/futures/_base.py", line 396, in __get_result
    raise self._exception
ImportError: cannot import name 'VimInsert' from 'textual.document._editing' (/home/runner/work/agent-comms/agent-comms/.venv/lib/python3.14/site-packages/textual/document/_editing.py)

trissim and others added 9 commits October 29, 2026 12:46
…wners

claude-code's review of 292f2dd:
- PinnedPatternPresent carried the submodule as a str field, and plan_phases.py
  wrote the same path twice more. pinned_audit already derives the skill
  directory, so it now declares SKILL once. The new AuditPatternPresent(pattern)
  finds the gitlink from agent_comms.skills' module path plus SKILL's name, and
  the package from audit's own location under SKILL.
- MainTree.pinned matched ls-tree's "commit" type string, which grew
  StringIdentity. It now reads the gitlink with rev-parse <commit>:<path>.
- The lock-owner test hand-wrote the three owners lock_owners() derives. It now
  asserts every derived owner exists and counts nothing there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
AgentCommsProject and ClientTypeErrors move out of the pinned audit into tools/, beside the
entry: agent-comms' facts change in agent-comms. debt_ratchet.py is
raise SystemExit(main(AgentCommsProject(Path.cwd()))); the audit owns the command line.
Every `from audit import agent_comms_project` side-effect import is gone; repairs and the
tests measure an AgentCommsProject instance. A carry step is a module under STEPS whose class
derives from the Carry family, not a file named carry_*. GodFunction's limit is LongFunction's.
The submodule pins refactor-audit 03ed7a0e (#7's head).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
…rces fix

carried() bound only Carry and its direct subclasses, so a step deriving from another step's
base (carry_toad_arrow_keys.py's ToadSettingsCarry, 0f896c5) read as no carry. It binds the
whole family now: 0f896c5, 0455ac6 and 01cc13c read carried, merge 4ca5c19 does not.
The content-cache test reads measuring_sources. The submodule pins refactor-audit 48b33bb0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
…import order

Review round 3 (claude-code e95b7b02ff80): tools and tests read every audit name as
audit.<module>.<Name> through `from agent_comms.pinned_audit import audit`, so no module needs
another to have put the scripts dir on sys.path first; module_layers' import is now used.
AuditPatternPresent reads the skills dir from the loaded package, not a stripped '.py'.
The hoist repair builds its AgentCommsProject once. The submodule pins refactor-audit b024c5f8.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
…es to Project

debt-tools on db41b7f refused tools/agent_comms_project.py: StringSubscript +4 and
RawRecordShapes +1 for match["path"/"line"/"message"] in ClientTypeErrors, and TypeErrors +3
(Mapping env, an abstract Carry in a type[Carry] list, parts narrowing repo to
AgentCommsProject). The client check reads audit's TypeErrors.reported(); ClientTypeErrors
types its repo as the audit Project; run takes a dict env. The submodule pins ca1670f7.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
…ern goes

Review round 4 (claude-code ce65f96693c8): carry_family reads Carry's members and takes each
one's MRO up to Carry, instead of calling members_with only to import the steps and then
walking subclasses. ClientTypeErrors' `finding` was read by nothing since the check reads
TypeErrors.reported(). The submodule pins the round-4 audit head.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
claude-code's run of the ratchet's own tests (which CI never runs)
found two crashes and one regression:

- stored_formats archived tools/stored_formats.py at any revision; at a
  revision before the reader (164c80c) git archive died on the
  pathspec. That revision declares no stored format: it answers {}.
  The fixtures that model agent-comms now ship the reader the way the
  repository does (test_carry, test_agent_comms_ratchet).
- AuditPatternPresent asked git for the submodule pin at a commit with
  no submodule. A commit that pins no audit holds none of its patterns.
- Pin bump to refactor-audit 342e2690: CensusRun takes its mechanism
  owners; Undeclared answers no project.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
…eads audit.lexical

The audit's Project renames absence_decoders to absence_boundaries (a decoder or an
encoder marks where absence meets the outside) and moves DecoratorBinding into
audit.lexical (refactor-audit#7, ceb14906). This head needs the pin bump to that
audit merge: at the current pin the abstract method is still absence_decoders.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
refactor-audit 3a3a8378 moves module facts to audit.lexical.ModuleScope and
DecoratorBinding.of takes it; one walk serves every Carry family.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
trissim and others added 2 commits October 29, 2026 19:20
refactor-audit#7 merged as d7401d6797feb839b014a258b9a44b9aba4d14c4 (reviewed head
785659a7, root 114/114 controls). Its Project declares absence_boundaries and
ModuleScope, which AgentCommsProject already implements on this branch, so debt-src
and debt-tools stop failing on the missing absence_decoders.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
trissim and others added 3 commits October 29, 2026 19:47
…mpty answer

AgentCommsProject.stored_formats probed each revision for tools/stored_formats.py and
answered {} when it was missing, so a client repo (Toad ships no reader) had its
stored-format check measure nothing and report clean on every run.
- StoredFormatReader family: RevisionReader (agent-comms measuring itself: each
  revision runs its own reader, since a head reader may import head-only modules;
  a revision without one fails loud) and CheckoutReader (a client repo borrows the
  ratchet checkout's reader, importing agent_comms from that checkout).
- AgentCommsProject.reader declares it, RevisionReader by default; the tracks()
  probe and the {} are deleted.
- tools/client_ratchet.py: the client entry, AgentCommsProject(cwd, CheckoutReader()).
  Toad's workflow switches its one ratchet line to it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
…once

claude-code #3606 review (9734177925da): StoredForm.of built required as a list
at :39/:41, a __post_init__ patched it into the frozenset the field declares, and
json.dumps(default=sorted) sorted anything JSON could not encode.
- StoredForm.of builds frozenset at both construction sites; __post_init__ deleted.
- StoredForm.wire() is the one JSON encoder (required as a sorted list, since JSON
  has no set); default=sorted deleted.
- AgentCommsProject decodes the list into frozenset once. The audit field becomes
  frozenset[str] in refactor-audit#8; the pin moves after it merges.
Encoder probe on a real versioned record: required arrives as a sorted list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
@trissim
trissim marked this pull request as ready for review October 29, 2026 23:54
@trissim
trissim enabled auto-merge October 29, 2026 23:54
Copilot AI balanced review requested due to automatic review settings October 29, 2026 23:54

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.

trissim and others added 2 commits October 29, 2026 19:58
The merge queue ran debt-tools on a fresh main commit and failed: stored_formats
extracts the base revision with git archive, which leaves the audit submodule out,
so the base's pinned_audit imported this checkout's audit and died on
ForeignAbsenceProbe (moved by refactor-audit#7). The stamp died first, but the reader
imports base modules that reach pinned_audit too (phase_evidence.py:28), so any
fresh base would have died the same way.
- PinnedAudit (this checkout's audit clone) places the audit at a revision's
  pin into the extracted tree, fetching the pin first when the clone lacks it.
- RevisionReader places the revision's reader and its pinned audit.
Replay: stored_formats at origin/main (audit pin 5a969d3a) from this checkout at
d7401d67 now returns instead of raising ImportError.
Also merges origin/main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
@trissim
trissim disabled auto-merge October 30, 2026 00:06
trissim and others added 4 commits October 29, 2026 20:20
Pin refactor-audit 705ebb65 (audit #10 carrying #9).

- tools/stored_formats.py: StoredForm deleted. It restated the audit's
  StoredFormat (three fields) to carry its own wire form, and treated only
  the top-level required as a set, so #3607's nested RegistryDocument
  required list reordering read as a format change. stored_format(record)
  builds StoredFormat.declared, and the audit owns sets at every depth and
  wire(). claude-code 8bfa094055fd, 580764ff8059, d98616a29150.
- tools/agent_comms_project.py: the probe output decodes through
  StoredFormat.declared(**form), with no subscripts. PinnedAudit.has and its
  bare subprocess git are deleted for Repository.has.
- ClientTypeErrors.findings runs mypy each comparison. The client commit read
  and the src identity, which existed only for the memo key, are gone. Mypy
  reads PEP 561 packages on PYTHONPATH that no content key names. Codex
  1a5fa2bdbb7a, 073483f8114b; carrier 3d3a357.
- tests: test_type_counts_follow_the_installed_dependency_not_a_stored_count
  is carried from 3d3a357 onto the TypeErrors/ClientTypeErrors CheckerSite
  API, for source and client. The 12-case
  test_declared_decoder_boundary_is_shared_by_both_contextual_absence_measures
  (imported, aliased, qualified, module, relative, undecorated,
  different-owner, duplicate, conditional, star, class-shadowed,
  parameter-shadowed) is carried for NoneAbsence and ForeignAbsenceProbe
  through AgentCommsProject.absence_boundaries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
…ched plan reading by path

claude-code BACK on f25539d (033285452d9a):
- tools/stored_formats.py: "is this record versioned" was answered three times
  (`vars(record).get("version") is not None`, `return None`, `form is not None`)
  and debt-tools counted the new NoneAbsence. stored_format(record) now yields
  zero or one StoredFormat, matching the class's own `version` attribute and the
  schema in one match; stored_formats is a comprehension over it. All three None
  tests and the `| None` are deleted.
- tools/agent_comms_project.py: ClientTypeErrors.checked folded into findings, so the
  one-line forwarder is gone. reading is a staticmethod cache over (path, commit),
  like carry_family (B019).
- I001 import blocks sorted in agent_comms_project.py, client_ratchet.py and repairs.py.
- Audit pin d1b1f1d1: unordered writes every nested required as a sorted list, and
  the listed encoder that re-tested frozensets is deleted (BOUND-1, project.py:80).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
trissim and others added 3 commits October 29, 2026 20:56
…ormats ignore schema annotations

P918's derived text descriptions reword the documentation inside the
ActiveRoute, WakeClaim and RegistryDocument record schemas; the audit's
StoredFormat now drops description/title/examples/$comment, so that is not a
format change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
Replaces the orphan pin 8659f603 (claude-code d2452ae823e2) with the merge
commit of refactor-audit #11: stored formats drop schema annotations and keep
default/enum/const values as written.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
@trissim
trissim added this pull request to the merge queue Oct 30, 2026
Merged via the queue into main with commit 3274448 Oct 30, 2026
9 checks passed
trissim added a commit that referenced this pull request Oct 30, 2026
- order.py, todos.py: take main's CommanderProject.linkable check (#3625 shape); the
  per-call Repo.selected validation is gone.
- observation.py: keep #3566's ReadOperation(UiRead); main's added hud.require_current()
  moves into CommanderUnitRead.read_as (order_tools.py).
- manual_compaction_bridge.py: main's completion.transcript_changed(partial(...)) with
  #3566's UnreadTranscriptCursor().
- order_tools.py, phase_evidence.py: union of imports, unused ones dropped.
- tools/debt_ratchet.py: main's #3606 entry-only shape; tests/guards/test_debt_ratchet.py
  stays deleted as on main. #3566's ratchet edits are superseded by refactor-audit c69c4daf.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RnH6dR85kyFKcc2tQAJLhK
trissim added a commit that referenced this pull request Oct 30, 2026
Main's #3606 made tools/debt_ratchet.py the entry over the pinned audit, with no
--ci-inputs argument; the merge kept #3566's workflow lines passing it, so debt-src and
debt-tools exited 2 on argparse. checker_stack.py and module_layers.py still declare it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RnH6dR85kyFKcc2tQAJLhK
trissim added a commit that referenced this pull request Oct 30, 2026
…fetched

#3566 made StackClient.fetched (module_layers.py:371) require uv, python and commands to
acquire each client's metadata; main's #3606 caller at agent_comms_project.py:252 kept the
old two-argument call, so debt-src died with TypeError after the merge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RnH6dR85kyFKcc2tQAJLhK
trissim added a commit that referenced this pull request Oct 30, 2026
…s CI's cuts

#3606 moved ClientTypeErrors into AgentCommsProject with a fresh stack clone and no way to
read the integration entrypoint's materialized cuts, so #3566 had to drop --ci-inputs from
debt_ratchet.py (a974c0f). AgentCommsProject now holds one ClientSources (default: the
head's declared stack, cloned once); AgentCommsProject.from_arguments decodes --ci-inputs into
MaterializedClients. ClientTypeErrors.parts asks it per compared side and also runs when the
source requires clients (a companion can change while Core does not). The static clone in
ClientTypeErrors.clients is deleted. Two tests still importing the deleted
debt_ratchet.ClientTypeErrors/compare now build the project with its clients.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
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