docs: the class diagram was under-reporting the model, and sidecars had no table - #13
Merged
Merged
Conversation
…pe class Two relations the chapter states and the drawing did not. A grant sits at whichever level the secret is shared: on the Service when every Workload holds it, on the Workload when only that one does ([0022](docs/adr/model/0022-grants-live-on-the-service.md)). The SVG drew only the Service composition, so it read as though a Workload cannot hold a secret of its own. Both edges are now drawn, and the Service one says which case it is rather than the bare word "shared", which invited reading it as shared between Services — no such level exists. `Scrape` was missing entirely. It joins the Workload band as an eleventh composite, and the mermaid at the foot of the chapter already carried both, so this closes a gap between the two.
A verifier pass over the exported SVG against the chapter turned up four places where the text mirror had drifted, plus one where the drawing was wrong. Chapter precedence says the SVG is the diagram and the mermaid is what gets fixed, so this is mostly the mermaid. - `Override` authored `field`. An override names a derivation by its own name and never a Kubernetes field ([0097](docs/adr/model/0097-authored-values-name-model-concepts.md)), which is what the drawing and the prose already said. - `Grant` carried only the `kv` arm. It is a discriminated union on `engine` ([0085](docs/adr/model/0085-a-grant-is-a-union-on-engine.md)), so `engine`, `role`, `key` and `operations` join it. - `Sidecar` was marked proposed and held no quantities. It is graded ([0064](docs/adr/model/0064-sidecars-are-workload-vocabulary.md)) and a sidecar declares its own `memory` and `cpu`, because resources are container-level in the API this renders to. - The eighteen closed vocabularies were in the drawing's enumeration panel and in the field tables but not in the mermaid. They are generated from the same list the drawing uses, and the block was rendered with mermaid-cli to check it parses. The drawing's own error: `DiskRequest` listed `size` as an authored attribute. `placement.disk.size` is derived — the sum of the Workload's volume sizes — so showing it in a layer-1 diagram contradicts chapter 16's single-authority property. It is gone; `media` stays authored.
0064 graded sidecars and pointed `normative:` at `#workload`, but that section never said what a sidecar declares. The ADR carried the field list, which is backwards: an ADR justifies and the chapter states. `### Sidecars` now carries the table — `name`, `image`, `memory`, `cpu`, `hardening` — plus the three rules that were only in the ADR: - The split follows Kubernetes, not the model: `nodeSelector` and affinity are pod-level, so the node dimensions stay on the Workload and a sidecar declares no `placement`; `resources` and `securityContext` are container-level, so a sidecar declares its own quantities and hardening. - Nothing is inherited. A Workload's exception list does not reach its sidecars, because `postgres-exporter` meets `restricted` while `postgres` does not. - Eligibility sums: the placement check adds every sidecar's `memory` and `cpu` to the Workload's, so `postgres` at 2Gi with a 64Mi exporter needs 2112Mi free rather than 2Gi. It also records what a sidecar is not: no identity, no probes, no exposure, no release semantics of its own — so `provides` stays on the Workload even when the listener is the sidecar, which is the attribution the model could not state before the field existed. `hardening` and the `Sidecar *-- HardeningException` composition are in both drawings. HardeningException moves next to Sidecar in the child band, so its second parent is a short hop rather than an edge across eight columns. 0064's `normative:` pointer moves to the section that now specifies it.
The two `secrets` compositions were labelled "every Workload holds it" and "this Workload only", which is chapter prose sitting on a connector: a class diagram states the role name and the multiplicity, and which level a given secret belongs at is a rule the Secrets section already carries. Both now read `0..* secrets`, and the two relations are told apart by their ends, which is what UML does. The three dependencies get stereotypes for the same reason — «resolves by name» and «byte-matches» rather than a clause each. The mermaid mirror follows.
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.
what this is
Three follow-ups to #12, found by pointing a verifier at the exported class
diagram and the chapter it draws. Two are drawing bugs, one is a spec gap the
drawing exposed.
the drawing was under-reporting the model
spec/v1/diagrams/10-service-intent-model.drawio.svgdrew onlyService *-- Grant, so it read as though a Workload cannot hold a secret of itsown. A grant sits at whichever level the secret is shared — on the Service when
every Workload holds it, on the Workload when only that one does
(0022) — so both
compositions are now drawn, and the Service one names its case instead of saying
"shared", which invited reading it as shared between Services. No such level
exists: a domain-level grant is refused, because a KV read covers the whole
document (0009).
Scrapewas missing from the drawing entirely, andDiskRequestlistedsizeas an authored attribute.
placement.disk.sizeis derived — the sum of theWorkload's volume sizes — so drawing it in a layer-1 diagram contradicts chapter
16's single-authority property.
mediastays authored;sizeis gone.the mermaid mirror had drifted
Chapter precedence says the SVG is the diagram and the mermaid is what gets
fixed, so this half is all mermaid:
Overrideauthoredfieldwhere an overridenames a derivation (0097),
Grantcarried only itskvarm rather than the union onengine(0085),
Sidecarwas stillmarked proposed, and the eighteen closed vocabularies were in the drawing's
enumeration panel but nowhere in the text. The enum block is generated from the
same list the drawing uses, and rendered with mermaid-cli to check it parses.
what a sidecar carries
0064 graded sidecars and
pointed
normative:at#workload, but that section never said what a sidecardeclares — the ADR held the field list, which is backwards for this repository.
Chapter 10 gains
### Sidecars: the table (name,image,memory,cpu,hardening), the pod-versus-container split that makes the field list followKubernetes rather than a rule of the model's own, and the two consequences that
were ADR-only. Nothing is inherited, because
postgres-exportermeetsrestrictedwhilepostgresdoes not. And eligibility sums: the placement checkadds every sidecar's quantities to the Workload's, so
postgresat 2Gi with a64Mi exporter needs 2112Mi free rather than 2Gi.
hardeningandSidecar *-- HardeningExceptionare in both drawings, withHardeningExceptionmoved besideSidecarin the child band so its secondparent is a short hop rather than an edge across eight columns. 0064's
normative:pointer now names the section that specifies it.verification
npm run verifyis green — 86 ADRs, 130 links, 85 rendered objects with zeroskipped, 63 tests — and the SVG crossing check still reports zero.