Skip to content

Add trace-commons-review and trace-commons-admin operator binaries - #125

Closed
zmanian wants to merge 1 commit into
trace-commons-operator-client-foundationfrom
trace-commons-operator-binaries-review-admin
Closed

zmanian wants to merge 1 commit into
trace-commons-operator-client-foundationfrom
trace-commons-operator-binaries-review-admin

Conversation

@zmanian

@zmanian zmanian commented May 19, 2026

Copy link
Copy Markdown
Collaborator

Context

PR #2 of the three-PR stack bringing operator-side CLI workflows to this repo. Stacked on #124 (the trace-commons-operator-client foundation). Companion to the prune in nearai/ironclaw#3738 — these binaries take over 20 of the 39 operator commands that left Ironclaw.

Merge order: #124 first, then this PR.

What lands

Two new binaries under crates/trace-commons-server/src/bin/, both depending on trace-commons-operator-client:

trace-commons-review (8 cmds) — gated by TRACE_COMMONS_REVIEWER_BEARER

Subcommand Endpoint
quarantine-list GET /v1/review/quarantine
active-learning-review-queue GET /v1/review/active-learning
review-decision POST /v1/review/decision
review-lease-claim POST /v1/review/lease/claim
review-lease-claim-next POST /v1/review/lease/claim-next
review-lease-claim-batch POST /v1/review/lease/claim-batch
review-lease-release POST /v1/review/lease/release
append-credit-event POST /v1/review/credit-event

trace-commons-admin (12 cmds) — gated by TRACE_COMMONS_ADMIN_BEARER

Subcommand Endpoint
maintenance-run POST /v1/admin/maintenance/run
retention-jobs-list GET /v1/admin/retention/jobs
retention-job-items GET /v1/admin/retention/jobs/{id}/items
export-access-grants-list GET /v1/admin/export/access-grants
export-jobs-list GET /v1/admin/export/jobs
benchmark-convert POST /v1/admin/benchmark/convert
benchmark-lifecycle-update POST /v1/admin/benchmark/lifecycle
replay-dataset-export POST /v1/admin/replay/dataset-export
replay-export-manifests GET /v1/admin/replay/export-manifests
analytics-summary GET /v1/admin/analytics/summary
operational-summary GET /v1/admin/operational/summary
config-status GET /v1/admin/config/status

Auth model

Each binary takes a single top-level --bearer-token-env <ENV> flag (defaults: TRACE_COMMONS_REVIEWER_BEARER / TRACE_COMMONS_ADMIN_BEARER). No per-subcommand bearer overrides here — that's worker territory and lands in PR #3.

CLI surface

Both binaries share the foundation flag set:

  • --endpoint <URL> or TRACE_COMMONS_ENDPOINT
  • --bearer-token-env <NAME>
  • --allowed-hosts <CSV> or TRACE_COMMONS_ALLOWED_HOSTS
  • --json (global; switches every subcommand to the JsonEnvelope wrapper format)

Tests

  • Review: 18 tests — 13 parse-through, 2 lease-body validation, 2 wiremock round-trip, 1 reject-unknown-subcommand.
  • Admin: 19 tests — 12 parse-through, 1 reject-unknown, 2 maintenance/score validation, 4 wiremock + body-validation.

Verification

RUSTFLAGS="-D warnings" cargo check --workspace --all-targets   # clean
RUSTFLAGS="-D warnings" cargo test --workspace --no-run         # clean
cargo test -p trace-commons-server --bins                       # 37 passed
cargo clippy -p trace-commons-server --bins -- -D warnings      # clean
cargo build --bin trace-commons-review                          # builds standalone
cargo build --bin trace-commons-admin                           # builds standalone

Net diff

3 files added (2 binaries + shared operator_common rendering helpers), 1 modified (Cargo.toml). +2,555 LOC.

Deviations from the Ironclaw reference at 3b5ca1fde:crates/ironclaw_reborn_cli/src/commands/traces.rs

  • replay-dataset-export always parses the response body as serde_json::Value (or Null for empty) before writing to --output. Ironclaw used a pretty_trace_commons_body helper; the foundation client returns the raw body which we either pretty-print or pass through verbatim.
  • config-status is JSON-only in the reference; preserved here (the --json flag is a no-op for it, the response is always pretty-printed JSON).
  • operational-summary non-JSON rendering is simplified (field: value lines + nested maps via render_json_map rather than the reference's per-section compact totals). Fields are all present; layout differs.
  • maintenance-run non-JSON rendering omits the reference's audit-chain / reconciliation extra-section lines and renders only the documented scalar field set. --json mode forwards the full server response unchanged.

Out of scope

🤖 Generated with Claude Code

Wire up the reviewer-audience (8 subcommands) and admin-audience
(12 subcommands) CLI binaries on top of the trace-commons-operator-client
foundation crate. Each binary takes a top-level --endpoint, --bearer-token-env,
--allowed-hosts, and --json flag and delegates per-endpoint typing to the
foundation Client. A shared operator_common module exposes table / kv / map
rendering helpers consumed by both bins via #[path = ...].

Coverage matches the Ironclaw reference handlers in
crates/ironclaw_reborn_cli/src/commands/traces.rs at the same paths
(/v1/review/*, /v1/admin/*, /v1/benchmarks/*, /v1/datasets/replay,
/v1/analytics/summary).
zmanian added a commit that referenced this pull request May 20, 2026
Lands the four-PR stack (#124, #125, #126, #127) as a single squash commit on main.

## What's in this squash

**1. `trace-commons-operator-client` foundation crate** (was #124)
- `Client` wrapper around `reqwest::Client` with bearer-token resolution from env, host allowlist enforcement, typed error mapping for `{"error": "<Label>"}` refusals.
- Error taxonomy: `BearerMissing`, `InvalidEndpoint`, `HostNotAllowed`, `Transport`, `HttpFailure`, `ServerLabel`, `MalformedResponse`. `Error::user_diagnostic()` strips query strings + fragments.
- `HostAllowlist` (CSV, exact-match, case-insensitive) sourced from `--allowed-hosts` or `TRACE_COMMONS_ALLOWED_HOSTS`.
- Output helpers: `JsonEnvelope` wrapper for `--json` mode, ASCII table renderer, key-value block renderer.

**2. `trace-commons-review` (8 cmds) + `trace-commons-admin` (12 cmds)** (was #125)
- Single shared bearer per binary (`TRACE_COMMONS_REVIEWER_BEARER`, `TRACE_COMMONS_ADMIN_BEARER`).
- 37 binary tests across both (parse-through, body validation, wiremock round-trips).

**3. `trace-commons-worker` (8 cmds) + `trace-commons-tenant` (11 cmds)** (was #126)
- Worker uses per-subcommand bearer envs (8 distinct env vars, one per route gate). Verified by `worker_per_route_bearer_resolution_uses_distinct_envs`.
- Tenant uses single shared `TRACE_COMMONS_TENANT_BEARER`.
- Operator runbook at `docs/operator/operator-binaries.md`.
- CI smoke job `operator-binaries-smoke` in `.github/workflows/ci.yml`, sibling to `pilot-bootstrap-smoke`.

**4. Privacy-filter-canary port** (was #127)
- New `trace_commons_operator_client::privacy_filter` module: `PrivacyFilterAdapter` trait, `CommandPrivacyFilterAdapter`, `SafePrivacyFilterRedaction`, `adapter_from_env`, `canary_leaked_tokens`. Wire shapes byte-identical to Ironclaw's sidecar protocol.
- Dual-name env-var compat: `TRACE_COMMONS_PRIVACY_FILTER_*` canonical, `IRONCLAW_TRACE_*` legacy fallback with warn-on-use.
- `trace-commons-tenant privacy-filter-canary` stub replaced with the real handler.

## Operator surface added

| Binary | Cmds | Bearer model |
|---|---:|---|
| `trace-commons-review` | 8 | Single `TRACE_COMMONS_REVIEWER_BEARER` |
| `trace-commons-admin` | 12 | Single `TRACE_COMMONS_ADMIN_BEARER` |
| `trace-commons-worker` | 8 | Per-subcommand defaults |
| `trace-commons-tenant` | 11 | Single `TRACE_COMMONS_TENANT_BEARER` |
| **Total** | **39** | |

These mirror the 39 operator commands removed from Ironclaw in nearai/ironclaw#3738.

## Verification

```
cargo check --workspace --all-targets   (-D warnings)   # clean
cargo test --workspace --no-run         (-D warnings)   # clean
cargo clippy --workspace --all-targets  (-D warnings)   # clean
cargo test -p trace-commons-operator-client            # 39 passed
cargo test -p trace-commons-server --bins              # all green
bash scripts/operator/operator-smoke.sh                # SmokeOperatorBinariesOK
```

Superseded PRs (closed): #124, #125, #126.
@zmanian

zmanian commented May 20, 2026

Copy link
Copy Markdown
Collaborator Author

Superseded by #127. The trace-commons-server stack (#124 → #125 → #126 → #127) was squash-merged top-down per the project's stacked-PR merge convention; #127's squash captures this PR's full diff (trace-commons-review + trace-commons-admin operator binaries). No code is lost.

Closing as superseded.

@zmanian zmanian closed this May 20, 2026
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