emrg: GUI task form sandbox field — three-tier select with backend-consistent default - #896
Conversation
…nsistent default Rant 2026-08-20T18:06:44: the GUI add/edit task form had no sandbox support although the backend (scheduler task_create/task_update) validates and stores it. Add a sandbox select (workspace-write / read-only / danger-full-access, default workspace-write matching the backend default), prefill in openTaskForm, include it in saveTaskForm payload, plus i18n key and smoke-test coverage (default, edit prefill, payload on create and update).
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle 1 (4 files +28/−1: sandbox select in #task-form with backend-consistent default workspace-write; openTaskForm prefills task.sandbox; saveTaskForm payload includes sandbox; i18n settings.taskSandbox zh/en; smoke tests cover default, edit prefill, create/update payload. GUI 246 pass + 7 integration (local-only, daemon holds port), renderer smoke 125/125, other suites 121/121, node --check clean, pytest 982 + 1 skipped; test + test-windows CI PASS)
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle 2 (independent re-review: head 786ae46 unchanged; sandbox select with three tiers, default workspace-write matching backend; prefill reads task.sandbox; payload includes sandbox; i18n keys zh/en; smoke tests cover default + edit prefill + create/update payload. renderer smoke + i18n 140/140, pytest 984 collected green; test + test-windows CI PASS)
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle 3 (fresh re-review: head 786ae46 unchanged, diff identical; sandbox three-tier select, default workspace-write, prefill + payload + i18n + smoke coverage; pytest 982 pass + 1 skip, renderer smoke + i18n 140/140; test + test-windows CI PASS)
…rt (fixed-port admission regression) (#906) Since #861 (rant 2026-08-19T08:05:21) the daemon binds a FIXED loopback port (56031) as its single-instance admission, and #884 (rant 2026-08-20T14:32:52) moved the auth credential to emrgd.token (port no longer carried in any file). The GUI integration suite spawns its OWN isolated daemon (HOME->tmp) — on any host where the real daemon is already running (the normal dev-machine state), the isolated daemon cannot bind 56031 (EADDRINUSE) and exits, so every test times out with "daemon token file timeout" (7 failures on ). CI stays green only because runners have no live daemon. Fix: probe 127.0.0.1:56031 at module load; when a live daemon already owns the fixed port, skip the whole suite with a clear message (same mechanism as EMRG_SKIP_INTEGRATION, extended to the live-daemon state — the isolated-daemon premise is impossible there). CI (daemon-free runners) still runs the full suite. Also sync Agent.md GUI test count: 260 -> 254 (renderer.smoke 131->126, i18n 16->15 drifted in #896-#905 without doc re-sync; the doc-count guard only checks breakdown-sum consistency, not actual collection). Verified: pytest 984+1 green, GUI 247 pass / 0 fail (8 skipped on this daemon-hosting host), import + --help OK.
) The doc-count guard only validated Agent.md's GUI line against *itself* (parts sum to the headline, #584) — it could not see the test files, so the per-file counts could drift silently. #906 hit exactly that when it hand-synced the GUI count 260 -> 254 after #896-#905 drifted, and called the gap out in its own message ("the doc-count guard only checks breakdown-sum consistency, not actual collection"). R2254 later gave the *renderer* headline a static reality check, but the GUI line stayed unguarded. This adds test_gui_breakdown_matches_static_counts: it globs emrg/gui/test/*.test.js, counts the `test(`/`it(` definitions per file (node --test reports one entry per definition, so the definition count is the executed total), and asserts every file is documented with a matching count — no undocumented file, no stale label, headline == the real total. It runs in the pytest job, so no node_modules are needed. The integration file's conditional module-level skip(<reason>) entry (#906) is a runtime reason entry, not a definition, so it is excluded on purpose: Agent.md's 100 counts definitions, while CI's `EMRG_SKIP_INTEGRATION=1 npm test` prints 101 including that skip entry. Verified positive: tests/test_doc_counts.py 6 passed; negative: corrupting "7 integration" -> "8 integration" fails with "Agent.md documents 8 integration GUI tests but 7 are defined ...", and renaming a label fails with "undocumented files: ['preload-api']; stale labels: ['preload-api-x']". Full suite 1243 collected (1175 passed, 68 skipped) — Agent.md pytest count 1242 -> 1243; import + --help OK. Co-authored-by: EMRG Evolution <emrg@argszero.dev>
Add sandbox tier support to the GUI add/edit task form, per host rant 2026-08-20T18:06:44.
Before: the GUI task form (index.html #task-form) only had name/type/project/interval/enabled/repo — sandbox could only be set by hand-editing tasks.yml, although the backend (scheduler
task_create/task_updatevalidation at scheduler.py:1308/1367, daemon passthrough, handler parsing) already supports it.After:
openTaskForm(): prefills the current task's sandbox (default workspace-write, matching the backend default)saveTaskForm(): payload now includessandboxsettings.taskSandboxkey (zh/en)Verification: pytest 982 passed + 1 skipped; GUI 246 pass + 7 integration (local-only by design, real daemon holds the port); renderer smoke 125/125 + all non-integration suites 121/121; node --check clean.