33 Commits

Author SHA1 Message Date
jj.wang 94a09e3bf0 Runbook: PAD-12 rollout record (keys, ping, smoke latencies, rollback) 2026-10-22 03:12:11 +00:00
jj.wang 5192e04088 PAD-12: per-terminal transport (direct Tailscale SSH or Warpgate, pre-session fallback, pinned host keys, agent key from Vault), one-call win10 launch and one-call collect, remote call timings, agentd ping 2026-10-22 02:59:37 +00:00
jj.wang 83bc0f243c Docs: usage guide for dispatching work through Plane (routing, labels, replies, cancel, phone app notes) 2026-10-22 02:01:33 +00:00
jj.wang ccbc68369c Runbook: exact API recovery time for the 2026-10-22 Plane restart 2026-10-22 01:31:43 +00:00
jj.wang 709d65ef83 Docs: Plane-side webhook enabled (allowlist applied on VM 506, v2 deliveries verified, latency record) 2026-10-22 01:29:47 +00:00
jj.wang 57887a90f2 Docs: static-port NAT path for the LXC, dispatcher back on LXC, Plane webhook allowlist notes 2026-10-21 15:45:54 +00:00
jj.wang 1b4d965baf Runbook: rollback record, dispatcher back on oregon (LXC to NAS path via DERP) 2026-10-21 14:22:29 +00:00
jj.wang 4ba6d0ca5f Docs: webhook receiver (runbook, design §10, deploy-lxc §8), PAD-7 rollout record
Runbook: service, endpoint, signature, logs, secret rotation, disabling,
heartbeat skipped reasons, new failure rows. Design: webhook trigger design,
notify hook, Plane SSRF guard (WEBHOOK_ALLOWED_IPS). Deploy: install steps.
Record: synthetic-delivery acceptance and measured latencies.
2026-10-21 13:52:19 +00:00
jj.wang f6c4221f0e Board protocol: no git writes on the win10 checkout 2026-10-21 13:33:06 +00:00
jj.wang 6dc7e72ac8 Webhook receiver: Plane deliveries trigger a tick (PAD-7)
agentd webhook-serve (agentd/webhook.py, stdlib): verifies X-Plane-Signature
(HMAC-SHA256 hex of the body, constant-time; 401 on missing/bad), routes by
data.project to a configured tenant (others 202), coalesces deliveries within
3 s into one tick, runs one more tick when deliveries arrive during a tick,
and retries every 15 s for up to 2 min while the lock is held (tick command
exit 75: flock -E 75 in the cron scripts, cli tick on Busy). Ticks run in a
systemd scope so restarting the receiver never kills one. Log:
<log_dir>/webhook.log; GET /healthz.

Config: webhook section (key names only, PLANE_WEBHOOK_SECRET scrubbed from
child envs like the Plane tokens), notify: {kind: none} as a no-op hook
called on every state move; the unused per-project webhook_secret_key is
gone (Plane webhooks are workspace-level). systemd unit for the LXC and
tools/plane-webhook.py to create/rotate the Plane webhook as the workspace
admin (secret straight into the Vault, never printed).
2026-10-21 13:24:04 +00:00
jj.wang 72681db46b Heartbeat: record why each Todo item was not dispatched
Each tick lists skipped items with terminal and reason (concurrency n/m with
the holding runs, serialize group holder, busy_process not started by agentd,
relay down, no route for assignee, start failed) in heartbeat.json "skipped".
A reason is logged (agentd.log / cron.log) only when it is new for that item;
the last set is kept in the state file as "skips".
2026-10-21 13:21:16 +00:00
jj.wang 19be2296bc Docs: LXC deployment as done (agentd-01), rollback to oregon, double-start guard, PAD-11 cutover record 2026-10-21 12:11:34 +00:00
jj.wang 27ea9119a5 LXC deployment: live config for agentd-01, oregon rollback config, win10 helpers and board protocol in the repo
- config/agentd.yaml is now the agentd-01 live config (state /var/lib/plane-agentd, logs /var/log/plane-agentd);
  config/agentd.oregon.yaml keeps the oregon dispatcher settings for rollback (cron/agentd-tick.sh uses it).
- cron/agentd-tick-lxc.sh: the LXC cron entry.
- tools/win10/: win10-ps.sh / win10-put.sh (vault client dir via AGENT_ACCESS_HOME); relative helpers_dir
  resolves against the repo, default tools/win10.
- config/protocols/gwent-board-protocol.md: copy of gwent/design/board-protocol.md used in prompts.
- agentd.log_dir (default state_dir).
- smoke --watch: create the item and wait for the scheduled dispatcher instead of ticking locally.
2026-10-21 11:56:15 +00:00
jj.wang 4f45d368ad Double-start guard: launching marker, probe-and-adopt, fresh-dir relaunch; skip unreachable terminals per tick
Before the launch call the planned run (run id, terminal, handle, bookkeeping) is saved as a launching
marker. If the launch call fails or agentd dies before recording the run, the next tick probes the run
directory (exit.txt / launch.pid / pid.txt): evidence -> adopt the run; nothing -> relaunch with the same
run id in <run_id>-r2 (-r3 ...); probe unreachable -> keep the marker, which holds the terminal slot.
Transports refuse to clean a run directory holding a pid file. A terminal whose relay fails is skipped
for the rest of the tick (heartbeat.down) while other terminals carry on.
2026-10-21 11:54:40 +00:00
jj.wang dbe305103c Runbook: remote oregon (P1-6) cutover, relay failure rows, tier defaults
Smoke through the Warpgate relay on oregon: round 1 and a resumed round 2 pass;
the Linux kill path was verified directly through the relay. The cancel smoke via
Plane is pending (Plane returned 502 from 08:14).
2026-10-21 09:36:31 +00:00
jj.wang 20e4e4ed73 Docs: LXC deployment guide, remote POSIX transport in the executor contract
deploy-lxc.md: Debian 12 packages, vault client + identity, Warpgate host key
(pinned by the identity), helper scripts and protocol file, all-remote config,
cron under exec --secret-env, logs/heartbeat, adding a terminal.
design.md 9: P1-6 done for Linux/macOS; Windows still on the helper scripts (TODO unify).
2026-10-21 08:25:14 +00:00
jj.wang dc8271a06a warpgate-ssh: remote Linux/macOS terminals through the relay; oregon launched remotely
The dispatcher moves to an LXC without agent CLIs (design 9), so every terminal is
reached through Warpgate. The relay call (agent-access.py run --target <t>) lives in
one helper; the target comes from the terminal config.

os linux/darwin (PosixWarpgateTransport): each primitive is one bash -c call. Files
go up as base64 (chunked above 60k), start_run stages prompt.md + run.sh and launches
in a single round trip; the runner is detached with setsid nohup (pid == pgid == sid,
$! kept in launch.pid); kill signals the process group and session (TERM, then KILL),
skipped once exit.txt exists. macOS detaches with perl POSIX::setsid.

os windows keeps the win10-ps.sh / win10-put.sh helper scripts (target win10) and
schtasks, now through the shared call() helper.

oregon is now warpgate-ssh (target oregon, run_root ~/.gwent-board/agentd-runs);
the local transport stays for co-located setups and tests.
2026-10-21 08:08:01 +00:00
jj.wang f2f7e4308a Per-model service tier default (codex: gpt-6.1-sol -> fast), tier:<x> / tier:none labels
executors.<x>.tier_defaults maps a model to the tier used when no label sets one;
a tier:<name> label sets it explicitly and tier:none drops the tier argument.
2026-10-21 08:08:01 +00:00
jj.wang 34b2ba1cc7 Runbook: live cron line, state dir, concurrency 0, P1-5 cutover notes 2026-10-21 07:49:48 +00:00
jj.wang 5ea931f24d Design: lean LXC dispatcher with remote-only terminals (P1-6 generic remote launch) 2026-10-21 07:41:07 +00:00
jj.wang a505c138e0 smoke: --labels to route the smoke item (e.g. model:sol) 2026-10-21 07:27:27 +00:00
jj.wang bcc5fd44e7 Cron entry script for oregon (tick every 2 minutes under exec --secret-env) 2026-10-21 07:19:39 +00:00
jj.wang 1ae44eb705 Allow concurrency 0 to pause a terminal
A paused terminal gets no new runs and is not probed; in-flight runs still finish.
2026-10-21 07:17:29 +00:00
jj.wang b17b1f1587 Live config for oregon: GWENT tenant, win10 codex + oregon claude-code
codex is not installed on oregon, so oregon only offers claude-code. The codex
resume template passes the sandbox as a -c override (exec resume takes no -s).
2026-10-21 07:17:14 +00:00
jj.wang ca2b47eb5f Docs: binary resolution, cancellation, progress cap, phase-1 deviations
- runbook: how executor binaries are resolved (bins or PATH) and what that
  assumes on oregon (no codex installed) and win10; cancellation and
  max_progress_rounds in the item lifecycle; secrets scrubbed from children.
- design: blocked-by ordering is a TODO (not read by the scheduler); failure
  classification, success-when-tagged, one-time immediate rebuild, retries
  outside the thread-round budget, ID-based new-comment filter.
- executor contract: how core reads ExecResult, kill used for cancel, Windows
  quoting assumptions, codex exec resume without -C/-s.
2026-10-21 07:14:20 +00:00
jj.wang efbc5f6e27 Core: cancel moved runs, retry bookkeeping, progress cap, safer classification
- A run whose item leaves In Progress is killed, gets a [worker] cancel comment,
  frees its terminal slot and serialize group and keeps its thread id; if the
  kill fails the slot stays taken and the cancel is retried next tick.
- Transient retries are the same logical round: they do not count toward
  max_rounds_per_thread and do not trigger a max-rounds rebuild.
- New project setting max_progress_rounds (default 12): after that many
  consecutive [progress] rounds the item goes to Waiting (answerer) with a note.
- retry/rebuild markers are consumed only after the run launched, so a failed
  start no longer leaves an In Progress item that is never picked again; a
  rebuild is no longer reported as a retry.
- State is saved after every finished round and every launched run.
- Failure classification: transient patterns only look at the tail, and an
  exit-0 failure is logic (never retried) unless the tail shows a transient error.
- First-line tag: tolerate BOM and a leading code fence / rule line.
- Start comment notes when a handoff summary was attached.
2026-10-21 07:13:18 +00:00
jj.wang 00d42267e5 Harden transports and state files
- Executors and relay helpers get an environment without any configured
  Plane token / webhook secret (design 8: executors hold no Plane credentials).
- Windows runner: Set-Location -LiteralPath, and a failed cd writes exit=97
  instead of running the agent in the wrong directory.
- schtasks launch: escape apostrophes and pass the script path as \"...\" so
  paths with spaces survive PowerShell 5.1 native quoting.
- State and heartbeat files are written temp + fsync + rename.
- Tests for the above plus codex run/resume command shapes and unique run dirs.
2026-10-21 07:10:41 +00:00
jj.wang 08e3a7cc55 Design: deployment placement (oregon first, dedicated agentd-01 node from phase 3) 2026-10-21 07:04:59 +00:00
jj.wang 8dc8c465a2 Executor contract and runbook 2026-10-21 07:04:32 +00:00
jj.wang 31850c4a81 Scheduling core, state store, CLI and unit tests
One tick polls in-flight runs, posts results, classifies the first line and
moves state/assignee; failures get a structured note with transient retry and
backoff, timeouts are killed and handed over, resume failures and long threads
rebuild with a handoff summary. Then the lowest Todo items are dispatched within
terminal concurrency and serialize groups, and a heartbeat is written.
CLI: tick, new, show, comment, state, assign, smoke, check-config.
2026-10-21 07:04:32 +00:00
jj.wang 9535122c99 Plane client, transports and executor adapters
Plane: paginated issue/comment/state/label/member access, one client per
terminal identity. Transports: local (setsid-detached runner) and warpgate-ssh
(win10-ps.sh / win10-put.sh relay, schtasks launch, taskkill on timeout).
Executors share a runner shape (prompt.md, exit.txt marker) with codex,
claude-code and shell adapters for last message and thread id.
2026-10-21 07:04:32 +00:00
jj.wang 28e71f3ba7 Config schema, example config and validating loader
config/schema.json mirrors design §5 (terminals, executors, projects with routing,
retry, timeouts). agentd/config.py loads YAML, validates with jsonschema when
available or a small built-in draft-07 subset, adds cross-reference checks, and
maps token_key to the environment variable injected by agent-access exec.
2026-10-21 07:04:32 +00:00
jj.wang df4b873d0b Initial design for plane-agentd: Plane-driven generic agent dispatcher 2026-10-21 06:49:31 +00:00