Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion spec/v1/10-project-intent.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,20 @@ repository holding three Applications rather than three repositories with three
publish workflows) and a project never spans repositories, so composition unions
fragments and never has to union a project (chapter 40).

**A composition fixture that stands in for an already-published fragment does
not carry `.project.yml`.** `spec/v1/examples/negative/*/intent*/` holds
documents fed directly to composition to exercise an invariant at the union
(chapter 40), never rendered and never read out of a `platform/` tree. The
suffix above names a file a publish step reads from a project's own
repository; putting it on a fixture that is published by nothing and has no
`platform/` tree to sit in would claim a layout that does not exist. The
difference is deliberate: a directory under `spec/v1/examples/<project>/` is a
worked project meant to render, and one under `spec/v1/examples/negative/` is
meant to make composition fail, at least one of them
(`duplicate-process-name`) before a union of two fragments ever runs. A test
that discovers project files by the `.project.yml` suffix is meant to find
only the former, and must keep finding only the former.

The split that matters is not file-level but concern-level. A secret's **access**
is declared in the project file, beside the `dependsOn` edge that motivates it; the
**environment variable** that carries it is a placeholder in the env file. Each
Expand Down Expand Up @@ -254,7 +268,7 @@ the others.
`name` and `instance` are both the Process name rather than one naming the
Application, because the selector must match exactly one controller's pods. A
`name` of the Application and an `instance` of the Process would read better and
would make every Process of a multi-Process Service selector-ambiguous the
would make every Process of a multi-Process Application selector-ambiguous the
moment anything selected on `name` alone.

No `app.kubernetes.io/version`. A version label would have to come from the
Expand Down
2 changes: 1 addition & 1 deletion spec/v1/examples/data/rendered/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ contributes routes and exposures to both; it owns neither object.
| `hpa.yaml` | The registered `kubernetes` adapter can emit one; nothing in layer 1 declares autoscaling |
| `vso.yaml` for rabbitmq and valkey | Neither declares `secrets` at either level. Their clients hold the credentials, which is what a provider looks like |
| `configmap.yaml` for rabbitmq and valkey | No `assets`, and their env files are not in this example set ([G-28](#g-28)) |
| `servicemonitor.yaml` for valkey | No `scrape`. No exporter runs beside it, so there is no metrics surface and none is invented, which is why the Application declares `alertClass: none` rather than a class it could not signal |
| `servicemonitor.yaml` for valkey | No `scrape`. No exporter runs beside it, so there is no metrics surface and none is invented, which is why the Application declares no `observability` block at all rather than a class it could not signal |
| a backup job for `valkey-data` | `durability: reconstructible` derives none. **The one absence in this project that is a decision rather than a hole** |
| `PrometheusRule`, anywhere | Not the model's to render. `alertClass` is published as a resolved fact and the monitoring stack that owns PromQL, severity and receivers reads it from the projection ([chapter 10](../../../10-project-intent.md#observability)) |
| `Role` / `RoleBinding` | No `rbac` adapter ([G-35](#g-35)) |
Expand Down
3 changes: 2 additions & 1 deletion spec/v1/examples/platform/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ nothing in it names a Kubernetes field, a Traefik key, a k3s flag or a command
|---|---|---|
| `substrate` | cluster facts that decide other decisions, named for what they are | [0057](../../../../docs/adr/model/0057-datastore-and-restore.md), [0028](../../../../docs/adr/model/0028-secrets-at-rest-gate.md) |
| `bootstrap` | what must exist before the first rendered object can apply | [0099](../../../../docs/adr/model/0099-bootstrap-set-is-recorded.md) |
| `tiers` | the shared edge is finite; four edge facts, and the Traefik Application each tier is | [0076](../../../../docs/adr/model/0076-middleware-has-one-producer.md), [0097](../../../../docs/adr/model/0097-authored-values-name-model-concepts.md) |
| `tiers` | the shared edge is finite; four edge facts, and the Traefik Service each tier is | [0076](../../../../docs/adr/model/0076-middleware-has-one-producer.md), [0097](../../../../docs/adr/model/0097-authored-values-name-model-concepts.md) |
| `durability` | a backup window is one node's IO, a destination one remote target | [0077](../../../../docs/adr/model/0077-durability-derives-a-backup.md) |
| `engines` | the method is an image; nothing authored is executable | [0097](../../../../docs/adr/model/0097-authored-values-name-model-concepts.md) |
| `monitors` | one scrape cadence for the estate, because ingest is shared and no Application knows better. It is the whole observability surface of this document: no receiver map, no severity mapping, no rule catalog ([chapter 14](../../14-platform-intent.md#monitor-cadence)) | [0021](../../../../docs/adr/model/0021-observability-scrape-and-alert-class.md), [0079](../../../../docs/adr/model/0079-alert-class-derives-from-a-rule-catalog.md) |
| `hardening` | one posture for every container the estate renders: thirty declarations of the only legal value are thirty copies of one decision. A Process authors no hardening at all, and there is no per-control exception surface to author, because a relaxation carried with a reason is an override under another name ([chapter 14](../../14-platform-intent.md#hardening-policy)) | [0016](../../../../docs/adr/model/0016-pod-hardening.md) |
| `probes`, `ephemeral` | one cadence and one size for the estate | [0088](../../../../docs/adr/model/0088-startup-probe-targets-liveness.md), [0092](../../../../docs/adr/model/0092-writable-paths-are-declared.md) |
| `providers` | something the estate reaches and does not deploy: a fact, not a hole | [0090](../../../../docs/adr/model/0090-edges-resolve-against-the-register.md), [0095](../../../../docs/adr/model/0095-platform-intent-is-the-second-authored-document.md) |

Expand Down
Loading