Commit Graph
10 Commits
Author SHA1 Message Date
host ee8d1e1e28 code-to10 v6 A5: admin CLI wiring for stale-worker reap
- New production caller cloud/worker_sweep.py (python -m
  cloud.worker_sweep): AuthStore.authenticate + CODEX_GLOBAL_ADMINS
  global-admin check (same fail-closed semantics as
  handler_admin._is_global_admin) before any reap call; denied
  authenticated non-admins get an admin_worker_sweep_denied audit
  row; authorized runs reuse reap_stale_workers (classify, re-verify,
  pre-kill audit fail-closed, per-pid SIGKILL only, post-kill
  verification) plus an admin_worker_sweep summary audit; --dry-run
  lists classifications only.
- No new HTTP route, no container enumeration, no name/prefix
  matching, no workers-row deletion; workers.py docstring only notes
  the new caller.
- Tests: cloud/tests/test_worker_sweep_admin.py, 6 cases (bad key,
  non-admin, unconfigured admin list fail-closed, authorized full
  chain, dry-run, CLI main authorized/refused).

(cherry picked from commit c7d217549c5ccedf61dcc924b8998fffeddc76c6)
2026-11-03 02:49:26 +00:00
host 6bceed484c code-to10 v5: solidify 7 provisional resolutions per user confirmation (2026-11-02)
- whitelist expansion (tr + exit builtin) confirmed, comment only
- B4 viewport wording: temp banner removed, wording untouched,
  change-list table stays in draft, not merged into body
- B3-tail (a)/(b): no content change (bullet still absent), recorded
  as decided; v2 record showed it unselected, no side picked here
- section 4: 6 templates/artifacts/ refs deleted per signed verdict;
  tripwire test updated 6 -> 0 to pin the new inventory
- CHANGELOG pointer line kept, no marker present
- workers audit landing migration confirmed, comment only
- verify-script gate evidence confirmed, gate hard untouched
- 2 temp stances NOT touched: actual-only quota, evidence binding
  not enforced / no anti-restamp
- behavior code unchanged; directional skill tests 39/39 OK
2026-11-03 02:49:26 +00:00
host c900a0f78d v2 provisional: clear integration 9 failures (whitelist tr+exit, B4 viewport draft, CHANGELOG pointer, workers audit via audit_on_conn, verify-multiuser gate evidence)
9 failures from v1 baseline 02835f6 cleared with provisional resolutions only;
each option pair is annotated provisional in verification/code-to10-v2-failures-summary.md
and awaits user confirmation. No check deleted, no skip added, no bare-phrase
stuffing, default hard merge gate untouched. Known remainder: one pre-existing
date-dependent test_arch_converge failure (Oct-dated fixture vs Nov current
month), failing on pristine v1 too, left for the quota track.
2026-11-03 02:49:26 +00:00
host 41e8c98512 feat: cloud 门禁/超时/成本/沙箱收敛为单一判定源
- 新增标准库叶子层 timeouts/gates/quota/sandbox_policy:
  审批 3600 与单轮 600 各有名常量与环境覆盖层,已建项
  expires_at 永不重算;目录/控制/合并状态门禁统一判定,
  目录违规无任何覆盖参数;配额取数与比较唯一来源
  (USD 先于无价、命中均为 >=、无价只计 actual 行);
  /tmp 隔离矩阵与失联清理判定纯函数化。
- 调用点委托:server/worker/automations/auto_memory 的
  配额 SQL 与比较、server/tree/marker 的目录解析、
  marker 的控制门、sandbox 的任务容器名正则、两处 300 秒
  陈旧阈值默认值均收敛,别名与错误文案不变。
- 统一两个 P0 口径分歧:服务端无价计数由全部 usd IS NULL
  行改为 actual-only;显式不限额用户在服务端准入亦不受
  无价上限约束(与 worker 运行时一致)。
- 不新增门禁种类与 record 模式(主线无此实现);不改
  skill_seed/skills/SKILL.md;不改 v1.1 契约与分支保护。
- 新增 test_arch_converge.py 18 项。
2026-11-03 02:49:25 +00:00
host 06710cf47b feat: 沙箱规模——/tmp 顺序加严、注册表寻址与失联精确清理、超时边界抽取
- Docker /tmp tmpfs 移到全部 -v 之前(父挂载在前,seed 子挂载在后);
  宿主级 bwrap /tmp 仍宣告未隔离,口径见 tmp_isolation_status()
- workers 表补 host/pid/address(老库幂等补列),心跳透传与保留语义,
  _claim 写 claimed_by_worker;orphaned_containers 精确识别失联容器,
  Worker.cleanup_orphaned_containers 默认只杀 pid_verified 的精确容器名
- docker_run_timeout() 纯函数抽取(行为与原内联一致),README 补边界与
  未验证清单;新增 test_sandbox_scale.py 20 项
2026-11-03 02:49:25 +00:00
host a9e2f70d9e workers: reap pid_verified stale workers with pre-kill audit and post-kill verification 2026-11-03 02:48:55 +00:00
host 8ea54cf66b workers: land host/pid/address columns with idempotent migration and pid_verified stale classification
- ensure_workers_table: new tables include host TEXT, pid BIGINT,
  address TEXT; old tables gain them via _ensure_hostpid_columns
  (PRAGMA column check, missing-only ALTER, old rows keep NULL,
  never fabricates host/pid). SQLite and Postgres share this path
  (PG via the db adapter's PRAGMA translation); POSTGRES_SCHEMA
  deliberately still excludes workers, which is volatile heartbeat
  data in UNMIGRATED_TABLES (adding it broke the P2 migration
  alignment tests, verified and reverted).
- heartbeat/register: given host/pid/address refresh, omitted
  values preserve the old row; address has no derived source.
  Local worker passes host_name + own pid; HTTP heartbeat only
  stores caller-supplied values, never the server's own.
- classify_stale_workers: kill only when age strictly exceeds the
  threshold AND host matches local host AND pid is proven dead;
  equal threshold, foreign host, missing pid, or live/unknown pid
  are list_only. Classification only, never kills, never matches
  by name/prefix, never touches infra containers.
2026-11-03 02:48:55 +00:00
host e0cecd70aa feat: P1 补齐(自动评审队列、自动化+分诊、并发 caps、运行时审批队列) 2026-10-27 15:53:50 +08:00
host e2d6a454bf Fix workers time columns to DOUBLE PRECISION on Postgres
SQLite REAL is 8-byte double, but Postgres REAL is 4-byte
float4 (~7 significant digits). Epoch seconds (10 digits) were
rounded to 128-second steps, so worker liveness ages were off
by up to +-64s and could even go negative (observed live on
the host: last_seen ahead of NOW() by 20s). New tables use
DOUBLE PRECISION; existing Postgres tables are upgraded only
when information_schema actually reports REAL, so the ALTER
does not run on every heartbeat (it would take an ACCESS
EXCLUSIVE lock each time). SQLite path is unchanged (its
REAL is already double precision).
Regression test asserts new tables use DOUBLE PRECISION.
2026-10-26 05:04:59 +08:00
host 306cdf0d0c Cloud dispatch pool + auto PR (opt-in, skip clearly)
Worker pool: workers table + register/heartbeat (heartbeat is
registration, no 404), GET /workers with alive (120s default),
POST /workers/heartbeat (X-API-Key, missing worker_id 400).
Tasks gain executor (local/docker/cloud, None = any worker);
worker claim filters by executor in pick_next and in the CAS
WHERE clause, CAS semantics unchanged; CloudExecutor _name
now correctly returns cloud, not local.
CloudExecutor: generic HTTP runner interface (endpoint from
explicit arg or CLOUD_RUNNER_ENDPOINT, auth header name only,
token value only from env into the request header, never into
logs/body/errors); no endpoint configured = explicit failure,
never silent downgrade. Vendor adapters (ECS/Cloud Run) are
out of scope, documented as such.
Auto PR: projects.auto_pr (0/1, create-time only, no PATCH
route exists); POST /tasks/{id}/pr (maintainer+ via
approve_merge) only for merged tasks (else 409); skip reasons
in order: auto_pr_disabled, no_worktree, no_remote, no_gh,
gh_not_authenticated — all return 200 with pr_skipped, task
stays merged, no push attempted; push/pr-create failure
returns 502 with step, task stays merged; success writes
pr_url/pr_number and audits pr_created. No default auto-push
from the worker. Remote URLs in errors are scrubbed of
userinfo; gh credentials are managed by gh itself, never
stored by the control plane.
Tests: host 27 pass, cloud 323 pass (8 skipped are
environment-dependent real-Postgres tests).
2026-10-26 04:57:37 +08:00