Skip to content

fix: ru-blocked WARP rule-sets, per-inbound artifacts, Caddy-edge HSTS/TLS issuer visibility, audit test hardening - #988

Merged
mikkelchokolate merged 16 commits into
mainfrom
fix/wave-zf
Sep 24, 2026
Merged

mikkelchokolate merged 16 commits into
mainfrom
fix/wave-zf

Conversation

@mikkelchokolate

@mikkelchokolate mikkelchokolate commented Sep 23, 2026 •

Copy link
Copy Markdown
Owner

Summary

Fixes a wave of confirmed audit issues across WARP routing, generated artifacts, panel TLS/HSTS handling, and test quality:

Test plan

  • go vet ./... — clean; gofmt — clean; git diff --check — clean; go mod tidy — no drift.
  • go test on all touched packages: internal/{bindregistry,caddycapabilities,caddycert,generatedconfig,inbounds,installer,livevalidation,managementstate,panel,protocols/...,renderer,routing,runtime,settings} — all pass (naiveproxy/protocols verified with a stub caddy list-modules --json binary; CI supplies the pinned real one).
  • internal/api (~918 tests) run as unprivileged uid in 6 shards + targeted re-runs — every test passes in isolation. Known environment limitations identical on the base commit f01442ce:
    • TestClientPatchOpenAPIAndGeneratedContractIncludesEveryDurableField, TestConstantTimePasswordEqualDoesNotHashPasswords, TestTrackedAutoApplyUsesSnapshotIsolationOutsideGlobalMutex — fail on clean base (pre-existing).
    • TestPublicSubscriptionUsesLastAppliedImmutableSnapshot, TestAuthenticatedLinksConvergeAfterSuccessfulApply, TestManagementApplyStagesWarpOutboundWhenEnabled — require live network/traffic endpoints unavailable in this sandbox; fail identically on base.
    • TestNaiveGeneratedConfig* — require a caddy binary on PATH (pinned in CI); verified passing with a stub.
  • go generate ./sdk/go + go test ./sdk/go/... — regenerated SDK includes the new TLSCertInfo fields; tests pass.

Closes #763
Closes #764
Closes #778
Closes #779
Closes #780
Closes #855
Closes #882
Closes #902
Closes #906
Closes #820
Closes #821
Closes #822
Closes #823
Closes #824
Closes #836
Closes #844
Closes #845
Closes #846
Closes #852
Closes #853
Closes #856
Closes #857
Closes #861
Closes #863
Closes #884
Closes #894
Closes #895
Closes #901
Closes #915
Closes #918
Closes #920
Closes #959
Closes #962
Closes #971

…edge HSTS/TLS issuer visibility, and harden audit tests

- renderer/warp: route geoip:ru-blocked and geosite:ru-blocked to the
  published runetfreedom russia-v2ray-rules-dat rule-sets instead of the
  nonexistent/misrouted SagerNet remaps (#763 #778 #779)
- routing: EnsureDatSource provisions only the dat files enabled matchers
  consume; geoip:private now pulls geoip.dat (#764)
- generatedconfig: per-inbound hysteria2/olcrtc artifacts use glob
  subpaths; exact generated-path and staged-path matching; ghost
  aggregate configs and bare @.service actions removed (#780 #855)
- api/renderer: emit HSTS for the Caddy-managed panel TLS edge (#902)
- api/runtime/caddycert: /api/tls reports managedBy/issuerSource/
  issuerKind so ACME->internal fallback stays visible; spec + SDK
  regenerated (#906)
- caddycapabilities: production Probe routes through parseModuleList
  (#882)
- audit test hardening across settings/routing/renderer/protocols/
  generatedconfig/livevalidation/bindregistry/api (#820-#971 set)

Refs #763 #764 #778 #779 #780 #820 #821 #822 #823 #824 #836 #844 #845
Refs #846 #852 #853 #855 #856 #857 #861 #863 #882 #884 #894 #895 #901
Refs #902 #906 #915 #918 #920 #959 #962 #971

@mikkelchokolate mikkelchokolate left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review (head a5962df2)

Verdict: COMMENT — would APPROVE after the web client regen below. Own-PR blocks APPROVE.

Blocker

  1. Frontend generated-client drift (CI frontend failed). docs/openapi.yaml and sdk/go gained TLSCertInfo.managedBy / issuerSource / issuerKind, but no web/ orval outputs were committed. CI regenerates and diffs:

Looks good

  • WARP ru-blocked (#763/#778/#779): geoRuleSetURL correctly routes both kinds to runetfreedom/russia-v2ray-rules-dat release .srs URLs; ordinary codes stay on SagerNet. Closes the 404/geoip-ru misroute.
  • DAT provisioning (#764): EnsureDatSource / rulesNeedRouteDat attach only needed geoip.dat / geosite.dat (incl. MatchPrivateIP → geoip).
  • Artifact catalog (#780/#855): exact + glob MatchesGeneratedPath / LivePathForStagedConfig; per-inbound hysteria2/olcrtc globs; installer reports the hysteria2 dir.
  • HSTS (#902): Caddyfile edge header + Go middleware tlsEdge when panelAccess=caddy; IP still skipped on the Go path.
  • /api/tls issuer visibility (#906): managedBy / IssuerSource / IssuerKind wired through tlsCertInfo + caddycert.Pair.
  • Caddy Probe (#882): production path goes through parseModuleList.
  • Test hardening matches the stated false-green closures.

Mild (non-blocking)

  1. Caddy HSTS vs IP exclusion: RenderPanelCaddyfile always emits HSTS with preload; Go middleware still skips IP hosts. If Domain were ever an IP literal under panelAccess=caddy, the edge would still advertise HSTS (browsers usually ignore HSTS for IPs). Slight mismatch with “IP hosts remain excluded.”
  2. panelAccess case: HSTS uses EqualFold(..., "caddy"); tlsCertInfo uses access != "caddy". Align to EqualFold.
  3. IssuerKind: HasPrefix(issuerName, "acme") covers Let’s Encrypt storage dirs; other ACME issuer dir names become "other" (acceptable).

CI (at review time)

  • failure: frontend (blocker above)
  • success: filesystem-faults, multi-process, sigkill, analyze (actions)
  • in_progress: lint, image-build, analyze (go), analyze (javascript-typescript)
  • skipped: package-smoke*, test, e2e, browser-e2e, install-acceptance, privilege-boundary
  • CodeQL neutral

Fix the orval commit and this is merge-ready from a code-review standpoint (pending remaining checks).

Comment thread docs/openapi.yaml
type: string
description: >-
Issuer classification — "acme", "internal" (Caddy local CA, an
untrusted fallback), or "other".

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocker: OpenAPI/sdk/go were updated for these three fields, but the frontend orval outputs were not committed. CI frontend fails on generated-client drift for web/src/api/generated/models/tLSCertInfo.ts, the MSW twin, and web/src/api/generated/zod/runtime/runtime.zod.ts. Please regen and commit those files (see job 107378529893).

# The panel is only ever served over HTTPS at this edge; pin HSTS here too —
# the Go handler behind reverse_proxy sees plain loopback HTTP and cannot
# detect the public TLS transport itself (#902).
header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mild: This always emits HSTS (includeSubDomains; preload) for whatever Domain is. The Go middleware still skips IP hosts. If an IP literal can ever be the Caddy site address under panelAccess=caddy, consider matching that IP exclusion here for consistency with #902.

Comment thread internal/api/runtime_routes.go Outdated
access = strings.TrimSpace(settings.PanelAccess)
}
if access != "caddy" {
return info

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mild: Prefer strings.EqualFold(access, "caddy") here to match router_composition’s HSTS tlsEdge wiring.

The generated web client drifted from docs/openapi.yaml (source +
issuerKind on TLSCertInfo) — the frontend drift gate regenerated dirty
output. Commit the orval output.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>

@mikkelchokolate mikkelchokolate left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review (head 7c398494)

Verdict: COMMENT — would APPROVE. Own-PR blocks APPROVE.

Prior blocker cleared

Frontend generated-client drift is fixed by commit 7c398494 ("Regenerate web client after TLSCertInfo OpenAPI additions"). Orval outputs now include managedBy / issuerSource / issuerKind on:

  • web/src/api/generated/models/tLSCertInfo.ts
  • web/src/api/generated/msw/models/tLSCertInfo.msw.ts
  • web/src/api/generated/zod/runtime/runtime.zod.ts

CI frontend on this head: success.

Looks good (re-checked)

  • WARP ru-blocked (#763/#778/#779): geoRuleSetURL routes both kinds to runetfreedom/russia-v2ray-rules-dat .srs URLs; ordinary codes stay on SagerNet. Tests lock full URL + tag contract and forbid the old 404/geoip-ru paths.
  • DAT provisioning (#764): selective geoip.dat / geosite.dat attach still sound.
  • Artifact catalog (#780/#855): exact + glob MatchesGeneratedPath / LivePathForStagedConfig; per-inbound hysteria2/olcrtc globs; bare template units not advertised as restartable.
  • HSTS (#902): Caddyfile edge header + Go middleware tlsEdge when panelAccess=caddy; Go path still skips IP hosts (tested).
  • /api/tls issuer visibility (#906): ManagedBy / IssuerSource / IssuerKind wired through tlsCertInfo + caddycert.Pair / IssuerKind.
  • Caddy Probe (#882): production path through parseModuleList.
  • Test hardening matches the stated false-green closures.

Mild (non-blocking; same as prior review)

  1. Caddy HSTS vs IP exclusion: RenderPanelCaddyfile always emits Strict-Transport-Security with preload; Go middleware still skips IP hosts. If Domain were an IP literal under panelAccess=caddy, the edge would still advertise HSTS (browsers usually ignore HSTS for IPs). Slight mismatch with “IP hosts remain excluded.”
  2. panelAccess case: HSTS wiring uses EqualFold(..., "caddy"); tlsCertInfo still uses access != "caddy". Align to EqualFold for consistency.
  3. IssuerKind: HasPrefix(issuerName, "acme") covers Let’s Encrypt storage dirs; other ACME issuer dir names become "other" (acceptable).
  4. Branch currency: mergeStateStatus=BEHIND — main is ahead by 2 commits (5eacacd3, 8defe84d). No clash with this PR’s surface; update-branch when convenient.

CI (at review time, head 7c398494)

  • success: frontend, lint, filesystem-faults, multi-process, sigkill, image-build, analyze (go/js-ts/actions), CodeQL
  • queued (longer suite): test, e2e, browser-e2e, privilege-boundary, install-acceptance (amd64/arm64), package-smoke-matrix (amd64/arm64)

No code blockers. Merge-ready from a review standpoint once remaining checks settle (and after updating the branch if desired).

Comment thread internal/api/runtime_routes.go Outdated
if access == "" {
access = strings.TrimSpace(settings.PanelAccess)
}
if access != "caddy" {

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mild / non-blocking: HSTS edge detection uses strings.EqualFold(..., "caddy") while this gate is a case-sensitive access != "caddy". Aligning to EqualFold would keep panelAccess handling consistent if an operator ever stores a mixed-case value.

A dial-level helper failure proves the promote request never reached the
helper, so no artifact could have been published. Previously such a job was
retained in recovery_pending forever: exact-phase recovery cannot proceed
without the helper, and the durable lease blocks every subsequent apply.

Tag dial-phase failures in the socket client as undelivered, report the
mutation as not-started on that path, and let the rollback marker consume
the artifacts_prepared receipt so the job reaches a terminal failed state
and releases the lease.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>

@mikkelchokolate mikkelchokolate left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review (head b4e0e067)

Verdict: COMMENT — would APPROVE. Own-PR blocks APPROVE.

Delta vs prior review (7c398494)

New commit b4e0e067 ("Finalize undelivered promote failures as terminal failed") closes a real lease-wedge: dial-level helper failures after MarkRuntimeMutationStarting previously left the job in recovery_pending forever because exact-phase recovery cannot proceed without the helper.

Wiring checked end-to-end:

  1. privileged.SocketClient.call — only the unix dial failure is wrapped in undeliveredError; post-dial encode/decode/helper errors stay untagged (correct ambiguity).
  2. IsUndelivered — errors.As + Unwrap so %w wrappers still match; non-dial / helper-side *Error rejected (unit tests cover dial, wrap, and rejection).
  3. management_apply_context.promoteStagedConfigs — returns the Promote error bare (return …, err), so the undelivered tag survives into applyflow.
  4. applyflow.Workflow — on promote error, skips MutationStarted/Ambiguous only when IsUndelivered; other promote failures remain ambiguous.
  5. apply.markRuntimePublicationRolledBack — phase IN now includes artifacts_prepared (the phase MarkRuntimeMutationStarting advances to). Without this, safe-rollback hit "publication intent is missing" and fell into recovery_pending.
  6. Regression — TestUndeliveredMutationFinalizesAsFailed asserts terminal failed, consumed publication receipt, applied revision unchanged, and a follow-up apply is not lease-wedged.

Prior frontend blocker remains cleared (7c398494 orval regen); CI frontend on this head: success.

Looks good (re-affirmed)

  • WARP ru-blocked (#763/#778/#779): still on runetfreedom/russia-v2ray-rules-dat .srs; ordinary codes on SagerNet.
  • DAT provisioning (#764), artifact catalog (#780/#855), HSTS (#902), /api/tls issuer fields (#906), Caddy Probe (#882): unchanged since last review; still sound.
  • Test hardening from the wave still matches the claimed false-green closures.

Blockers

None.

Mild (non-blocking)

  1. Caddy HSTS vs IP exclusion (still open): RenderPanelCaddyfile always emits Strict-Transport-Security with preload; Go middleware still skips IP hosts. Edge/Go mismatch if Domain were an IP literal under panelAccess=caddy.
  2. panelAccess case (still open): HSTS uses EqualFold(..., "caddy"); tlsCertInfo still uses access != "caddy". Align to EqualFold.
  3. IssuerKind: HasPrefix(issuerName, "acme") covers LE storage dirs; other ACME issuer dir names become "other" (acceptable).
  4. applyflow coverage gap: TestWorkflowReturns500OnPromoteError only checks status/err for a plain promoteErr. Worth asserting MutationStarted/Ambiguous for an IsUndelivered promote error vs a post-dial/helper failure (the layered apply + socket tests already cover the pieces).
  5. PR body: Summary does not yet mention the undelivered-promote finalize fix from b4e0e067.
  6. Branch currency: behind_by=3 / diverged from main. No obvious clash with this surface; update-branch when convenient.

CI (at review time, head b4e0e067)

  • success: frontend, lint, filesystem-faults, multi-process, sigkill, image-build, analyze (go/js-ts/actions), CodeQL
  • in_progress: test, e2e, browser-e2e, privilege-boundary, install-acceptance (amd64/arm64), package-smoke-matrix (amd64/arm64)
  • failures: none observed

No code blockers. Merge-ready from a review standpoint once the longer suite settles (and after updating the branch if desired).

The root helper resolves promoted artifacts through its own
VEIL_APPLY_ROOT/VEIL_LIVE_ROOT (packaged veil-helper.service exports
them the same way). The harness launched it without them, so it fell
back to /var/lib/veil/staging + /etc/veil/generated while the :2098
panel staged under /var/lib/veil/apply + /var/lib/veil/live, and once
geo rules started promoting rules/geoip.dat the helper-side open()
failed ENOENT and every :2098 apply wedged recovery_pending.

@mikkelchokolate mikkelchokolate left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review (head 21229060fca98ab8bc3766062c6bedca4d01162c) — would APPROVE

Own-PR: GitHub blocks APPROVE from the author, so COMMENT with explicit would-APPROVE.

Delta vs prior reviewed head b4e0e067553e7502910f8091dd7ac3fc3fd02e33

Not a merge-from-main. One new commit:

  • 21229060 — Align e2e helper roots with the helper-backed panel
  • Single file: scripts/ci/browser-e2e.sh (+5/−0)

The root helper launch for the :2098 production-layout panel now exports:

VEIL_STATE_PATH / VEIL_KEY_PATH / VEIL_APPLY_ROOT=/var/lib/veil/apply / VEIL_LIVE_ROOT=/var/lib/veil/live

alongside the existing VEIL_BACKUP_MAX_BYTES bound. This matches the :2098 panel env a few lines later. Without it, privileged.DefaultPolicy falls back to …/staging + …/generated, so Promote cannot open panel-staged artifacts (ENOENT) and :2098 applies wedge recovery_pending once geo DAT promotion is in play. Correct, localized harness fix; comments explain the failure mode clearly.

Prior b4e0e067 undelivered-promote terminalization is unchanged by this delta.

Product issue coverage (re-verified; delta does not regress)

#763/#778/#779 ru-blocked rule-sets, #764 DAT provisioning, #780/#855 per-inbound artifacts, #902 HSTS at Caddy edge, #906 TLS issuer visibility, #882 Caddy capability probing, and the #820–#971 test-hardening set remain intact on this head. The e2e root alignment is a CI/harness correctness fix that supports exercising those paths under helper-backed apply.

Blockers

None.

Mild notes

  1. Comment precision (non-blocking): the new comment says packaged veil-helper.service “exports them too.” The unit does export VEIL_APPLY_ROOT/VEIL_LIVE_ROOT, but with production values /var/lib/veil/staging + /etc/veil/generated (same as veil.service). The harness intentionally uses apply/live for :2098; the important invariant is panel↔helper parity inside the harness, which this commit restores.
  2. Dir creation: production-layout setup mkdirs /var/lib/veil/backups but not apply/live explicitly (isolated panels do). Pre-existing vs this delta; panel/helper usually create roots on first use — watch only if a race shows up before first write.
  3. Carry-forward from prior review: undelivered dial-level promote terminalization on b4e0e067 still looks sound; no new concerns from this delta.

CI (21229060)

Run cancelled mid-flight when the branch advanced (merge main → newer tip). Observed on this SHA before cancel:

Result Jobs
success multi-process, filesystem-faults, sigkill, image-build, analyze (actions)
neutral CodeQL (config-not-found warning)
cancelled (superseded) lint, frontend, test, e2e, browser-e2e, package-smoke, package-smoke-matrix, install-acceptance, privilege-boundary, analyze (go), analyze (javascript-typescript)

No failed conclusions on this SHA. Full suite (esp. browser-e2e, which this commit targets) did not complete here — re-check on the post-merge tip.

Mergeability

At this head: behind main by 4 (5eacacd3, 8defe84d #972, 1aa5e6fb #975, a2282ae0 #977). mergeable_state was behind at review time for this SHA.

Verdict: would APPROVE — ship the e2e root alignment; update branch / re-run CI on the merged tip separately.

@mikkelchokolate mikkelchokolate left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review (head c9c79770)

Verdict: COMMENT — would APPROVE. Own-PR blocks APPROVE.

Delta vs prior review (b4e0e067)

  1. 21229060 — Align e2e helper roots with the helper-backed panel. scripts/ci/browser-e2e.sh now exports VEIL_STATE_PATH / VEIL_KEY_PATH / VEIL_APPLY_ROOT=/var/lib/veil/apply / VEIL_LIVE_ROOT=/var/lib/veil/live on the root helper so they match the :2098 panel. Without this, the helper fell back to packaged defaults (/var/lib/veil/staging + /etc/veil/generated) while the panel staged under apply/live, so Promote hit ENOENT on artifacts such as rules/geoip.dat and wedged applies into recovery_pending. Correct fix; comment explains the contract.
  2. c9c79770 — Merge main into fix/wave-zf. Brings #972 / #975 / #977. behind_by=0 vs main (a2282ae0). Spot-checked product surfaces still intact on this head: geoRuleSetURL → runetfreedom for ru-blocked, SagerNet otherwise (internal/renderer/warp.go); TLSCertInfo.managedBy / issuerSource / issuerKind in generated web client; undelivered-promote terminal-failed regression still present.

Product / prior findings

  • #763 / #778 / #779 / #764 / #780 / #855 / #902 / #906 / #882 and undelivered-promote lease release: still OK.
  • Prior b4e0e067 blockers: none (unchanged).

Blockers

None.

Mild / nits

  1. Harness roots ≠ packaged unit roots (intentional). :2098 + helper use /var/lib/veil/apply + /var/lib/veil/live, while packaging/systemd/veil{,-helper}.service use /var/lib/veil/staging + /etc/veil/generated. Both sides of each pair stay matched; just don’t copy the e2e literals into packaging without aligning both units.
  2. CI still settling on c9c79770 at review time (filesystem-faults success; frontend / lint / multi-process / sigkill / image-build / CodeQL matrix queued). Re-check before merge if anything reds.

CI (head c9c79770)

  • success: filesystem-faults
  • queued/in progress: frontend, lint, multi-process, sigkill, image-build, analyze (go|javascript-typescript|actions)

@mikkelchokolate mikkelchokolate left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review (head 59505d77)

Verdict: COMMENT — would APPROVE. Own-PR blocks APPROVE.

Delta vs prior review (c9c79770)

Ahead_by=2, behind_by=0 vs that tip — merge-main only:

  1. 263bd7ec — Fix false-green CI/workflow/script contracts and harden their tests (#978)
  2. 59505d77 — Merge branch main into fix/wave-zf

File delta is CI/workflow/script/contract-test focused (ci.yml, release.yml, Dockerfile, internal/cli/* contract helpers, scripts/ci/*, scripts/package-smoke.sh, packaging/docker/entrypoint.sh, runtimeinstall, etc.). No conflict markers on inspected overlaps. Overlap files that also existed on the prior tip (privilege-boundary.sh, install-acceptance.sh, package-smoke.sh, promotion/transactional-install regression tests, ci.yml) resolve cleanly to main/#978 (blob SHA == main). Diff prior→main for those scripts is #978 hardening only (exact-line grep -qxF unit contracts, install-acceptance binary stash/restore + probe_panel_healthz, package-smoke bulk try-restart completeness) — no wave-zf product surface lost.

behind_by=0 vs main (263bd7ec). mergeable=true.

Product / prior findings (re-verified at head; merge did not touch)

Blob SHA-identical vs c9c79770 for the wave-zf product surfaces spot-checked:

  • #763/#778/#779 — geoRuleSetURL → runetfreedom for ru-blocked; SagerNet otherwise (internal/renderer/warp.go)
  • #764 — EnsureDatSource selective geoip/geosite attach (internal/routing/source.go)
  • #780/#855 — per-inbound hysteria2/*.yaml / olcrtc/*.yaml + exact/glob MatchesGeneratedPath (artifact_catalog.go)
  • #902 — Caddyfile HSTS (panel_caddy.go header Strict-Transport-Security … preload) + Go tlsEdge middleware (router_security.go)
  • #906 — TLSCertInfo.managedBy / issuerSource / issuerKind (OpenAPI + internal/runtime/tls.go + web orval tLSCertInfo.ts)
  • #882 — Probe → parseModuleList (caddycapabilities/capabilities.go)
  • b4e0e06 — undelivered-promote terminal failed regression still present
  • 2122906 — browser-e2e helper roots VEIL_APPLY_ROOT=/var/lib/veil/apply VEIL_LIVE_ROOT=/var/lib/veil/live intact

#978 carry-forward at head: install-acceptance stash/restore + package-smoke fail-closed / exact-line contracts intact (matches the favorable #978 review).

Blockers

None.

Mild (non-blocking; carry-forward unchanged by this merge)

  1. Caddy HSTS vs IP exclusion: RenderPanelCaddyfile always emits HSTS with preload; Go middleware still skips IP hosts.
  2. panelAccess EqualFold inconsistency in tlsCertInfo vs HSTS wiring.
  3. IssuerKind HasPrefix("acme") — other ACME issuer dir names become "other" (acceptable).
  4. Harness roots ≠ packaged unit roots (intentional) — :2098 uses apply/live; packaged units use staging/generated.

CI (head 59505d77, review time ~14:33 MSK / 11:33 UTC)

  • success: lint, image-build, filesystem-faults, multi-process, sigkill, analyze (go), analyze (javascript-typescript), analyze (actions), CodeQL
  • pending: frontend
  • Longer matrix (test, e2e, browser-e2e, privilege-boundary, install-acceptance, package-smoke*) not yet reported on this SHA — still settling; no failures observed.

No code blockers. Would APPROVE; merge-ready from review once remaining checks settle.

@mikkelchokolate mikkelchokolate left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review (head 45a29198)

Verdict: COMMENT — would APPROVE. Own-PR blocks APPROVE.

Delta vs prior review (59505d77)

Not a merge-from-main. One new commit:

  • 45a29198 — Restore registerMux contract extraction and v1 bindings GET
  • Three files: internal/api/client_v1_routes.go, internal/api/router_composition.go, internal/api/openapi_real_router_contract_test.go

What it does (checked end-to-end):

  1. GET /api/v1/clients/{id}/bindings — implements the OpenAPI-documented list endpoint by returning ClientView.Bindings as {items: [...]} (nil → empty slice). methodNotAllowed now advertises GET+POST. Blob SHA identical to main (#973).
  2. RouterComposition.registerMux — extracts the live mux registrations into one helper so contract tests can call mux.Handler on the exact production set (issue #923). Build() delegates to it.
  3. Honest OpenAPI↔router contracts — rewrites TestRealRouterCoversOpenAPIStageEndpoints / TestOpenAPIDocumentsEveryRegisteredStageRoute to:
    • derive the probe set from the full stage OpenAPI surface (not a hand-maintained subset),
    • prove registration via mux.Handler (resource-404 ≠ mux-miss),
    • scrape mux.Handle(Func) registrations from package sources for the reverse check,
    • reject 405 and missing auth-policy 404s.
      Blob SHA identical to main (#973).

Intentional divergence from main in router_composition.go only (wave-zf product surfaces preserved inside registerMux / Build):

  • RuntimeRoutes{TLSInfo: state.tlsCertInfo} (#906 issuer visibility) — main still has RuntimeRoutes{}
  • securityHeadersMiddleware(..., EqualFold(panelAccess, "caddy")) (#902 HSTS at Caddy edge)

So this commit correctly backports the #973 contract/bindings restore onto fix/wave-zf without dropping TLS/HSTS wiring.

Product / prior findings (re-verified; blob-identical to 59505d77)

warp.go (ru-blocked), routing/source.go (DAT), artifact_catalog.go, panel_caddy.go + router_security.go (HSTS), runtime/tls.go + TLSCertInfo, caddycapabilities Probe→parseModuleList, undelivered-promote regression, browser-e2e helper roots — all untouched by this commit.

Blockers (code)

None.

Mergeability (process — not a code defect in this commit)

mergeable=false / mergeStateStatus=DIRTY / behind_by=1 vs main tip e1cd657d (#973). Conflicts are expected on the same three API files (plus other wave-zf overlaps). When resolving:

  • keep this branch’s RuntimeRoutes{TLSInfo: state.tlsCertInfo} and HSTS panelAccess=caddy wiring;
  • take main’s OpenAPI enrichment for GET …/bindings 200 (content/schema with items: BindingView) — this head’s OpenAPI still has description-only 200 for that path;
  • client_v1_routes.go + openapi_real_router_contract_test.go are already blob-identical to main, so those sides should merge cleanly once router_composition.go is resolved.

Mild (non-blocking)

  1. OpenAPI GET bindings 200 schema — still description-only on this head; main/#973 adds items: BindingView. Comes in with the main merge.
  2. CI not yet queued on 45a29198 at review time (no Actions runs / check-runs / status contexts). Prior head 59505d77 CI+CodeQL were success. Re-check once workflows fire; dirty merge state may be delaying PR-triggered runs.
  3. Carry-forward: Caddy HSTS vs IP exclusion mismatch; panelAccess EqualFold inconsistency in tlsCertInfo; harness apply/live roots ≠ packaged staging/generated (intentional).

CI (head 45a29198)

  • this SHA: no runs observed yet
  • prior tip 59505d77: ci + codeql success

Verdict: would APPROVE the commit itself. Update/rebase onto main (#973) and preserve TLSInfo + HSTS when resolving router_composition.go before merge.

# Conflicts:
#	internal/api/router_composition.go

@mikkelchokolate mikkelchokolate left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review (own-PR → COMMENT only)

Verdict: would APPROVE

Delta vs prior head 45a29198

Merge-only: 4e3c8bc = merge origin/main (e1cd657 — #973 OpenAPI/SDK contract drift, web-base-path collisions, false-green test hardening) into fix/wave-zf. No new wave-zf feature commits after the prior review’s registerMux / bindings / OpenAPI contract restore.

Meaningful product delta from #973 (not merge noise):

  • webbasepath.Normalize: reserved first-segment set expands beyond s to root-mux collisions (api, metrics, healthz/livez/readyz, assets, favicon/robots) — correct for #765.
  • Settings/setup reads: empty panelAccess write-sentinel surfaces as effective "local"; OpenAPI enums drop ''; new openapi_schema_drift_test.go locks ClientView / BindingCapability / ExpirationEnforcement / panelAccess / Redocly allowlist.
  • GET /api/v1/clients/{id}/bindings OpenAPI now documents {items: BindingView[]} matching the live items envelope.
  • Dead isReadOnlyDiagnosticRequest removed (never consulted; wrongly lumped /api/client-links/qr with viewer diagnostics).
  • Regenerated SDK / web client / zod / msw for the #973 schema fixes.

Product surface status (wave-zf)

Blob-identical vs 45a29198 for the wave-zf cores:

  • WARP geoRuleSetURL / ru-blocked → runetfreedom .srs URLs; ordinary codes stay SagerNet
  • EnsureDatSource → geoip/geosite/private/disabled/no-geo selection intact
  • MatchesGeneratedPath / LivePathForStagedConfig → exact + path.Match per-inbound globs
  • HSTS / tlsEdge → still emitted under panelAccess=caddy; IP hosts excluded
  • TLSCertInfo managedBy / issuerSource / issuerKind (+ OpenAPI) intact
  • Probe → parseModuleList intact
  • registerMux + GET /api/v1/clients/{id}/bindings (items envelope) + OpenAPI↔router contracts intact

Blockers

none

Mild / nits

  • Several CI jobs still in progress at review time (test, e2e, browser-e2e, install-acceptance amd64/arm64, package-smoke-matrix amd64/arm64). Already green: lint, frontend, image-build, privilege-boundary, multi-process, filesystem-faults, sigkill, CodeQL analyze (go/js/actions). Not a code blocker; re-check before merge if any fail.
  • mergeable_state=blocked is expected (own-PR cannot self-APPROVE; checks still settling).

CI summary (head 4e3c8bc1)

Check Status
lint / frontend / image-build success
privilege-boundary / multi-process / filesystem-faults / sigkill success
CodeQL analyze (go, js-ts, actions) success
test / e2e / browser-e2e / install-acceptance / package-smoke in_progress

behind_by

0 vs main (compare 4e3c8bc1...main → main not ahead).

# Conflicts:
#	internal/api/router_composition.go
#	internal/api/runtime_routes.go
#	internal/api/tls_test.go
#	sdk/go/veilclient.gen.go

@mikkelchokolate mikkelchokolate left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review (head b8be193e)

Verdict: COMMENT — would APPROVE. Own-PR blocks APPROVE.

Delta vs prior review (4e3c8bc1)

Merge-only: ahead_by=2, behind_by=0 vs that tip.

  1. dd4bc437 — fix: wave-zc audit hardening — meaningful assertions, TLS via Caddy certs, token gating (#976)
  2. b8be193e — Merge remote-tracking branch origin/main into fix/wave-zf

behind_by=0 vs main (dd4bc437). mergeable=true / mergeStateStatus=BLOCKED (own-PR + checks settling).

Merge resolution (product-critical)

#976 rewired /api/tls from RuntimeRoutes{TLSInfo: state.tlsCertInfo} to RuntimeRoutes{State: state} + ReadTLSCertForDomain (#905 SAN/domain check). Conflict resolution on this branch correctly kept wave-zf #906 issuer visibility on top of that architecture:

  • router_composition.go: RuntimeRoutes{State: state}.Register(mux) (matches main) and HSTS securityHeadersMiddleware(..., EqualFold(panelAccess, "caddy")) (#902) still present vs main’s bare middleware.
  • runtime_routes.go vs main: adds servePanelAccess override, and sets ManagedBy / IssuerSource / IssuerKind on the Caddy path (main’s #976 path had Source: "caddy" only).
  • internal/runtime/tls.go: gains #976 Source + ReadTLSCertForDomain; ManagedBy/IssuerSource/IssuerKind fields remain.
  • OpenAPI + web orval tLSCertInfo still expose managedBy / issuerSource / issuerKind (plus new source from #976).

Product surfaces (wave-zf) — re-verified

Blob-identical vs 4e3c8bc1 (unaffected by merge):

  • #763/#778/#779 — geoRuleSetURL → runetfreedom for ru-blocked; SagerNet otherwise (warp.go)
  • #764 — EnsureDatSource selective geoip/geosite (routing/source.go)
  • #780/#855 — per-inbound globs + exact/path.Match (artifact_catalog.go)
  • #902 — Caddyfile HSTS (panel_caddy.go) + Go tlsEdge (router_security.go)
  • #882 — Probe → parseModuleList (caddycapabilities)
  • 2122906 — browser-e2e helper VEIL_APPLY_ROOT/VEIL_LIVE_ROOT apply/live roots
  • b4e0e06 — undelivered-promote terminal-failed regression blob-identical

#906 issuer visibility: preserved through the new RuntimeRoutes.State path (see above).

Blockers

None.

Mild (non-blocking)

  1. Caddy HSTS vs IP exclusion (carry-forward): RenderPanelCaddyfile always emits HSTS with preload; Go middleware still skips IP hosts. Edge/Go mismatch if Domain were an IP literal under panelAccess=caddy.
  2. panelAccess EqualFold — prior mild note is cleared by this merge: tlsCertInfo now uses strings.EqualFold(access, "caddy") (aligned with HSTS).
  3. IssuerKind HasPrefix("acme") — other ACME issuer dir names become "other" (acceptable).
  4. Harness roots ≠ packaged unit roots (intentional) — :2098 uses apply/live; packaged units use staging/generated.
  5. Longer CI matrix still queued on this SHA — no failures observed; re-check before merge if anything reds.

CI (head b8be193e, review time ~16:00 MSK / 13:00 UTC)

Result Jobs
success lint, frontend, image-build, multi-process, filesystem-faults, sigkill, analyze (javascript-typescript), analyze (actions)
in_progress analyze (go)
queued test, e2e, browser-e2e, privilege-boundary, install-acceptance (amd64/arm64), package-smoke-matrix (amd64/arm64)
neutral CodeQL (config-not-found warning)
failures none

No code blockers. Would APPROVE; merge-ready from review once the longer suite settles.

@mikkelchokolate
mikkelchokolate enabled auto-merge (squash) September 24, 2026 13:21

@mikkelchokolate mikkelchokolate left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review (head bf370336beb2f71adab6e1fb5344cc8647fb1842)

Verdict: would APPROVE (own-PR: GitHub blocks APPROVE → COMMENT).

Delta vs prior reviewed head b8be193ea3e079b0dce06bf61dcb94c08438bc58

Merge-main only. Compare b8be193e...bf370336:

  • 2 commits: d38f37c7 chore(deps-dev): bump lighthouse (#989); bf370336 Merge branch main into fix/wave-zf
  • Files: test/browser/package.json + package-lock.json only (lighthouse 13.4.1 → 13.5.0)
  • No conflict resolutions on wave-zf product surfaces (router_composition.go, runtime_routes.go, tls.go, openapi, web client untouched in this delta)
  • behind_by vs main: 0 (main tip = #989 d38f37c7)

Product re-verify @ bf370336 (blob spot-checks)

Surface Status
internal/renderer/warp.go — ru-blocked → runetfreedom geoRuleSetURL (#763/#778/#779) OK
internal/routing/source.go — EnsureDatSource selective DAT (#764) OK
internal/generatedconfig/artifact_catalog.go — per-inbound globs (#780/#855) OK
internal/renderer/panel_caddy.go + internal/api/router_security.go — HSTS (#902) OK
internal/api/runtime_routes.go + internal/runtime/tls.go + caddycert — ManagedBy/IssuerSource/IssuerKind (#906) atop RuntimeRoutes{State} (#976) OK
internal/api/router_composition.go — RuntimeRoutes{State: state} + HSTS EqualFold(panelAccess, "caddy") OK
internal/caddycapabilities/capabilities.go — Probe → parseModuleList (#882) OK
scripts/ci/browser-e2e.sh — VEIL_APPLY_ROOT/VEIL_LIVE_ROOT helper roots OK
undelivered-promote path (internal/apply/undelivered_promote_regression_test.go + related) OK

Blockers

none

Mild (carry-forward; non-blocking)

  • Caddy-edge HSTS pin vs IP/hostname exclusion edge cases (unchanged)
  • caddycert.IssuerKind: HasPrefix(issuerName, "acme") classification (unchanged; still correct for current Caddy storage names)
  • Harness VEIL_APPLY_ROOT/LIVE_ROOT ≠ packaged staging/generated layout (documented helper-root divergence; unchanged)
  • Prior mild panelAccess case-sensitivity: cleared on b8be193e (EqualFold retained)

CI @ bf370336 (snapshot)

Check Status
lint / frontend / image-build / filesystem-faults / multi-process / sigkill success
analyze (actions) / analyze (javascript-typescript) success
CodeQL completed (neutral)
analyze (go) in_progress
test / e2e / browser-e2e / privilege-boundary / install-acceptance (amd64/arm64) / package-smoke-matrix (amd64/arm64) queued

No failures observed. Pending/queued checks are not treated as blockers unless they later show a code defect in this PR's product delta (here: lighthouse bump only).

Summary

Wave-zf product cores remain blob-intact after absorbing #989. Ready to merge once required checks settle green.

@mikkelchokolate mikkelchokolate left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review (head 870fb119db5c4d102065e3c74ca8800e95c94ed3)

Verdict: would APPROVE (own-PR: GitHub blocks APPROVE / REQUEST_CHANGES from the author account, so this is COMMENT).

Delta vs prior review (bf370336)

Merge-main only — four commits:

  • c6f24fe / merge: #974 honest apply outcomes (pre-mutation failures + ambiguous history)
  • 888df6c / merge: #991 github/codeql-action init+analyze 4.38.0 → 4.38.1 (1c5b675)

No new wave-zf product commits on this branch.

Product wave-zf — blob-identical vs prior head

Checked against bf370336: docs/openapi.yaml, internal/caddycapabilities/capabilities.go, internal/caddycert/caddycert.go, internal/generatedconfig/{artifact_catalog,paths}.go, internal/installer/install_apply.go, internal/panel/panel_routing_card.go, internal/renderer/{panel_caddy,warp}.go, internal/routing/source.go, sdk/go/veilclient.gen.go — all unchanged. Prior findings on #763/#778/#779 ru-blocked rule-sets, #764 DAT selection, #780/#855 per-inbound artifacts, #902 HSTS at Caddy edge, #906 TLS issuer fields, #882 capability probing, and the audit-test hardening set still stand.

Merged #974 surface (spot-check)

  • PreMutationError / MarkPreMutationError keep promote failures before mutation out of the ambiguous path; post-mutation failures set response.Ambiguous and stage "ambiguous" (#968).
  • ApplyHistoryEntry.Ambiguous + panel stage filter option ambiguous wired through.
  • RoutingPresetApplication.Apply deep-copies Source.Files (#947) — correct fix for shared backing-array leak; only routing touch in this delta besides tests.

Merged #991

Pin bump only on CodeQL actions; matches already-reviewed #991 on main.

Blockers

None for merge of wave-zf content.

Mild / notes

  • behind_by=0 vs main (12 commits ahead).
  • CI on this head still settling: CodeQL analyze (js-ts/actions) success + CodeQL neutral; analyze (go) / sigkill in progress; frontend / lint / multi-process / filesystem-faults / image-build queued. No failures observed at review time. mergeStateStatus=BLOCKED is expected until checks (and a non-author approval) settle.
  • Own-PR limitation unchanged: cannot leave a formal APPROVE from mikkelchokolate.

@mikkelchokolate mikkelchokolate left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review (head 8e10a90d46951a8536e86640bebf33e5d1d725f6)

Verdict: would APPROVE (own-PR: GitHub blocks APPROVE / REQUEST_CHANGES from the author account, so this is COMMENT).

Delta vs prior review (870fb119db5c4d102065e3c74ca8800e95c94ed3)

Merge-main only — two commits:

  • b1a51c8bc255 — #994 harden false-green assertions across api, serve, and e2e
  • 8e10a90d4695 — Merge branch 'main' into fix/wave-zf

No new wave-zf product commits on this branch. Delta file set (15) is entirely #994: api/cli/serve/testguard/e2e test hardening plus a small behavior-preserving extract of resolvedHelperSocket() in internal/cliflow/serve/http_server.go (empty helper socket → privileged.DefaultSocketPath).

Product wave-zf — blob-identical vs prior head

Checked 24 PROD paths against 870fb119 (openapi, capability catalog / router security / runtime routes, apply finalize + workflow, caddycapabilities, caddycert, generatedconfig artifact_catalog+paths, installer, panel routing card, privileged socket client, renderer panel_caddy+warp, routing source, runtime tls, settings validation, browser-e2e script, sdk/go client, web TLSCertInfo models + zod) — all unchanged.

Prior findings still stand:

  • #763 / #778 / #779 — geoip:ru-blocked / geosite:ru-blocked → runetfreedom rule-sets (not broken SagerNet remaps)
  • #764 — EnsureDatSource only pulls dat files enabled matchers consume
  • #780 / #855 — per-inbound globs + MatchesGeneratedPath exact/glob matching; bare template units not restartable
  • #902 — HSTS at Caddy edge when panelAccess=caddy
  • #906 — TLSCertInfo managedBy / issuerSource / issuerKind
  • #882 — production Probe → parseModuleList
  • Audit false-green test hardening set from the wave-zf body

Merged #994 surface (spot-check)

  • False-green assertion hardening across api / serve / e2e — matches already-reviewed #994 on main (COMMENT would-APPROVE on that PR).
  • Sole prod touch: resolvedHelperSocket() extraction; Build() still wires the same default socket path. No wave-zf interaction.

Blockers

None for merge of wave-zf content.

Mild / notes

  • behind_by=0 vs main (13 commits ahead).
  • CI on this head still settling at review time: success lint, multi-process, sigkill, filesystem-faults, image-build, analyze (actions), analyze (javascript-typescript); in_progress frontend + analyze (go); CodeQL neutral (“2 configurations not found” vs main — known workflow-surface noise post-#991, not a product fail). No failures observed. mergeStateStatus=BLOCKED expected until remaining checks (and a non-author approval) settle.
  • Own-PR limitation unchanged: cannot leave a formal APPROVE from mikkelchokolate.

@mikkelchokolate mikkelchokolate left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review (re-check on merge-main head)

Head: 830b2758a3252e03142be9750f5964f47548077f
Prior review head: 8e10a90d46951a8536e86640bebf33e5d1d725f6
Event: COMMENT (own-PR — GitHub blocks APPROVE from the author; would APPROVE)

Delta vs prior review head

  • ahead_by=2, behind_by=0
  • Commits: merge main bringing #990 (chore(deps-dev): bump the web-dependencies group in /web with 2 updates) + the merge commit itself
  • Files touched only:
    • web/package.json — @babel/parser 8.0.5→8.0.6, orval ^8.33.0→^8.35.0 (blob 238c56d1…)
    • web/pnpm-lock.yaml (blob dfd01913…)
    • web/src/api/generated/zod/clients/clients.zod.ts — PatchApiV1ClientsIdBody.quotaResetPolicy regenerated to zod.union([…literals…, zod.literal(null)]).nullish() (blob ac875d0c…)

No wave-zf product / Go / OpenAPI / WARP / Caddy / generatedconfig paths in the delta.

Product verification (wave-zf)

Compared 24 curated PROD paths (WARP ru-blocked renderer + tests, EnsureDatSource / routing source, generatedconfig per-inbound artifact/paths/catalog, Caddy HSTS/TLS issuer + caddycapabilities Probe, panel_caddy, capability catalog, install_apply, related settings) vs last primary product tip a5962df2c359…:

product OK blob-identical 24/24

Also confirmed HEAD ≡ prior review head on those same 24 paths (merge #990 did not touch them).

CI snapshot (830b2758…)

  • Completed success: analyze (javascript-typescript / actions / go), CodeQL, privilege-boundary, multi-process, frontend, image-build, filesystem-faults, lint, sigkill
  • Still in_progress: test, e2e, browser-e2e, install-acceptance (amd64/arm64), package-smoke-matrix (amd64/arm64)

No failures observed on completed checks.

Blockers

none

Mild notes

  • quotaResetPolicy on PatchApiV1ClientsIdBody remains zod.union([zod.literal('never'|'daily'|'weekly'|'monthly'), zod.literal(null)]).nullish() from the #990 orval bump — redundant nullability (literal(null) inside a .nullish() union). Pre-existing from #990; not introduced by wave-zf product work; no merge blocker.

Verdict

Would APPROVE. Delta is merge-main / web-deps only; wave-zf product surface remains intact; no blockers.

@mikkelchokolate mikkelchokolate left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review (head 851e06f2)

Verdict: would APPROVE (own-PR blocks APPROVE → COMMENT).

Delta vs prior reviewed head 830b2758

Merge-main only (2 commits):

  1. c1e3fb9 — fix: metrics path labels, audit spool honesty, privileged fencing, and API mutation edge cases (#992)
  2. 851e06f — Merge branch main into fix/wave-zf

No new product commits on wave-zf itself.

Product wave-zf status

Re-verified core wave-zf themes still present and intact on this head:

  • WARP ru-blocked: internal/renderer/warp.go routes ru-blocked via runetfreedom/russia-v2ray-rules-dat sing-box rule-set URLs; presets/tests cover geoip:ru-blocked / geosite:ru-blocked.
  • EnsureDatSource: internal/routing/source.go + callers; geoip:private → geoip.dat coverage in tests.
  • Per-inbound artifacts: hysteria2/*.yaml / olcrtc/*.yaml globs in artifact_catalog.go.
  • HSTS / panelAccess=caddy: Caddyfile HSTS header in panel_caddy.go; Go securityHeadersMiddleware(..., panelAccess==caddy) retained in router_composition.go.
  • TLS issuer visibility: managedBy / issuerSource / issuerKind in OpenAPI, runtime/tls.go, caddycert, generated tLSCertInfo.
  • Probe → parseModuleList: production Probe in caddycapabilities routes through parseModuleList (#882).

Blob check vs 830b2758: 72/73 PR paths identical. Sole diff is internal/api/router_composition.go (+6/−3 from the #992 merge): correctly wires state.metrics, moves MetricsMiddleware inside the post-strip path (issue #979), and keeps the wave-zf HSTS panelAccess=caddy gate. Clean merge — both waves preserved.

Spot-check of merged #992

runtime_fence.go lease acquire/release with dead-owner retry looks sound; fencing/audit-spool/expiration/binding-patch test additions are additive. No conflict residue that weakens wave-zf.

CI snapshot (851e06f2, filter=latest)

Success: lint, filesystem-faults, image-build, sigkill, multi-process, analyze (actions), analyze (javascript-typescript), CodeQL (no new alerts).
In progress: frontend, analyze (go).
No failures observed. mergeStateStatus=BLOCKED is expected (reviews/branch protection), not a product defect.

Blockers

None.

Mild (carry-forward from #990 merge; not introduced here)

web/src/api/generated/zod/clients/clients.zod.ts still has quotaResetPolicy: zod.union([...literals, zod.literal(null)]).nullish() — redundant nullability from orval; harmless generated noise, not a wave-zf regression.

Summary

Wave-zf product surface is unchanged and still correct; #992 merge is clean. Would APPROVE when own-PR policy allows.

@mikkelchokolate mikkelchokolate left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review (head 4d7a0b0eeeff)

Verdict: would APPROVE (own-PR cannot APPROVE via this account) — COMMENT.

Delta vs prior review (851e06f2): merge main only — #993 (audit-hardening wave zb: honest regression tests + clone/health fixes). No new wave-zf product commits.

Merge integrity

  • Wave-zf–only paths vs prior tip: 68/68 blob-identical (0 changed / 0 missing).
  • Spot-checked product blobs unchanged: internal/renderer/warp.go, internal/routing/{source,routing_presets}.go, internal/generatedconfig/{artifact_catalog,warp_renderer,warp_routing_rules}.go, internal/renderer/panel_caddy.go, internal/caddycert/caddycert.go, internal/caddycapabilities/capabilities.go, internal/runtime/tls.go, web/.../tLSCertInfo.ts.
  • TLSCertInfo OpenAPI block (managedBy / issuerSource / issuerKind) SHA-identical across the merge; SDK still exposes the three fields.
  • #993 inbound overlap is test/hardening only (stronger goldens in inbound_renderer_more_test, warp_renderer_test, DAT retry attempt pin, healthcheck {"status":"ok"} contract, deep InboundClone via model.CloneInbound) plus OpenAPI role/binding GET + generated clients — no conflict with wave-zf WARP/HSTS/TLS/catalog changes.

Product (unchanged, still OK)

  • WARP ru-blocked: runetfreedom rule-sets; ordinary geo keeps SagerNet.
  • DAT provisioning: attach only what enabled matchers consume.
  • Artifacts: per-inbound globs; exact/path.Match; bare @.service not restartable.
  • HSTS at Caddy edge + middleware when panelAccess=caddy; IP hosts excluded.
  • /api/tls issuer visibility + OpenAPI/SDK.
  • Caddy Probe via parseModuleList; HTTP3 from http module.
  • Test hardening wave still honest (exact URL/tag/path/credential checks).

Blockers

None from this merge.

Mild (carry-forward, non-blocking)

  • web/src/api/generated/zod/clients/clients.zod.ts: quotaResetPolicy patch schema remains zod.union([..., zod.literal(null)]).nullish() (from earlier #990 web-deps regen). Harmless; worth a follow-up if orval keeps emitting the null literal.

CI (head 4d7a0b0eeeff)

Settling after the push: CodeQL analyze (actions) success; analyze (go) / analyze (javascript-typescript) in_progress; ci workflow pending. Prior head 851e06f2 had CodeQL success and CI still running. behind_by=0 vs main.

Ship when CI is green.

@mikkelchokolate
mikkelchokolate merged commit 881a09e into main Sep 24, 2026
19 checks passed
@mikkelchokolate
mikkelchokolate deleted the fix/wave-zf branch September 24, 2026 17:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant