Artifacts and observability
Every meaningful run leaves durable evidence under $GFORM_HOME. Treat this as a core product feature — not an afterthought log dump.
Related: commands/run · restore · clean · limitations
Layout
$GFORM_HOME/artifacts/
index.json # cache for run list/view (auto-heals)
a3f9c1e2b4d60718/ # 16-hex id
manifest.json
config.yaml # frozen source YAML
run.log
content/ # file-step bytes when copied
screenshots/ # fail-only by default; every step with --trace
pw-trace.zip # with --pw-trace
b7e14d90c2a81f33/ # batch parent
batch.json
config.yaml
r01/ … rNN/Ids are 16 lowercase hex. Sort order for run list comes from manifest startedAt, not the directory name.
index.json is a cache. Create/finish write through it; list/view rebuild when stale. gform run delete / run rm removes one top-level dir, drops its index row, and rewrites matching history.jsonl lines.
Live (status=running with recent writes) artifacts are protected: delete/clean skip them unless --force. Outside mutations during a live run log a warning.
Browse past runs
gform run list
gform run list --form <form> --policy load
gform run list --status success
gform run view <id-or-prefix>
gform run view <batch-id>/r01
gform run last
gform run last -v # expand batch children
gform run delete <id> # one artifact + history rows
gform run rm <id> --yes
gform restore <id>Aliases: run ls → list, run v → view, run rm → delete.
Illustrative finish line:
✓ <form> · 5× · ✓5 ✗0 ⊘0
id a3f9c1e2b4d60718
→ gform run view a3f9c1e2b4d60718Manifests, reasons, answers
Finished or skipped runs freeze:
reason+ humanmessage(stable codes; list/view color by tone)answers— post-pool resolved valuessubmit— outcome when a submit step ran (ok,closed,already,login,captcha,validation,timeout,error, …)content[]— file attachments when present
Run status is success only when submit.outcome === "ok" (or the YAML has no submit step).
Batches do not invent a parent message — list shows summary counts (✓/✗/⊘/■) and a shared parent reason only when every child shares the same code.
Skipped duplicates / unique collisions still get a tiny manifest.json (status: skipped).
Config snapshot + restore
Every new run/batch copies form YAML into config.yaml:
gform restore <id> # → $GFORM_HOME/forms/<name>.yaml
gform restore <id> --save-as other
gform restore <id> --force
gform rs <id> -a otherOlder artifacts without config.yaml cannot be restored this way.
Screenshots and traces
| Mode | Behavior |
|---|---|
| default | Screenshot failed steps only |
--trace | Screenshot every step |
--pw-trace | Playwright pw-trace.zip in the run dir — npx playwright show-trace path/to/pw-trace.zip |
Debug and live panel
| Flag | Effect |
|---|---|
-d / --debug | Opt-in content resolve/fetch/accept, fill, merge, fingerprints — stderr + run.log (auto-decide is debug-only) |
| default TTY | Live worker panel for concurrent batches |
-nl / --no-live | Print-and-go logs |
JSON (-j) stays machine-readable and is not rewritten by the live panel. Planned quieter aggregation of repeated notices: roadmap Phase 4 — not shipped yet.
Investigating a failure
gform run last
gform run list --status failed
gform run view <id>
gform run view <id> -v # batch childrenCheck: reason/message → Answers → Submit → Content → screenshots → run.log → optional pw-trace.zip.
History and clean
Successful payloads append to $GFORM_HOME/history.jsonl (fingerprints for --once / -sd / unique).
gform clean artifacts
gform clean history
gform clean allSee commands/clean.