Compare commits

..
Author SHA1 Message Date
jakman85andClaude Opus 5 f1d16f44b8 chore(decisions): record the CI reading, and why the metrics policy is NOT here
gate / gate (pull_request) Failing after 1m43s
gate / conformance (pull_request) Has been skipped
Follow-up to the branch's one substantive commit; no code change.

CI on 99560c2d, read from the commit's /statuses rather than from a tick:
  gate / gate (pull_request)         state=failure   desc='Failing after 1m44s'
  gate / conformance (pull_request)  state=pending   desc='Blocked by required conditions'
The second line is PENDING, not the `success` + "Has been skipped" trap -- the
conformance job is gated on the gate job, which failed, so it never ran.

MY LOCAL `approval-policy: green` WAS MEANINGLESS AND I NEARLY REPORTED IT AS
EVIDENCE. ci/approval-policy.sh:47 reads GITHUB_EVENT_NAME, unset outside CI, so
it short-circuits to "N/A": a clean local gate STRUCTURALLY cannot catch a
sensitive-path problem. Verified by re-running with
GITHUB_EVENT_NAME=pull_request PR_NUMBER=34, where the stage evaluates and fails
CLOSED on the missing token while every other stage stays green -- which bounds
the CI failure to that one stage. I could NOT read CI's job log to confirm it
from CI's own output: this Gitea answers 404 on /actions/runs and on
/actions/jobs/{task}/logs, so only /actions/tasks is available. Attribution
therefore rests on the local reproduction plus the sensitive-path rule, not on
CI's log -- weaker evidence than PR #28 had, named rather than papered over.

Branch protection and the runner re-measured against the live API (CLAUDE.md
2b), not inherited from the CLAUDE.md table: protected=True,
user_can_push=False, enable_status_check=True, contexts=['gate / gate
(pull_request)'], required_approvals=1; runner id=1 incluster-dind online. So a
human is required on every PR here regardless of path. I did NOT provoke a
rejected push to main, so user_can_push is the API's word only.

DECLINED, with reasons: bundling Ines Dubois's metrics-ingress NetworkPolicy.
The coordinator asked for my judgement and the answer is to queue it as the next
PR, not to drop it. Principally because it is a MODEL question, not a policy to
bolt on: schema 1.6.0's observability.metricsEndpoint already renders the
monitoring-namespace ingress allow, and what the model cannot express is a
SECOND metrics endpoint belonging to a sidecar the RENDERER injected. Keying a
bespoke policy off the pod label auth-mode=forward-auth hardcodes "forward-auth
implies 44180" instead of deriving it -- the "list, don't derive" anti-pattern
oauth2-proxy-cookie-names-distinct assertion (5) forbids, one directory from the
check that forbids it. Also: it is a trust-boundary ingress allow and a
different requirement set (R-NET-01/02, R-OBS-01 vs R-IDP-02), so it should not
be reviewed in the shadow of an --api-route headline; the conflict argument does
not apply to my diff, which regenerates TWO goldens not five, and a
CiliumNetworkPolicy is a different document in files git merges independently;
every fact in the finding is hers and I have measured none of it; and the
PodMonitor it serves is in HER PR #29, so shipping the policy alone would open
an ingress allow for a scraper that selects nothing.

Also records that the sidecars' metrics remain UNSCRAPABLE and that this branch
does not change that.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-10-01 22:30:01 -05:00
@@ -344,23 +344,19 @@ rendered sidecar against its **own ServiceDefinition**, which is the only readin
rather than leaving "something is red" as the whole report. Fail-closed is correct here and
deliberate: unlike `gitea-settings`, where a missing credential is a lock-out, a skip of this
stage would be a bypass (CLAUDE.md §1).
- **CI, read from each commit's `/statuses` rather than from a tick.** Both contexts report, and
**only one of them runs**. Identical on `99560c2d`, `df1b25b6` and `f1d16f44`:
- **CI, read from the commit's `/statuses` rather than from a tick.** On the branch head
`df1b25b6`, both contexts have reported and **only one of them ran**:
gate / gate (pull_request) state=failure desc='Failing after ~1m43-1m45s'
gate / gate (pull_request) state=failure desc='Failing after 1m45s'
gate / conformance (pull_request) state=success desc='Has been skipped'
**That second line is §2b's trap in the wild**: a *skipped* Gitea job reports
`state=success`. The conformance job did not execute, so its green tick certifies nothing —
read the description, not the colour. The duration is given as a range on purpose: it differs
by a second or two per run, and pinning one number inside the file whose commit triggers the
next run is a self-reference, not a measurement. The load-bearing fields are the **state** and
the **description**, and those are stable across all three.
Worth recording that the **same context changed its answer over time**: on the first push it
briefly read `state=pending desc='Blocked by required conditions'` — still waiting on the gate
job it depends on — and resolved to `success` only once that job settled. So sampling a status
once can show either a pending **or** a green tick for a job that never executed.
read the description, not the colour. Worth recording the earlier reading too, because the
**same context changed its answer**: on the first push (`99560c2d`) it was
`state=pending desc='Blocked by required conditions'`, i.e. still waiting on the gate job it
depends on; once that job settled, the skip resolved to `success`. Anyone sampling a status
once can therefore see either a pending or a green tick for a job that never ran.
**I could NOT read the CI job log to confirm the failing stage from CI's
own output**: this Gitea's `/api/v1/repos/{owner}/{repo}/actions/runs` endpoint answers
**404** (only `/actions/tasks` exists, which lists tasks without logs), and