feat: parse the minimal project intent in both implementations and match its oracle - #112
Merged
Merged
Conversation
This was referenced Sep 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #83 (parent #78). First of three pull requests rewriting #77: this one carries the
minimalcase through both implementations; #84 widens the language to every accepted example; #85 adds the refusals and closes #38.What this branch does
minimal's authored project file now parses in both implementations, and both are compared with the committedexpected/intent.jsonbyte for byte.TypeScript, the production implementation
src/wire/project-intent/: the Zod schema for the fieldsminimaluses, a YAML reader that accepts one document with no anchors, aliases or explicit tags, and the mapper into the domain.src/domain/project-intent/: the domain model and the closed vocabularies, declared once and enumerated by the schema.src/application/parse-project-intent.ts: text in, aResultof the validated document and the domain model out, orschemadiagnostics carrying an RFC 6901 JSON Pointer.Java, the model-driven implementation
emf/metamodel/:project-intent.ecore, hand-written, with its.genmodel; an MWE2 workflow runs EMF'sEcoreGeneratoringenerate-sources, so the typed Java lands undertarget/and is never committed.emf/syntax/: the Xtext grammar for the YAML subset, importing that metamodel, so the parser yields instances of the graded model directly. Indentation is handled by a token source: a deeper line opens a block, a dash opens one around the item that follows it, and a flow collection opens and closes one on a line, so{ path: /, match: prefix }and the indented form parse through one rule. Keys are unordered groups.emf/cli/: the pipeline entry, and the reflective reader that turns a parsed model into the intent JSON. A feature is named as the authored key it holds, a map entry is written as an object, an enumeration as its literal, and an optional feature the document left out is absent.emf/parity/: the parity suite, table-driven over every case that carries an intent oracle. It is now an Eclipse bundle, because it depends oncli.Decisions worth naming
The metamodel is the authored shape, not the domain shape. The Java side compares
intent.json, which is the authored document canonicalised, so its features carry authored names. The TypeScript side keeps Zod for that shape and a mapper into a domain model that renames (projecttoname,exposuretoexposures,providesto a map). Both agree on the oracle, which is what the contract asks.The Xtext language binds
.yml, not.project.yml. EMF resolves a factory by the last extension, so a two-segment extension registers something nothing looks up. Routing by file name lands with the Platform document in #84.Mutation testing now runs on
src/. Stryker, with the break threshold at the measured score (100%), aMutationCI job,RULE-064andREQ-022. The runner config lists the suites that reachsrc/: the oracle suite reads the git index, which Stryker's sandbox does not have, and is named with its reason intest/mutation-contract.test.ts.Generated code is excluded by naming each generated package. JaCoCo's
*reaches across package separators, so the first exclusion glob silently excluded the hand-written token source too, and the module reported 0% with a green agent. The agent takes class names and the report takes file paths, so each is configured on its own execution.Verification
./mvnw clean verifyinemf/: 76 tests, line coverage 100.0%, mutation score 100.0% (169 of 169).npm run verify: 422 tests,src/at 100% statements, branches, functions and lines; Stryker 158 of 158 mutants killed. Coverage ratchet raised to statements 98.46, branches 93.44, functions 100, lines 98.35, with README.md matching.minimal's committedexpected/intent.jsonbyte for byte, and each suite carries the negative case: one changed field no longer matches the oracle.What this does not do yet
auth,data,knowledgeand the platform files (#84), the descriptor and the committed JSON Schema (#84), the refusal fixtures and their diagnostics oracles (#85), andstateful's removal from the specification (#38, in #85).