Skip to content

The price of a module is read before it is paid - #294

Merged
evkir merged 4 commits into
mainfrom
feat/the-price-of-a-module-is-read-before-it-is-paid
Sep 23, 2026
Merged

evkir merged 4 commits into
mainfrom
feat/the-price-of-a-module-is-read-before-it-is-paid

Conversation

@evkir

@evkir evkir commented Sep 23, 2026

Copy link
Copy Markdown
Owner

Four commits:

  1. scripts/scope_price.py — the errors a candidate brings and where the
    two boundary counters land with it inside, measured through a config
    file in a temporary directory so pyproject.toml is never edited.
    Named by CONTRIBUTING.md, since a script nobody is told to run is a
    producer with no consumer.
  2. A guard that the projected price equals the charged one: the pricer
    and the boundary guard return one pair of numbers, a module already
    inside costs no movement, a run with no verdict prices nothing, and
    an error belongs to the module it names.
  3. The rule written from three moves does not survive sixty-eight. The
    scope page said a leaf pays one counter and an entry point pays both;
    projecting all 68 undeclared modules gives eleven classes, not two.
    core/cache.py is a leaf that moves both. Two stale docstring counts
    restated against the same measurement.
  4. Three modules priced at zero are declared. Success on 107 rather than
    104, 272 errors outside the scope rather than 275, drift none,
    crossers and reached unmoved at 22 and 30.

Badge 2988 collected, mypy 107/172.

What this changes

How it was measured

Checklist

  • ruff format --check cyberai/ tests/ and ruff check cyberai/ tests/ pass
  • pytest -W ignore::DeprecationWarning -m "not slow and not smoke" passes
  • New behaviour is covered by a test that fails without the change
  • I have read CLA.md and I hereby sign the CLA

Three times on 2026-09-21 the boundary counters moved as modules entered
[tool.mypy] files, and three times the expected numbers were corrected
after the fact by rerunning the guard and reading its failure. The price
was paid first and read afterwards.

scripts/scope_price.py reports it first: the errors a candidate brings
under the declared flags, and where the two boundary counters land with
it inside. The scoped run is driven by a config file written to a
temporary directory, so pyproject.toml is never edited and an interrupted
run leaves no half-applied scope behind. The counters are counted from
the import graph, the way the guard counts them, so the two numbers are
comparable by construction rather than by luck.

Measured against the tree it reports on: 104 modules, 22 crossers
reaching 30, which is what the green guard asserts independently.

CONTRIBUTING.md names it, since a script nobody is told to run is a
producer with no consumer.
Two files count the same crossing: the boundary guard holds the numbers
the scope page states, and the pricer projects where they land when a
candidate moves inside. They agree today because one was written from the
other, and nothing kept them agreeing. The day their import handling
diverges, the price read before a change and the price charged after it
differ, and only the second one reds.

Four assertions, each one killing a mutant that survived the last round:
the two readers return one pair of numbers; a module already inside the
scope moves neither counter, so the projection must keep asking which
side of the edge a target sits on; a run with no verdict line prices
nothing rather than pricing a module at zero; and an error belongs to the
module it names, so notes are not errors and a neighbour's errors are not
the candidate's.

The sibling guard is loaded by location. Importing it as tests.architecture
asks the suite to be a package on sys.path, which the manifest gate reads
as a third-party dependency named tests -- and the dependency it would
really name is the install mode.
…-eight

The scope page summarised three boundary moves as a rule: a leaf pays one
counter, an entry point pays both. scripts/scope_price.py projected every
undeclared module on 2026-09-23 and the moves fall into eleven classes,
not two.

core/cache.py refutes it plainly. It imports nothing outside the scope, so
the rule calls it a leaf paying one counter, and it moves both: intel/
epss_client.py is the only module in the scope that reaches it and reaches
nothing else, so declaring cache.py retires a crosser and a reached module
at once. integrations/phantom_grid.py retires two crossers, which no rule
about leaves permits, and core/orchestrator.py adds two reached modules
while joining no crossing of its own.

What the projection shows is two independent sums, which is why the
observed pairs run from -2 and -1 to +1 and +5, and why the largest class
is twenty modules that move nothing at all. The paragraph now states the
mechanism and stops predicting the number.

Two docstrings restated against the same measurement: the drift report
said the scope named seventy-two individual modules and it names
eighty-five, and the boundary guard opened on 95 modules and 19 crossers
where the tree now has 104 and 22. Both were true when written. Neither
is held by anything, so both are dated.
scripts/scope_price.py projected all 68 undeclared modules and twenty of
them move neither boundary counter. Three of those carried a single error
each, and each error was a missing type parameter rather than a contract
to renegotiate:

  core/exploit_memory.py     Counter        -> Counter[str]
  bench/apps/_server.py      tuple          -> tuple[str, str]
  agents/web3/immunefi_severity.py  dict    -> Dict[str, Any]

Every parameter was read off the code that fills it: the counter is built
from lowercased tokens, the route key is assembled as (method, path) with
both halves str, and to_dict returns Dict[str, Any].

Priced before the fact at zero errors and +0 on both counters, and the
tree agrees afterwards: Success on 107 rather than 104, 272 errors outside
the scope rather than 275, drift none, crossers and reached unmoved at 22
and 30. That is the first time the price was read before it was paid
rather than corrected after.
@codecov

codecov Bot commented Sep 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@evkir
evkir merged commit 101a1d2 into main Sep 23, 2026
10 checks passed
@evkir
evkir deleted the feat/the-price-of-a-module-is-read-before-it-is-paid branch September 23, 2026 13:52
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.

1 participant