feat: widen the Project Intent metamodel to every worked example, with its descriptor and JSON Schema - #113
Merged
Merged
Conversation
…h its descriptor and JSON Schema
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 #84 (parent #78). Second of three pull requests rewriting #77; #85 adds the refusals and closes #38.
What this branch does
The Project Intent language is now whole in both implementations: every worked example parses, and both write the same canonical intent, the same descriptor, byte for byte.
arch,site,disk,gpu,capabilities), route-levelaudienceandredirectTo, and the probe forms.none; a grant is a KV, database or transit grant. Java models each as an abstract class with its concrete cases, TypeScript as a Zod union; the descriptor shows them as the same thing.spec/v1/examples/expected/descriptor.json: every class with its features (types, required, many, map), every closed vocabulary with its literals. TypeScript builds it from the Zod schemas throughz.toJSONSchema()and a normaliser; Java walks theEPackagereflectively. The two agreed on the first run.spec/v1/schemas/project-intent.schema.json: generated from the input variant of the schema and committed, with a test that regenerates it and fails on a diff.RULE-043moves from pending to enforced.auth,dataandknowledgegainedexpected/intent.json, written from the production parser, reviewed, and matched by the model-driven one.Decisions worth naming
The three worked examples gained the document header. Chapter 10 states
apiVersionandkind, andminimaland the refusal fixtures carry them, butauth,dataandknowledgestarted atschemaVersion. They now match the chapter.statefulis gone from the authored examples. #38 deletes it from the language; the object kind derives fromlifecycleand volumes. The prose that still mentions it (chapter 10, chapter 20, the rendered-tree READMEs) is rewritten in #85, where #38 closes.The block token source grew a fold.
auth'sreplicas.reasonis a folded scalar, so the token source now turns the lines under>,>-,|or|-into one scalar token, with the indentation stripped. A#indented inside the block is content; one at or left of the key is a comment.A grant that names an engine names it first. The three grant shapes are told apart by
engine, which an unordered group cannot look ahead for. The subset requires the key first, which every example already does.The discriminator is its own vocabulary.
SecretEnginebecomesDatabaseEngineandTransitEngine, one literal each, so the Ecore enumeration and the Zod literal describe the same feature and the descriptor agrees. Thekvarm carries noengineat all, as the chapter says.Optional attributes are
unsettablein Ecore. An enumeration's first literal is its default, so an optionalcontentPolicy: strictwas indistinguishable from an absent one and vanished from the intent. Unsettable features carry "not written" as a state.One equivalent mutant is disabled with its reason.
z.toJSONSchema(..., { io: "input" })produces the same document as the output variant until a field has a platform default, so no test can tell the option apart. The option stays; the mutant is named and skipped.Verification
./mvnw clean verifyinemf/: 102 tests, line coverage 100.0%, mutation score 100.0% (232 of 232).npm run verify: 447 tests,src/at 100% statements, branches, functions and lines; Stryker 378 of 378 killed (2 ignored, as above). Ratchet raised to statements 98.6, branches 93.8, functions 100, lines 98.51, with README.md matching.minimal,auth,dataandknowledge'sexpected/intent.jsonand the shareddescriptor.jsonbyte for byte; each suite keeps its negative case.What this does not do yet
The refusal fixtures and their diagnostics oracles, the OCL invariants, and the removal of
statefulfrom the prose (#85, which closes #38). References within a document are still names rather than model references (#39), and the Platform document is #41.