Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
bef9d18
Record Deno background work, add behavior-diff tracing agent
evlawler Sep 24, 2026
1eab09b
CI: install deno in node job so Deno e2e tests run on every PR
Claude Sep 24, 2026
3d00c68
acceptance(fullstack): expectations for supabase edge-functions app +…
evlawler Sep 24, 2026
2a7da6f
acceptance: bring in the bulletproof-react and supabase-restful-tasks…
evlawler Sep 24, 2026
a32a126
Retire the PetClinicGo-backed e2e test; point the docs at the OSS ful…
evlawler Sep 24, 2026
10c88df
acceptance(fullstack): one-command React + Deno e2e on supabase's edg…
evlawler Sep 24, 2026
7ff389f
CI: run every test on every PR, each suite as its own job
evlawler Sep 24, 2026
6402f0d
Record each request in its own async context; mark overlapping intera…
evlawler Sep 24, 2026
6c8680c
Capture values without running app code (observer effect)
evlawler Sep 24, 2026
32157ad
Inject the interaction recorder as a URL the browser can load
evlawler Sep 24, 2026
753a208
Record and stamp XMLHttpRequest traffic (axios apps)
evlawler Sep 24, 2026
49fee5c
Make the recorder package installable and importable by another app
evlawler Sep 24, 2026
4893004
Emit valid AppMap: required fields, 100-char values, one call tree
evlawler Sep 24, 2026
78af23c
acceptance(fullstack): log step failures in detail; keep the parallel…
evlawler Sep 24, 2026
1315646
Redact credentials from recorded values, headers and query parameters
evlawler Sep 24, 2026
971f16b
Keep open Deno recordings when the process dies
evlawler Sep 24, 2026
0ad3121
Record thrown plain objects by class and message
evlawler Sep 24, 2026
cfcffce
Instrument React.useCallback / React.useMemo callbacks
evlawler Sep 24, 2026
d4be568
Record the anonymous Deno.serve handler
evlawler Sep 24, 2026
84bae82
appmap-trace: trace standalone request maps in their own lane
evlawler Sep 24, 2026
d77f15a
acceptance(fullstack): fix the sign-up race that failed S4 on Actions…
evlawler Sep 24, 2026
e7ea4e4
acceptance(fullstack): evidence and results from a fresh-clone CI=tru…
evlawler Sep 24, 2026
4ffff9f
Merge fix/recorder-worst-bugs into integration/pr1
evlawler Sep 24, 2026
9a7389c
Never break a cross-origin app: stamp traceparent only where it is al…
evlawler Sep 24, 2026
7225ea2
Vite plugin: parse JSX in .js files; never fail a request over a pars…
evlawler Sep 24, 2026
aca9d44
Vite plugin: globs in include/exclude; keep test files out by default
evlawler Sep 24, 2026
31a8918
appmap-link: draw the frontend handler and the backend's outgoing calls
evlawler Sep 24, 2026
0fdc935
Interaction recorder: record the page load in its own window
evlawler Sep 24, 2026
c02e032
acceptance(restful-tasks): compare URLs as url + message (AppMap spec)
evlawler Sep 24, 2026
8227fac
appmap-trace: pair same-named interactions with their own baselines
evlawler Sep 24, 2026
ad26266
acceptance(restful-tasks): allow the recorded Deno.serve handler as t…
evlawler Sep 24, 2026
5b5d581
acceptance(restful-tasks): identify the supabase client parameter by …
evlawler Sep 24, 2026
21900af
acceptance(restful-tasks): I counts only other requests' events as leaks
evlawler Sep 24, 2026
09244e1
acceptance(restful-tasks): W4 requires two separate recordings, no cr…
evlawler Sep 24, 2026
081f893
acceptance(restful-tasks): H reads the query from appmap-trace; the l…
evlawler Sep 24, 2026
2cc967c
acceptance: build the recorder before installing it into the app
evlawler Sep 24, 2026
b9ec2bd
acceptance(bulletproof-react): documented plugin import; list the API…
evlawler Sep 24, 2026
481a510
acceptance(fullstack): compare URLs as url + message (AppMap spec)
evlawler Sep 24, 2026
3bb6a22
acceptance(fullstack): a rejected fetch is recorded as unanswered (Ap…
evlawler Sep 24, 2026
876dc21
acceptance(fullstack): zero-touch must not stamp the cross-origin cal…
evlawler Sep 24, 2026
d097d29
acceptance(fullstack): H requires the query change in the trace diff …
evlawler Sep 24, 2026
f652594
Record a plain object's fields as parameter properties
evlawler Sep 24, 2026
c658fa2
acceptance(bulletproof-react): compare URLs as url + message (AppMap …
evlawler Sep 24, 2026
0369b02
acceptance(bulletproof-react): a field name may be found in parameter…
evlawler Sep 24, 2026
4e509ac
acceptance(bulletproof-react): record checkAccess's line as "expectat…
evlawler Sep 24, 2026
1c623ba
acceptance(bulletproof-react): normalize the mock backend's random id…
evlawler Sep 24, 2026
f7c7411
acceptance(bulletproof-react): H requires the query change in the tra…
evlawler Sep 24, 2026
a619051
acceptance(bulletproof-react): report whether B5's merged window is m…
evlawler Sep 24, 2026
0ddada4
acceptance: shellcheck-clean run.sh and infra scripts
evlawler Sep 24, 2026
6795ba3
acceptance: RESULTS for integration/pr1; stop saying the suites fail …
evlawler Sep 24, 2026
479faeb
acceptance: RESULTS numbers from the local CI run; explain L1 in the …
evlawler Sep 24, 2026
4965306
acceptance(bulletproof-react): H ignores the mock backend's random ids
evlawler Sep 25, 2026
7877d44
CI: hold each acceptance suite to a ledger of its verdicts
evlawler Sep 25, 2026
364f453
acceptance(bulletproof-react): RESULTS for H and the verdict ledger
evlawler Sep 25, 2026
279c2e0
acceptance: stop committing generated evidence
evlawler Sep 25, 2026
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
187 changes: 187 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
name: CI

# Every push and every PR runs every test. Nothing is allowed to skip
# silently: tests that skip themselves locally when a tool is missing
# (deno, ...) fail instead when CI=true, which GitHub Actions always sets.
#
# The three acceptance jobs run real open-source apps end to end
# (acceptance/*/run.sh), each through acceptance/known-failures.mjs: every
# verdict must match acceptance/<suite>/KNOWN_FAILURES.json exactly. A new
# failure, a changed verdict, or a known failure that starts passing all
# fail the job. Known failures are documented limitations and are still
# reported as FAIL in the job log and RESULTS.md; nothing is
# continue-on-error.
on:
push:
pull_request:

permissions:
contents: read

env:
NODE_VERSION: '22'
DENO_VERSION: 'v2.x'
# Chromium r1194, the build the acceptance harnesses were written against.
PLAYWRIGHT_VERSION: '1.56.1'
APPMAP_TELEMETRY_DISABLED: 'true'

jobs:
build:
name: typecheck + build
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: ${{ env.NODE_VERSION }}
cache: npm
- run: npm ci
- run: npm run typecheck --workspaces --if-present
- run: npm run build --workspaces --if-present

unit:
name: unit tests (Vitest)
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: ${{ env.NODE_VERSION }}
cache: npm
- run: npm ci
- run: npm test --workspace recorder --workspace linker --workspace deno
# The example app's unit tests; its e2e tests run in the e2e-deno job.
- run: npx vitest run --exclude 'test/e2e/**'
working-directory: examples/petclinic-react

deno:
name: Deno tests (native)
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: ${{ env.NODE_VERSION }}
cache: npm
# Deno resolves the recorder's npm deps (e.g. npm:@types/node during
# type-checking) from node_modules, so install them first.
- run: npm ci
- uses: denoland/setup-deno@22d081ff2d3a40755e97629de92e3bcbfa7cf2ed # v2.0.5
with:
deno-version: ${{ env.DENO_VERSION }}
- run: deno test -A --unstable-sloppy-imports deno/appmap_test.ts

e2e-deno:
name: Deno e2e (real deno run + React <-> Deno join)
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: ${{ env.NODE_VERSION }}
cache: npm
- run: npm ci
- uses: denoland/setup-deno@22d081ff2d3a40755e97629de92e3bcbfa7cf2ed # v2.0.5
with:
deno-version: ${{ env.DENO_VERSION }}
- run: deno --version
# examples/deno-edge smoke test: the unmodified function through appmap-deno.
- run: npm test --workspace examples/deno-edge
# React <-> this repo's own deno-edge example, joined by appmap-link.
- run: npx vitest run test/e2e
working-directory: examples/petclinic-react

acceptance-supabase-edge-functions-app:
name: acceptance / full-stack e2e (supabase edge-functions app, React + Deno)
runs-on: ubuntu-24.04
timeout-minutes: 45
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: ${{ env.NODE_VERSION }}
cache: npm
- uses: denoland/setup-deno@22d081ff2d3a40755e97629de92e3bcbfa7cf2ed # v2.0.5
with:
deno-version: ${{ env.DENO_VERSION }}
- name: PostgreSQL server binaries (initdb/pg_ctl; the harness runs its own cluster)
run: |
ls /usr/lib/postgresql/*/bin/initdb 2>/dev/null ||
{ sudo apt-get update && sudo apt-get install -y postgresql; }
ls /usr/lib/postgresql/*/bin/initdb
- name: Chromium (Playwright's build, installed in Actions only)
run: |
npx -y "playwright@${PLAYWRIGHT_VERSION}" install --with-deps chromium
echo "CHROME=$(find ~/.cache/ms-playwright -type f -path '*chromium-*/chrome-linux*/chrome' | head -1)" >> "$GITHUB_ENV"
- run: npm ci
# Downloads GoTrue + PostgREST release binaries, clones the app at its
# pinned SHA, runs everything on 127.0.0.1; verdicts held to KNOWN_FAILURES.json.
- run: node acceptance/known-failures.mjs acceptance/supabase-edge-functions-app -- acceptance/supabase-edge-functions-app/run.sh
env:
WORK: ${{ runner.temp }}/acc-fullstack
- if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: acceptance-supabase-edge-functions-app
path: |
acceptance/supabase-edge-functions-app/evidence
${{ runner.temp }}/acc-fullstack/logs
if-no-files-found: warn

acceptance-bulletproof-react:
name: acceptance / React recorder (bulletproof-react)
runs-on: ubuntu-24.04
timeout-minutes: 60
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: ${{ env.NODE_VERSION }}
cache: npm
- name: yarn, bc (used by run.sh)
run: |
command -v yarn || npm install -g yarn@1.22.22
command -v bc || { sudo apt-get update && sudo apt-get install -y bc; }
- name: Chromium (Playwright's build, installed in Actions only)
run: |
npx -y "playwright@${PLAYWRIGHT_VERSION}" install --with-deps chromium
echo "CHROME=$(find ~/.cache/ms-playwright -type f -path '*chromium-*/chrome-linux*/chrome' | head -1)" >> "$GITHUB_ENV"
- run: npm ci
- run: node acceptance/known-failures.mjs acceptance/bulletproof-react -- acceptance/bulletproof-react/run.sh "$RUNNER_TEMP/acc-bulletproof"
- if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: acceptance-bulletproof-react
path: ${{ runner.temp }}/acc-bulletproof/out
if-no-files-found: warn

acceptance-supabase-restful-tasks:
name: acceptance / Deno recorder (supabase restful-tasks)
runs-on: ubuntu-24.04
timeout-minutes: 45
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: ${{ env.NODE_VERSION }}
cache: npm
- uses: denoland/setup-deno@22d081ff2d3a40755e97629de92e3bcbfa7cf2ed # v2.0.5
with:
deno-version: ${{ env.DENO_VERSION }}
- name: PostgreSQL server binaries (initdb/pg_ctl; the harness runs its own cluster)
run: |
ls /usr/lib/postgresql/*/bin/initdb 2>/dev/null ||
{ sudo apt-get update && sudo apt-get install -y postgresql; }
ls /usr/lib/postgresql/*/bin/initdb
- run: npm ci
# Downloads PostgREST, clones the app at its pinned SHA, runs everything
# on 127.0.0.1; verdicts held to KNOWN_FAILURES.json.
- run: node acceptance/known-failures.mjs acceptance/supabase-restful-tasks -- acceptance/supabase-restful-tasks/run.sh
env:
WORK: ${{ runner.temp }}/acc-deno
- if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: acceptance-supabase-restful-tasks
path: acceptance/supabase-restful-tasks/evidence
if-no-files-found: warn
152 changes: 132 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

An [AppMap](https://appmap.io) agent for React (browser) apps and Deno
edge functions, sharing one recorder core. Together they record
[AppMap v1.2](https://github.com/getappmap/appmap) JSON from component
renders, hooks, event handlers, `fetch` calls, and `Deno.serve`
[AppMap](https://github.com/getappmap/appmap) 1.12 JSON — checked with
the official validator, see [doc 12](docs/design/12-format-validity.md) —
from component
renders, hooks, event handlers, `fetch` and `XMLHttpRequest` calls,
and `Deno.serve`
requests — and the headline goal is **full-stack linking**:
correlating frontend AppMaps with backend AppMaps via W3C Trace
Context, so a user interaction can be followed from click to SQL. This
Expand All @@ -28,16 +31,41 @@ specific to this repo is in `docs/design/`.

## Status

Nine design docs, listed below with what each one proved. Highlights:
full-stack linking (doc 02) now has a real end-to-end test with no
external dependency (doc 09), and both runtimes record with zero
application-code changes (docs 06 and 07). Interaction-window capture
is still pending a manual real-browser run (doc 04).
Twelve design docs, listed below with what each one proved. Highlights:
full-stack linking (doc 02) is tested end to end against a **real
open-source app neither side was built around** — Supabase's
edge-functions example (a React app calling a Deno edge function, with
real Postgres, GoTrue and PostgREST on localhost) — in
[`acceptance/supabase-edge-functions-app`](acceptance/supabase-edge-functions-app),
which CI runs on every PR. Read its `RESULTS.md` for the current state:
the recorder bugs it found are fixed, and the join works end to end once
the function's CORS allows `traceparent`; the suite still fails on two
checks that are not recorder bugs (the app is Create React App, which the
recorder cannot hook without the app switching to Vite, and at the pinned
commit the function's CORS refuses the header).
Both runtimes record with zero application-code changes on this repo's
own examples (docs 06 and 07). Interaction-window capture in a real
browser is exercised by the acceptance runs.

### Acceptance suites (real OSS apps, run by CI on every PR)

| Suite | What it proves | App |
|---|---|---|
| [`acceptance/supabase-edge-functions-app`](acceptance/supabase-edge-functions-app) | the full-stack join: a real Chromium click in the React app → `fetch` with `traceparent` → Deno backend map with matching `parent_span_id` → `appmap-link` stitch | `supabase/supabase` examples/edge-functions (app + `select-from-table-with-auth-rls`) @ `74a3be9` |
| [`acceptance/bulletproof-react`](acceptance/bulletproof-react) | the React recorder, checks A–J, Vitest + real browser | `alan2207/bulletproof-react` @ `9506629` |
| [`acceptance/supabase-restful-tasks`](acceptance/supabase-restful-tasks) | the Deno recorder, checks A–J | `supabase/supabase` examples/edge-functions `restful-tasks` @ `74a3be9` |

Each has `EXPECTATIONS.md` (written before any recording), `run.sh`
(clean clone at the pinned SHA → every check, non-zero exit on any
failure) and `RESULTS.md`.

- [`recorder/`](recorder) — the recorder core (Enter/Exit + CallToken
contract, value capture with size caps, `fetch` →
`http_client_request`/`response` events with `traceparent` stamping,
AppMap v1.2 serializer), Vitest per-test recording hooks
contract, side-effect-free value capture with size caps and credential
redaction, `fetch` and
`XMLHttpRequest` (axios) → `http_client_request`/`response` events
with `traceparent` stamping,
AppMap 1.12 serializer, validated by the official
`@appland/appmap-validate`), Vitest per-test recording hooks
(`./vitest`), and the Vite plugin (`./vite`) that auto-instruments
top-level functions in configured paths — dev/test only, with
components and hooks labeled by naming convention.
Expand All @@ -51,12 +79,13 @@ is still pending a manual real-browser run (doc 04).
to backend request maps via W3C Trace Context (`traceparent`) ids,
emitting `appmap-links.json` and a stitched PlantUML sequence
diagram per interaction (click → component → fetch → handler →
SQL). A clearly-marked simulator can synthesize backend maps, and a
**real end-to-end integration test** boots the actual PetClinicGo
server (with its new AppMap middleware) and asserts the stitch on
real maps — it runs automatically when the Go toolchain and the Go
sibling repo are present (`PETCLINIC_GO_DIR` to point elsewhere),
and skips itself otherwise. See the doc 02 amendment.
SQL). A clearly-marked simulator can synthesize backend maps for the
demo. The real end-to-end proof is
[`acceptance/supabase-edge-functions-app`](acceptance/supabase-edge-functions-app)
(a real OSS React + Deno app, real browser, real backend recordings);
see the doc 02 amendment of 2026-09-24. The earlier PetClinicGo-backed
e2e test was retired: it depended on this project's own experimental
Go tracer and a sibling repo, and skipped itself in CI.
- [`deno/`](deno) — `withAppMap`, a per-request session driver for
`Deno.serve` / Supabase edge functions: reuses the same recorder
core and the same build-time transform (unchanged), adding only a
Expand All @@ -72,6 +101,17 @@ is still pending a manual real-browser run (doc 04).
**not** Supabase Edge Functions, which expose no equivalent hook —
that gap is named, not silently missing. See
[doc 06](docs/design/06-zero-touch-deno.md).
Work a handler hands to `EdgeRuntime.waitUntil` (runs after the
response is sent) is recorded too, and a recording cut off by a
signal, a crash or even `kill -9` is kept (truncated) rather than
lost. See
[doc 11](docs/design/11-waituntil-background-work.md).
- [`linker/bin/appmap-trace.mjs`](linker/bin/appmap-trace.mjs) — the
tracing agent: shows each interaction as an ASCII call tree and a
mermaid sequence diagram, and with `--baseline <dir>` shows a
behavior diff (added, removed and changed steps) against an earlier
set of recordings. Label-aware, no dependencies. See
[doc 10](docs/design/10-behavior-diff-tracing-agent.md).

## Quickstart

Expand All @@ -84,10 +124,71 @@ npm run link:demo # tests + simulate backend + lin
ls examples/petclinic-react/tmp/appmap/links/ # appmap-links.json + .puml diagrams

npm test --workspace examples/deno-edge # real deno run, if deno is on PATH
# (this also runs the real React <-> Deno
# e2e test in examples/petclinic-react, doc 09)
# (examples/petclinic-react also has a React <-> Deno
# e2e test against this repo's own deno-edge example, doc 09;
# with CI=true both fail instead of skipping without deno)

# full-stack e2e on a real OSS app (needs deno, postgres binaries, chromium; see run.sh)
acceptance/supabase-edge-functions-app/run.sh

# tracing agent: ASCII + mermaid per interaction (add --baseline <dir> to diff)
node linker/bin/appmap-trace.mjs examples/petclinic-react/tmp/appmap
```

### Using the recorder in another Vite/Vitest app

The recorder package is built to `recorder/dist` (`npm run build`;
`npm pack` builds it for you) and imported by these specifiers:

```bash
npm pack --workspace recorder # -> funwithappmap-react-recorder-<ver>.tgz
cd your-app && npm install -D /path/to/funwithappmap-react-recorder-<ver>.tgz
```

```ts
// vite.config.ts
import { appmapVitePlugin } from '@funwithappmap/react-recorder/vite';
export default defineConfig({
plugins: [appmapVitePlugin({ include: ['src'], app: 'your-app' }), react()],
test: { setupFiles: ['./appmap.setup.ts'] },
});

// appmap.setup.ts (Vitest: one AppMap per test in tmp/appmap/tests)
import { registerAppMapHooks } from '@funwithappmap/react-recorder/vitest';
registerAppMapHooks({ app: 'your-app' });
```

`include`/`exclude` take directory prefixes or globs
(`'**/*.stories.tsx'`); test files (`__tests__/`, `__mocks__/`,
`*.test.*`, `*.spec.*`) are excluded by default (`defaultExclude`, doc 03).

With `app` set, `vite` dev also records one AppMap per user interaction
into `tmp/appmap/interactions` (doc 07). Installing straight from a
checkout (`file:…/recorder`) works too, once `npm run build` has run
there.

**Linking to a backend on another origin needs one setting.** Every
request made while recording is recorded, but only same-origin requests
carry the `traceparent` header that links a frontend map to its backend
map. A cross-origin request carries it only when its origin is listed,
because a header the backend's CORS policy does not allow makes the
browser block the request and would break your app (this is
OpenTelemetry's `propagateTraceHeaderCorsUrls` model):

```ts
appmapVitePlugin({
include: ['src'],
app: 'your-app',
propagateTraceHeaderOrigins: ['https://api.example.com'], // or APPMAP_PROPAGATE_TRACE_HEADER_ORIGINS=https://api.example.com
});
```

That backend must also allow the header: `traceparent` in its
`Access-Control-Allow-Headers` (for a Supabase edge function, add it to
`corsHeaders` in `_shared/cors.ts`). Server-side code (Deno, Node) has no
CORS and stamps every outgoing request. See doc 02, "Cross-origin
requests".

To run the example app against a live PetClinicGo backend
(`FunwithAppMapandClaudeGolang/examples/PetClinicGo` on :8080):

Expand Down Expand Up @@ -122,12 +223,23 @@ not history rewrites.
Edge Runtime gap explicitly rather than leaving it implicit)
- [07 — zero-touch interaction recording for React](docs/design/07-zero-touch-react.md)
(the same standard applied to the frontend: `main.tsx` no longer
calls `installInteractionRecorder` itself; verified against a real
dev server and a real production build, not just a unit test)
calls `installInteractionRecorder` itself; the 2026-09-24 amendment
fixes the injected import so a real browser actually loads it, proven
with a real dev server and headless Chromium)
- [08 — labels: comment tags and built-in patterns](docs/design/08-labels.md)
(`@label` comments, no import required; automatic
`security.authentication` / `io.sql` / `security.crypto` labels for
Supabase, Web Crypto, bcrypt/argon2/scrypt, and JWT calls)
- [09 — real end-to-end test: React ↔ real Deno backend](docs/design/09-real-e2e-deno.md)
(no sibling repo needed, unlike the Go e2e test — real appmap-deno
process, real fetch, real appmap-link, on every checkout with `deno`)
- [10 — behavior-diff tracing agent](docs/design/10-behavior-diff-tracing-agent.md)
(ASCII + mermaid views and a computed behavior diff; spiked by
`appmap-trace` over the example recordings, checked against the real
mermaid parser)
- [11 — recording background work (`EdgeRuntime.waitUntil`)](docs/design/11-waituntil-background-work.md)
(found by the first real edge function the Deno driver met; also
repairs recordings cut off mid-write)
- [12 — format validity and the declared version](docs/design/12-format-validity.md)
(every recording mode checked with the official validator; calls
serialized as a tree; why the declared version is 1.12)
2 changes: 2 additions & 0 deletions acceptance/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Regenerated by each run; CI uploads it as an artifact.
evidence/
Loading