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
22 changes: 13 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Paragent

**Record a browser agent once. Replay it deterministically, without the model. Repair it when the page changes.**
**Record a browser task once. Replay it deterministically, without the model. Repair it when the page changes.**

[![CI](https://github.com/DevToolie/Paragent/actions/workflows/ci.yml/badge.svg)](https://github.com/DevToolie/Paragent/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](./LICENSE)
Expand All @@ -11,7 +11,7 @@ a dashboard, and it re-reads the DOM, re-plans, and re-infers every click — bu
tokens and wall-clock to rediscover a path it already found yesterday, with a fresh
chance of getting it wrong.

Paragent takes the model out of the second run. It records an agent's **successful** trajectory
Paragent takes the model out of the second run. It records a developer's **successful** trajectory
through a web UI, compiles it into a deterministic replayable script with a
**post-condition assertion on every step**, and replays it with no model in the loop.
When an assertion fails — a button moved, a label changed — the model is called back
Expand All @@ -25,9 +25,12 @@ in to repair just that step, and the repaired script is what runs next time.
<sub>
Real run against the bundled fixture, driven by an illustrative script rather than the
documented <code>npm run</code> commands. The <b>record</b> and <b>replay</b> beats are what
the repo ships. The <b>repair</b> beat is not: Paragent ships
<code>StubRepairModelClient</code>, which proposes nothing, so repair needs a model client
that is <a href="https://github.com/DevToolie/Paragent/issues/27">not yet wired (#27)</a>.
the repo ships — <b>record</b> today means a developer typing the trajectory by hand
(<code>src/recorder/cli.ts</code>), not an agent proposing it; that on-ramp is scoped but
<a href="https://github.com/DevToolie/Paragent/issues/127">not yet built (#127)</a>. The
<b>repair</b> beat is not: Paragent ships <code>StubRepairModelClient</code>, which proposes
nothing, so repair needs a model client that is
<a href="https://github.com/DevToolie/Paragent/issues/27">not yet wired (#27)</a>.
</sub>
</p>

Expand All @@ -37,7 +40,7 @@ in to repair just that step, and the repaired script is what runs next time.

| Stage | What happens | Model involved? |
| --- | --- | --- |
| **Record** | An agent completes the task once. Every action and its post-condition is captured as a trajectory. | Yes |
| **Record** | A developer completes the task once, by hand. Every action and its post-condition is captured as a trajectory. | No |
| **Compile** | The trajectory becomes a bundle of cache rows — one per step, each with its assertion. Typed values become parameter slots. | No |
| **Replay** | Steps execute in order. Each asserts its post-condition before the next runs. | No |
| **Repair** | On assertion failure, the model is called to fix that step; the updated script is written back. | Only on failure |
Expand Down Expand Up @@ -100,9 +103,10 @@ persisted to disk. Full command list: [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md)
## Where this fits

Most browser-agent frameworks optimise the *first* run — better planning, better DOM
grounding, better recovery. Paragent assumes you already have one that works and
optimises every run after it. It composes with them rather than replacing them: record
whatever agent you already trust, then replay its output.
grounding, better recovery. Paragent is meant to compose with them rather than replace them:
record whatever agent you already trust, then replay its output. That's the target, not what
ships today — the recorder captures a developer's hand-typed actions, not an arbitrary agent's,
until [#127](https://github.com/DevToolie/Paragent/issues/127) lands.

It's aimed at work that is **repeated**, in a **browser**, where **no clean API
exists** — the cases where you'd write a script if the UI would just hold still.
Expand Down
7 changes: 4 additions & 3 deletions docs/INTEGRITY-AUDIT.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ doc_type: brief
status: draft
owner: D2
created: 2026-07-25
updated: 2026-07-29
updated: 2026-08-14
confidence: HIGH
supersedes: null
sources_verified: true
Expand All @@ -18,12 +18,12 @@ D2 consolidator pass (2026-07-25), **after** C4 + C5 merges. **Surfaces conflict

| Category | Count |
| --- | --- |
| A. Unsourced / under-sourced claims | 10 |
| A. Unsourced / under-sourced claims | 11 |
| B. Placeholder / unmeasured metrics | 8 |
| C. LOW-confidence findings load-bearing in a decision | 6 |
| D. Document disagreements (5 resolved) | 8 |
| E. Documentation-standard violations (fixed or flagged) | 12 |
| **Total** | **44** |
| **Total** | **45** |

---

Expand All @@ -41,6 +41,7 @@ D2 consolidator pass (2026-07-25), **after** C4 + C5 merges. **Surfaces conflict
| A-08 | Proof-points F10 | Solo self-kill as diligence asset | Interpretation ASSUMED |
| A-09 | Pitch Ask | Financing ask | Founder TBD |
| A-10 | Any spoken gate % outside measured artifact | Performance | Must cite Track-1 output; none yet |
| A-11 | (was) Root README tagline (L3), hero (L14), "How it works" table, "Where this fits" (L105-108) | "Record a browser agent once" / "records an agent's successful trajectory" / "record whatever agent you already trust" | **Resolved** — recorder is human-driven (`agent_model: "human"`), not agent-driven; all four spots now say so (tagline drops "agent," hero says "developer's," table says "A developer... by hand" / "No," positioning paragraph is marked target-not-shipped) with a #127 annotation, and the locator-choice consequence is recorded in `docs/gate/testbed.md` / `recorder.md` |

---

Expand Down
13 changes: 12 additions & 1 deletion docs/gate/recorder.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ doc_type: runbook
status: draft
owner: B2
created: 2026-07-25
updated: 2026-08-12
updated: 2026-08-14
confidence: MED
supersedes: null
sources_verified: true
Expand Down Expand Up @@ -232,6 +232,17 @@ it back. Version tolerance belongs in the preamble and nowhere else. Running the
against a later version is therefore expected to exit **4** (`STEP NOT RECORDABLE`) naming the
step — and nothing is written, because a hand-patched trajectory invalidates the gate.

**These locators are also hand-picked, and that is a second, separate asterisk on whatever
survival number the matrix eventually reports.** The 12 selectors above were chosen by a
developer reading the 9.5.21 DOM — picking `data-testid`/`aria-label` where one exists, falling
back to structure only where neither does (step 7's note above) — not proposed by an agent acting
at runtime with no such look-ahead. `provenance.agent_model` is `"human"` on this trajectory for
exactly that reason. See
[`docs/gate/testbed.md` § Honesty second](./testbed.md#honesty-second--hand-picked-locators-not-agent-picked)
for why that makes the gate number an upper bound, not an estimate, and
[issue #127](https://github.com/DevToolie/Paragent/issues/127) for the unbuilt agent-driven
on-ramp that would close it.

### Two recordings, diffed

Recorded three times, each on a **freshly created container** (`--down` then up, so the Grafana
Expand Down
31 changes: 30 additions & 1 deletion docs/gate/testbed.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ doc_type: spec
status: draft
owner: B1
created: 2026-07-25
updated: 2026-07-28
updated: 2026-08-14
confidence: HIGH
supersedes: null
sources_verified: true
Expand All @@ -29,6 +29,35 @@ Do not present matrix results as “we measured real production churn.” Presen
them as “we measured survival across known OSS console redesigns under
accelerated upgrades.” Gate numbers derived here inherit this limitation.

## Honesty second — hand-picked locators, not agent-picked

A second asterisk sits alongside the one above, and it attaches to the *recorded trajectory*
rather than to the matrix. `src/recorder/cli.ts` is a hand-written script: a developer reads the
live DOM and types literal Playwright locators, one per step (`RECORDED_AGAINST = "9.5.21"`,
[`docs/gate/recorder.md`](./recorder.md)). `contracts/trajectory.schema.json`'s own
`provenance.agent_model` field anticipates the distinction — "Model id used for the driving
agent, or 'human' for manual capture" — and every trajectory this repo has recorded carries
`"agent_model": "human"` (`contracts/examples/trajectory.example.json`).

That matters because a developer and an agent do not pick locators the same way. A developer
reading the DOM can see which attributes are stable — `data-testid`, `aria-label`, structural
position — before typing a single selector, and picks accordingly. An agent recording the same
task at runtime sees only what is rendered in the moment; it has no equivalent look-ahead. A gate
that measures whether *hand-picked* locators survive a version bump is therefore measuring a
better-than-real case: the survival rate M2–M4 report is an upper bound on what an agent-recorded
trajectory would achieve, not an estimate of it. This is not a defect in the harness — it is a
property of who is recording, and it holds regardless of how the version-bump-churn proxy above
resolves.

There is no fix in this repo yet. An agent-driven recorder is scoped as
[issue #127](https://github.com/DevToolie/Paragent/issues/127) and is not built; the checklist
item that would close this asterisk is "an agent-recorded number exists to compare against the
hand-recorded one." Until then, every gate number this harness produces carries **both**
asterisks — proxy churn (above) and hand-picked locators (here) — and neither should be dropped
when the number is quoted. See also [`docs/gate/recorder.md`](./recorder.md) for where the
locators in the committed trajectory were chosen and why they are deliberately not
version-tolerant.

## Choice

See [ADR-0003](../decisions/ADR-0003-testbed-grafana-oss.md). Target:
Expand Down
Loading