duaer-spec 0.14.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/.duaer/active-job.json +4 -4
  2. package/.duaer/memory/testing.md +27 -8
  3. package/.duaer/specs/054-live-l3-smoke/delivery.json +9 -0
  4. package/.duaer/specs/054-live-l3-smoke/spec.md +41 -0
  5. package/.duaer/specs/054-live-l3-smoke/tasks.md +10 -0
  6. package/.duaer/specs/055-release-015/delivery.json +8 -0
  7. package/.duaer/specs/055-release-015/spec.md +16 -0
  8. package/.duaer/specs/055-release-015/tasks.md +4 -0
  9. package/.duaer/specs/056-revise-reliability/delivery.json +13 -0
  10. package/.duaer/specs/056-revise-reliability/spec.md +44 -0
  11. package/.duaer/specs/056-revise-reliability/tasks.md +10 -0
  12. package/.duaer/specs/057-progress-accepted/delivery.json +9 -0
  13. package/.duaer/specs/057-progress-accepted/spec.md +42 -0
  14. package/.duaer/specs/057-progress-accepted/tasks.md +8 -0
  15. package/.duaer/specs/058-revise-progress-track/delivery.json +13 -0
  16. package/.duaer/specs/058-revise-progress-track/spec.md +48 -0
  17. package/.duaer/specs/058-revise-progress-track/tasks.md +9 -0
  18. package/.duaer/specs/059-revise-preempt-order/delivery.json +13 -0
  19. package/.duaer/specs/059-revise-preempt-order/spec.md +47 -0
  20. package/.duaer/specs/059-revise-preempt-order/tasks.md +8 -0
  21. package/.duaer/specs/060-release-016/delivery.json +10 -0
  22. package/.duaer/specs/060-release-016/spec.md +24 -0
  23. package/.duaer/specs/060-release-016/tasks.md +4 -0
  24. package/CHANGELOG.md +39 -0
  25. package/README.md +5 -1
  26. package/README.zh-CN.md +5 -1
  27. package/bin/duaer-live.mjs +365 -53
  28. package/docs/agent/e2e-test-plan.md +8 -0
  29. package/package.json +4 -2
  30. package/web/live-dev/app.js +74 -15
  31. package/web/live-dev/i18n.js +33 -0
@@ -1,6 +1,6 @@
1
1
  {
2
- "featureDir": ".duaer/specs/053-release-014",
3
- "branch": "feat/release-014",
4
- "worktree": ".worktree/feat-release-014",
5
- "status": "active"
2
+ "featureDir": ".duaer/specs/060-release-016",
3
+ "branch": "feat/release-016",
4
+ "worktree": ".worktree/feat-release-016",
5
+ "status": "accepted"
6
6
  }
@@ -1,21 +1,22 @@
1
1
  # Testing expectations (project contract)
2
2
 
3
3
  Agents **must** read this file before marking work verified or accepting a job.
4
- Replace command examples with the adopting project's real scripts. Keep the
5
- level model and risk rules unless an ADR documents a change.
4
+ This file is the **duaer-spec** repo contract. Adopters replace command examples
5
+ with their product scripts; keep the level model and risk rules unless an ADR
6
+ documents a change.
6
7
 
7
8
  ## Levels
8
9
 
9
- | Level | What | Typical commands (replace) | Default owner |
10
+ | Level | What | Typical commands (this repo) | Default owner |
10
11
  |---|---|---|---|
11
- | **L0** | Lint / typecheck / static | `npm run lint`, `tsc --noEmit` | After every implementation pass |
12
- | **L1** | Unit tests for changed modules | `npm test` (or package subset) | Default for code changes |
12
+ | **L0** | Lint / typecheck / static | `node --check bin/duaer-live.mjs` `node --check web/live-dev/app.js` | After every implementation pass |
13
+ | **L1** | Unit tests for changed modules | `npm test` when unit files exist under `test/` | Default for code changes |
13
14
  | **L2** | Integration / product acceptance at changed boundaries | project acceptance or integration suite | When boundaries or core paths change |
14
- | **L3** | Automated E2E / browser for user-visible paths | `npm run test:e2e` or equivalent **subset** | When UI / protocol UX changes |
15
+ | **L3** | Automated E2E / protocol smoke for user-visible paths | **`npm run test:live`** (live desk shell + `/api/validate` gate; mock LLM, no paid API) | When live desk UI / protocol UX changes |
15
16
  | **L4** | Manual account / device path when automation cannot cover auth or real data | documented steps in the Brief | When UI/auth and no automated substitute |
16
17
 
17
18
  IDE Browser / MCP exploration is **optional discovery**. It does **not** replace
18
- L3 automation when the project has an E2E suite.
19
+ L3 when `npm run test:live` covers the touched path.
19
20
 
20
21
  ## Risk table (what to run)
21
22
 
@@ -24,12 +25,30 @@ L3 automation when the project has an E2E suite.
24
25
  | Docs / comments only | None (note in Brief) |
25
26
  | Internal code, same behavior | L0 + L1 for affected packages |
26
27
  | API / data / core path | L0 + L1 + L2 (or documented equivalent) |
27
- | User-visible or protocol-visible UI/UX | L0 + L1 + **L3 subset for touched flows** + update E2E catalog |
28
+ | User-visible or protocol-visible UI/UX (live desk) | L0 + **`npm run test:live` (L3)** + update E2E catalog |
28
29
  | Auth / payments / irreversible ops | Above + L4 if L3 cannot cover |
29
30
 
30
31
  Prefer **targeted subsets** over full monorepo suites. Do not skip a required
31
32
  level without an explicit waiver in the feature docs (`tasks.md` or Spec).
32
33
 
34
+ ## Live desk L3 (`npm run test:live`)
35
+
36
+ Covers without a paid LLM:
37
+
38
+ 1. Desk shell HTML/CSS/JS markers (three columns, structured confirm fields,
39
+ `validationAllowsSend`)
40
+ 2. Local validate failures (empty / too-short card)
41
+ 3. `/api/validate` pass and `/api/validate/fix` via an in-process mock
42
+ OpenAI-compatible server
43
+
44
+ Also run `npm test` (includes revise-reliability contract tests: Brief
45
+ snapshot/rollback helpers + source markers for `PREEMPT_FAILED` / longer
46
+ client timeout).
47
+
48
+ Does **not** cover: real model quality, live Terminal CLI launch against a
49
+ real Cursor/Claude session. Those stay manual E2E catalog rows (E2E-055) or
50
+ future suites.
51
+
33
52
  ## Opt-in (still need an explicit ask or Spec note)
34
53
 
35
54
  Mark these in the project table when they are expensive:
@@ -0,0 +1,9 @@
1
+ {
2
+ "status": "accepted",
3
+ "summary": "Added npm run test:live L3 smoke for desk shell + validate gate; documented in manuals and testing.md; CI on develop/main.",
4
+ "verification": {
5
+ "levels": ["L0", "L3"],
6
+ "commands": ["npm run test:live", "node --check bin/duaer-live.mjs"],
7
+ "notes": "Mock LLM; no paid API. E2E-054."
8
+ }
9
+ }
@@ -0,0 +1,41 @@
1
+ # Feature Specification: Live desk L3 smoke suite
2
+
3
+ **Feature Branch**: `feat/live-l3-smoke`
4
+
5
+ **Created**: 2026-09-17
6
+
7
+ **Status**: Active
8
+
9
+ ## Goal
10
+
11
+ Add an automated L3 smoke suite for the live desk (confirm validate gate +
12
+ desk shell markers) that agents run before accept on live UI changes, and
13
+ document it in the manuals / testing contract.
14
+
15
+ ## In scope
16
+
17
+ - `npm run test:live` — start isolated live + mock LLM; cover validate fail/pass,
18
+ validate/fix path, static desk markers (three columns, structured fields,
19
+ validationAllowsSend)
20
+ - Wire into `.duaer/memory/testing.md` as the L3 command for this repo
21
+ - Update README EN/ZH + CHANGELOG + E2E catalog
22
+ - Optional lightweight CI job on push/PR
23
+
24
+ ## Out of scope
25
+
26
+ - Full Playwright browser interaction / paid live LLM
27
+ - Revise Terminal dispatch end-to-end
28
+ - npm version bump / publish (docs only unless user asks)
29
+
30
+ ## Acceptance
31
+
32
+ 1. `npm run test:live` passes without network LLM
33
+ 2. Covers: empty/short card fail, good card pass via mock, fix endpoint,
34
+ HTML/JS/CSS desk markers for layout + gate
35
+ 3. README (EN/ZH) and testing.md document the command
36
+ 4. E2E catalog notes automated subset
37
+
38
+ ## Assumptions
39
+
40
+ - Worktree: `.worktree/feat-live-l3-smoke`
41
+ - Brief: `.duaer/specs/054-live-l3-smoke/`
@@ -0,0 +1,10 @@
1
+ # Tasks: Live desk L3 smoke suite
2
+
3
+ **Brief**: `.duaer/specs/054-live-l3-smoke/`
4
+
5
+ ## Checklist
6
+
7
+ - [x] Add `test/live-smoke.test.mjs` + mock LLM helper
8
+ - [x] `package.json` script `test:live`; update testing.md
9
+ - [x] README EN/ZH + CHANGELOG + E2E-054; CI workflow
10
+ - [x] Run `npm run test:live`; accept; merge develop
@@ -0,0 +1,8 @@
1
+ {
2
+ "status": "accepted",
3
+ "summary": "Release 0.15.0 with live L3 smoke suite.",
4
+ "verification": {
5
+ "levels": ["L3"],
6
+ "commands": ["npm run test:live"]
7
+ }
8
+ }
@@ -0,0 +1,16 @@
1
+ # Feature Specification: Release 0.15.0
2
+
3
+ **Feature Branch**: `feat/release-015`
4
+
5
+ **Created**: 2026-09-17
6
+
7
+ **Status**: Active
8
+
9
+ ## Goal
10
+
11
+ Ship **0.15.0** (live L3 smoke) to main + npm.
12
+
13
+ ## Acceptance
14
+
15
+ 1. package.json 0.15.0; CHANGELOG section dated
16
+ 2. main tagged v0.15.0; GitHub Release; npm latest 0.15.0
@@ -0,0 +1,4 @@
1
+ # Tasks: Release 0.15.0
2
+
3
+ - [x] Bump 0.15.0 + CHANGELOG
4
+ - [ ] Promote main; push; tag; gh release
@@ -0,0 +1,13 @@
1
+ {
2
+ "status": "accepted",
3
+ "summary": "Revise dispatch: honest preempt, Brief rollback on launch fail, structured retryable errors, terminal status line, longer client wait.",
4
+ "verification": {
5
+ "levels": ["L0", "L3"],
6
+ "commands": [
7
+ "node --check bin/duaer-live.mjs",
8
+ "npm run test:live",
9
+ "node --test test/revise-reliability.test.mjs"
10
+ ],
11
+ "notes": "E2E-055 manual for live Terminal preempt path."
12
+ }
13
+ }
@@ -0,0 +1,44 @@
1
+ # Feature Specification: Revise round reliability
2
+
3
+ **Feature Branch**: `feat/revise-reliability`
4
+
5
+ **Created**: 2026-09-17
6
+
7
+ **Status**: Active
8
+
9
+ ## Goal
10
+
11
+ Revise dispatch is **observable**, **retryable**, and failures are **readable**:
12
+ confirm → Terminal enqueue must not report success when preempt failed; Brief
13
+ mutations must not stick after a failed launch; client timeout matches server
14
+ budgets; status exposes Terminal busy/queue; UI keeps dispatch unlocked when
15
+ retryable.
16
+
17
+ ## In scope
18
+
19
+ - Honest preempt outcome (no false preempted / false HTTP 200)
20
+ - Rollback Brief writes if launch/enqueue fails
21
+ - Structured revise errors (`code`, `retryable`) + UI copy
22
+ - Align client `/api/revise` abort with recreate/init budgets (~3 min)
23
+ - `/api/status` includes `terminal: { busy, queueDepth, runnerHealthy }`
24
+ - Minimal status/hint line; extend L3 smoke for error shape / rollback unit
25
+
26
+ ## Out of scope
27
+
28
+ - Desk layout / column redesign
29
+ - Full Playwright Terminal automation
30
+ - Paid live LLM quality
31
+
32
+ ## Acceptance
33
+
34
+ 1. When preempt cannot clear leftover agents, `/api/revise` fails with
35
+ `PREEMPT_FAILED` and does **not** lock the revise card
36
+ 2. Failed launch does not leave a new Revision block in Brief (rollback)
37
+ 3. Client wait ≥ worst-case recreate path; timeout message mentions retry
38
+ 4. Status poll shows terminal busy/queue when revising
39
+ 5. `npm run test:live` still passes; new smoke/unit covers rollback or error codes
40
+
41
+ ## Assumptions
42
+
43
+ - Worktree: `.worktree/feat-revise-reliability`
44
+ - Brief: `.duaer/specs/056-revise-reliability/`
@@ -0,0 +1,10 @@
1
+ # Tasks: Revise round reliability
2
+
3
+ **Brief**: `.duaer/specs/056-revise-reliability/`
4
+
5
+ ## Checklist
6
+
7
+ - [x] Honest preempt + PREEMPT_FAILED; Brief rollback on launch fail
8
+ - [x] Structured errors on `/api/revise`; status.terminal
9
+ - [x] UI: longer timeout, retryable unlock, terminal line, i18n
10
+ - [x] L3 / unit smoke; docs; accept; merge develop
@@ -0,0 +1,9 @@
1
+ {
2
+ "status": "accepted",
3
+ "summary": "On delivery accepted, progress shows N/N and reconciles unchecked tasks.md boxes.",
4
+ "verification": {
5
+ "levels": ["L0", "L3"],
6
+ "commands": ["npm test"],
7
+ "notes": "E2E-056."
8
+ }
9
+ }
@@ -0,0 +1,42 @@
1
+ # Feature Specification: Progress sync when delivery accepted
2
+
3
+ **Feature Branch**: `fix/progress-accepted`
4
+
5
+ **Created**: 2026-09-17
6
+
7
+ **Status**: Active
8
+
9
+ ## Goal
10
+
11
+ Task progress must not show `0/N · delivery accepted · 工单完成`. When
12
+ `delivery.json` is `accepted`, the desk treats tasks as complete (done ===
13
+ total) and reconciles unchecked boxes in `tasks.md` when safe.
14
+
15
+ ## Problem
16
+
17
+ `dispatchStatus` only rewrites `progress.current` on accept; `done` stays at
18
+ the unchecked count. Agents often stamp `delivery.json` without flipping every
19
+ `- [ ]` to `- [x]`, so 任务跟进 shows a contradictory `0/3 · …工单完成`.
20
+
21
+ ## In scope
22
+
23
+ - Normalize progress when accepted: `done = total`, all task rows `done: true`
24
+ - Reconcile `tasks.md` unchecked boxes to `[x]` once when accepted (idempotent)
25
+ - Unit/smoke coverage; short README/CHANGELOG/E2E note
26
+
27
+ ## Out of scope
28
+
29
+ - Changing how agents are prompted (except if a one-line reminder helps)
30
+ - Progress column layout redesign
31
+
32
+ ## Acceptance
33
+
34
+ 1. Accepted delivery never surfaces `done < total` with an “工单完成 /
35
+ delivery accepted” current line
36
+ 2. Unchecked tasks in Brief are marked `[x]` after status observes accept
37
+ 3. `npm test` / `npm run test:live` pass
38
+
39
+ ## Assumptions
40
+
41
+ - Worktree: `.worktree/fix-progress-accepted`
42
+ - Brief: `.duaer/specs/057-progress-accepted/`
@@ -0,0 +1,8 @@
1
+ # Tasks: Progress sync when delivery accepted
2
+
3
+ **Brief**: `.duaer/specs/057-progress-accepted/`
4
+
5
+ ## Checklist
6
+
7
+ - [x] Normalize progress on accept; reconcile tasks.md
8
+ - [x] Tests + docs; accept; merge develop
@@ -0,0 +1,13 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-17T09:50:00.000Z",
4
+ "summary": "Revise-round progress scopes to Revision N / R{n}-* tasks; lagging accepted + busy Terminal no longer freezes on 工单完成.",
5
+ "verification": {
6
+ "levels": ["L0", "L1", "L3"],
7
+ "commands": [
8
+ "node --check bin/duaer-live.mjs",
9
+ "npm test"
10
+ ],
11
+ "result": "pass (14 tests)"
12
+ }
13
+ }
@@ -0,0 +1,48 @@
1
+ # Feature Specification: Track revise-round task progress
2
+
3
+ **Feature Branch**: `fix/revise-progress-track`
4
+
5
+ **Created**: 2026-09-17
6
+
7
+ **Status**: Accepted
8
+
9
+ ## Goal
10
+
11
+ After **Confirm revise and dispatch**, 任务跟进 shows **this revision’s**
12
+ checklist and updates as work starts — not the prior dispatch’s completed
13
+ `T001…` pile, and not a frozen “delivery accepted · 工单完成” while Terminal
14
+ is already running the revise.
15
+
16
+ ## Problem
17
+
18
+ Progress parses the whole `tasks.md`. After revise, old tasks stay `[x]` so
19
+ the bar looks finished (or accepted-normalized to N/N) while the new `R{n}-*`
20
+ round has started. Live `revisionCount` can lag; status may still say
21
+ `accepted`, so the wrong run-block is updated and revise work looks untracked.
22
+
23
+ ## In scope
24
+
25
+ - Scope progress to dispatch (pre-Revision section) vs active `Revision N`
26
+ - Infer active revision from job / delivery / tasks.md headers and `R{n}` ids
27
+ - While revising (or Terminal busy with open `R{n}` tasks), do not force
28
+ accept-complete progress
29
+ - Persist inferred `revisionCount` onto the live job when missing
30
+ - Tests + CHANGELOG / E2E note
31
+
32
+ ## Out of scope
33
+
34
+ - Layout / column redesign
35
+ - Changing revise launch / preempt behavior
36
+
37
+ ## Acceptance
38
+
39
+ 1. After Confirm revise, progress shows only this revision’s tasks (e.g. `0/3`
40
+ then rising), under the Revision N run block
41
+ 2. While revise is active, status is not stuck on `delivery accepted · 工单完成`
42
+ 3. When revise delivery accepts, that revision shows `N/N · …完成`
43
+ 4. `npm test` passes
44
+
45
+ ## Assumptions
46
+
47
+ - Worktree: `.worktree/fix-revise-progress-track`
48
+ - Brief: `.duaer/specs/058-revise-progress-track/`
@@ -0,0 +1,9 @@
1
+ # Tasks: Track revise-round task progress
2
+
3
+ **Brief**: `.duaer/specs/058-revise-progress-track/`
4
+
5
+ ## Checklist
6
+
7
+ - [x] Scope parseTasksProgress by revision; infer active revision
8
+ - [x] Revising / busy Terminal skips accept-complete normalize
9
+ - [x] Tests + docs; merge develop
@@ -0,0 +1,13 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-17T10:05:00.000Z",
4
+ "summary": "priorAccepted revise preempts leftovers before enqueue so Confirm revise no longer returns PREEMPT_FAILED while the revise Agent is already running.",
5
+ "verification": {
6
+ "levels": ["L0", "L1", "L3"],
7
+ "commands": [
8
+ "node --check bin/duaer-live.mjs",
9
+ "npm test"
10
+ ],
11
+ "result": "pass (14 tests)"
12
+ }
13
+ }
@@ -0,0 +1,47 @@
1
+ # Feature Specification: Honest revise preempt (enqueue after clear)
2
+
3
+ **Feature Branch**: `fix/revise-preempt-order`
4
+
5
+ **Created**: 2026-09-17
6
+
7
+ **Status**: Accepted
8
+
9
+ ## Goal
10
+
11
+ After Confirm revise, either the revise Agent is launched and the desk
12
+ reports success, or preempt truly failed and nothing was started — never
13
+ “Could not preempt…” while Terminal is already running the revise job.
14
+
15
+ ## Problem
16
+
17
+ `launchInTerminal` enqueues the revise job **before** preempt. Within the
18
+ post-preempt wait, the runner starts the new Agent; status then sees
19
+ `busy && agentsLeft > 0` and throws `PREEMPT_FAILED`. The API rolls back
20
+ Brief while the queued revise Agent keeps working — UI error, work already
21
+ underway; retries kill that Agent.
22
+
23
+ ## In scope
24
+
25
+ - Preempt leftover agents **before** enqueueing the revise Terminal job
26
+ - Fail `PREEMPT_FAILED` only when prior agents remain (nothing queued yet)
27
+ - Do not treat the newly started revise Agent as a preempt failure
28
+ - Tests + CHANGELOG / E2E note
29
+
30
+ ## Out of scope
31
+
32
+ - Progress scoping (058)
33
+ - Changing when priorAccepted revise preempts vs waits
34
+
35
+ ## Acceptance
36
+
37
+ 1. priorAccepted revise: preempt clears leftovers, then enqueue; HTTP 200
38
+ 2. If leftover agents cannot be cleared, `PREEMPT_FAILED` and **no** new
39
+ Terminal job for that attempt
40
+ 3. Desk does not show preempt failure while revise Agent is already running
41
+ from that same Confirm tap
42
+ 4. `npm test` passes
43
+
44
+ ## Assumptions
45
+
46
+ - Worktree: `.worktree/fix-revise-preempt-order`
47
+ - Brief: `.duaer/specs/059-revise-preempt-order/`
@@ -0,0 +1,8 @@
1
+ # Tasks: Honest revise preempt (enqueue after clear)
2
+
3
+ **Brief**: `.duaer/specs/059-revise-preempt-order/`
4
+
5
+ ## Checklist
6
+
7
+ - [x] Preempt before enqueue; fail only on leftover prior agents
8
+ - [x] Tests + docs; merge develop
@@ -0,0 +1,10 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-18T00:00:00.000Z",
4
+ "summary": "Release 0.16.0: honest revise preempt, revise progress scope, accept progress sync.",
5
+ "verification": {
6
+ "levels": ["L0", "L1", "L3"],
7
+ "commands": ["npm test"],
8
+ "result": "pass (14 tests)"
9
+ }
10
+ }
@@ -0,0 +1,24 @@
1
+ # Feature Specification: Release 0.16.0
2
+
3
+ **Feature Branch**: `feat/release-016`
4
+
5
+ **Created**: 2026-09-18
6
+
7
+ **Status**: Accepted
8
+
9
+ ## Goal
10
+
11
+ Ship **0.16.0** to `main` + npm: revise reliability (honest preempt order),
12
+ revise-round progress tracking, and accept progress sync.
13
+
14
+ ## Acceptance
15
+
16
+ 1. `package.json` version `0.16.0`; CHANGELOG dated section; Unreleased cleared
17
+ 2. `main` tagged `v0.16.0`; GitHub Release; npm `latest` is `0.16.0`
18
+ 3. `npm test` passes before promote
19
+
20
+ ## Assumptions
21
+
22
+ - Worktree: `.worktree/feat-release-016`
23
+ - Brief: `.duaer/specs/060-release-016/`
24
+ - User ask「发版」authorizes push + promote `develop` → `main`
@@ -0,0 +1,4 @@
1
+ # Tasks: Release 0.16.0
2
+
3
+ - [x] Bump 0.16.0 + CHANGELOG + light README notes
4
+ - [x] Verify `npm test`; merge develop; promote main; tag + npm
package/CHANGELOG.md CHANGED
@@ -1,5 +1,44 @@
1
1
  # Changelog
2
2
 
3
+ ## Unreleased
4
+
5
+ ## 0.16.0 — 2026-09-18
6
+
7
+ ### Honest revise preempt
8
+
9
+ - priorAccepted revise preempts leftover Agents **before** enqueueing the new
10
+ Terminal job (no false `PREEMPT_FAILED` while the revise Agent already runs)
11
+ - `PREEMPT_FAILED` only when leftovers remain — nothing queued for that attempt
12
+
13
+ ### Revise progress tracking
14
+
15
+ - After Confirm revise, task progress scopes to the active `Revision N` checklist
16
+ (not the prior dispatch’s completed `T*` pile)
17
+ - While revise is active (or Terminal is busy on open `R{n}` work), status does
18
+ not freeze on the accepted “job complete” label
19
+ - Live `revisionCount` is inferred from Brief/`tasks.md` when the job stamp lags
20
+
21
+ ### Progress sync when delivery accepted
22
+
23
+ - When `delivery.json` is `accepted`, task progress shows `N/N` (not `0/N` with
24
+ an accepted label)
25
+ - Unchecked `tasks.md` boxes are reconciled to `[x]` on status poll after accept
26
+
27
+ ### Revise round reliability
28
+
29
+ - Honest Terminal preempt: no false `preempted` / HTTP 200 when agents still run (`PREEMPT_FAILED`, retryable)
30
+ - Rollback Brief `spec.md` / `tasks.md` / `delivery.json` if revise launch fails
31
+ - `/api/status` includes `terminal: { busy, queueDepth, runnerHealthy }`; desk shows the line
32
+ - Client revise wait raised to ~3 minutes; structured error codes + keep Confirm revise unlocked on failure
33
+ - Stuck revising (busy Terminal, no task progress) resurfaces **Revise again**
34
+
35
+ ## 0.15.0 — 2026-09-17
36
+
37
+ ### Live desk L3 smoke
38
+
39
+ - `npm run test:live` — automated desk shell + `/api/validate` / `/api/validate/fix` with mock LLM
40
+ - Documented in `.duaer/memory/testing.md`, README EN/ZH; CI runs on push/PR to develop/main
41
+
3
42
  ## 0.14.0 — 2026-09-17
4
43
 
5
44
  ### Live desk layout
package/README.md CHANGED
@@ -64,6 +64,10 @@ Open the printed URL (default `http://127.0.0.1:8787`). The desk is **full-width
64
64
  with three columns: **chat** | **requirements / confirm / dispatch / revise** |
65
65
  **task progress**.
66
66
 
67
+ **Verify (maintainers / agents):** after live desk UI or validate-gate changes,
68
+ run `npm run test:live` (L3 smoke: desk shell markers + `/api/validate` with a
69
+ mock LLM — no paid API).
70
+
67
71
  **Flow**
68
72
 
69
73
  1. Dialogue → fill the confirm card (structured goal / out-of-scope / acceptance /
@@ -73,7 +77,7 @@ with three columns: **chat** | **requirements / confirm / dispatch / revise** |
73
77
  3. Choose a **CLI** digital employee: **Cursor Agent** or **Claude Code** (install Cursor CLI if needed: `curl https://cursor.com/install -fsS | bash`)
74
78
  4. Edit the start command (must begin with `Duaer`) → dispatch creates `.worktree/feat-*` and opens **Terminal** to run the CLI
75
79
  5. Watch progress in the right column (`tasks.md`); when `delivery.json` is `accepted`, open **View product** (`preview.url` or auto-detected `index.html`)
76
- 6. If the result is not right: click **Continue improving (left chat)**, clarify why and what to change, confirm the revise card (same validate gate), then the desk relaunches with `agent --continue` / `claude --continue` on the same worktree
80
+ 6. If the result is not right: click **Continue improving (left chat)**, clarify why and what to change, confirm the revise card (same validate gate), then the desk relaunches on the same worktree (preempt leftover Agents before enqueueing revise). Progress tracks this revision’s `R{n}-*` tasks. Failed launch rolls back the Brief Revision and keeps **Confirm revise** available; status shows Terminal busy/queue.
77
81
  7. If the job needs hosting / a public URL, deploy with **GitHub CLI (`gh`) + Actions** (Pages template under `.duaer/templates/deploy-github-pages.yml`; see [`docs/agent/deploy-github.md`](docs/agent/deploy-github.md))
78
82
 
79
83
  Worktree id ≠ Brief folder name — use `.worktree/feat-<name>/`, Brief under `.duaer/specs/<nnn-slug>/` inside that worktree.
package/README.zh-CN.md CHANGED
@@ -64,6 +64,10 @@ duaer live
64
64
  浏览器打开提示地址(默认 `http://127.0.0.1:8787`)。台面**全屏宽**,三列:
65
65
  **对话** | **需求 / 确认 / 派工 / 改进** | **任务进度**。
66
66
 
67
+ **验收(维护者 / 数字员工):** 改现场台 UI 或确认校验门禁后,跑
68
+ `npm run test:live`(L3 冒烟:台面结构标记 + `/api/validate`,内置 mock 模型,
69
+ 不产生付费 API 调用)。
70
+
67
71
  **流程**
68
72
 
69
73
  1. 多轮对话 → 确认卡(目标 / 不做 / 验收 / 假设,结构化展示)。须**校验通过**后才能点确认;失败可自动修订
@@ -71,7 +75,7 @@ duaer live
71
75
  3. 只选 **CLI 数字员工**:**Cursor Agent** 或 **Claude Code**(未装 Cursor 时页面会提示:`curl https://cursor.com/install -fsS | bash`)
72
76
  4. 编辑「启动命令」(须以 `Duaer` 开头)→ 派工建 `.worktree/feat-*`,并打开 **Terminal** 跑对应 CLI
73
77
  5. 右侧进度列轮询 `tasks.md`;`delivery.json` 为 `accepted` 后出现 **查看成品**(`preview.url`,或自动发现 `index.html`)
74
- 6. 成品不满意:点 **继续改进(左侧对话)**,说清原因与期望,确认改进卡(同样须校验通过)后,用 Terminal `agent --continue` / `claude --continue` 续派(`POST /api/revise`)
78
+ 6. 成品不满意:点 **继续改进(左侧对话)**,说清原因与期望,确认改进卡(同样须校验通过)后续派(先清残留 Agent 再入队)。进度跟本轮 `R{n}-*` 任务。启动失败会回滚本轮 Brief Revision,并可再点「再派一版」;状态行显示 Terminal 忙闲/队列。
75
79
  7. 若需求需要上线 / 公网访问:默认用 **GitHub CLI(`gh`)+ Actions** 自动化部署(静态站可参考 `.duaer/templates/deploy-github-pages.yml`;说明见英文 [`docs/agent/deploy-github.md`](docs/agent/deploy-github.md))
76
80
 
77
81
  ### 文档语言