docs: finish what the hierarchy rename left in the examples and chapter 10 - #119
Merged
Merged
Conversation
…and missing hardening row The tiers table cell still read "Application" where #100's rename should have left the Kubernetes Service alone; #107 restored other external spellings but missed this one. Also add the row for platform.intent.yml's hardening block, which the table never carried: one posture for every container, no per-control exception surface, decided by 0016.
…: none Chapter 10 is explicit that Alert Class has no none member: an omitted observability block already says "no monitoring", and a member that means "I wrote the field to say I did not want the field" is ceremony. valkey's row said the Application "declares alertClass: none", which is not a value this schema accepts; it declares no observability block at all.
…d convention spec/v1/examples/negative/*/intent*/ fixtures stand in for Intent Fragments already handed to composition, not files in a repository's platform/ tree, and renaming them to .project.yml would pull them into three tests that discover project files by that suffix, at least one of them (duplicate-process-name) failing where those tests expect every file to parse clean. Renaming is left for its own change; this commit instead states the convention in chapter 10 so the suffix difference reads as a rule rather than an oversight, and none of the three tests' selections move: 14 .project.yml files for the diagram test, 4 cases for the Project Intent test, and (by inspection of its source, without running Maven) 4 files for the EMF worked-examples test, which walks the same suffix excluding refusals/.
The label-set section's hypothetical alternate labelling reads "would make every Process of a multi-Process Service selector-ambiguous". Before #100 this said "multi-Workload Service"; the rename converted Workload to Process but left this one "Service" unconverted, where it names what the estate now calls an Application (compare "a two-Process Application" in chapter 30) rather than a Kubernetes Service, which the surrounding paragraph never mentions: it is about a Deployment's pod selector. It now reads "multi-Process Application". Re-grepped spec/v1/*.md for Service used as the retired hierarchy word: the three remaining occurrences (10-project-intent.md's IngressRoute paragraph, 30-deliverables.md's adapter table, 16-dependencies.md's diagram node) are all the Kubernetes object and are left alone.
Shape
CoverageBaseline:
This pull request changed no covered line. |
ExtraToast
added a commit
that referenced
this pull request
Sep 15, 2026
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.
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.
Follows #115.
What this fixes
The three things #115 left for a follow-up, and one more leftover of the same rename found while doing them.
spec/v1/examples/platform/README.mdsaid "the Traefik Application each tier is", where it means the Kubernetes Service each tier's route targets. It read Service before refactor: rename the authored hierarchy to Project, Application and Process #100's rename and fix: restore the external names the hierarchy rename rewrote #107's restoration pass missed it.hardening:blockplatform.intent.ymlcarries. It has one now, saying the posture is declared once for every container, a Process authors none, and there is no exception surface, linking chapter 14 and ADR 0016.alertClass: none.spec/v1/examples/data/rendered/README.mdsaid the valkey Application "declaresalertClass: none". Chapter 10 says Alert Class has nononemember, anddata.project.ymlopts out by omitting theobservabilityblock, which is what the README now says. It was the only occurrence in the repository.nameof the Application "would make every Process of a multi-Process Service selector-ambiguous". The paragraph is about a controller's pod selector, not a Kubernetes Service, and the text read "multi-Workload Service" before refactor: rename the authored hierarchy to Project, Application and Process #100, which converted Workload to Process but left this Service behind. It now says Application, as chapter 30 already does. A re-grep of the chapters found three other bareServiceuses, and all three are the Kubernetes object.The negative fixtures keep their names
The composition fixtures under
spec/v1/examples/negative/*/intent*/do not carry.project.yml, and this keeps it that way on purpose. Chapter 10's "Two artefacts" section now says so: those files stand in for an Intent Fragment that has already been published and is fed to composition, not a file in a repository'splatform/tree, so the suffix rule for what a publish step reads does not apply to them.Renaming them was the alternative, and it would have been unsafe. The EMF
WorkedExamplesTestselects every*.project.ymlunder the examples, excludes onlyrefusals/, and asserts each parses with no diagnostics.duplicate-process-nameis a single-file violation that would very likely raise one, so a rename would either break that test or need its expectations redesigned without Maven to prove the redesign.The suffix-selecting tests select exactly what they did before: 14 files for the diagram test, 4 cases for the Project Intent test, and 4 worked files for the EMF test, the last reasoned from its source.
Verification
npm run lint:links: 178 files clean.npm run lint:meaning: 157 files clean.npm run verifyexit 0: 619 tests, coverage unchanged.