Skip to content

feat: the first-hour findings name their fields, and the agent collects them (ADR 0048) - #81

Merged
kfeofantov merged 1 commit into
mainfrom
feat/first-hour-collection-gaps
Aug 28, 2026
Merged

kfeofantov merged 1 commit into
mainfrom
feat/first-hour-collection-gaps

Conversation

@kfeofantov

Copy link
Copy Markdown
Contributor

Runs the collection question backwards: name the sentence the report has to say,
then find what it needs. Five findings are meant to be true from one read of a
cluster; checking each against what ships found four fields missing.

What is collected

  • Probe schedules, per container, in workload_metadata — delays, period,
    timeout, thresholds and the handler's kind. Nothing about what any probe
    checks.
  • The workload's update strategy, in a workload scope block beside the
    existing pod one (ADR 0014). Read at flush time, not at describe time: a
    maxUnavailable edit causes no pod event, so a value captured at describe
    would stay wrong indefinitely.
  • The Services routing to a workload, in workload_policy. One new
    ClusterRole grant, services, resolved through admitted pods like a budget's
    selector, degrading like every other policy source.
  • A version on every module in go_build, reversing ADR 0017 §2.

The hole this turned up

ADR 0046 moved env/args/command to the informer transform so they are
never held, not merely never shipped. A probe's exec handler is a command
and its httpGet handler carries httpHeaders — where an Authorization
value is written by hand. Both have been in the controller's cache since the
first informer, as have the preStop/postStart hooks, which nothing reads.
All are now cleared at the transform. The test enumerates every watched kind
and fails without the fix.

Two things stated rather than hidden

go_build is now a bill of materials. security.md claimed it "carries
module paths only, so it is not and cannot be used as a vulnerability-scanning
feed". That sentence is now false; it is rewritten, and §10.4 discloses the
widening. ADR 0048 §3 argues the reversal rather than performing it quietly.

An unread controller says so. A Job does not roll; an Argo Rollout rolls in
a way the agent holds no RBAC to read. Reporting nothing for both would tell a
customer their Argo workloads have no rollout strategy. Those records carry
rollout: {unread: true} and nothing else. No CRD is read and the closed
ClusterRole gains no vendor resource — reading Argo properly is its own ADR.

Prose budget

security.md §8 came out four lines smaller: room was found by deleting ADR
rationale that had drifted back in. The section ceiling did not move. The file
ceiling moves 920 → 930 for a grant, a field class and a disclosure the document
did not owe before (ADR 0044).

Evidence

make test, make lint, make chart-lint, make vulncheck: green.

On kind (Kubernetes 1.36.1) — policy-e2e, inventory-e2e, lifecycle-e2e,
node-e2e and the imageless suite all pass:

policy for .../web: budget web-pdb allows 0 disruptions, autoscaler web-hpa
  caps at 5, service web (ClusterIP) routes to it
shape of .../web: liveness exec every 11s ×4, rollout RollingUpdate 100%/0,
  and the probe command is absent
sample dependency: github.com/cespare/xxhash/v2 v2.3.0 (of 1 modules)

The probe fixture writes a marker into its exec command; the check greps the
whole workload-metadata.json, not the record.

Not run: watch-e2e (18 minutes by nature — it waits for client-go to
re-establish a watch). Its first half is covered: policy-e2e fails if
unavailable_sources is non-empty, and services is now in that list.

🤖 Generated with Claude Code

https://claude.ai/code/session_011YRKuL97KRndaopfpixrhp

…ts them (ADR 0048)

Four fields the five first-hour findings need and the agent did not ship:

- probe schedules per container, without what any probe checks;
- how a workload replaces its own replicas, nested in a `workload` scope block;
- the Services routing to a workload, in `workload_policy` (+1 ClusterRole grant);
- a version on every module in `go_build`, reversing ADR 0017 §2.

Reading the probe fields turned up a filter-early hole ADR 0046 missed: a probe's
exec command and its httpGet headers have been held in the informer cache since
the first informer, as have the lifecycle hooks. All are now cleared at the
transform, so they are not held rather than not shipped.

`go_build` is now a bill of materials and `security.md` §10.4 says so. §8 came
out four lines smaller; the file ceiling moves 920 → 930 (ADR 0044).

make test, lint, chart-lint, vulncheck: green. On kind (Kubernetes 1.36.1):

    policy for .../web: budget web-pdb allows 0 disruptions, autoscaler web-hpa
      caps at 5, service web (ClusterIP) routes to it
    shape of .../web: liveness exec every 11s ×4, rollout RollingUpdate 100%/0,
      and the probe command is absent
    sample dependency: github.com/cespare/xxhash/v2 v2.3.0 (of 1 modules)

policy-e2e, inventory-e2e, lifecycle-e2e, node-e2e and the imageless suite all
pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011YRKuL97KRndaopfpixrhp
@kfeofantov
kfeofantov merged commit adf1c82 into main Aug 28, 2026
3 checks passed
@kfeofantov
kfeofantov deleted the feat/first-hour-collection-gaps branch August 28, 2026 19:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant