[
     {
          "Id": "5620e137f15d7b7f677270d8147bbdfdbbd9ba123e18acc8827fb962bd7dfc43",
          "Created": "2026-08-08T04:42:56.476948327+03:00",
          "Path": "/usr/bin/tini",
          "Args": [
               "--",
               "/bin/sh",
               "-c",
               "[ -n \"${HOME-}\" ] || { echo 'agent_cred: HOME unset in container' >&2; exit 10; }\nagent_cred_target=\"${HOME%/}/.codex/auth.json\"\ntrap 'rm -f \"$agent_cred_target\"' EXIT HUP INT TERM\nmkdir -p \"${agent_cred_target%/*}\" || { echo 'agent_cred: cannot create credential directory' >&2; exit 10; }\n[ -r '/sandbox-secrets/codex/auth.json' ] || { echo 'agent_cred: staging mount missing: /sandbox-secrets/codex/auth.json' >&2; exit 10; }\ncp '/sandbox-secrets/codex/auth.json' \"$agent_cred_target\" || { echo 'agent_cred: credential copy failed' >&2; exit 10; }\nchmod 600 \"$agent_cred_target\" || { echo 'agent_cred: cannot restrict credential mode' >&2; exit 10; }\n\"$@\"",
               "sh",
               "codex",
               "exec",
               "--sandbox",
               "danger-full-access",
               "--skip-git-repo-check",
               "-m",
               "gpt-5.6-sol",
               "-c",
               "model_reasoning_effort=low",
               "Build a live trace reader for the overdeck v3 software factory.\n\nRepo root: the directory you are started in. Work only there. Do not touch /home/user/Projects/overdeck (the shared main checkout).\n\n## The problem\n\nThe factory (a vendored copy of super-simple-software-factory at modules/harness/factory/) records everything it does into a global SQLite trace db while a run is in progress. Nothing reads it. The owner's single biggest complaint across three versions is \"I have no observability — why it failed? what failed? what did the agent do? anything? nothing.\" The data is already there; there is no viewer. That is the whole gap you are closing.\n\nUpstream SSSF shipped a web visualizer that polls `events.rowid` every 500ms. Overdeck deliberately did NOT ship it (see docs/plans/2026-08-05-sssf-v3-adoption.md — reference only). No replacement was ever built.\n\n## What to build\n\nA `factory watch` subcommand that streams a live run to the terminal.\n\nFiles:\n  modules/harness/factory/adw_modules/watch.py   (create)\n  modules/harness/factory/bin/factory            (modify — route the `watch` subcommand)\n  modules/harness/factory/tests/test_watch.py    (create)\n\nRead these first, do not guess:\n- `modules/harness/factory/adw_modules/tracer.py` — the full schema (sessions, phases, events, envelopes, gate_results, processes, agent_sessions, decisions) and exactly what each event type carries. The schema is the contract; do not invent columns.\n- `modules/harness/factory/adw_modules/control.py` — how an existing control subcommand resolves the config, the db path and the repo. `watch` MUST reuse that exact resolution, not re-derive it.\n- `modules/harness/factory/bin/factory` — `run_control()` and the `stop|reconcile|decisions|answer` dispatch case. `watch` joins that set.\n- `modules/harness/reference/sssf/` — upstream's visualizer queries, for what is worth showing. Reference only; ship nothing from it.\n\n## Contract\n\n`factory watch [ADW_ID] [--repo PATH] [--config PATH] [--follow/--no-follow] [--since-start] [--json] [--poll-ms N]`\n\n- No ADW_ID: attach to the most recent session that is still running. If none is running, attach to the most recent session and print its history (implies no-follow). Say plainly which session was chosen and why.\n- `--follow` (default true): poll `events.rowid` strictly greater than the last one printed, at `--poll-ms` (default 500). Never re-print an event. Exit cleanly when the session's `ended_at` is set and no new rows remain. Ctrl-C exits 0 without a traceback.\n- `--since-start`: print the session's whole history first, then follow. Default is to start from the current tail.\n- `--json`: one JSON object per line, for piping. Otherwise human-readable lines.\n\nHuman output must answer, at a glance: which phase is running, what the agent is doing right now, what a gate checked and whether it passed, and — when something fails — the actual error text, not a classification. Show the artifact path for anything too large to inline (quality command logs, raw agent output). Include elapsed time per phase and mark a phase that is still open.\n\n## Hard requirements\n\n- **Read-only.** Open the db with `mode=ro` via a URI. `watch` must never write to the trace db, never mutate a run, never kill anything.\n- **A missing artifact is a field, never an exception.** If a log path does not exist, print that it is absent. Never let a filesystem error terminate the stream. The engine this replaces died exactly this way: an unguarded read of a log that was never created threw ENOENT, and the exception became the failure reason, destroying the real one.\n- The db is in WAL mode and is being written by a live run. Concurrent reads must not block the writer or crash on a partial write.\n- A session with zero events is a valid state, not an error.\n- Never invent, estimate or fabricate a value. If usage/tokens/cost is NULL, show it as unknown.\n\n## Acceptance — run it and report its REAL output. Never claim a pass you did not observe.\n\n    cd modules/harness/factory && uv run pytest tests/test_watch.py -q\n\nThe tests must build a temporary SQLite db against the real tracer schema and prove: follow mode emits each new event exactly once and never re-emits; a session with no events does not error; a missing artifact path renders as absent rather than raising; `--json` output is one valid JSON object per line; selection with no ADW_ID picks the running session over a newer finished one.\n\nAlso confirm the CLI parses and does not regress the existing control commands:\n\n    ./modules/harness/factory/bin/factory --help\n    ./modules/harness/factory/bin/factory watch --help\n\n## Commit\n\n    git add modules/harness/factory/adw_modules/watch.py modules/harness/factory/bin/factory modules/harness/factory/tests/test_watch.py && git commit -m 'stream a live factory run to the terminal'\n\nReport: what you built, the verbatim acceptance output, and your commit sha — the commit carrying YOUR files, never another task's. A repo-wide tooling or dependency warning outside your three files is the owner's to fix, not yours: report it and judge your task on its own files."
          ],
          "State": {
               "OciVersion": "1.2.1",
               "Status": "exited",
               "Running": false,
               "Paused": false,
               "Restarting": false,
               "OOMKilled": false,
               "Dead": false,
               "Pid": 0,
               "ExitCode": 0,
               "Error": "",
               "StartedAt": "2026-08-08T04:42:56.669848075+03:00",
               "FinishedAt": "2026-08-08T04:46:19.249975888+03:00",
               "CheckpointedAt": "0001-01-01T00:00:00Z",
               "RestoredAt": "0001-01-01T00:00:00Z"
          },
          "Image": "b1f0e605dca88041db84124d554a87c90f1e67b0afd39a1e6eb5fdd69b2333ef",
          "ImageDigest": "sha256:a04c8666e3eb0dfed42cd16d577c383649555d1d05f214546c06d9377ef7a456",
          "ImageName": "localhost/overdeck-agent-sandbox:d1c7f17660b1",
          "Rootfs": "",
          "Pod": "",
          "ResolvConfPath": "/run/user/1000/containers/overlay-containers/5620e137f15d7b7f677270d8147bbdfdbbd9ba123e18acc8827fb962bd7dfc43/userdata/resolv.conf",
          "HostnamePath": "/run/user/1000/containers/overlay-containers/5620e137f15d7b7f677270d8147bbdfdbbd9ba123e18acc8827fb962bd7dfc43/userdata/hostname",
          "HostsPath": "/run/user/1000/containers/overlay-containers/5620e137f15d7b7f677270d8147bbdfdbbd9ba123e18acc8827fb962bd7dfc43/userdata/hosts",
          "StaticDir": "/home/user/.local/share/containers/storage/overlay-containers/5620e137f15d7b7f677270d8147bbdfdbbd9ba123e18acc8827fb962bd7dfc43/userdata",
          "OCIConfigPath": "/home/user/.local/share/containers/storage/overlay-containers/5620e137f15d7b7f677270d8147bbdfdbbd9ba123e18acc8827fb962bd7dfc43/userdata/config.json",
          "OCIRuntime": "crun",
          "ConmonPidFile": "/run/user/1000/containers/overlay-containers/5620e137f15d7b7f677270d8147bbdfdbbd9ba123e18acc8827fb962bd7dfc43/userdata/conmon.pid",
          "PidFile": "/run/user/1000/containers/overlay-containers/5620e137f15d7b7f677270d8147bbdfdbbd9ba123e18acc8827fb962bd7dfc43/userdata/pidfile",
          "Name": "overdeck-sandbox-revfix-f75a34a90c55",
          "RestartCount": 0,
          "Driver": "overlay",
          "MountLabel": "",
          "ProcessLabel": "",
          "AppArmorProfile": "",
          "EffectiveCaps": null,
          "BoundingCaps": null,
          "ExecIDs": [],
          "GraphDriver": {
               "Name": "overlay",
               "Data": {
                    "LowerDir": "/home/user/.local/share/containers/storage/overlay/d49a100797e83202ba1ecfc6175b67d1fe8e5fe75f54da3ee4262308a916622b/diff:/home/user/.local/share/containers/storage/overlay/d43056af101e2d4cdc651cfdf040d6f107c81620d77808f41223f6f9991ce581/diff:/home/user/.local/share/containers/storage/overlay/c438e503bc1c229234bb171b4b77992a7423bd688d9f96fee535288d2c85060f/diff:/home/user/.local/share/containers/storage/overlay/48792945e4e1b9f4c26265b925061931e57a2748839cbbd458091e793b01c483/diff:/home/user/.local/share/containers/storage/overlay/4219c648e7a6ce168560334375bcf7ebe4d60674c7e0ed1d2133bf7c0a2403ce/diff:/home/user/.local/share/containers/storage/overlay/a7dd58a7a982534dd1c90283ee4304eabae7b47cdaae59a8260c9dfab477d11d/diff:/home/user/.local/share/containers/storage/overlay/2ca4754021bf0d5cfbb2854036b912ad2e5707084c80bd8d188e438201b8e52e/diff:/home/user/.local/share/containers/storage/overlay/ca1f4233d2b0487eac3cf4495286478f0c62d9aa65a38723143748143eabb908/diff:/home/user/.local/share/containers/storage/overlay/e715b54c9641f9e832d1a136ae3cf414ffa2ada20630de35a799e6198d6110f4/diff:/home/user/.local/share/containers/storage/overlay/4e167893ba2f7243ffacc715fa832ddbb596f0a83fa1e1dcfcc7480a05dd6b72/diff:/home/user/.local/share/containers/storage/overlay/cd7010618e91c57771c4e70c076ca7ebed5051f2dadd9cf3594c39535026152a/diff:/home/user/.local/share/containers/storage/overlay/7249826692473065bd49c116884f426135dc4b7a6375219adc1527c5eb880e3b/diff:/home/user/.local/share/containers/storage/overlay/f000331b42681cdec47aebef7ef03be564c1f7d756aae241cec523a997b8ada3/diff:/home/user/.local/share/containers/storage/overlay/45fc035401d0739c04295700f1a0956d14007b33830e7df90d24e6e2ed6e6925/diff:/home/user/.local/share/containers/storage/overlay/33abc4ad76e2099a56041549ac0643312ed831660ea7f28e07f05bc228e12f78/diff",
                    "UpperDir": "/home/user/.local/share/containers/storage/overlay/ba03cbea833805f781728afaec43fca55233e4161d8f7e350ca9cc959cb1583c/diff",
                    "WorkDir": "/home/user/.local/share/containers/storage/overlay/ba03cbea833805f781728afaec43fca55233e4161d8f7e350ca9cc959cb1583c/work"
               }
          },
          "Mounts": [
               {
                    "Type": "bind",
                    "Source": "/home/user/cdx-offload/git-common/overdeck-73dd7c243420",
                    "Destination": "/home/user/cdx-offload/git-common/overdeck-73dd7c243420",
                    "Driver": "",
                    "Mode": "",
                    "Options": [
                         "rbind"
                    ],
                    "RW": true,
                    "Propagation": "rprivate"
               },
               {
                    "Type": "bind",
                    "Source": "/home/user/cdx-offload/git-common/overdeck-73dd7c243420/worktrees/revfix",
                    "Destination": "/home/user/cdx-offload/git-common/overdeck-73dd7c243420/worktrees/revfix",
                    "Driver": "",
                    "Mode": "",
                    "Options": [
                         "rbind"
                    ],
                    "RW": true,
                    "Propagation": "rprivate"
               },
               {
                    "Type": "bind",
                    "Source": "/home/user/.local/state/overdeck-sandbox/creds/1786153366011159073-967191-17968/codex/auth.json",
                    "Destination": "/sandbox-secrets/codex/auth.json",
                    "Driver": "",
                    "Mode": "",
                    "Options": [
                         "rbind"
                    ],
                    "RW": false,
                    "Propagation": "rprivate"
               },
               {
                    "Type": "bind",
                    "Source": "/home/user/sandbox",
                    "Destination": "/sandbox",
                    "Driver": "",
                    "Mode": "",
                    "Options": [
                         "rbind"
                    ],
                    "RW": true,
                    "Propagation": "rprivate"
               },
               {
                    "Type": "bind",
                    "Source": "/home/user/.local/share/overdeck-sandbox/secrets/e2e_key",
                    "Destination": "/sandbox-secrets/e2e_key",
                    "Driver": "",
                    "Mode": "",
                    "Options": [
                         "rbind"
                    ],
                    "RW": false,
                    "Propagation": "rprivate"
               },
               {
                    "Type": "bind",
                    "Source": "/home/user/.local/share/overdeck-sandbox/secrets/e2e_known_hosts",
                    "Destination": "/sandbox-secrets/e2e_known_hosts",
                    "Driver": "",
                    "Mode": "",
                    "Options": [
                         "rbind"
                    ],
                    "RW": false,
                    "Propagation": "rprivate"
               }
          ],
          "Dependencies": [],
          "NetworkSettings": {
               "EndpointID": "",
               "Gateway": "",
               "IPAddress": "",
               "IPPrefixLen": 0,
               "IPv6Gateway": "",
               "GlobalIPv6Address": "",
               "GlobalIPv6PrefixLen": 0,
               "MacAddress": "",
               "Bridge": "",
               "SandboxID": "",
               "HairpinMode": false,
               "LinkLocalIPv6Address": "",
               "LinkLocalIPv6PrefixLen": 0,
               "Ports": {},
               "SandboxKey": "",
               "Networks": {
                    "pasta": {
                         "EndpointID": "",
                         "Gateway": "",
                         "IPAddress": "",
                         "IPPrefixLen": 0,
                         "IPv6Gateway": "",
                         "GlobalIPv6Address": "",
                         "GlobalIPv6PrefixLen": 0,
                         "MacAddress": "",
                         "NetworkID": "pasta",
                         "DriverOpts": null,
                         "IPAMConfig": null,
                         "Links": null
                    }
               }
          },
          "Namespace": "",
          "IsInfra": false,
          "IsService": false,
          "KubeExitCodePropagation": "invalid",
          "lockNumber": 0,
          "Config": {
               "Hostname": "sandbox-revfix-f75a34a90c55",
               "Domainname": "",
               "User": "agent",
               "AttachStdin": false,
               "AttachStdout": false,
               "AttachStderr": false,
               "Tty": false,
               "OpenStdin": true,
               "StdinOnce": false,
               "Env": [
                    "PNPM_STORE_DIR=/sandbox/store/pnpm",
                    "PLAYWRIGHT_BROWSERS_PATH=/ms-playwright",
                    "SANDBOX_E2E_PORT=2222",
                    "DEBIAN_FRONTEND=noninteractive",
                    "HOME=/sandbox/home",
                    "LANG=C.UTF-8",
                    "container=podman",
                    "BASH_ENV=/etc/overdeck-sandbox/toolgap.bash",
                    "DISABLE_AUTOUPDATER=1",
                    "SANDBOX_IMAGE=localhost/overdeck-agent-sandbox:d1c7f17660b1",
                    "SANDBOX_E2E_TARGET=user@host.containers.internal",
                    "SANDBOX_ID=revfix-f75a34a90c55",
                    "PATH=/usr/local/node/bin:/sandbox/home/.local/share/pnpm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                    "PNPM_HOME=/sandbox/home/.local/share/pnpm",
                    "PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1",
                    "COREPACK_ENABLE_DOWNLOAD_PROMPT=0",
                    "SANDBOX_TOOLGAP_FILE=/sandbox/toolgap/gaps.jsonl",
                    "HOSTNAME=sandbox-revfix-f75a34a90c55"
               ],
               "Cmd": [
                    "/bin/sh",
                    "-c",
                    "[ -n \"${HOME-}\" ] || { echo 'agent_cred: HOME unset in container' \u003e\u00262; exit 10; }\nagent_cred_target=\"${HOME%/}/.codex/auth.json\"\ntrap 'rm -f \"$agent_cred_target\"' EXIT HUP INT TERM\nmkdir -p \"${agent_cred_target%/*}\" || { echo 'agent_cred: cannot create credential directory' \u003e\u00262; exit 10; }\n[ -r '/sandbox-secrets/codex/auth.json' ] || { echo 'agent_cred: staging mount missing: /sandbox-secrets/codex/auth.json' \u003e\u00262; exit 10; }\ncp '/sandbox-secrets/codex/auth.json' \"$agent_cred_target\" || { echo 'agent_cred: credential copy failed' \u003e\u00262; exit 10; }\nchmod 600 \"$agent_cred_target\" || { echo 'agent_cred: cannot restrict credential mode' \u003e\u00262; exit 10; }\n\"$@\"",
                    "sh",
                    "codex",
                    "exec",
                    "--sandbox",
                    "danger-full-access",
                    "--skip-git-repo-check",
                    "-m",
                    "gpt-5.6-sol",
                    "-c",
                    "model_reasoning_effort=low",
                    "Build a live trace reader for the overdeck v3 software factory.\n\nRepo root: the directory you are started in. Work only there. Do not touch /home/user/Projects/overdeck (the shared main checkout).\n\n## The problem\n\nThe factory (a vendored copy of super-simple-software-factory at modules/harness/factory/) records everything it does into a global SQLite trace db while a run is in progress. Nothing reads it. The owner's single biggest complaint across three versions is \"I have no observability — why it failed? what failed? what did the agent do? anything? nothing.\" The data is already there; there is no viewer. That is the whole gap you are closing.\n\nUpstream SSSF shipped a web visualizer that polls `events.rowid` every 500ms. Overdeck deliberately did NOT ship it (see docs/plans/2026-08-05-sssf-v3-adoption.md — reference only). No replacement was ever built.\n\n## What to build\n\nA `factory watch` subcommand that streams a live run to the terminal.\n\nFiles:\n  modules/harness/factory/adw_modules/watch.py   (create)\n  modules/harness/factory/bin/factory            (modify — route the `watch` subcommand)\n  modules/harness/factory/tests/test_watch.py    (create)\n\nRead these first, do not guess:\n- `modules/harness/factory/adw_modules/tracer.py` — the full schema (sessions, phases, events, envelopes, gate_results, processes, agent_sessions, decisions) and exactly what each event type carries. The schema is the contract; do not invent columns.\n- `modules/harness/factory/adw_modules/control.py` — how an existing control subcommand resolves the config, the db path and the repo. `watch` MUST reuse that exact resolution, not re-derive it.\n- `modules/harness/factory/bin/factory` — `run_control()` and the `stop|reconcile|decisions|answer` dispatch case. `watch` joins that set.\n- `modules/harness/reference/sssf/` — upstream's visualizer queries, for what is worth showing. Reference only; ship nothing from it.\n\n## Contract\n\n`factory watch [ADW_ID] [--repo PATH] [--config PATH] [--follow/--no-follow] [--since-start] [--json] [--poll-ms N]`\n\n- No ADW_ID: attach to the most recent session that is still running. If none is running, attach to the most recent session and print its history (implies no-follow). Say plainly which session was chosen and why.\n- `--follow` (default true): poll `events.rowid` strictly greater than the last one printed, at `--poll-ms` (default 500). Never re-print an event. Exit cleanly when the session's `ended_at` is set and no new rows remain. Ctrl-C exits 0 without a traceback.\n- `--since-start`: print the session's whole history first, then follow. Default is to start from the current tail.\n- `--json`: one JSON object per line, for piping. Otherwise human-readable lines.\n\nHuman output must answer, at a glance: which phase is running, what the agent is doing right now, what a gate checked and whether it passed, and — when something fails — the actual error text, not a classification. Show the artifact path for anything too large to inline (quality command logs, raw agent output). Include elapsed time per phase and mark a phase that is still open.\n\n## Hard requirements\n\n- **Read-only.** Open the db with `mode=ro` via a URI. `watch` must never write to the trace db, never mutate a run, never kill anything.\n- **A missing artifact is a field, never an exception.** If a log path does not exist, print that it is absent. Never let a filesystem error terminate the stream. The engine this replaces died exactly this way: an unguarded read of a log that was never created threw ENOENT, and the exception became the failure reason, destroying the real one.\n- The db is in WAL mode and is being written by a live run. Concurrent reads must not block the writer or crash on a partial write.\n- A session with zero events is a valid state, not an error.\n- Never invent, estimate or fabricate a value. If usage/tokens/cost is NULL, show it as unknown.\n\n## Acceptance — run it and report its REAL output. Never claim a pass you did not observe.\n\n    cd modules/harness/factory \u0026\u0026 uv run pytest tests/test_watch.py -q\n\nThe tests must build a temporary SQLite db against the real tracer schema and prove: follow mode emits each new event exactly once and never re-emits; a session with no events does not error; a missing artifact path renders as absent rather than raising; `--json` output is one valid JSON object per line; selection with no ADW_ID picks the running session over a newer finished one.\n\nAlso confirm the CLI parses and does not regress the existing control commands:\n\n    ./modules/harness/factory/bin/factory --help\n    ./modules/harness/factory/bin/factory watch --help\n\n## Commit\n\n    git add modules/harness/factory/adw_modules/watch.py modules/harness/factory/bin/factory modules/harness/factory/tests/test_watch.py \u0026\u0026 git commit -m 'stream a live factory run to the terminal'\n\nReport: what you built, the verbatim acceptance output, and your commit sha — the commit carrying YOUR files, never another task's. A repo-wide tooling or dependency warning outside your three files is the owner's to fix, not yours: report it and judge your task on its own files."
               ],
               "Image": "localhost/overdeck-agent-sandbox:d1c7f17660b1",
               "Volumes": null,
               "WorkingDir": "/sandbox/workspaces/revfix-f75a34a90c55",
               "Entrypoint": [
                    "/usr/bin/tini",
                    "--"
               ],
               "OnBuild": null,
               "Labels": {
                    "io.buildah.version": "1.43.2"
               },
               "Annotations": {
                    "io.container.manager": "libpod",
                    "io.podman.annotations.cid-file": "/home/user/.local/share/overdeck-sandbox/runs/revfix-f75a34a90c55/cid",
                    "io.podman.annotations.pids-limit": "512",
                    "io.podman.annotations.userns": "keep-id",
                    "org.opencontainers.image.stopSignal": "15",
                    "org.systemd.property.KillSignal": "15",
                    "org.systemd.property.TimeoutStopUSec": "uint64 10000000"
               },
               "StopSignal": "SIGTERM",
               "HealthcheckOnFailureAction": "none",
               "HealthLogDestination": "local",
               "HealthcheckMaxLogCount": 5,
               "HealthcheckMaxLogSize": 500,
               "CreateCommand": [
                    "podman",
                    "run",
                    "--replace",
                    "--interactive",
                    "--cidfile",
                    "/home/user/.local/share/overdeck-sandbox/runs/revfix-f75a34a90c55/cid",
                    "--name",
                    "overdeck-sandbox-revfix-f75a34a90c55",
                    "--hostname",
                    "sandbox-revfix-f75a34a90c55",
                    "--userns=keep-id",
                    "--cap-drop=ALL",
                    "--security-opt=no-new-privileges",
                    "--pids-limit",
                    "512",
                    "--memory",
                    "12g",
                    "--memory-swap",
                    "12g",
                    "--cpus",
                    "4",
                    "--cpu-shares",
                    "256",
                    "--volume",
                    "/home/user/sandbox:/sandbox:rw",
                    "--volume",
                    "/home/user/.local/share/overdeck-sandbox/secrets/e2e_key:/sandbox-secrets/e2e_key:ro",
                    "--volume",
                    "/home/user/.local/share/overdeck-sandbox/secrets/e2e_known_hosts:/sandbox-secrets/e2e_known_hosts:ro",
                    "--volume",
                    "/home/user/cdx-offload/git-common/overdeck-73dd7c243420:/home/user/cdx-offload/git-common/overdeck-73dd7c243420:rw",
                    "--volume",
                    "/home/user/cdx-offload/git-common/overdeck-73dd7c243420/worktrees/revfix:/home/user/cdx-offload/git-common/overdeck-73dd7c243420/worktrees/revfix:rw",
                    "--volume",
                    "/home/user/.local/state/overdeck-sandbox/creds/1786153366011159073-967191-17968/codex/auth.json:/sandbox-secrets/codex/auth.json:ro",
                    "--workdir",
                    "/sandbox/workspaces/revfix-f75a34a90c55",
                    "--env",
                    "SANDBOX_ID=revfix-f75a34a90c55",
                    "--env",
                    "SANDBOX_IMAGE=localhost/overdeck-agent-sandbox:d1c7f17660b1",
                    "--env",
                    "SANDBOX_E2E_TARGET=user@host.containers.internal",
                    "--env",
                    "SANDBOX_E2E_PORT=2222",
                    "localhost/overdeck-agent-sandbox:d1c7f17660b1",
                    "/bin/sh",
                    "-c",
                    "[ -n \"${HOME-}\" ] || { echo 'agent_cred: HOME unset in container' \u003e\u00262; exit 10; }\nagent_cred_target=\"${HOME%/}/.codex/auth.json\"\ntrap 'rm -f \"$agent_cred_target\"' EXIT HUP INT TERM\nmkdir -p \"${agent_cred_target%/*}\" || { echo 'agent_cred: cannot create credential directory' \u003e\u00262; exit 10; }\n[ -r '/sandbox-secrets/codex/auth.json' ] || { echo 'agent_cred: staging mount missing: /sandbox-secrets/codex/auth.json' \u003e\u00262; exit 10; }\ncp '/sandbox-secrets/codex/auth.json' \"$agent_cred_target\" || { echo 'agent_cred: credential copy failed' \u003e\u00262; exit 10; }\nchmod 600 \"$agent_cred_target\" || { echo 'agent_cred: cannot restrict credential mode' \u003e\u00262; exit 10; }\n\"$@\"",
                    "sh",
                    "codex",
                    "exec",
                    "--sandbox",
                    "danger-full-access",
                    "--skip-git-repo-check",
                    "-m",
                    "gpt-5.6-sol",
                    "-c",
                    "model_reasoning_effort=low",
                    "Build a live trace reader for the overdeck v3 software factory.\n\nRepo root: the directory you are started in. Work only there. Do not touch /home/user/Projects/overdeck (the shared main checkout).\n\n## The problem\n\nThe factory (a vendored copy of super-simple-software-factory at modules/harness/factory/) records everything it does into a global SQLite trace db while a run is in progress. Nothing reads it. The owner's single biggest complaint across three versions is \"I have no observability — why it failed? what failed? what did the agent do? anything? nothing.\" The data is already there; there is no viewer. That is the whole gap you are closing.\n\nUpstream SSSF shipped a web visualizer that polls `events.rowid` every 500ms. Overdeck deliberately did NOT ship it (see docs/plans/2026-08-05-sssf-v3-adoption.md — reference only). No replacement was ever built.\n\n## What to build\n\nA `factory watch` subcommand that streams a live run to the terminal.\n\nFiles:\n  modules/harness/factory/adw_modules/watch.py   (create)\n  modules/harness/factory/bin/factory            (modify — route the `watch` subcommand)\n  modules/harness/factory/tests/test_watch.py    (create)\n\nRead these first, do not guess:\n- `modules/harness/factory/adw_modules/tracer.py` — the full schema (sessions, phases, events, envelopes, gate_results, processes, agent_sessions, decisions) and exactly what each event type carries. The schema is the contract; do not invent columns.\n- `modules/harness/factory/adw_modules/control.py` — how an existing control subcommand resolves the config, the db path and the repo. `watch` MUST reuse that exact resolution, not re-derive it.\n- `modules/harness/factory/bin/factory` — `run_control()` and the `stop|reconcile|decisions|answer` dispatch case. `watch` joins that set.\n- `modules/harness/reference/sssf/` — upstream's visualizer queries, for what is worth showing. Reference only; ship nothing from it.\n\n## Contract\n\n`factory watch [ADW_ID] [--repo PATH] [--config PATH] [--follow/--no-follow] [--since-start] [--json] [--poll-ms N]`\n\n- No ADW_ID: attach to the most recent session that is still running. If none is running, attach to the most recent session and print its history (implies no-follow). Say plainly which session was chosen and why.\n- `--follow` (default true): poll `events.rowid` strictly greater than the last one printed, at `--poll-ms` (default 500). Never re-print an event. Exit cleanly when the session's `ended_at` is set and no new rows remain. Ctrl-C exits 0 without a traceback.\n- `--since-start`: print the session's whole history first, then follow. Default is to start from the current tail.\n- `--json`: one JSON object per line, for piping. Otherwise human-readable lines.\n\nHuman output must answer, at a glance: which phase is running, what the agent is doing right now, what a gate checked and whether it passed, and — when something fails — the actual error text, not a classification. Show the artifact path for anything too large to inline (quality command logs, raw agent output). Include elapsed time per phase and mark a phase that is still open.\n\n## Hard requirements\n\n- **Read-only.** Open the db with `mode=ro` via a URI. `watch` must never write to the trace db, never mutate a run, never kill anything.\n- **A missing artifact is a field, never an exception.** If a log path does not exist, print that it is absent. Never let a filesystem error terminate the stream. The engine this replaces died exactly this way: an unguarded read of a log that was never created threw ENOENT, and the exception became the failure reason, destroying the real one.\n- The db is in WAL mode and is being written by a live run. Concurrent reads must not block the writer or crash on a partial write.\n- A session with zero events is a valid state, not an error.\n- Never invent, estimate or fabricate a value. If usage/tokens/cost is NULL, show it as unknown.\n\n## Acceptance — run it and report its REAL output. Never claim a pass you did not observe.\n\n    cd modules/harness/factory \u0026\u0026 uv run pytest tests/test_watch.py -q\n\nThe tests must build a temporary SQLite db against the real tracer schema and prove: follow mode emits each new event exactly once and never re-emits; a session with no events does not error; a missing artifact path renders as absent rather than raising; `--json` output is one valid JSON object per line; selection with no ADW_ID picks the running session over a newer finished one.\n\nAlso confirm the CLI parses and does not regress the existing control commands:\n\n    ./modules/harness/factory/bin/factory --help\n    ./modules/harness/factory/bin/factory watch --help\n\n## Commit\n\n    git add modules/harness/factory/adw_modules/watch.py modules/harness/factory/bin/factory modules/harness/factory/tests/test_watch.py \u0026\u0026 git commit -m 'stream a live factory run to the terminal'\n\nReport: what you built, the verbatim acceptance output, and your commit sha — the commit carrying YOUR files, never another task's. A repo-wide tooling or dependency warning outside your three files is the owner's to fix, not yours: report it and judge your task on its own files."
               ],
               "Umask": "0022",
               "Timeout": 0,
               "StopTimeout": 10,
               "Passwd": true,
               "sdNotifyMode": "container"
          },
          "HostConfig": {
               "Binds": [
                    "/home/user/cdx-offload/git-common/overdeck-73dd7c243420:/home/user/cdx-offload/git-common/overdeck-73dd7c243420:rw,rprivate,rbind",
                    "/home/user/cdx-offload/git-common/overdeck-73dd7c243420/worktrees/revfix:/home/user/cdx-offload/git-common/overdeck-73dd7c243420/worktrees/revfix:rw,rprivate,rbind",
                    "/home/user/.local/state/overdeck-sandbox/creds/1786153366011159073-967191-17968/codex/auth.json:/sandbox-secrets/codex/auth.json:ro,rprivate,rbind",
                    "/home/user/sandbox:/sandbox:rw,rprivate,rbind",
                    "/home/user/.local/share/overdeck-sandbox/secrets/e2e_key:/sandbox-secrets/e2e_key:ro,rprivate,rbind",
                    "/home/user/.local/share/overdeck-sandbox/secrets/e2e_known_hosts:/sandbox-secrets/e2e_known_hosts:ro,rprivate,rbind"
               ],
               "CgroupManager": "systemd",
               "CgroupMode": "private",
               "ContainerIDFile": "/home/user/.local/share/overdeck-sandbox/runs/revfix-f75a34a90c55/cid",
               "LogConfig": {
                    "Type": "journald",
                    "Config": null,
                    "Path": "",
                    "Tag": "",
                    "Size": "-1B"
               },
               "NetworkMode": "pasta",
               "PortBindings": {},
               "RestartPolicy": {
                    "Name": "no",
                    "MaximumRetryCount": 0
               },
               "AutoRemove": false,
               "AutoRemoveImage": false,
               "Annotations": {
                    "io.container.manager": "libpod",
                    "io.podman.annotations.cid-file": "/home/user/.local/share/overdeck-sandbox/runs/revfix-f75a34a90c55/cid",
                    "io.podman.annotations.pids-limit": "512",
                    "io.podman.annotations.userns": "keep-id",
                    "org.opencontainers.image.stopSignal": "15",
                    "org.systemd.property.KillSignal": "15",
                    "org.systemd.property.TimeoutStopUSec": "uint64 10000000"
               },
               "VolumeDriver": "",
               "VolumesFrom": null,
               "CapAdd": [],
               "CapDrop": [
                    "CAP_CHOWN",
                    "CAP_DAC_OVERRIDE",
                    "CAP_FOWNER",
                    "CAP_FSETID",
                    "CAP_KILL",
                    "CAP_NET_BIND_SERVICE",
                    "CAP_SETFCAP",
                    "CAP_SETGID",
                    "CAP_SETPCAP",
                    "CAP_SETUID",
                    "CAP_SYS_CHROOT"
               ],
               "Dns": [],
               "DnsOptions": [],
               "DnsSearch": [],
               "ExtraHosts": [],
               "HostsFile": "",
               "GroupAdd": [],
               "IpcMode": "shareable",
               "Cgroup": "",
               "Cgroups": "default",
               "Links": null,
               "OomScoreAdj": 0,
               "PidMode": "private",
               "Privileged": false,
               "PublishAllPorts": false,
               "ReadonlyRootfs": false,
               "SecurityOpt": [
                    "no-new-privileges"
               ],
               "Tmpfs": {},
               "UTSMode": "private",
               "UsernsMode": "private",
               "IDMappings": {
                    "UidMap": [
                         "0:1:1000",
                         "1000:0:1",
                         "1001:1001:64536"
                    ],
                    "GidMap": [
                         "0:1:1000",
                         "1000:0:1",
                         "1001:1001:64536"
                    ]
               },
               "ShmSize": 65536000,
               "Runtime": "oci",
               "ConsoleSize": [
                    0,
                    0
               ],
               "Isolation": "",
               "CpuShares": 256,
               "Memory": 12884901888,
               "NanoCpus": 4000000000,
               "CgroupParent": "user.slice",
               "BlkioWeight": 0,
               "BlkioWeightDevice": null,
               "BlkioDeviceReadBps": null,
               "BlkioDeviceWriteBps": null,
               "BlkioDeviceReadIOps": null,
               "BlkioDeviceWriteIOps": null,
               "CpuPeriod": 100000,
               "CpuQuota": 400000,
               "CpuRealtimePeriod": 0,
               "CpuRealtimeRuntime": 0,
               "CpusetCpus": "",
               "CpusetMems": "",
               "Devices": [],
               "DiskQuota": 0,
               "KernelMemory": 0,
               "MemoryReservation": 0,
               "MemorySwap": 12884901888,
               "MemorySwappiness": -1,
               "OomKillDisable": false,
               "PidsLimit": 512,
               "Ulimits": [
                    {
                         "Name": "RLIMIT_NOFILE",
                         "Soft": 524288,
                         "Hard": 524288
                    },
                    {
                         "Name": "RLIMIT_NPROC",
                         "Soft": 127162,
                         "Hard": 127162
                    }
               ],
               "CpuCount": 0,
               "CpuPercent": 0,
               "IOMaximumIOps": 0,
               "IOMaximumBandwidth": 0,
               "CgroupConf": null
          },
          "UseImageHosts": false,
          "UseImageHostname": false
     }
]
