Skip to content

Map the Tier-2a ECCN shape key onto the CCL's own keys - #10

Merged
JSv4 merged 1 commit into
mainfrom
feat/eccn-shape-equivalences
Aug 25, 2026
Merged

Map the Tier-2a ECCN shape key onto the CCL's own keys#10
JSv4 merged 1 commit into
mainfrom
feat/eccn-shape-equivalences

Conversation

@JSv4

@JSv4 JSv4 commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Companion to OpenContracts #2276. Neither is much use without the other.

Why

#2276 moves ECCN citation extraction out of the Tier-1 registry extractor into
the Tier-2a grammars, and changes what it emits:

before (in extractor.py):  ECCN 3A611  ->  ccl:3a611
after  (in grammars.py):   ECCN 3A611  ->  eccn:3a611

That is the correct split. ECCN 3A611 is anchored on a literal, so core
recognises the form without knowing whether a Commerce Control List corpus is
installed — which makes it a SHAPE, and a shape must not emit ccl:, the
prefix this pack happens to bind. The old code looked the prefix up through a
hardcoded "ccl" alias string, baking one pack's naming convention into the
framework. usreporter: and htsus: already establish the opposite pattern.

The consequence for this repo: the pack now has to close the loop. Without
these rows every extracted ECCN citation resolves to nothing.

What

638 eccn:<code>ccl:<code> rows, one per CCL section.

Generated by the ITAR workspace's build/gen_equivalences.py, not hand-written
— and generated for every section rather than the ones some document
happens to cite, so the next document to cite an ECCN works without anyone
remembering this. The existing act:eccn-<code> prose-form rows are unchanged.

They live in ear rather than in the domain pack because ownership is decided
by to_key alone, and eccn: is a shape prefix that no pack declares — so
these are not cross-pack rows.

The diff is purely additive; the ccl prefix's existing aliases are untouched.

Verification

Run from the registry root, not from the build workspace:

$ python3 scripts/validate_pack.py ear
ear: OK
$ python3 scripts/validate_domain.py --all
us-export-control: OK
$ python3 scripts/validate_domain.py --self-test
self-test: 18/18 checks behaved as expected
$ python3 scripts/validate_pack.py --self-test
self-test ok (broken pack raised 6 errors as expected)

And the split gate in the build workspace:

monolith: 21 corpora, 24 prefixes, 4,679 sections, 2,855 rows
split:    21 corpora, 24 prefixes across 14 packs, 2,663 pack rows + 192 cross-pack
split preserves the monolith exactly

🤖 Generated with Claude Code

OpenContracts #2276 moves ECCN citation extraction out of the Tier-1 registry
extractor and into the Tier-2a grammars, where it emits a SHAPE-level key
(`eccn:3a611`) instead of `ccl:3a611`.

That change is right — core recognises "ECCN 3A611" without knowing whether a
Commerce Control List corpus is installed, so emitting `ccl:` would hardcode
the prefix THIS pack happens to bind into the framework, exactly as the
`usreporter:`/`htsus:` precedent warns. But it means the pack now has to close
the loop: without these rows every extracted ECCN citation resolves to nothing.

638 rows, one per CCL section, generated by `build/gen_equivalences.py` rather
than hand-written — and generated for EVERY section rather than the ones some
document happens to cite, so the next document to cite an ECCN works without
anyone remembering this.

They belong here rather than in the domain pack: ownership is decided by
`to_key` alone, and `eccn:` is a shape prefix no pack declares, so these are
not cross-pack rows.

Verified from the registry root: `validate_pack.py ear` OK,
`validate_domain.py --all` OK, both self-tests behaving. The ITAR workspace's
`verify_split.py` gate confirms the split still preserves the monolith exactly
(2,855 rows: 2,663 to packs, 192 cross-pack, 0 resolving to no pack).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@JSv4
JSv4 merged commit ecb32d1 into main Aug 25, 2026
4 checks passed
@JSv4
JSv4 deleted the feat/eccn-shape-equivalences branch August 25, 2026 12:39
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