Skip to content

feat(verifier): admin console package (search, reschedule, recovery, action log) - #1500

Merged
tt-cll merged 1 commit into
mainfrom
tt/admin-1
Oct 8, 2026
Merged

tt-cll merged 1 commit into
mainfrom
tt/admin-1

Conversation

@tt-cll

@tt-cll tt-cll commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Bottom of a 3-PR stack splitting #1471, reworked per review: the console is scoped to the single verifier it runs beside — no multi-node [[nodes]] config, no separate console database, no read-only mode.

This PR adds the self-contained console package plus its direct dependencies:

  • verifier/pkg/admin — server-rendered UI (templ/htmx, Gin) over the verifier's own application DB: message search, message detail, gated reschedule (archive + attestation freshness re-checked on every execution), source-range recovery (replay / reset-reader with durable operations), and a fail-closed action log (intent row before every mutation).
  • verifier/migrations/postgres/00010_admin_actions.sql — the action log lives in the verifier's own migrations, not a separate goose table/DB.
  • verifier/pkg/vsecrets — optional [admin_ui] basic-auth credential in the verifier secrets file.
  • integration/storageaccess — unauthenticated aggregator results read client used for attestation freshness checks (aggregator-only; the indexer path was dropped per review).

Nothing serves the console yet — that wiring is #1501.

Note: admin.Deps.ResultsDialer is an optional injection seam for the attestation read path; production wiring leaves it nil (real aggregator dial), tests and the demo harness (#1502) substitute a canned client.

Stack: this PR → #1501 → #1502. Supersedes the package portion of #1471.

@tt-cll
tt-cll requested review from a team as code owners October 7, 2026 21:54
Copilot AI balanced review requested due to automatic review settings October 7, 2026 21:54
@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown

👋 tt-cll, thanks for creating this pull request!

To help reviewers, please consider creating future PRs as drafts first. This allows you to self-review and make any final changes before notifying the team.

Once you're ready, you can mark it as "Ready for review" to request feedback. Thanks!

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Missing proxy identities are accepted, and recovery, rescheduling, and audit paths have correctness gaps.

10 open findings
What changed in this PR

Adds the currently unwired verifier admin-console package for searching failures, rescheduling jobs, managing recovery operations, and auditing mutations.

Changes:

  • Adds the Gin/templ console, authentication, CSRF protection, views, and assets.
  • Implements attestation-gated rescheduling, durable recovery controls, and action logging.
  • Adds storage clients, migration, secrets schema, documentation, and tests.
File Description
verifier/​pkg/​admin/​actionlog.go Persists and lists audit actions.
verifier/​pkg/​admin/​actionlog_test.go Tests action-log persistence.
verifier/​pkg/​admin/​attestation.go Checks aggregator attestation state.
verifier/​pkg/​admin/​attestation_test.go Tests freshness outcomes.
verifier/​pkg/​admin/​auth.go Defines access-policy and basic-auth handling.
verifier/​pkg/​admin/​auth_test.go Tests authentication rules.
verifier/​pkg/​admin/​config.go Defines console configuration.
verifier/​pkg/​admin/​config_test.go Tests configuration validation.
verifier/​pkg/​admin/​detail.go Builds message-detail data.
verifier/​pkg/​admin/​detail_test.go Tests message details.
verifier/​pkg/​admin/​handlers.go Provides shared handlers and core routes.
verifier/​pkg/​admin/​recoveryops.go Implements recovery operations and evidence.
verifier/​pkg/​admin/​recoveryops_test.go Tests recovery workflows.
verifier/​pkg/​admin/​reschedule.go Implements guarded rescheduling.
verifier/​pkg/​admin/​reschedule_test.go Tests rescheduling safety.
verifier/​pkg/​admin/​search.go Implements archived-job search.
verifier/​pkg/​admin/​server.go Builds and runs the HTTP server.
verifier/​pkg/​admin/​server_test.go Tests routing and CSRF.
verifier/​pkg/​admin/​stores.go Adapts verifier database stores.
verifier/​pkg/​admin/​views/​actions.templ Defines the action-log page.
verifier/​pkg/​admin/​views/​actions_templ.go Generated action-log view.
verifier/​pkg/​admin/​views/​detail.templ Defines the detail page.
verifier/​pkg/​admin/​views/​detail_templ.go Generated detail view.
verifier/​pkg/​admin/​views/​layout.templ Defines the shared layout.
verifier/​pkg/​admin/​views/​layout_templ.go Generated layout view.
verifier/​pkg/​admin/​views/​recovery.templ Defines recovery UI.
verifier/​pkg/​admin/​views/​recovery_templ.go Generated recovery view.
verifier/​pkg/​admin/​views/​reschedule.templ Defines rescheduling UI.
verifier/​pkg/​admin/​views/​reschedule_templ.go Generated rescheduling view.
verifier/​pkg/​admin/​views/​search.templ Defines search UI.
verifier/​pkg/​admin/​views/​search_templ.go Generated search view.
verifier/​pkg/​admin/​views/​static.go Embeds browser assets.
verifier/​pkg/​admin/​views/​static/​admin.css Styles the console.
verifier/​pkg/​admin/​views/​static/​favicon.svg Adds the console icon.
verifier/​pkg/​admin/​views/​static/​htmx.min.js Vendors htmx.
verifier/​pkg/​vsecrets/​vsecrets.go Adds admin UI credentials.
verifier/​pkg/​vsecrets/​doccomments_gen.go Documents the new secret fields.
verifier/​migrations/​postgres/​00010_admin_actions.sql Creates the audit table.
integration/​storageaccess/​aggregator_results_client.go Adds the aggregator results client.
integration/​storageaccess/​aggregator_results_client_test.go Tests protobuf translation.
tools/​configdoc/​registry/​registry.go Registers example admin credentials.
docs/​config/​verifier/​secrets.documented.toml Documents [admin_ui].
go.mod Adds templ.
go.sum Records templ checksums.
Files not reviewed (2)
  • verifier/pkg/admin/views/actions_templ.go: Generated file
  • verifier/pkg/admin/views/detail_templ.go: Generated file

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread verifier/pkg/admin/reschedule.go Outdated
Comment on lines +211 to +212
// One target at a time: the gate, the intent row, the mutation, then the
// outcome row — so the audit log reads as adjacent intent/outcome pairs.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done — each reschedule target now generates a correlation UUID, written into operation_id on both the intent and the outcome row, so concurrent requests can no longer break the pairing (rows also keep actor/action/target).\n\nThis also answers the operation_id empty note: it is never empty for reschedule rows now, and the Action.OperationID doc comment states the correlation semantics.

Comment thread verifier/pkg/admin/server.go Outdated
Comment thread verifier/pkg/admin/handlers.go Outdated
Comment thread verifier/pkg/admin/recoveryops.go Outdated
Comment thread verifier/pkg/admin/search.go Outdated
Comment thread integration/storageaccess/aggregator_results_client.go Outdated
Comment thread verifier/pkg/admin/config.go Outdated
Comment thread verifier/pkg/admin/reschedule.go Outdated
Comment thread verifier/pkg/admin/stores.go Outdated
Comment thread verifier/pkg/admin/views/detail.templ Outdated
@tt-cll
tt-cll added this pull request to stack #1503 October 7, 2026 22:23
@tt-cll
tt-cll force-pushed the tt/admin-1 branch 2 times, most recently from 4e233e0 to 96e2f75 Compare October 7, 2026 23:40

@makramkd makramkd left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Awesome stuff! I have some more simplification suggestions below, let me know what you think.

Comment on lines +2 to +4
-- Admin console action log. The console runs in the verifier process and audits its
-- mutations here, in the verifier's own application database.
CREATE TABLE IF NOT EXISTS ccv_admin_actions (

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Just sanity-checking: migrations added here are typically added to the CL migrations as well. But since this feature will probably never be enabled in CL mode, I guess its safe to skip this one?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

And I guess this is basically an audit trail for the admin of what they ended up doing in the admin mode right?

We don't have this kind of thing in the chainlink operator UI AFAIK, so I think its OK to axe and keep things in-mem. We could create a follow-up ticket to persist it if its something that we think is useful.

Comment thread verifier/pkg/admin/config.go Outdated
Comment on lines +39 to +40
// Access configures how the console identifies who is acting.
Access AccessConfig `toml:"access"`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think we can remove this, seems like too much knobs. Looking at the docstring from the AccessConfig struct, it might be a relic of the previous admin UI that we were thinking could potentially connect to multiple verifier nodes. But since that isn't the case, we can remove it.

Comment thread verifier/pkg/admin/config.go Outdated
Comment on lines +43 to +49
type AccessConfig struct {
// ActorHeader names the HTTP header carrying an authenticated identity from a
// fronting proxy (shared hosting). Empty means self-hosted loopback: actor "local".
// Non-loopback serving requires this header or [admin_ui] basic auth, and a
// configured-but-absent header rejects the request (validated at startup).
ActorHeader string `toml:"actor_header"`
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Can remove, like I mentioned above.

Comment thread verifier/pkg/admin/config.go Outdated
Comment on lines +32 to +35
// AggregatorAddress (optional, host:port) overrides the aggregator used for
// attestation freshness checks via the unauthenticated GetVerifierResultsForMessage.
// Empty uses the verifier's own first configured aggregator.
AggregatorAddress string `toml:"aggregator_address"`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Also curious about this - we typically configure multiple aggregators, and it seems like we have access to that since the docstring here says "Empty uses the verifier's own first configured aggregator".

Can we just use that for now, and maybe in a followup, we can check the attestation reached all aggregators, if that's not too complex a lift? That way operators would not have to reconfigure same info in multiple places.

Concretely that means we can get rid of this config and just use the first configured aggregator for now, and in the future, we automatically check in all configured aggregators (or a subset, maybe from some UI toggle/checklist/dropdown).

@makramkd

makramkd commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator

One more question, since I probably missed it from the diff view: how is the frontend built? Wondering if we need some extra CI checks to validate freshness (if we commit the fully compiled frontend).

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown

Code coverage report:

Package main tt/admin-1 Diff
github.com/smartcontractkit/chainlink-ccv/aggregator 46.26% 46.28% +0.02%
github.com/smartcontractkit/chainlink-ccv/bootstrap 65.67% 65.67% +0.00%
github.com/smartcontractkit/chainlink-ccv/cli 54.90% 54.90% +0.00%
github.com/smartcontractkit/chainlink-ccv/cmd 41.12% 41.12% +0.00%
github.com/smartcontractkit/chainlink-ccv/common 46.09% 46.09% +0.00%
github.com/smartcontractkit/chainlink-ccv/executor 42.14% 42.14% +0.00%
github.com/smartcontractkit/chainlink-ccv/indexer 34.40% 34.40% +0.00%
github.com/smartcontractkit/chainlink-ccv/integration 61.99% 61.81% -0.18%
github.com/smartcontractkit/chainlink-ccv/internal 0.00% 0.00% +0.00%
github.com/smartcontractkit/chainlink-ccv/migration 78.70% 78.70% +0.00%
github.com/smartcontractkit/chainlink-ccv/pkg 84.62% 84.62% +0.00%
github.com/smartcontractkit/chainlink-ccv/pricer 0.00% 0.00% +0.00%
github.com/smartcontractkit/chainlink-ccv/protocol 66.31% 66.31% +0.00%
github.com/smartcontractkit/chainlink-ccv/tools 34.10% 38.36% +4.26%
github.com/smartcontractkit/chainlink-ccv/verifier 36.41% 40.05% +3.64%
Total 50.80% 45.60% -5.20%

Files added (in tt/admin-1):

  • github.com/smartcontractkit/chainlink-ccv/integration/storageaccess/aggregator_results_client.go
  • github.com/smartcontractkit/chainlink-ccv/verifier/pkg/admin/actionlog.go
  • github.com/smartcontractkit/chainlink-ccv/verifier/pkg/admin/attestation.go
  • github.com/smartcontractkit/chainlink-ccv/verifier/pkg/admin/auth.go
  • github.com/smartcontractkit/chainlink-ccv/verifier/pkg/admin/config.go
  • github.com/smartcontractkit/chainlink-ccv/verifier/pkg/admin/detail.go
  • github.com/smartcontractkit/chainlink-ccv/verifier/pkg/admin/handlers.go
  • github.com/smartcontractkit/chainlink-ccv/verifier/pkg/admin/recoveryops.go
  • github.com/smartcontractkit/chainlink-ccv/verifier/pkg/admin/reschedule.go
  • github.com/smartcontractkit/chainlink-ccv/verifier/pkg/admin/search.go
  • github.com/smartcontractkit/chainlink-ccv/verifier/pkg/admin/server.go
  • github.com/smartcontractkit/chainlink-ccv/verifier/pkg/admin/stores.go
  • github.com/smartcontractkit/chainlink-ccv/verifier/pkg/admin/views/actions_templ.go
  • github.com/smartcontractkit/chainlink-ccv/verifier/pkg/admin/views/detail_templ.go
  • github.com/smartcontractkit/chainlink-ccv/verifier/pkg/admin/views/layout_templ.go
  • github.com/smartcontractkit/chainlink-ccv/verifier/pkg/admin/views/recovery_templ.go
  • github.com/smartcontractkit/chainlink-ccv/verifier/pkg/admin/views/reschedule_templ.go
  • github.com/smartcontractkit/chainlink-ccv/verifier/pkg/admin/views/search_templ.go

@tt-cll
tt-cll added this pull request to the merge queue Oct 8, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 8, 2026
@tt-cll
tt-cll added this pull request to the merge queue Oct 8, 2026
Merged via the queue into main with commit bb0c396 Oct 8, 2026
57 checks passed
@tt-cll
tt-cll deleted the tt/admin-1 branch October 8, 2026 17:02
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.

4 participants