Skip to content

Trajectories are hand-written, not agent-recorded — run 1 costs a developer-day and zero tokens #127

Description

@myselfsiddharth

Context

The README's first sentence is:

Paragent ... records an agent's successful trajectory through a web UI, compiles it into a deterministic replayable script ...

There is no agent. src/recorder/cli.ts is a hand-written script: the trajectory is produced by a developer typing literal Playwright calls, one per step, with hardcoded selectors, hardcoded intents, and a hardcoded TASK_KEY. Adding a task means writing more of that file. Verified by reading it end to end — the fixture flow and the live Grafana flow are both spelled out as explicit recorder.navigate(...) / recorder.click(...) sequences.

Verified separately: no model client exists anywhere in the repo. grep -riE "anthropic|openai|claude|gpt-" across src/, experiments/, and package.json returns nothing, and the only dependency is playwright. Repair is StubRepairModelClient (#27); the fresh baseline is unmeasured (#39). Neither of those is this issue — this is the third hole and it has no issue.

Why this matters

The token-efficiency claim is a ratio: expensive first run, cheap subsequent runs. Today the numerator is produced by a human writing code, which means:

  • Run 1 costs zero tokens and a developer-day. There were never tokens to save. The amortization curve's first point is not "what it cost a model to figure this out" but "what it cost a person to write it down" — and those are not interchangeable, either in the demo or in the business case.
  • The system does not scale to "cache all browser tasks." It caches the tasks someone hand-coded. Every new task is a pull request against src/recorder/cli.ts. There is no on-ramp.
  • The recorded trajectory is unrepresentative of the thing being tested. A developer picks stable, well-chosen selectors while reading the DOM. An agent picks what it can see at runtime. If the gate measures whether hand-picked locators survive churn, it is measuring a better-than-real case, and the §9 number inherits that asterisk — alongside the version-bump-as-churn-proxy asterisk already recorded in docs/gate/testbed.md.

That third point is the one that affects the gate's validity, and it should be stated in the gate memo whether or not this issue is built.

What to build

An agent-driven path from a task description to a trajectory.schema.json document — the on-ramp the pipeline currently lacks.

  1. A driver that lets a model act. A model receives a goal and the same page context the repair loop is authorized to see (the context-budget decision blocks this — see Repair sees only landmark role names — decide the context budget before #27 spends tokens against it #125), proposes one action at a time, and the recorder captures each successful action into the trajectory it already knows how to write. The recorder's capture format does not change; what changes is who decides the next action.
  2. Reuse the existing guarantees, do not re-implement them. assertNoLiteralSecrets runs on the serialized trajectory before write (src/recorder/session.ts:243) and must run identically here. Parameterization stays: every value becomes a slot, password is secret_ref, never a literal (invariant 3, docs/architecture.md).
  3. Measure what run 1 costs. This is the natural home for the first point of the amortization curve, and it overlaps Measure the fresh-reasoning baseline cost (the §9 denominator) #39's fresh-baseline runner substantially — Measure the fresh-reasoning baseline cost (the §9 denominator) #39 measures a model doing the task without producing a reusable artifact; this measures a model doing the task and producing one. Decide whether they are one component or two before building either. If they are two, the token-accounting convention must be identical or the ratio is meaningless.
  4. Only successful trajectories get recorded. A trajectory is the record of a run that worked. Failed exploration is cost, not artifact — but its tokens still count toward run 1, and dropping them would understate the first point.

Constraints

  • Same privacy posture as the human recorder, mechanically enforced by the same code. A model-driven session is not a reason to relax redact.ts.
  • No estimated token counts. If the driver's cost is not measured, it is no_data (CONTRIBUTING rule 1).
  • Do not promote experiments/gate-v1/ into this path — the harness is throwaway and src/ must not import it (invariant 5).
  • This does not block the gate. M2–M4 can complete on the hand-recorded task; what must not happen is the gate memo claiming an agent-recorded number. If the memo ships before this lands, it says so plainly.

How to test

npm run test              # driver proposes → recorder captures → trajectory validates against
                          # contracts/trajectory.schema.json; secret refusal still fires
npm run validate:contracts
npm run test:integration  # agent-recorded trajectory → compile → replay, end to end
npm run ci

Before you open the PR

Found during an architecture review of the token-efficiency claim: the system that exists to save tokens currently has no component that spends any. Related: #27 (repair client), #39 (fresh baseline), and #125 (both need the same context-budget decision).

Metadata

Metadata

Labels

area: recorderTouches recorderenhancementNew feature or requestproposalDesign / governance proposalsize/L<= 600 changed linestrack-1Technical gate / churn harness

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions