Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
240 changes: 75 additions & 165 deletions BUILD_REPORT.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,198 +2,108 @@

## sprint objective

Implement Sprint 6D by exposing deterministic user-scoped read-only trace review APIs for:

- `GET /v0/traces`
- `GET /v0/traces/{trace_id}`
- `GET /v0/traces/{trace_id}/events`

The sprint stayed limited to explain-why trace reads over existing persisted `traces` and `trace_events` data.
Implement Sprint 6E by replacing the fixture-only `/traces` route with a live explain-why review surface that uses the shipped backend trace review APIs when API configuration is present, while preserving explicit fixture fallback only when live configuration is absent.

## completed work

- introduced stable trace review contracts in `apps/api/src/alicebot_api/contracts.py`
- `TraceReviewSummaryRecord`
- `TraceReviewRecord`
- `TraceReviewListSummary`
- `TraceReviewListResponse`
- `TraceReviewDetailResponse`
- `TraceReviewEventRecord`
- `TraceReviewEventListSummary`
- `TraceReviewEventListResponse`
- `TRACE_REVIEW_LIST_ORDER`
- `TRACE_REVIEW_EVENT_LIST_ORDER`
- added a narrow trace review module in `apps/api/src/alicebot_api/traces.py`
- `list_trace_records()`
- `get_trace_record()`
- `list_trace_event_records()`
- `TraceNotFoundError`
- extended `apps/api/src/alicebot_api/store.py` with read-only trace review queries
- `list_trace_reviews()`
- `get_trace_review_optional()`
- deterministic list SQL with trace-event counts
- deterministic trace-event SQL ordering
- added FastAPI endpoints in `apps/api/src/alicebot_api/main.py`
- extended `apps/web/lib/api.ts` with typed trace review reads for:
- `GET /v0/traces`
- `GET /v0/traces/{trace_id}`
- `GET /v0/traces/{trace_id}/events`
- added unit coverage in `tests/unit/test_traces.py` for
- deterministic list ordering
- stable detail shape
- stable event-list shape
- invisible-trace not-found behavior
- endpoint translation and 404 mapping
- added Postgres-backed integration coverage in `tests/integration/test_traces_api.py` for
- deterministic trace list ordering
- trace detail reads
- ordered trace-event reads
- cross-user isolation
- invisible-trace 404 behavior
- moved `/traces` fixture data into `apps/web/lib/fixtures.ts` and added `getFixtureTrace()` for explicit no-config fallback
- replaced `apps/web/app/traces/page.tsx` with live route wiring that:
- uses live trace list/detail/event reads when API configuration is present
- stays fixture-backed when API configuration is absent
- shows an explicit API-unavailable state when live trace reads fail
- keeps partial live detail bounded when detail or event reads fail
- added `apps/web/app/traces/loading.tsx` route-level loading UI
- updated `apps/web/components/trace-list.tsx` to render:
- live trace summaries
- key metadata
- ordered event review
- empty state
- API-unavailable state
- bounded partial event-unavailable state
- added narrow frontend coverage in:
- `apps/web/lib/api.test.ts`
- `apps/web/components/trace-list.test.tsx`
- route-level `/traces` branching coverage for fixture-backed, live-unavailable, and partial live-event states

## incomplete work

- none inside the sprint’s scoped backend deliverables
- no UI migration from fixture-backed `/traces`
- no trace creation or mutation changes
- no filtering, search, or expanded explainability surface beyond the three read endpoints
- none inside the sprint’s scoped `/traces` UI deliverables
- intentionally not added:
- trace filtering
- trace search
- trace pagination
- trace mutation UI
- backend changes

## files changed

- `apps/api/src/alicebot_api/contracts.py`
- `apps/api/src/alicebot_api/main.py`
- `apps/api/src/alicebot_api/store.py`
- `apps/api/src/alicebot_api/traces.py`
- `tests/unit/test_traces.py`
- `tests/integration/test_traces_api.py`
- `apps/web/app/traces/page.tsx`
- `apps/web/app/traces/loading.tsx`
- `apps/web/components/trace-list.tsx`
- `apps/web/lib/api.ts`
- `apps/web/lib/fixtures.ts`
- `apps/web/lib/api.test.ts`
- `apps/web/components/trace-list.test.tsx`
- `BUILD_REPORT.md`

## exact ordering rules
## route backing mode

- `/traces` is live-API-backed when API configuration is present
- `/traces` is fixture-backed when API configuration is absent
- `/traces` shows an explicit unavailable state when live API configuration is present but trace reads fail
- the route is not mixed in the steady-state implementation

- trace list reads use `created_at DESC, id DESC`
- trace-event reads use `sequence_no ASC, id ASC`
## backend endpoints consumed

- `GET /v0/traces`
- `GET /v0/traces/{trace_id}`
- `GET /v0/traces/{trace_id}/events`

## tests run

- `./.venv/bin/python -m pytest tests/unit/test_traces.py`
- `npm run lint`
- PASS
- `5` tests passed
- `./.venv/bin/python -m pytest tests/integration/test_traces_api.py`
- initial sandboxed run could not reach local Postgres on `localhost:5432`
- rerun as part of the full integration suite below passed
- `./.venv/bin/python -m pytest tests/unit`
- `npm test`
- PASS
- `451` tests passed
- `./.venv/bin/python -m pytest tests/integration`
- `3` test files passed
- `13` tests passed
- `npm run build`
- PASS
- `143` tests passed

## unit and integration test results

- unit result: PASS
- trace review module coverage and endpoint translation coverage passed
- integration result: PASS
- live Postgres-backed trace review list/detail/event and isolation coverage passed

## example trace list response

```json
{
"items": [
{
"id": "00000000-0000-4000-8000-000000000002",
"thread_id": "11111111-1111-4111-8111-111111111111",
"kind": "tool.proxy.execute",
"compiler_version": "response_generation_v0",
"status": "completed",
"created_at": "2026-03-17T09:00:00+00:00",
"trace_event_count": 2
},
{
"id": "00000000-0000-4000-8000-000000000001",
"thread_id": "11111111-1111-4111-8111-111111111111",
"kind": "context.compile",
"compiler_version": "continuity_v0",
"status": "completed",
"created_at": "2026-03-17T09:00:00+00:00",
"trace_event_count": 1
}
],
"summary": {
"total_count": 2,
"order": ["created_at_desc", "id_desc"]
}
}
```

## example trace detail response

```json
{
"trace": {
"id": "00000000-0000-4000-8000-000000000002",
"thread_id": "11111111-1111-4111-8111-111111111111",
"kind": "tool.proxy.execute",
"compiler_version": "response_generation_v0",
"status": "completed",
"limits": {
"max_sessions": 1,
"max_events": 2
},
"created_at": "2026-03-17T09:00:00+00:00",
"trace_event_count": 2
}
}
```

## example trace-event list response

```json
{
"items": [
{
"id": "10000000-0000-4000-8000-000000000002",
"trace_id": "00000000-0000-4000-8000-000000000002",
"sequence_no": 1,
"kind": "tool.proxy.execute.request",
"payload": {
"approval_id": "approval-2"
},
"created_at": "2026-03-17T09:00:00+00:00"
},
{
"id": "10000000-0000-4000-8000-000000000001",
"trace_id": "00000000-0000-4000-8000-000000000002",
"sequence_no": 2,
"kind": "tool.proxy.execute.summary",
"payload": {
"approval_id": "approval-2"
},
"created_at": "2026-03-17T09:00:00+00:00"
}
],
"summary": {
"trace_id": "00000000-0000-4000-8000-000000000002",
"total_count": 2,
"order": ["sequence_no_asc", "id_asc"]
}
}
```

## exact commands run

- `cd /Users/samirusani/Desktop/Codex/AliceBot/apps/web && npm run lint`
- `cd /Users/samirusani/Desktop/Codex/AliceBot/apps/web && npm test`
- `cd /Users/samirusani/Desktop/Codex/AliceBot/apps/web && npm run build`

## lint, test, and build results

- lint result: PASS
- test result: PASS
- build result: PASS

## desktop and mobile visual verification notes

- no browser-based visual QA pass was executed in this turn
- desktop note: code inspection indicates the existing split review layout remains in place for `/traces`, with summary, metadata, and ordered events kept in bounded cards
- mobile note: code inspection indicates the trace route still collapses to one column below the shared shell breakpoints in `apps/web/app/globals.css`

## blockers/issues

- no remaining product-scope blockers
- one execution-time environment issue occurred during verification
- sandboxed integration setup could not connect to local Postgres on `localhost:5432`
- rerunning the required integration suite with local database access resolved verification
- no implementation blockers remain inside sprint scope
- no backend contract changes were required

## recommended next step

Hook the existing `/traces` web surface off these live endpoints in a separate sprint, while preserving the same narrow persisted-data-only contract.
Run a browser-based QA pass against a live configured backend with real trace records to validate the wording and density of the generated live summaries and event facts.

## intentionally deferred after this sprint

- any UI changes
- any trace mutation endpoints
- any new trace production behavior
- any connector, Gmail, Calendar, approval-flow, or execution-scope expansion
- any search, filtering, pagination, or explainability enrichment beyond persisted trace and trace-event reads
- any Gmail, Calendar, auth, runner, or broader task workflow scope
- any redesign outside the existing `/traces` shell
- any trace enrichment beyond the shipped list/detail/event endpoints
- any search, filtering, pagination, or mutation controls
49 changes: 24 additions & 25 deletions REVIEW_REPORT.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,49 +6,48 @@ PASS

## criteria met

- `GET /v0/traces`, `GET /v0/traces/{trace_id}`, and `GET /v0/traces/{trace_id}/events` are implemented in `apps/api/src/alicebot_api/main.py`.
- The sprint stayed limited to read-only trace review over existing persisted `traces` and `trace_events` data.
- Stable trace review contracts were added in `apps/api/src/alicebot_api/contracts.py`.
- The review seam in `apps/api/src/alicebot_api/traces.py` returns deterministic list, detail, and event payloads.
- Deterministic ordering is explicit and test-backed:
- trace list: `created_at DESC, id DESC`
- trace events: `sequence_no ASC, id ASC`
- User isolation is preserved through user-scoped connections plus existing row-level security behavior, and invisible traces return `404`.
- Unit coverage was added for ordering, response shape, endpoint mapping, and invisible-trace handling.
- Integration coverage was added for list/detail/event reads, cross-user isolation, and invisible-trace `404` behavior.
- Acceptance verification passed:
- `./.venv/bin/python -m pytest tests/unit` -> `451 passed`
- `./.venv/bin/python -m pytest tests/integration` -> `143 passed`
- The sprint stayed a UI sprint and did not widen backend scope.
- `/traces` now uses the shipped trace review APIs when API configuration is present via the shared helper reads in [apps/web/lib/api.ts](/Users/samirusani/Desktop/Codex/AliceBot/apps/web/lib/api.ts) and the route wiring in [apps/web/app/traces/page.tsx](/Users/samirusani/Desktop/Codex/AliceBot/apps/web/app/traces/page.tsx).
- `/traces` no longer depends exclusively on local fixture data. When API configuration is absent, the route falls back explicitly to fixture data from [apps/web/lib/fixtures.ts](/Users/samirusani/Desktop/Codex/AliceBot/apps/web/lib/fixtures.ts).
- Loading, empty, unavailable, and bounded partial-detail/event states are implemented across [apps/web/app/traces/loading.tsx](/Users/samirusani/Desktop/Codex/AliceBot/apps/web/app/traces/loading.tsx), [apps/web/app/traces/page.tsx](/Users/samirusani/Desktop/Codex/AliceBot/apps/web/app/traces/page.tsx), and [apps/web/components/trace-list.tsx](/Users/samirusani/Desktop/Codex/AliceBot/apps/web/components/trace-list.tsx).
- The trace UI keeps the intended bounded visual hierarchy: summary first, key metadata second, ordered events third.
- The implementation stays within the Sprint 6E in-scope files and does not add Gmail, Calendar, auth, runner, filtering, search, pagination, mutation, or backend changes.
- `BUILD_REPORT.md` is aligned to Sprint 6E and documents the route mode, shipped endpoints, exact commands, verification results, visual notes, and deferred scope.
- Frontend coverage was added in:
- [apps/web/lib/api.test.ts](/Users/samirusani/Desktop/Codex/AliceBot/apps/web/lib/api.test.ts)
- [apps/web/components/trace-list.test.tsx](/Users/samirusani/Desktop/Codex/AliceBot/apps/web/components/trace-list.test.tsx)
- Verification passed in `apps/web`:
- `npm run lint`
- `npm test`
- `npm run build`
- current totals: `3` test files, `13` tests
- `next build` did not leave tracked churn in `apps/web/tsconfig.json` or `apps/web/next-env.d.ts`.

## criteria missed

- none
- None.

## quality issues

- none blocking
- No sloppy scope expansion was found. The diff is confined to the intended API/store/contracts/test surface plus `BUILD_REPORT.md`.
- No blocking quality issues found in the current Sprint 6E implementation.

## regression risks

- Low risk overall. The new seam is narrow and read-only.
- The main ongoing dependency is correct use of `user_connection()` so row-level security remains active for trace visibility. Current unit and integration coverage exercises that path.
- Residual product risk is limited to real-data wording and density because the visual verification notes are code-inspection notes rather than a browser QA pass. This does not block Sprint 6E acceptance but is still worth validating against a live configured backend.

## docs issues

- none blocking
- `BUILD_REPORT.md` matches the sprint packet requirements, including contracts, ordering rules, commands run, example responses, and deferred scope.
- No blocking docs issues remain for Sprint 6E.

## should anything be added to RULES.md?

- no
- No.

## should anything update ARCHITECTURE.md?

- no required update for sprint acceptance
- Optional future update: document the new read-only trace review API surface when the `/traces` UI switches from fixtures to live backend reads.
- No.

## recommended next action

- Accept the sprint.
- In a follow-up sprint, replace the fixture-backed `/traces` UI with these live endpoints without widening the backend contract.
- Sprint 6E can be considered review-passed.
- Next follow-up should be a browser-based QA pass against a live configured backend with real trace records to validate the operator-facing wording and event density.
51 changes: 51 additions & 0 deletions apps/web/app/traces/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { PageHeader } from "../../components/page-header";
import { SectionCard } from "../../components/section-card";
import { StatusBadge } from "../../components/status-badge";

export default function Loading() {
return (
<div className="page-stack" aria-busy="true">
<PageHeader
eyebrow="Explainability"
title="Trace and explain-why review"
description="Loading live trace summaries, the selected trace detail, and ordered event review."
meta={
<div className="header-meta">
<span className="subtle-chip">Loading route state</span>
</div>
}
/>

<div className="split-layout">
<SectionCard
eyebrow="Trace list"
title="Loading traces"
description="The explain-why list is being read from the current backing source."
className="loading-card"
>
<div className="detail-stack">
<StatusBadge status="loading" label="Loading" />
<div className="loading-placeholder loading-placeholder--card" />
<div className="loading-placeholder loading-placeholder--card" />
<div className="loading-placeholder loading-placeholder--card" />
</div>
</SectionCard>

<SectionCard
eyebrow="Trace detail"
title="Loading selected trace"
description="The detail panel waits for summary, metadata, and ordered event review to resolve."
className="loading-card"
>
<div className="detail-stack">
<StatusBadge status="loading" label="Loading" />
<div className="loading-placeholder loading-placeholder--line loading-placeholder--wide" />
<div className="loading-placeholder loading-placeholder--line" />
<div className="loading-placeholder loading-placeholder--line" />
<div className="loading-placeholder loading-placeholder--card" />
</div>
</SectionCard>
</div>
</div>
);
}
Loading