feat: link a route's and a scrape's names to the Process and surface they mean - #118
Merged
Merged
Conversation
Shape
CoverageBaseline:
Lines this pull request changed: 38/38 covered (100.00%). |
ExtraToast
added a commit
that referenced
this pull request
Sep 15, 2026
REQ-029 collided with #118's own row landed on main; this branch's AGENTS.md script-list requirement moves to REQ-030. #118 also moved the coverage baseline, so the ratchet in vitest.config.ts and README's quoted numbers are recomputed against the rebased tree rather than the pre-rebase measurement.
ExtraToast
added a commit
that referenced
this pull request
Sep 15, 2026
* docs: route every agent through AGENTS.md Add AGENTS.md as the one instruction file every coding agent reads: the estate pointer, the repository map, setup, every npm script, the testing strategy, code style, the Boundaries section, the repository skills, the claiming procedure, and the moved emf/ and MDE coursework sections. CLAUDE.md becomes an import of it plus Claude-specific notes only. * docs: configure repository skills and agent tooling Four skills (adr, spec-change, gate-triage, new-rule) live in .agents/skills, and .claude/skills is a committed symlink to that directory (git ls-files -s reads mode 120000). .claude/settings.json holds a read-only permission allowlist plus the one labelled write the claim procedure needs, and enables the mattpocock-skills, typescript-lsp and drawio plugins. .mcp.json holds context7. docs/agents/ configures the mattpocock-skills engineering skills: the GitHub issue tracker with cross-repository references written in full, the estate status: labels mapped to the five canonical triage roles, and the single-context domain doc layout with spec/v1 normative over an ADR. * test: fail when a script escapes AGENTS.md's script list Add lint:agents (scripts/lint-agents.ts), wired into the contracts CI job and npm run verify, with a fixture (test/agents-contract.test.ts) proving it fires on an undocumented script. Ledger rows REQ-029 and RULE-069 record it, and docs/architecture.md's Gates table gains a row and its count moves to nineteen, per 0102 and 0104. The new gate's own coverage (96%/94.73%/100%/95.83%) carries the same one-line command-guard gap every sibling gate script already does; the suite's aggregate moves to 98.98%/96.06%/100%/98.89%, so the ratchet in vitest.config.ts and README's quoted numbers move with it. * feat(ci): claim the issue a pull request names A non-gating workflow that adds status: in-progress (and removes status: ready-for-agent) on the issue a pull request's title, body or branch name references, and on its parent, when the pull request opens; releases the claim when it closes. Labels only: the project board's own Status field needs a token scope the default GITHUB_TOKEN does not carry, and the job says so in its own log rather than claiming a fix it cannot make. * docs: extend CONTRIBUTING.md with change shape and release flow Below the existing contribution policy: the shape of a change, when a change takes a decision, Conventional Commits, what runs where across the five non-gating workflows beside ci.yml, and release candidates and releasing. * test: recompute the coverage ratchet after rebasing onto main REQ-029 collided with #118's own row landed on main; this branch's AGENTS.md script-list requirement moves to REQ-030. #118 also moved the coverage baseline, so the ratchet in vitest.config.ts and README's quoted numbers are recomputed against the rebased tree rather than the pre-rebase measurement. * test: hold the ratchet at main's floor after the AGENTS.md gate Cover lint-agents.ts's own entrypoint guard and default output parameter with an in-process module reload, the way test/package-contents-contract.test.ts and test/secret-scan-contract.test.ts already do for theirs, so the new gate is the first to leave nothing uncovered. Rebased onto main again (#119, docs-only); REQ-030 and RULE-069 remain free. Every metric now sits above main's floor (99.06/96.17/100/98.97): statements 99.07%, branches 96.25%, functions 100%, lines 98.99%, and vitest.config.ts and README.md carry the measured values. * fix(ci): claim only what closes, fixes or resolves a pull request The claim workflow read every bare #NNN in a title or body as a claim, labelling any issue merely mentioned ("follows #115", "blocked by #39", "unlike #41"), the exact shape of the labelling incident this fixes. It also released a claimed issue's parent on every child close, and depended on gh issue view's --json parent field without confirming it exists on the runner. scripts/claim-issue.ts (test/claim-issue.test.ts, no gh call) now extracts candidates from a GitHub closing keyword (closes, fixes, resolves, and their inflections) immediately naming an issue, or the branch name's leading number, stripping fenced code blocks first. The workflow calls it for the candidate list and keeps every gh call in its own bash: on claim, the parent is claimed too if unclaimed; on release, only the named issue is released, never the parent, which stays a human's call or a later workflow's. Dropped synchronize from the triggers, since a push re-runs the same extraction over the same fields and can only repeat what already holds. Confirmed gh issue view --json parent is real and supported: added in gh CLI 2.94.0 (2026-06-10 changelog), and the ubuntu-latest runner image ships 2.100.0. A gh issue view failure is now logged with its real error text rather than assumed to mean "not an issue". Coverage rises again with the new file's own full coverage (statements 99.09%, branches 96.32%, functions 100%, lines 99.01%), still above main's floor; vitest.config.ts and README.md carry the measured values. * fix(test): keep agent configuration out of the mutation sandbox Stryker copies the repository into its sandbox before running, and its copyfile call dies on .claude/skills: a symlink to a directory, which copyfile refuses outright (EISDIR). ignorePatterns (a real, documented Stryker option, confirmed against node_modules/@stryker-mutator/core's own stryker-schema.json for the pinned 10.0.0) now excludes /.claude and /.agents, neither of which the mutation run needs: Claude Code configuration and skill content, not src/. The symlink itself is untouched; only the sandbox copy skips it. * test: hold the ratchet at main's floor after rebasing onto #120 #120 (the Platform document reader) took REQ-030 for an unrelated behaviour and added REQ-031; this branch's AGENTS.md script-list requirement moves to REQ-032, the ledger now states 32 rows. #120 added no npm script, so AGENTS.md's script list needed no change (lint:agents confirms all 22 scripts still resolve). Coverage rises with #120's own new, fully-tested code: statements 99.15%, branches 96.49%, functions 100%, lines 99.08%, still above main's floor (99.06/96.17/100/98.97, which #120 left untouched); vitest.config.ts and README.md carry the measured values.
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 #39 (parent #35).
What this branch does
A route's and a scrape's
processandsurfaceare now references in both implementations, linked when the document is read, and a name that links to nothing is refused with a code at the pointer of what wrote it.src/wire/project-intent/link.tsresolves the names inside the Application that holds them. The domainRouteandScrapehold theProcessandSurfaceobjects themselves, and a Process carriessurfacesrather than aprovidesmap.Route.process/surfaceandScrape.process/surfaceare non-containment Ecore references, parsed as Xtext cross-references.ProjectIntentScopesoffers the Application's Processes and the linked Process's surfaces, andUnlinkedNamesturns an unresolved name into its specification code.E_UNKNOWN_PROCESS, new in chapter 10, for a route or scrape naming a Process its Application does not have.E_UNKNOWN_SURFACEnow fires for a scrape too.diagnostics.json:unknown-surface(a route) andscrape-unknown-process.reference, whose one type is the target class, and a map names itsentry(Surface), so a reference can point at a map's entries.nonewhere it is dangerous), and its class diagram drawsRoute --> Surfaceas an association.Decisions worth naming
Dependency edges stay names. They point into another project file; #46 links them over the composed union.
${exposure:...}placeholders are left for the ticket that first parses env files. Neither implementation reads env files yet.A surface is not reported when its Process did not link. There is nothing to look it up in, and the Process's own refusal already says what is wrong. Both implementations follow this.
The class diagram is regenerated, not hand-edited.
scripts/diagrams/class-diagram.pylearns associations and names every distinct link into a shared target; the SVG is exported with the draw.io CLI as the script's usage says, which also retires the extra row the Process box kept after #114.Scrape --> Surfaceis left to the chapter text: across that row the line would run through six boxes, which is the layout rule the script already enforces for long links.The Java token source keeps braces as hidden tokens. It used to drop
{and}when it turned them into block markers, which left every later node one character off. Nothing read node text until cross-references did:auth-apilinked asuth-api,. The coverage test now includes a flow mapping and a flow sequence.Verification
./mvnw clean verifyinemf/: 125 tests, line coverage 100.0%, mutation score 100.0% (258 of 258).npm run verify: 629 tests,src/at 100%; Stryker 606 of 608 killed, 2 ignored as before. Ratchet raised to statements 99.06, branches 96.17, functions 100, lines 98.97, with README.md matching.npm run lint:codes: 60 codes defined, 11 exercised, 49 pending.