Skip to content

Decide what each settled decision does about the claim under it that failed #366

Closed

Description

@ExtraToast

Question

What does each settled decision do about the claim under it that failed?

Find the claims behind the settled decisions that no source supports found six claims that fail against a primary source. The evidence is in docs/research/unsupported-claims.md, by claim id. Each needs one decision:

  • C4, the LAN Traefik serves the wildcard too (Decide how the foundation's HelmReleases are rendered and owned). Whether cert-manager still retires, with a second ACME resolver, stored state and Cloudflare token on the LAN Traefik, or stays as the one issuer that hands both proxies a Secret.
  • C28, Alloy holds no host privilege (same decision). Whether log-collector leaves the Node Agent catalog and Alloy is declared as an ordinary Process.
  • C17, the Frankfurt node has no address pool (Decide how the model meets the live needs no chapter covers). How a Process on a node with one public address and no pool is exposed at L4: stalwart's mail ports and the public Traefik's 80 and 443 both use hostPort there today, and low ports stay refused.
  • C33, a non-root process can bind a low port on k3s (same decision). Whether E_PRIVILEGED_PORT_UNDER_NONROOT and the four image changes stay, on a hazard this substrate does not have. The claim is read from source and should be drilled first.
  • C8, no workload reads a RabbitMQ dynamic credential (same decision). Whether rabbitmq still joins the grant union, given that the estate dropped the dynamic credential after an outage.
  • C43, a dashboard without a uid does not collide (Decide how the model meets human access grants and Grafana content). What the uid check refuses and why, now that the hazard is a changing address on recreation, not an overwrite.

Activity

  1. added
    type: docsDocumentation-only change.
    area: deployhomelab-deploy, deploy-v2, manifests, and rollout flow.
    wayfinder:grillingWayfinder ticket resolved by conversation (HITL)
    on Oct 12, 2026
  2. self-assigned this
    on Oct 12, 2026
  3. ExtraToast commented on Oct 12, 2026

    @ExtraToast
    ContributorAuthor

    Resolution

    Settled with the maintainer on 2026-10-12, under Re-state the goals and non-goals against the scale premise: every live need gets a concept, and a refusal stays only where its hazard is real at this scale. Input: docs/research/unsupported-claims.md, by claim id, and one drill run for this ticket.

    The drill behind C33

    Run on the live cluster (k3s v1.35.2+k3s1, node enschede-t1000-1) on 2026-10-12, in a throwaway namespace that was deleted afterwards. One pod, busybox:1.36, with runAsUser: 1000, runAsNonRoot: true, allowPrivilegeEscalation: false, capabilities.drop: [ALL], a read-only root file system and the RuntimeDefault seccomp profile, off the host network, running httpd -f -p 80.

    • id printed uid=1000 gid=1000.
    • CapPrm, CapEff and CapBnd in /proc/self/status were all zero.
    • /proc/sys/net/ipv4/ip_unprivileged_port_start read 0.
    • netstat showed a listener on :::80, and a request to 127.0.0.1:80 got an HTTP answer.

    C33 is therefore settled by test, not only by reading the source: on this substrate a non-root process with no capability binds a port below 1024.

    Decisions

    1. C4: every tier that terminates TLS issues its own certificate. cert-manager still retires. A tier with certificates: acme derives a resolver, a reconstructible claim for the ACME state and the Cloudflare token through VSO, on that tier's proxy. Nothing is shared between the two proxies, so no Secret, Certificate or hand-written TLSStore is needed, and the earlier decision that no admission webhook is rendered stands. The estate's Platform document declares the lan tier as listener: plain with certificates: none, which is not what runs and cannot run, because every hostname is under .dev; it is corrected to tls and acme. Both proxies run one replica today, which is what a resolver requires.
    2. C28: Alloy is an ordinary Process. log-collector leaves the Node Agent catalog, which keeps four entries, all host-privileged: gpu-device, gpu-metrics, node-metrics and l4-speaker. Alloy is declared in the observability project with a cluster-scope api read on pods and their logs, admitted by the Platform document like any other API access (0092). Its replica count is its own and not one per node. The catalog's meaning stays "host-privileged", not "runs once per node".
    3. C17: the Platform document declares named L4 Addresses, of two kinds. A pool is a range announced on one site's network segment and renders a LoadBalancer Service with the Local traffic policy, as decided before. A node address is a node's own address and renders hostPort on the Process, with a hard pin to that node derived from the declaration. An L4 exposure names an L4 Address by its name, the same shape as mounting a node dataset, so no Application names a node and no address is written in a project file. A port and protocol used twice on one node address is refused at build. The client-facing port stays a fact of the exposure, separate from the port the container listens on. stalwart's eight ports use the Frankfurt node address. hostPort is not a second mechanism an author picks: the kind of the L4 Address decides the rendering.
    4. A tier names the L4 Address its proxy listens on. This is a fifth tier fact. The traefik adapter derives the proxy's ports from listener, as it already derives the entry points, so ports 80 and 443 are never authored. The public tier names the Frankfurt node address and the lan tier names an address in the Enschede pool.
    5. C33: E_PRIVILEGED_PORT_UNDER_NONROOT is cut. The hazard it guards does not exist on this substrate, as the drill shows. auth-ui, agents-ui, AdGuard and stalwart keep the ports they listen on, and the four image changes are dropped. Chapter 14 records the fact once, under its substrate facts: k3s lets a pod that is off the host network bind any port without a capability. No authored Process can use the host network (only catalog node agents do), so the one exception to that fact reaches nothing an author writes. The cut lands with chapter 11's rewrite, after emf/ is deleted, in that chapter's own pull request: it widens what the build accepts, so it does not wait for the 1.0.0 contract pull request. 0020 loses its low-port clause in the same pull request.
    6. C8: rabbitmq still joins the grant union as a dynamic credential, on corrected grounds. It models nothing live: the estate dropped the dynamic credential after Vault revoked a user under a running pod. The cause was the Vault Agent injector running once and never renewing the lease, and the injector retires. VSO renews a lease and then replaces the credential and restarts its consumers, the cycle the estate already runs for Postgres. The reasons to keep it are that it reuses the database grant's shape with no new grant kind, gives each consumer its own role, and retires the shared KV credential. The decision carries one condition: a drill rotates the credential under a connected consumer before chapter 17 is rewritten. If the drill fails, the question reopens with that result.
    7. C43: both uid refusals stay, for two different reasons. A uid used twice is refused because one dashboard silently overwrites the other. A dashboard file without a uid is refused because its address would be the Kubernetes UID of its object, which changes whenever the object is recreated, as a namespace Move recreates it, and every saved link then breaks. The JSON file stays the one place a uid lives; the adapter does not derive one.

    Consequences for other tickets

    Record

    This answer is recorded here, on the ticket. Nothing is written into spec/v1, CONTEXT.md or the register now. The chapter pull requests carry it:

    • L4 Address (kinds pool and node) enters CONTEXT.md with chapter 12, and the tier's fifth fact with chapter 14.
    • The Node Agent catalog enters chapters 14 and 15 with four entries, and 0046 is rewritten to that split.
    • 0020 is rewritten with chapter 11, and 0029 with chapter 17, after the drill.
    • No new ADR.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area: deployhomelab-deploy, deploy-v2, manifests, and rollout flow.type: docsDocumentation-only change.wayfinder:grillingWayfinder ticket resolved by conversation (HITL)

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions