diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 110ab3c..1ee8361 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -232,8 +232,8 @@ The checklist, in order: MIT. By contributing you agree your contribution is licensed on the same terms. You keep copyright over your own work — there is no CLA and no copyright assignment. The notice in -[LICENSE](LICENSE) reads *"Riko, Vicko, Faiq and the Traces contributors"* precisely so that it stays -accurate as people join, without anyone having to remember to edit it. +[LICENSE](LICENSE) reads *"the Traces contributors"* precisely so that it stays accurate as people +join, without anyone having to remember to edit it. Git history is the authoritative record of who contributed what. We don't keep a separate `AUTHORS` file, because those go stale and then quietly undercredit exactly the people they were meant to diff --git a/LICENSE b/LICENSE index caee404..78983f1 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2026 Riko, Vicko, Faiq and the Traces contributors +Copyright (c) 2026 the Traces contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 8151714..a5421cf 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,29 @@ +
+ # Traces **A session replay engine that an AI agent can interrogate — through WebMCP.** +[![Live demo](https://img.shields.io/badge/demo-traces.ribdsp.com-111827?style=flat-square)](https://traces.ribdsp.com) +[![Video](https://img.shields.io/badge/video-under_3_min-b91c1c?style=flat-square)](https://youtu.be/KyME2kG7_PI) +[![WebMCP tools](https://img.shields.io/badge/WebMCP-17_tools-374151?style=flat-square)](docs/tools.md) +[![Tests](https://img.shields.io/badge/tests-309_passing-374151?style=flat-square)](CONTRIBUTING.md) +[![Licence](https://img.shields.io/badge/licence-MIT-374151?style=flat-square)](LICENSE) + +
+ Traces turns a recorded browser session into something an agent can *ask questions of*: not "summarize this video", but "find the exact millisecond the pay button became disabled, and tell me what happened just before it." -Built for [The WebMCP Challenge](https://webmcp.devpost.com/) by Riko, Vicko, and Faiq. +Built for [The WebMCP Challenge](https://webmcp.devpost.com/). -- **Live demo:** -- **Video (3 min):** -- **Tool reference:** [docs/tools.md](docs/tools.md) +![The agent stops, says it cannot see the screen, and asks a human to look at a specific moment](docs/images/ask-human-visual.png) -> **Status: work in progress.** The design is settled and documented; the implementation is being -> built during the challenge window. Sections marked are placeholders, and every -> measured number in these docs is filled in from a real run rather than estimated. If a claim here -> isn't yet backed by code, [Status and limitations](#status-and-limitations) says so explicitly. +- **Live demo:** [traces.ribdsp.com](https://traces.ribdsp.com) +- **Video:** [youtu.be/KyME2kG7_PI](https://youtu.be/KyME2kG7_PI) +- **Tool reference:** [docs/tools.md](docs/tools.md) +- **Architecture:** [docs/architecture.md](docs/architecture.md) · **Threat model:** [docs/threat-model.md](docs/threat-model.md) --- @@ -90,6 +98,28 @@ click that only a human could make. --- +## What it looks like + +Three moments from one investigation. Every number in these screenshots came out of a real run +against a synthetic recording in [`bugbait/`](bugbait) — none of it is mocked up. + +**The agent narrows a 45-second recording to one millisecond, and the activity feed records who did +it.** Seventeen probes, then the human's playhead is moved to the answer. + +![Activity feed showing the agent bisecting to 28.049 seconds in 17 probes, then seeking there](docs/images/bisect-activity.png) + +**Ranked explanations, each one citing evidence you can click.** A card with no evidence behind it is +rejected by the page rather than rendered. + +![Four ranked hypothesis cards, each citing timestamped evidence, with promote and reject buttons](docs/images/ranked-hypotheses.png) + +**A bug report whose reproduction steps are checked against the event stream.** Nine steps, nine +verified, and the human still has to approve it. + +![A drafted bug report with nine reproduction steps, each marked verified against recorded events](docs/images/report-draft.png) + +--- + ## Why this needs WebMCP WebMCP is the [W3C draft](https://github.com/webmachinelearning/webmcp) that lets a page expose tools @@ -467,13 +497,13 @@ Stated plainly, because a README that oversells is worse than one that's short. - No authentication, no multi-tenancy, no rate limiting. This is a local-first tool. - Recordings must be rrweb format. There's no importer for LogRocket or FullStory exports. +**Left as a stub:** `registerDynamicTool` (`traces/src/lib/webmcp/register-tools.ts:133`) throws, and +nothing calls it — promoting a hypothesis does not mint an eighteenth tool. It's the one piece of the +design that didn't get built. + **Not attempted:** automated fixes, integration with issue trackers, replay of network responses, mobile-native sessions. - - --- ## Contributing @@ -484,7 +514,7 @@ repository**. ## Licence -[MIT](LICENSE) — © 2026 Riko, Vicko, Faiq and the Traces contributors. +[MIT](LICENSE) — © 2026 the Traces contributors. The collective notice is deliberate: everyone who contributes keeps copyright over their own work, and the licence covers all of it on the same terms. Git history is the authoritative list of who diff --git a/docs/images/ask-human-visual.png b/docs/images/ask-human-visual.png new file mode 100644 index 0000000..4f19325 Binary files /dev/null and b/docs/images/ask-human-visual.png differ diff --git a/docs/images/bisect-activity.png b/docs/images/bisect-activity.png new file mode 100644 index 0000000..f4dc571 Binary files /dev/null and b/docs/images/bisect-activity.png differ diff --git a/docs/images/ranked-hypotheses.png b/docs/images/ranked-hypotheses.png new file mode 100644 index 0000000..f3f69ec Binary files /dev/null and b/docs/images/ranked-hypotheses.png differ diff --git a/docs/images/report-draft.png b/docs/images/report-draft.png new file mode 100644 index 0000000..1bf60bc Binary files /dev/null and b/docs/images/report-draft.png differ diff --git a/traces/src/lib/dom/compress-dom.test.ts b/traces/src/lib/dom/compress-dom.test.ts index e6cf6e6..fd84af3 100644 --- a/traces/src/lib/dom/compress-dom.test.ts +++ b/traces/src/lib/dom/compress-dom.test.ts @@ -15,7 +15,7 @@ function buildFormFixture(): Element {

Shipping address

- + diff --git a/traces/src/lib/webmcp/tools/tool-support.test.ts b/traces/src/lib/webmcp/tools/tool-support.test.ts index f1e0121..d6a462f 100644 --- a/traces/src/lib/webmcp/tools/tool-support.test.ts +++ b/traces/src/lib/webmcp/tools/tool-support.test.ts @@ -4,7 +4,7 @@ import { HYPOTHESES_MAX, normaliseConfidences, validateHypotheses } from './prop import { capList, capText, clampToRecording } from './tool-support' /** - * The validators and budgets Vicko's tools are built on, tested away from the store and the gate. + * The validators and budgets the blocking tools are built on, tested away from the store and the gate. * * These are the parts where a bug is silent rather than loud. A confidence set that does not sum to 1 * still renders — as bars that all look near-certain. A choice one character too long still renders — as diff --git a/traces/src/types/domain.ts b/traces/src/types/domain.ts index 6cd778b..36fd8bb 100644 --- a/traces/src/types/domain.ts +++ b/traces/src/types/domain.ts @@ -1,12 +1,12 @@ /** * The frozen interface contract. * - * Everything in this file was agreed on Day 1 and is what lets three people work in parallel: + * Everything in this file was agreed on Day 1 and is what lets several people work in parallel: * `lib/` produces these shapes, `lib/webmcp/` serialises them, `components/` renders them. Nobody * has to read anybody else's implementation. * - * Owner: Riko. If you need a new type, ask in the group rather than editing — this is the one file - * all three of us touch, so it's the one file where a silent change costs someone an afternoon. + * If you need a new type, raise it rather than editing — this is the one file every area touches, + * so it's the one file where a silent change costs someone an afternoon. * * Every JSON key here is camelCase, because these shapes go out over the wire to a model verbatim. */ @@ -337,7 +337,7 @@ export type Gate = { // --------------------------------------------------------------------------- /** - * The single state store. Owner: Vicko. + * The single state store. * * Read by components, written only through actions, and every action carries `author`. * Actions return new objects — per-contribution undo needs the previous state intact.