Skip to content

Registry: the lock closes every form and resolution is proved by a corpus - #330

Merged
the-homeless-god merged 5 commits into
devfrom
a/the-registry-properties-and-the-js-twin
Oct 8, 2026
Merged

the-homeless-god merged 5 commits into
devfrom
a/the-registry-properties-and-the-js-twin

Conversation

@the-homeless-god

Copy link
Copy Markdown
Member

Two P1 tasks about the registry: 2031 (no form of a dependency reaches the lock) and the remainder of 4909 (properties 2 and 3 of ADR-0059 section 7). Point 4 of 4909 was closed earlier today as false from birth and is not touched here.

4909, properties 2 and 3

A new guard scripts/guards/registry-resolution-guard.fscript plays a corpus in packaging/registry/cases (a ledger of seven rows and six cases written as key = value lines).

  • Property 2, the answer does not depend on the order of the ledger rows. Every case of kind "choice" runs on all rotations of the ledger plus the reversed order — seven rows give eight orders — and the answers are compared byte for byte. Run: cases 6, ledger orders 20, removed chosen entries 4, exit 0.
  • The mandatory negative control is inside the check, not beside it. One answer over eight orders also goes green on an instrument that never reads the ledger, which is the mistake the measurement of the ADR fell into once. So for every choice case the guard drops one chosen entry in turn and demands the answer change; all four removals change it. Measured by hand as well: cutting Логика | 1.2.0 out of the corpus ledger turns the guard red, exit 1, two findings, the answer becoming Логика 1.0.0.
  • Property 3, a refusal is named rather than swallowed. The four requests of the ADR table are corpus cases of kind "refusal", and both the code and the reason text are compared character for character. The run gives the promised FLANG_REESTR_KONFLIKT, FLANG_REESTR_KONFLIKT, FLANG_REESTR_ZAPROS, FLANG_REESTR_STROKA and four texts that agree with section 5.
  • Forgery. The Forgery plan strips the list of ranges and versions out of every expected reason and appends a word to every expected answer: exit 1, six findings, every case named.
  • Property 1 was repaired by the ledger reprint earlier today; here it gets its own shortcut registry-prints:check and its own called probe, so the fingerprints are checked by a job and not by hand. Negative control: one digit bent gives "not matched: 1, matched 6", exit 1.

The CI job registry-resolution runs the probes before the checks. Both checks also join the pre-push hook (4.5 s and 3.4 s here).

2031, the lock

Two edits, both in flang/src/emit/c/flang_repl.c:

  1. lock_scan dropped an import without a "from" key by a bare continue. It is now resolved by repl_find_module — the same places and the same order the loader uses, because a list of places of its own would mean the lock records a file other than the one that will build.
  2. lock_collect now opens a .flang-package whole through pkg_take_nested, the same body a package over a package uses, instead of handing it to the flang parser.

Runs after the fix, binary 0.7.24:

form before after
by name, orders-api.flang exit 0, 149 B, 0 modules at 4 files exit 0, 109766 B, 3 modules at 4 files
package by path, shop.flang exit 1, FLANG_PARSE exit 0, 1 module at 2 files
path import, hmac.flang exit 0, 87465 B, 1 module at 4 files exit 0, 168237 B, 3 modules at 4 files

The third row is the control and it moved too: sha256.flang inside the closure of hmac.flang imports Numbers and UTF-8 by name, and both were lost silently. So "one module" in the old measurement was not the boundary of the path form but the same defect inside it.

The end to end run of the task is green: lock shop.flang into an empty directory, flang check there gives exit 0 and "two files with the imports", and the same directory without the lock refuses with FLANG_PACKAGE, exit 1.

The instrument is scripts/guards/lock-closes-every-form.fscript: over all three forms it compares the length of the модули list with the file count check names, minus the entry file. Run: forms 3, exit 0, 9 s (check --fast names the same count but takes 3.5 s instead of 149 s on hmac.flang).

Two probes, not one. The cheap one replaces the measured length by zero. The honest one restores the old behaviour in the seed (wanted_bytes != 0 → == 0), rebuilds the binary and demands that lock-forms:check itself go red: measured here as "by name 0 modules at 4 files" and "path 1 at 4", exit 1, while the package form stays green because its repair is a different one.

Delivery

The edit fell only into flang/src/emit/c, so the seed is refreshed the fast way in its own commit, not reprinted. flang/self is untouched, so this needs no print batch.

The fingerprint names the commit of this branch, so it dies on the next rebase: the trunk then needs one line of repair, bootstrap-reprint.sh --perekommit. Same note as the reseed of the LSP fix earlier today.

Counted marks follow by instrument, not by arithmetic: three line marks in docs/tree-inventory.md (C lines +100, bootstrap +50, emit runtimes +50) and one row in scripts/ledgers/proved-share-ledger.txt. DESCRIPTION.md lost the limitation "a module found by name is not written to the lock" because it is no longer true.

All 24 pre-push checks green, 61 s.

🤖 Generated with Claude Code

https://claude.ai/code/session_01X5n29umGpiervMVgnvvqht

the-homeless-god and others added 5 commits October 8, 2026 14:32
ADR-0059 section 7 names four properties of version resolution and asks
each to be settled by a run with a forgery. Two of them had no
instrument at all, and no CI job called the registry: a search for
"registry" over .github/workflows and .githooks found one hit, a comment
about registry-url in actions/setup-node.

Property 2, the answer does not depend on the order of the ledger rows.
The new guard runs every "choice" case on all rotations of the ledger
plus the reversed order, seven rows giving eight orders, and compares
the answers byte for byte. Run: cases 6, ledger orders 20, removed
chosen entries 4, exit 0.

The mandatory negative control lives inside the check instead of
standing beside it, because one answer over eight orders also goes green
on an instrument that never reads the ledger. For every choice case the
guard drops one chosen entry in turn and demands that the answer change;
all four removals change it. Measured by hand as well: cutting the row
"Logic 1.2.0" out of the corpus ledger turns the guard red with exit 1
and two findings, the answer becoming Logic 1.0.0.

Property 3, a refusal is named rather than swallowed. The four requests
of the ADR table are corpus cases of kind "refusal", and both the code
and the reason text are compared character for character. The run gives
the promised four codes and four texts. The Forgery plan strips the list
of ranges and versions out of every expected reason and appends a word
to every expected answer: exit 1, six findings, every case named.

Property 1 was repaired by the ledger reprint earlier today; it gets its
own shortcut and its own called probe here, so the fingerprints are
checked by a job and not by hand. Negative control: one digit of a
fingerprint bent gives "not matched: 1, matched 6", exit 1.

The corpus is packaging/registry/cases, named by a path relative to the
plan directory: flang io resolves order paths from the plan directory,
not from the current one, and a run from outside the tree once rewrote
tree files because of that.

The CI job registry-resolution runs three probes before the two checks,
and both checks also join the pre-push hook under the names reestr and prints, 4.5 s and 3.4 s here,
so the hook now has 23 checks instead of 21. who-calls-the-guards answers
"guards without a caller: 28, all named in the ledger", exit 0.
ADR-0021 point 4 promises that a ready flang lock is called after an
install, and ADR-0059 section 6 point 4 makes the closure of the lock the
acceptance condition of the registry. Neither held. A program with three
imports by name locked to "modules: []" while flang check counted four
files with the imports, and a package named by path was handed to the
flang parser, which answered FLANG_PARSE "a document must begin with the
word category" on exactly the form DESCRIPTION.md calls the way to use a
package.

Two edits, both in flang/src/emit/c/flang_repl.c. In lock_scan an import
without a "from" key was dropped by a bare continue; it is now resolved
by repl_find_module, the same places and the same order the loader uses,
because a list of places of its own would mean the lock records a file
other than the one that will build. In lock_collect a .flang-package is
opened whole through pkg_take_nested, the same body a package over a
package uses, instead of being read as source.

Runs after the fix, binary 0.7.24. By name: exit 0, 109766 bytes, three
modules, against "four files with the imports" from check. Package by
path: exit 0, one module. The control, a path import on a plain .flang,
moved too: hmac.flang now locks three modules instead of one, because
sha256.flang in its closure imports Numbers and UTF-8 by name and both
were being lost silently. So "one module" in the old measurement was not
the boundary of the path form but the same defect inside it.

The end to end run of the task is green: the lock of shop.flang into an
empty directory, flang check there exit 0 with "two files with the
imports", and the same directory without the lock refusing with
FLANG_PACKAGE and exit 1.

The instrument is scripts/guards/lock-closes-every-form.fscript. Over
all three forms it compares the length of the modules list with the
number of files check names, minus the entry file. Run: forms 3, by name
3 modules at 4 files, package 1 at 2, path 3 at 4, exit 0. It costs 9 s
because check --fast names the same file count as the full check but
takes 3.5 s instead of 149 s on hmac.flang.

Two probes, not one. The cheap one replaces the measured length by zero
and must turn the guard red. The honest one restores the old behaviour in
the seed, rebuilds the binary and demands that the check itself go red:
measured here as "by name 0 modules at 4 files" and "path 1 at 4", exit
1, while the package form stays green because its repair is a different
one.

The edit fell only into flang/src/emit/c, so the seed is refreshed the
fast way rather than reprinted, and that refresh is the next commit, as
on dev. flang/self is untouched, so no print batch is needed.

The counted marks of the tree follow by instrument, not by arithmetic:
three line marks in docs/tree-inventory.md and one row in
scripts/ledgers/proved-share-ledger.txt. All 24 pre-push checks green.
The lock fix in flang_repl.c keeps its code and loses three comment
blocks. The registry-resolution CI job is rewritten without comments,
with English shell names and messages. The corpus file of resolution
cases loses its comment header; the format it described is now a
paragraph in ADR-0059 section 7, and the ADR states the lock result
without the dates of the runs. The pre-push check is named registry.
The two C line counts in docs/tree-inventory.md follow the source.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PNHrA3rG7FTWhB11E7pjDQ
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PNHrA3rG7FTWhB11E7pjDQ
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PNHrA3rG7FTWhB11E7pjDQ
@the-homeless-god
the-homeless-god force-pushed the a/the-registry-properties-and-the-js-twin branch from b7188cd to 609a794 Compare October 8, 2026 14:59
@the-homeless-god
the-homeless-god merged commit ec2571d into dev Oct 8, 2026
36 checks passed
@the-homeless-god
the-homeless-god deleted the a/the-registry-properties-and-the-js-twin branch October 8, 2026 15:17
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