aws-samples / aws-samples/sample-autonomous-cloud-coding-agents

bga list: unfiltered output groups by status instead of sorting by created_at

Aperta
#51 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub
cli
Lingua principale
TypeScript
Stelle
143
Fork
46
Merge medio
3g 10h
PR unite (30g)
24

Descrizione

## Problem

`bga list` (no filters) shows tasks grouped by status, then sorted by timestamp within each group. Example:

```
FAILED 2026-04-22T04:09:02Z [old]
FAILED 2026-04-22T04:05:07Z [old]
...
COMPLETED 2026-04-29T00:20:07Z [newest task]
...
CANCELLED 2026-04-28T23:49:53Z
```

The newest task is buried behind older FAILED tasks because of lexicographic ordering across the composite sort key: `FAILED > COMPLETED > CANCELLED > ... > SUBMITTED`.

## Root cause

`cdk/src/handlers/list-tasks.ts` queries the `UserStatusIndex` GSI with:

- **KeyCondition**: `user_id = :uid` (partition-only; no sort-key condition)
- **ScanIndexForward: false**

The GSI sort key is `status_created_at` = `{status}#{created_at}`, so DynamoDB sorts lexicographically across the full composite. Without a status-prefix `begins_with()` condition, older rows with higher-lexicographic status values rank above newer rows with lower-lexicographic status values.

## Status-filtered queries are separately broken

`bga list --status COMPLETED` returns "No tasks found." even when many COMPLETED tasks exist. The handler puts `status` in a `FilterExpression` (post-query filter) rather than a KeyCondition `begins_with(status_created_at, "COMPLETED#")`. With the default `--limit 20`, DDB scans the first 20 GSI rows then filters — if those 20 are not COMPLETED, the response is empty despite more matching rows existing further back in the index.

## Options

1. **Add a second GSI `UserCreatedAtIndex`** (PK=`user_id`, SK=`created_at`). Best UX: `bga list` is newest-first regardless of status. Status filtering still uses `UserStatusIndex` via `begins_with(status_created_at, "#")`. Adds one GSI.
2. **Rework `list-tasks.ts` to use `begins_with` key-condition when a status filter is present**, fall back to multi-status fan-out-and-merge when not. No schema change, but the unfiltered `list` still needs work.
3. **Base-table Scan with user filter.** Don't do this at scale.

## Recommendation

Option 1. The existing GSI is fine for "my RUNNING tasks" / "my FAILED tasks" queries; add a parallel GSI for the default newest-first use case.

## Context

The data layer is now consistent. Prior to the `fix(agent): maintain status_created_at on RUNNING/terminal transitions` commit, the Python agent-side writers (`write_running`, `write_terminal`) did not update `status_created_at` on transitions, so the GSI sort key lied about the current status. That is fixed — the GSI now returns correct results when queried with a status prefix. The CLI/handler just doesn't yet use that query pattern.

## Reproduction

On a deployed dev stack with at least one COMPLETED task newer than the oldest FAILED task:

```bash
bga list --limit 10 # newest COMPLETED task is NOT at the top
bga list --status COMPLETED --limit 5 # "No tasks found." despite matching rows existing
```

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

Inizia da cdk/src/handlers/list-tasks.ts e riproduci i due comandi mostrati nell’issue su un dev stack. Traccia il modo in cui viene interrogato UserStatusIndex e confronta le opzioni elencate, in particolare l’approccio consigliato con UserCreatedAtIndex. Il lavoro è completato quando la lista bga non filtrata mostra prima gli elementi più recenti e i risultati filtrati per stato vengono restituiti correttamente.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
aws, typescript
Ambito
backend, cli, databases
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Tranquilla
Chiarezza
Specificata chiaramente
Idoneità per principianti
55/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.