From 013eb3934edd860f2f051d260a87260cf02def42 Mon Sep 17 00:00:00 2001 From: Goon Date: Fri, 12 Jun 2026 00:46:56 +0700 Subject: [PATCH 1/2] feat(traces): add search filter flags --- CHANGELOG.md | 1 + README.md | 5 + cmd/traces.go | 41 +++++++ cmd/traces_contract_test.go | 12 +- cmd/traces_list_test.go | 72 +++++++++-- docs/codebase-summary.md | 6 +- docs/project-roadmap.md | 20 ++- .../phase-01-contract-lock.md | 60 +++++++++ .../phase-02-tdd-implementation.md | 74 ++++++++++++ .../phase-03-verification-and-ship.md | 76 ++++++++++++ .../plan.md | 114 ++++++++++++++++++ ...red-team-260612-trace-search-filter-cli.md | 34 ++++++ ...reviewer-260612-trace-search-filter-cli.md | 61 ++++++++++ ...lidation-260612-trace-search-filter-cli.md | 32 +++++ 14 files changed, 594 insertions(+), 14 deletions(-) create mode 100644 plans/260612-0023-trace-search-filter-cli/phase-01-contract-lock.md create mode 100644 plans/260612-0023-trace-search-filter-cli/phase-02-tdd-implementation.md create mode 100644 plans/260612-0023-trace-search-filter-cli/phase-03-verification-and-ship.md create mode 100644 plans/260612-0023-trace-search-filter-cli/plan.md create mode 100644 plans/260612-0023-trace-search-filter-cli/reports/red-team-260612-trace-search-filter-cli.md create mode 100644 plans/260612-0023-trace-search-filter-cli/reports/reviewer-260612-trace-search-filter-cli.md create mode 100644 plans/260612-0023-trace-search-filter-cli/reports/validation-260612-trace-search-filter-cli.md diff --git a/CHANGELOG.md b/CHANGELOG.md index dcda86c..a75935c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,7 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - `goclaw agents evolution update` now maps `--action=accept|reject` to the server-compatible `status=approved|rejected` payload. **P6 — Backend-unblocked surfaces (gateway `v3.12.0-beta.20`+)** +- `goclaw traces list --q --agent-query --channel-query --from --to --min-input-tokens --max-input-tokens --min-output-tokens --max-output-tokens --min-tool-calls --max-tool-calls --tool-name --has-tool-calls` — forwards the trace search and advanced filters added by server PR #155 while preserving existing `--agent` as `agent_id`. - `goclaw traces follow --session-key|--agent [--since RFC3339] [--limit N]` — one-shot incremental trace polling (`GET /v1/traces/follow`). Re-invoke with returned cursor to advance; no WS stream, no watch loop. - `goclaw traces timeline [--session-key K] [--limit N] [--offset N]` — read archived run timeline items (`GET /v1/runs/{runID}/timeline`) without replaying or mutating a run. - `goclaw providers reconnect ` — hot-reconnect a provider, bumping the registry without touching credentials (`POST /v1/providers/{id}/reconnect`). diff --git a/README.md b/README.md index 5704609..19307bf 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,11 @@ plus the run timeline archive endpoint: # Paginated trace listing with server-supported filters goclaw traces list [--agent ] [--user ] [--session-key ] \ [--status ] [--channel ] [--limit ] [--offset ] +goclaw traces list --q "refund error" [--agent-query ] [--channel-query ] \ + [--from ] [--to ] [--min-input-tokens ] \ + [--max-input-tokens ] [--min-output-tokens ] [--max-output-tokens ] \ + [--min-tool-calls ] [--max-tool-calls ] [--tool-name ] \ + [--has-tool-calls ] # Incremental trace polling (one shot; rerun with returned cursor) goclaw traces follow --session-key [--since ] [--limit ] diff --git a/cmd/traces.go b/cmd/traces.go index 7b7b5e5..e9b6a56 100644 --- a/cmd/traces.go +++ b/cmd/traces.go @@ -39,6 +39,19 @@ var tracesListCmd = &cobra.Command{ if v, _ := cmd.Flags().GetString("channel"); v != "" { q.Set("channel", v) } + setStringQueryFlag(cmd, q, "q", "q") + setStringQueryFlag(cmd, q, "agent-query", "agent") + setStringQueryFlag(cmd, q, "channel-query", "channel_query") + setStringQueryFlag(cmd, q, "from", "from") + setStringQueryFlag(cmd, q, "to", "to") + setChangedIntQueryFlag(cmd, q, "min-input-tokens", "min_input_tokens") + setChangedIntQueryFlag(cmd, q, "max-input-tokens", "max_input_tokens") + setChangedIntQueryFlag(cmd, q, "min-output-tokens", "min_output_tokens") + setChangedIntQueryFlag(cmd, q, "max-output-tokens", "max_output_tokens") + setChangedIntQueryFlag(cmd, q, "min-tool-calls", "min_tool_calls") + setChangedIntQueryFlag(cmd, q, "max-tool-calls", "max_tool_calls") + setStringQueryFlag(cmd, q, "tool-name", "tool_name") + setStringQueryFlag(cmd, q, "has-tool-calls", "has_tool_calls") if v, _ := cmd.Flags().GetInt("limit"); v > 0 { q.Set("limit", fmt.Sprintf("%d", v)) } @@ -115,6 +128,21 @@ func validateTraceID(id string) error { return nil } +func setStringQueryFlag(cmd *cobra.Command, q url.Values, flagName, queryName string) { + v, _ := cmd.Flags().GetString(flagName) + if v != "" { + q.Set(queryName, v) + } +} + +func setChangedIntQueryFlag(cmd *cobra.Command, q url.Values, flagName, queryName string) { + if !cmd.Flags().Changed(flagName) { + return + } + v, _ := cmd.Flags().GetInt(flagName) + q.Set(queryName, fmt.Sprintf("%d", v)) +} + var tracesExportCmd = &cobra.Command{ Use: "export ", Short: "Export trace to file", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { @@ -308,6 +336,19 @@ func init() { tracesListCmd.Flags().String("session-key", "", "Filter by session key") tracesListCmd.Flags().String("status", "", "Filter: running, success, error") tracesListCmd.Flags().String("channel", "", "Filter by channel") + tracesListCmd.Flags().String("q", "", "Search trace id, previews, session/channel labels, agent/channel labels, and span previews") + tracesListCmd.Flags().String("agent-query", "", "Search agent display name or key") + tracesListCmd.Flags().String("channel-query", "", "Search channel instance name, display name, or type") + tracesListCmd.Flags().String("from", "", "Filter traces from RFC3339 start time") + tracesListCmd.Flags().String("to", "", "Filter traces up to RFC3339 start time") + tracesListCmd.Flags().Int("min-input-tokens", 0, "Minimum total input tokens") + tracesListCmd.Flags().Int("max-input-tokens", 0, "Maximum total input tokens") + tracesListCmd.Flags().Int("min-output-tokens", 0, "Minimum total output tokens") + tracesListCmd.Flags().Int("max-output-tokens", 0, "Maximum total output tokens") + tracesListCmd.Flags().Int("min-tool-calls", 0, "Minimum tool-call count") + tracesListCmd.Flags().Int("max-tool-calls", 0, "Maximum tool-call count") + tracesListCmd.Flags().String("tool-name", "", "Search span tool names") + tracesListCmd.Flags().String("has-tool-calls", "", "Filter traces by tool-call presence: true or false") tracesListCmd.Flags().Int("limit", 20, "Max results") tracesListCmd.Flags().Int("offset", 0, "Pagination offset") tracesListCmd.Flags().String("since", "", "Deprecated: use traces follow --since") diff --git a/cmd/traces_contract_test.go b/cmd/traces_contract_test.go index 44b88bd..73e1d36 100644 --- a/cmd/traces_contract_test.go +++ b/cmd/traces_contract_test.go @@ -16,12 +16,22 @@ func rawJSON(t *testing.T, w http.ResponseWriter, payload any) { func resetTracesListFlags(t *testing.T) { t.Helper() - for _, name := range []string{"agent", "user", "session-key", "status", "channel", "since"} { + for _, name := range []string{ + "agent", "user", "session-key", "status", "channel", "since", + "q", "agent-query", "channel-query", "from", "to", "tool-name", "has-tool-calls", + } { resetTestFlag(tracesListCmd, name, "") } resetTestFlag(tracesListCmd, "root-only", "false") resetTestFlag(tracesListCmd, "limit", "20") resetTestFlag(tracesListCmd, "offset", "0") + for _, name := range []string{ + "min-input-tokens", "max-input-tokens", + "min-output-tokens", "max-output-tokens", + "min-tool-calls", "max-tool-calls", + } { + resetTestFlag(tracesListCmd, name, "0") + } } func assertNoTracesReplayCommand(t *testing.T) { diff --git a/cmd/traces_list_test.go b/cmd/traces_list_test.go index 5aaa056..efb9721 100644 --- a/cmd/traces_list_test.go +++ b/cmd/traces_list_test.go @@ -87,6 +87,19 @@ func TestTracesList_ServerFilters(t *testing.T) { "--session-key=session-1", "--status=failed", "--channel=telegram", + "--q=trace_%", + "--agent-query=helper", + "--channel-query=ops", + "--from=2026-06-10T01:02:03Z", + "--to=2026-06-11T04:05:06Z", + "--min-input-tokens=10", + "--max-input-tokens=20", + "--min-output-tokens=30", + "--max-output-tokens=40", + "--min-tool-calls=1", + "--max-tool-calls=3", + "--tool-name=web_%", + "--has-tool-calls=true", "--limit=5", "--offset=10", ) @@ -94,13 +107,26 @@ func TestTracesList_ServerFilters(t *testing.T) { t.Fatalf("traces list: %v", err) } want := map[string]string{ - "agent_id": "agent-1", - "user_id": "user-1", - "session_key": "session-1", - "status": "failed", - "channel": "telegram", - "limit": "5", - "offset": "10", + "agent_id": "agent-1", + "user_id": "user-1", + "session_key": "session-1", + "status": "failed", + "channel": "telegram", + "q": "trace_%", + "agent": "helper", + "channel_query": "ops", + "from": "2026-06-10T01:02:03Z", + "to": "2026-06-11T04:05:06Z", + "min_input_tokens": "10", + "max_input_tokens": "20", + "min_output_tokens": "30", + "max_output_tokens": "40", + "min_tool_calls": "1", + "max_tool_calls": "3", + "tool_name": "web_%", + "has_tool_calls": "true", + "limit": "5", + "offset": "10", } for key, val := range want { if got := query.Get(key); got != val { @@ -112,6 +138,38 @@ func TestTracesList_ServerFilters(t *testing.T) { } } +func TestTracesList_ServerFiltersForwardExplicitFalseAndZero(t *testing.T) { + t.Cleanup(func() { resetTracesListFlags(t) }) + var query url.Values + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + query = r.URL.Query() + rawJSON(t, w, traceListFixture()) + })) + defer srv.Close() + t.Setenv("GOCLAW_SERVER", srv.URL) + t.Setenv("GOCLAW_TOKEN", "test-token") + t.Setenv("GOCLAW_OUTPUT", "json") + + err := runCmd(t, "traces", "list", + "--min-input-tokens=0", + "--max-tool-calls=0", + "--has-tool-calls=false", + ) + if err != nil { + t.Fatalf("traces list: %v", err) + } + want := map[string]string{ + "min_input_tokens": "0", + "max_tool_calls": "0", + "has_tool_calls": "false", + } + for key, val := range want { + if got := query.Get(key); got != val { + t.Fatalf("%s = %q, want %q; query=%s", key, got, val, query.Encode()) + } + } +} + func TestTracesReplayCommandAbsent(t *testing.T) { assertNoTracesReplayCommand(t) } diff --git a/docs/codebase-summary.md b/docs/codebase-summary.md index 18ac127..6254330 100644 --- a/docs/codebase-summary.md +++ b/docs/codebase-summary.md @@ -1,7 +1,7 @@ # GoClaw CLI - Codebase Summary -**Generated from:** `repomix-output.xml` (2026-04-15), updated manually 2026-06-11 -**Phase Status:** P0-P4 Complete (AI-First Expansion); Super Admin API Parity Complete; Domain Coverage P5 + P6 (Backend-Unblocked) Implemented +**Generated from:** `repomix-output.xml` (2026-04-15), updated manually 2026-06-12 +**Phase Status:** P0-P4 Complete (AI-First Expansion); Super Admin API Parity Complete; Domain Coverage P5 + P6 (Backend-Unblocked) Implemented; Trace Search/Filter CLI Implemented **Total Files:** 80+ **Estimated Tokens:** 80,000+ **Total Size:** 220+ KB @@ -10,7 +10,7 @@ ## Overview -GoClaw CLI is a production-ready Go application providing comprehensive command-line management for GoClaw AI agent gateway servers. Built with Cobra framework, it supports 30+ command groups across modular command files with dual modes: interactive (human) and automation (CI/agent). Phases 0-4 (AI-first expansion) add AI ergonomics, admin/ops, migration, vault, and advanced agent/team/memory support. The 2026-05-18 super-admin parity work adds gateway upgrade, package updates, workstations, webhooks, MCP user credentials, secure env reveal, media/TTS/storage/channel fillers, and focused route-contract tests. The 2026-05-19 P3/P4 filler pass adds first-class profile commands, `GOCLAW_PROFILE`, `sessions compact`, WS health, trace filter polish, `codex-pool`, `api-keys rotate`, `config defaults`, chat session convenience wrappers, and `tools invoke --args`. The 2026-05-20 P5 filler pass adds team attachment download, skill-specific evolution suggestion apply, and fixes evolution update payload compatibility. The 2026-05-27 P6 backend-unblocked pass adds seven new surfaces wired to backend PRs `#37` and `#44`: `traces follow`, `providers reconnect`, `sessions branch`, `sessions follow`, `channels writers test`, `activity aggregate`, and `logs aggregate` — all one-shot HTTP commands (no new watch loops; reuse the existing `client.FollowStream` only for true streaming surfaces). The 2026-06-11 traces contract pass aligns `traces list/get/follow/export` with server `dev` envelopes and adds `traces timeline`. +GoClaw CLI is a production-ready Go application providing comprehensive command-line management for GoClaw AI agent gateway servers. Built with Cobra framework, it supports 30+ command groups across modular command files with dual modes: interactive (human) and automation (CI/agent). Phases 0-4 (AI-first expansion) add AI ergonomics, admin/ops, migration, vault, and advanced agent/team/memory support. The 2026-05-18 super-admin parity work adds gateway upgrade, package updates, workstations, webhooks, MCP user credentials, secure env reveal, media/TTS/storage/channel fillers, and focused route-contract tests. The 2026-05-19 P3/P4 filler pass adds first-class profile commands, `GOCLAW_PROFILE`, `sessions compact`, WS health, trace filter polish, `codex-pool`, `api-keys rotate`, `config defaults`, chat session convenience wrappers, and `tools invoke --args`. The 2026-05-20 P5 filler pass adds team attachment download, skill-specific evolution suggestion apply, and fixes evolution update payload compatibility. The 2026-05-27 P6 backend-unblocked pass adds seven new surfaces wired to backend PRs `#37` and `#44`: `traces follow`, `providers reconnect`, `sessions branch`, `sessions follow`, `channels writers test`, `activity aggregate`, and `logs aggregate` — all one-shot HTTP commands (no new watch loops; reuse the existing `client.FollowStream` only for true streaming surfaces). The 2026-06-11 traces contract pass aligns `traces list/get/follow/export` with server `dev` envelopes and adds `traces timeline`. The 2026-06-12 trace search/filter pass exposes server PR #155 filters on `traces list` with `--q`, `--agent-query`, `--channel-query`, date ranges, token ranges, tool-call ranges, `--tool-name`, and `--has-tool-calls`. **Key Metrics:** - **70+ command files** in `cmd/` (modularized for maintainability) diff --git a/docs/project-roadmap.md b/docs/project-roadmap.md index 94a22fe..0848b33 100644 --- a/docs/project-roadmap.md +++ b/docs/project-roadmap.md @@ -1,9 +1,23 @@ # GoClaw CLI - Project Roadmap -**Last Updated:** 2026-05-20 +**Last Updated:** 2026-06-12 **Phase Structure:** Legacy Phases 1-9 (bootstrap → CI/CD) + AI-First Expansion Phases 0-5 (2026-04-15) -**Current Status:** Legacy Phases 1-9 ✓ COMPLETE; P0-P4 ✓ COMPLETE; Super Admin API Parity ✓ COMPLETE; Domain Coverage P5 implemented pending release. -**Next Phase:** Ship Domain Coverage P5 PR to `dev` and verify beta release. +**Current Status:** Legacy Phases 1-9 ✓ COMPLETE; P0-P6 ✓ COMPLETE; Super Admin API Parity ✓ COMPLETE; trace contract and trace search/filter CLI support implemented. +**Next Phase:** Ship trace search/filter CLI PR to `dev` and verify beta release. + +--- + +## 2026-06-12: Trace Search/Filter CLI IMPLEMENTED + +**Objective:** Expose server PR #155 trace search and advanced filters through `goclaw traces list`. + +**Deliverables:** +- [x] Added `traces list --q --agent-query --channel-query --from --to --min-input-tokens --max-input-tokens --min-output-tokens --max-output-tokens --min-tool-calls --max-tool-calls --tool-name --has-tool-calls`. +- [x] Preserved existing `--agent` as `agent_id` for backward compatibility; `--agent-query` maps to the server `agent` text search. +- [x] Added focused tests for full query forwarding, explicit `false`, explicit zero values, and replay absence. +- [x] Synced README, changelog, codebase summary, and plan artifacts. + +**Validation:** `/usr/local/go/bin/go test -count=1 ./cmd -run 'TestTracesList|TestTracesReplayCommandAbsent'`; `/usr/local/go/bin/go test -count=1 ./cmd`; `/usr/local/go/bin/go test -count=1 ./...`; `/usr/local/go/bin/go vet ./...`; `/usr/local/go/bin/go build ./...`. --- diff --git a/plans/260612-0023-trace-search-filter-cli/phase-01-contract-lock.md b/plans/260612-0023-trace-search-filter-cli/phase-01-contract-lock.md new file mode 100644 index 0000000..fc3f859 --- /dev/null +++ b/plans/260612-0023-trace-search-filter-cli/phase-01-contract-lock.md @@ -0,0 +1,60 @@ +--- +phase: 1 +title: Contract Lock +status: completed +priority: P1 +effort: 1h +dependencies: [] +--- + +# Phase 1: Contract Lock + +## Overview + +Lock the merged server contract from `digitopvn/goclaw#155` before implementation. The output of this phase is a testable list of query mappings and explicit exclusions. + +## Requirements + +- Functional: map every new server list filter to one CLI flag. +- Non-functional: preserve existing `traces list` automation contract and avoid speculative server behavior. + +## Architecture + +`traces list` remains a one-shot `GET /v1/traces` command. The CLI only builds `url.Values`; all matching semantics, wildcard escaping, date parsing, and tenant scoping stay server-side. + +## Related Code Files + +- Modify: `cmd/traces_contract_test.go` +- Read: `cmd/traces.go` +- Read: `cmd/traces_list_test.go` +- Read: upstream `digitopvn/goclaw#155` + +## Implementation Steps + +1. Verify the server PR is merged and capture exact query names. +2. Add or update a contract test helper that resets all trace list flags, including new ones. +3. Confirm existing replay-absence coverage stays in place. + +## Todo List + +- [x] Capture exact query parameter names from server PR #155. +- [x] Update `resetTracesListFlags` for all new flags. +- [x] Keep `TestTracesReplayCommandAbsent` green. + +## Success Criteria + +- [x] Contract test names all new query params. +- [x] No plan or test implies `traces replay` exists. +- [x] No unresolved scope questions remain. + +## Risk Assessment + +Misnaming `agent` as `agent_id` would silently change semantics. The test must assert both `--agent` and `--agent-query` mappings to keep ID and query search distinct. + +## Security Considerations + +No credentials or live traces are used. Tests use synthetic `httptest` requests and server-shaped fixtures only. + +## Next Steps + +Proceed to Phase 2 only after focused contract tests fail for missing flags. diff --git a/plans/260612-0023-trace-search-filter-cli/phase-02-tdd-implementation.md b/plans/260612-0023-trace-search-filter-cli/phase-02-tdd-implementation.md new file mode 100644 index 0000000..19f4ea3 --- /dev/null +++ b/plans/260612-0023-trace-search-filter-cli/phase-02-tdd-implementation.md @@ -0,0 +1,74 @@ +--- +phase: 2 +title: TDD Implementation +status: completed +priority: P1 +effort: 2h +dependencies: + - 1 +--- + +# Phase 2: TDD Implementation + +## Overview + +Add focused failing tests for the new trace list filters, then implement the smallest CLI change in `cmd/traces.go`. + +## Requirements + +- Functional: `traces list` forwards all PR #155 filter flags when supplied. +- Functional: zero-valued numeric filters can be forwarded when the user explicitly sets them. +- Functional: `--has-tool-calls=false` is forwarded, not dropped. +- Non-functional: no output shape or command behavior changes outside list query construction. + +## Architecture + +The command keeps using `url.Values`. A small helper may copy changed string/int/bool-like string flags to query params if it reduces repetitive flag handling without creating a generic framework. + +## Related Code Files + +- Modify: `cmd/traces.go` +- Modify: `cmd/traces_list_test.go` +- Modify: `cmd/traces_contract_test.go` + +## Implementation Steps + +1. Extend `TestTracesList_ServerFilters` to include all new flags and expected query names. +2. Add a focused test for false/zero explicit forwarding: + `--has-tool-calls=false`, `--min-tool-calls=0`, `--min-input-tokens=0`. +3. Run focused tests and confirm failure before implementation. +4. Add flags to `tracesListCmd`: + `--q`, `--agent-query`, `--channel-query`, `--from`, `--to`, + `--min-input-tokens`, `--max-input-tokens`, + `--min-output-tokens`, `--max-output-tokens`, + `--min-tool-calls`, `--max-tool-calls`, + `--tool-name`, `--has-tool-calls`. +5. Map flags to server params: + `q -> q`, `agent-query -> agent`, `channel-query -> channel_query`, + ranges to snake_case names, `has-tool-calls -> has_tool_calls`. +6. Run focused tests again and fix only failures in this scope. + +## Todo List + +- [x] Add red tests for new filter forwarding. +- [x] Add explicit false/zero forwarding test. +- [x] Implement flag registration and query mapping. +- [x] Keep existing basic filter test green. + +## Success Criteria + +- [x] Focused trace list tests pass. +- [x] No changes to `traces follow`, `get`, `export`, or `timeline`. +- [x] `cmd/traces.go` remains compilable and has no duplicated large blocks. + +## Risk Assessment + +The main regression risk is accidentally changing `--agent` from agent ID to label search. Keep `--agent` as `agent_id` for backward compatibility and add `--agent-query` for the server `agent` query. + +## Security Considerations + +User-provided filter strings are only URL query values encoded through `url.Values`. No shell execution, path usage, or local file reads are introduced. + +## Next Steps + +After focused tests pass, update README and docs in Phase 3. diff --git a/plans/260612-0023-trace-search-filter-cli/phase-03-verification-and-ship.md b/plans/260612-0023-trace-search-filter-cli/phase-03-verification-and-ship.md new file mode 100644 index 0000000..d391135 --- /dev/null +++ b/plans/260612-0023-trace-search-filter-cli/phase-03-verification-and-ship.md @@ -0,0 +1,76 @@ +--- +phase: 3 +title: Verification and Ship +status: in-progress +priority: P1 +effort: 2h +dependencies: + - 2 +--- + +# Phase 3: Verification and Ship + +## Overview + +Update user-facing docs, run verification, review the change, ship a beta PR, review the PR with fix loop, merge, and watch CI until success. + +## Requirements + +- Functional: docs show the new filters and preserve existing trace examples. +- Non-functional: full Go validation passes before PR. +- Non-functional: beta PR targets `dev`, not `main`. + +## Architecture + +No architecture changes. Documentation reflects the Cobra command surface and the upstream server query contract. + +## Related Code Files + +- Modify: `README.md` +- Modify: `CHANGELOG.md` +- Modify: `docs/project-roadmap.md` +- Modify: `docs/codebase-summary.md` +- Read: `.github/workflows/*` + +## Implementation Steps + +1. Update README trace list example with the new advanced filters. +2. Add a concise CHANGELOG entry for trace search/filter CLI support. +3. Update project docs status for the 2026-06-12 trace filter slice. +4. Run verification: + - `go test -count=1 ./cmd -run 'TestTracesList|TestTracesReplayCommandAbsent'` + - `go test -count=1 ./cmd` + - `go test -count=1 ./...` + - `go vet ./...` + - `go build ./...` +5. Run code review and address actionable findings. +6. Ship beta PR to `dev`. +7. Run PR review with fix loop. +8. Merge PR and watch/fix checks until success. + +## Todo List + +- [x] README updated. +- [x] CHANGELOG updated. +- [x] Project docs updated. +- [x] Focused and full verification pass. +- [x] Code review passes. +- [ ] Beta PR merged and CI success confirmed. + +## Success Criteria + +- [ ] Pull request to `dev` is merged. +- [ ] GitHub checks for the merged PR are successful or explicitly confirmed not present. +- [ ] Final report lists commits, PR URL, verification commands, and unresolved questions. + +## Risk Assessment + +CI may run a broader release matrix than local validation. If PR checks fail, inspect the exact job logs, patch only relevant failures, push, and re-watch. + +## Security Considerations + +Do not stage secrets or local config. Verify `git diff --cached` before commit and keep changes to code, tests, docs, and plan artifacts. + +## Next Steps + +Use the requested `/ck:ship beta` path after local review passes. diff --git a/plans/260612-0023-trace-search-filter-cli/plan.md b/plans/260612-0023-trace-search-filter-cli/plan.md new file mode 100644 index 0000000..6689210 --- /dev/null +++ b/plans/260612-0023-trace-search-filter-cli/plan.md @@ -0,0 +1,114 @@ +--- +title: Trace Search Filter CLI +description: >- + Add goclaw-cli support for the GET /v1/traces search and advanced filter query + parameters merged in digitopvn/goclaw#155. +status: in-progress +priority: P1 +branch: codex/trace-search-filter-traces +tags: + - traces + - cli + - api + - tdd + - beta +blockedBy: [] +blocks: [] +created: '2026-06-11T17:23:28.191Z' +createdBy: 'ck:plan' +source: skill +--- + +# Trace Search Filter CLI + +## Overview + +`digitopvn/goclaw#155` is merged into server `dev` and extends `GET /v1/traces` with search and advanced filters. `goclaw-cli` already supports basic trace list filters, server-shaped list envelopes, detail, export, follow, and timeline. This plan adds only the missing list filter flags and documentation, using tests first. + +## Expected Output + +Users can run `goclaw traces list` with these additional flags and the CLI forwards them to `GET /v1/traces`: + +```bash +goclaw traces list --q "error refund" --agent-query helper --channel-query telegram \ + --from 2026-06-10T00:00:00Z --to 2026-06-12T00:00:00Z \ + --min-input-tokens 10 --max-input-tokens 1000 \ + --min-output-tokens 5 --max-output-tokens 500 \ + --min-tool-calls 1 --max-tool-calls 3 \ + --tool-name web_search --has-tool-calls true +``` + +## Acceptance Criteria + +- `traces list` forwards exact server query names: + `q`, `agent`, `channel_query`, `from`, `to`, `min_input_tokens`, `max_input_tokens`, `min_output_tokens`, `max_output_tokens`, `min_tool_calls`, `max_tool_calls`, `tool_name`, `has_tool_calls`. +- Existing filters remain unchanged: + `agent_id`, `user_id`, `session_key`, `status`, `channel`, `limit`, `offset`. +- JSON/YAML output still prints the server list envelope; table output still renders rows from `traces`. +- CLI does not client-escape wildcard characters inside search strings; server handles wildcard escaping. +- `traces follow`, `traces get`, `traces export`, and `traces timeline` behavior stays unchanged. +- No `traces replay` command is added. +- README, CHANGELOG, and project docs mention the new list filters without implying watch loops or server-side replay. + +## Scope Boundary + +In scope: +- Add `traces list` flags for the merged server PR #155 list filters. +- Add focused `httptest` contract coverage for query forwarding. +- Update docs for the new CLI flags. + +Out of scope: +- Server changes in `digitopvn/goclaw`. +- New trace UI work. +- `POST /v1/traces/{id}/replay`. +- New streaming/watch behavior. +- Changing output payload shapes or trace table columns. + +## Touchpoints + +- Modify: `cmd/traces.go` +- Modify: `cmd/traces_contract_test.go` +- Modify: `cmd/traces_list_test.go` +- Modify: `README.md` +- Modify: `CHANGELOG.md` +- Modify: `docs/project-roadmap.md` +- Modify: `docs/codebase-summary.md` +- Read-only contract sources: + `digitopvn/goclaw#155`, `internal/http/traces.go`, `internal/store/tracing_store.go` + +## Phases + +| Phase | Name | Status | +|-------|------|--------| +| 1 | [Contract Lock](./phase-01-contract-lock.md) | Completed | +| 2 | [TDD Implementation](./phase-02-tdd-implementation.md) | Completed | +| 3 | [Verification and Ship](./phase-03-verification-and-ship.md) | In Progress | + +## Dependencies + +| Relationship | Plan | Reason | +|--------------|------|--------| +| Related | `../260611-2303-complete-traces-cli-contract/plan.md` | Existing completed traces contract work provides the list envelope and replay exclusion baseline. | +| Supersedes detail only | `../260528-1357-fix-trace-details-by-id/plan.md` | Older trace detail plan remains out of scope for this list-filter slice. | + +## Validation Gates + +- Focused red/green: `go test -count=1 ./cmd -run 'TestTracesList|TestTracesReplayCommandAbsent'` +- Command compile: `go test -count=1 ./cmd` +- Full verification: `go test -count=1 ./...` +- Static check: `go vet ./...` +- Compile: `go build ./...` + +## Risk Assessment + +| Risk | Mitigation | +|------|------------| +| Flag naming could confuse server `agent_id` with server `agent` label query | Keep CLI `--agent` for existing ID behavior and use `--agent-query` for the server `agent` query; document mapping in tests. | +| Boolean flag cannot express server false filter if modeled as Cobra bool with default false | Use a string flag `--has-tool-calls` and forward only when explicitly changed; accept `true` or `false` as server parses bool. | +| Numeric range flags with default zero could accidentally filter | Forward int range flags only when the flag changed. | +| Search wildcard characters might be escaped twice | Forward raw values; server PR #155 owns wildcard escaping. | +| `cmd/traces.go` is already over 200 lines | Keep edits local and minimal; do not refactor unrelated trace commands in this slice. | + +## Unresolved Questions + +None. diff --git a/plans/260612-0023-trace-search-filter-cli/reports/red-team-260612-trace-search-filter-cli.md b/plans/260612-0023-trace-search-filter-cli/reports/red-team-260612-trace-search-filter-cli.md new file mode 100644 index 0000000..6028cf2 --- /dev/null +++ b/plans/260612-0023-trace-search-filter-cli/reports/red-team-260612-trace-search-filter-cli.md @@ -0,0 +1,34 @@ +# Red Team: Trace Search Filter CLI + +## Verdict + +PASS with three accepted guardrails. + +## Findings + +### Accepted: `--agent` collision can break scripts + +Risk: server PR #155 uses query param `agent` for display-name/key search, but CLI already uses `--agent` for `agent_id`. + +Resolution: keep `--agent -> agent_id`; add `--agent-query -> agent`. + +### Accepted: false and zero filters can be silently dropped + +Risk: current code forwards ints only when `> 0`, which would drop explicit filters like `--has-tool-calls=false` and `--min-tool-calls=0`. + +Resolution: new numeric and boolean-like filters must use `cmd.Flags().Changed(name)`. + +### Accepted: client wildcard escaping can double-escape server behavior + +Risk: PR #155 explicitly added wildcard escaping in server stores. Client-side escaping would change search semantics. + +Resolution: CLI only URL-encodes query values through `url.Values`; server owns wildcard escaping. + +## Rejected Findings + +- Add local RFC3339/date validation: rejected. Server already returns structured invalid-request errors for `from` and `to`; adding client validation duplicates logic and can drift. +- Add a new trace search subcommand: rejected. Existing server contract is list filtering; no extra subcommand needed. + +## Unresolved Questions + +None. diff --git a/plans/260612-0023-trace-search-filter-cli/reports/reviewer-260612-trace-search-filter-cli.md b/plans/260612-0023-trace-search-filter-cli/reports/reviewer-260612-trace-search-filter-cli.md new file mode 100644 index 0000000..fafb7dd --- /dev/null +++ b/plans/260612-0023-trace-search-filter-cli/reports/reviewer-260612-trace-search-filter-cli.md @@ -0,0 +1,61 @@ +# Reviewer: Trace Search Filter CLI + +## Scope + +- Files: `cmd/traces.go`, `cmd/traces_contract_test.go`, `cmd/traces_list_test.go`, README/docs/changelog, plan artifacts. +- LOC: 143 insertions, 14 deletions in tracked diff; 6 untracked plan/report files. +- Focus: pending diff, spec compliance, code quality, adversarial edge cases. +- Scout findings: query construction only; render helpers unchanged; no replay command added; upstream `digitopvn/goclaw#155` merged and uses the same query names. + +## Overall Assessment + +PASS for code. New `traces list` flags map to server PR #155 names, existing `--agent -> agent_id` stays intact, explicit numeric zero and `has_tool_calls=false` are covered, and output rendering path is unchanged. + +## Critical Issues + +None. + +## High Priority + +None. + +## Medium Priority + +None. + +## Low Priority + +- [plans/260612-0023-trace-search-filter-cli/phase-01-contract-lock.md:40] Phase status says completed, but Todo/Success Criteria boxes remain unchecked. + Fix: Lead/planner can mark completed boxes or leave phase status less final. +- [plans/260612-0023-trace-search-filter-cli/phase-02-tdd-implementation.md:53] Same stale checkbox issue for completed implementation phase. + Fix: Lead/planner can sync plan bookkeeping after review. + +## Edge Cases Found by Scout + +- Existing filters verified unchanged at `cmd/traces.go:27`: `--agent` still forwards `agent_id`. +- New server filters verified at `cmd/traces.go:42`: `q`, `agent`, `channel_query`, date, token, tool-call, tool-name, and `has_tool_calls`. +- Explicit zero forwarding verified by changed-int helper at `cmd/traces.go:138` and test at `cmd/traces_list_test.go:141`. +- Explicit `false` forwarding verified by string flag behavior at `cmd/traces.go:54` and test at `cmd/traces_list_test.go:156`. +- No `traces replay` command registered; `cmd/traces.go:377`, `cmd/traces_follow.go:91`, and `cmd/traces_timeline.go:84` register list/get/export/follow/timeline only. + +## Positive Observations + +- Uses `url.Values`, so search strings are URL-encoded without client-side wildcard escaping. +- Tests cover exact query names and legacy filter preservation in one request. +- Docs keep one-shot language and do not imply new trace streaming/watch behavior. + +## Recommended Actions + +1. No source change required before ship. +2. Optional: sync phase Todo checkboxes before final plan handoff. + +## Metrics + +- Type Coverage: N/A (Go compile/typecheck via build). +- Test Coverage: not measured. +- Linting Issues: 0 from `go vet ./...`. +- Verification: focused `./cmd`, package `./cmd`, full `./...`, vet, build all passed on rerun with `/usr/local/go/bin/go`. + +## Unresolved Questions + +None. diff --git a/plans/260612-0023-trace-search-filter-cli/reports/validation-260612-trace-search-filter-cli.md b/plans/260612-0023-trace-search-filter-cli/reports/validation-260612-trace-search-filter-cli.md new file mode 100644 index 0000000..e88a61b --- /dev/null +++ b/plans/260612-0023-trace-search-filter-cli/reports/validation-260612-trace-search-filter-cli.md @@ -0,0 +1,32 @@ +# Validation: Trace Search Filter CLI + +## Result + +PASS after naming revision. + +## Critical Questions + +1. Expected output? + `goclaw traces list` forwards PR #155 search/filter flags to `GET /v1/traces` and keeps current output behavior. + +2. Acceptance criteria? + Exact query forwarding, existing basic filters unchanged, JSON/table output unchanged, no replay command, docs updated. + +3. Scope boundary? + Only `traces list` query construction, focused tests, docs. No server changes, UI changes, replay, or streaming. + +4. Non-negotiable constraints? + Backward compatibility for `--agent -> agent_id`; one-shot HTTP; server owns wildcard/date/bool validation; Go build/test/vet must pass. + +5. Touchpoints? + `cmd/traces.go`, `cmd/traces_list_test.go`, `cmd/traces_contract_test.go`, `README.md`, `CHANGELOG.md`, `docs/project-roadmap.md`, `docs/codebase-summary.md`. + +## Plan Changes From Validation + +- Replaced draft `--search`, `--agent-label`, `--channel-label` with `--q`, `--agent-query`, `--channel-query`. +- Kept existing `--agent` semantics locked to `agent_id`. +- Explicitly required `Flags().Changed(...)` forwarding for zero/false filters. + +## Unresolved Questions + +None. From c3a33bdc1f501a244d2b85d06c07eb182564c39c Mon Sep 17 00:00:00 2001 From: Goon Date: Fri, 12 Jun 2026 00:50:51 +0700 Subject: [PATCH 2/2] fix(traces): sync review report --- .../reports/reviewer-260612-trace-search-filter-cli.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/plans/260612-0023-trace-search-filter-cli/reports/reviewer-260612-trace-search-filter-cli.md b/plans/260612-0023-trace-search-filter-cli/reports/reviewer-260612-trace-search-filter-cli.md index fafb7dd..83c7b88 100644 --- a/plans/260612-0023-trace-search-filter-cli/reports/reviewer-260612-trace-search-filter-cli.md +++ b/plans/260612-0023-trace-search-filter-cli/reports/reviewer-260612-trace-search-filter-cli.md @@ -25,10 +25,7 @@ None. ## Low Priority -- [plans/260612-0023-trace-search-filter-cli/phase-01-contract-lock.md:40] Phase status says completed, but Todo/Success Criteria boxes remain unchecked. - Fix: Lead/planner can mark completed boxes or leave phase status less final. -- [plans/260612-0023-trace-search-filter-cli/phase-02-tdd-implementation.md:53] Same stale checkbox issue for completed implementation phase. - Fix: Lead/planner can sync plan bookkeeping after review. +None. Earlier phase checkbox drift was resolved before shipping the PR branch. ## Edge Cases Found by Scout @@ -47,7 +44,7 @@ None. ## Recommended Actions 1. No source change required before ship. -2. Optional: sync phase Todo checkboxes before final plan handoff. +2. No source change required before ship. ## Metrics