duaer-spec 0.25.1 → 0.27.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 (93) hide show
  1. package/.claude/rules/ai-ui-copy.md +2 -2
  2. package/.cursor/rules/ai-ui-copy.mdc +3 -3
  3. package/.cursor/rules/fde-8787-only.mdc +7 -7
  4. package/.duaer/active-job.json +3 -3
  5. package/.duaer/specs/252-release-0251/delivery.json +14 -0
  6. package/.duaer/specs/252-release-0251/tasks.md +1 -1
  7. package/.duaer/specs/253-docs-cursor-claude/delivery.json +9 -0
  8. package/.duaer/specs/253-docs-cursor-claude/spec.md +25 -0
  9. package/.duaer/specs/253-docs-cursor-claude/tasks.md +3 -0
  10. package/.duaer/specs/254-console-rename/delivery.json +13 -0
  11. package/.duaer/specs/254-console-rename/spec.md +27 -0
  12. package/.duaer/specs/254-console-rename/tasks.md +4 -0
  13. package/.duaer/specs/255-dispatch-arch-view/delivery.json +13 -0
  14. package/.duaer/specs/255-dispatch-arch-view/spec.md +16 -0
  15. package/.duaer/specs/255-dispatch-arch-view/tasks.md +4 -0
  16. package/.duaer/specs/256-chat-voice/delivery.json +13 -0
  17. package/.duaer/specs/256-chat-voice/spec.md +15 -0
  18. package/.duaer/specs/256-chat-voice/tasks.md +6 -0
  19. package/.duaer/specs/257-composer-voice-compact/delivery.json +9 -0
  20. package/.duaer/specs/257-composer-voice-compact/spec.md +13 -0
  21. package/.duaer/specs/257-composer-voice-compact/tasks.md +4 -0
  22. package/.duaer/specs/258-chat-stt/delivery.json +14 -0
  23. package/.duaer/specs/258-chat-stt/spec.md +16 -0
  24. package/.duaer/specs/258-chat-stt/tasks.md +5 -0
  25. package/.duaer/specs/259-voice-guide-stt/delivery.json +13 -0
  26. package/.duaer/specs/259-voice-guide-stt/spec.md +13 -0
  27. package/.duaer/specs/259-voice-guide-stt/tasks.md +4 -0
  28. package/.duaer/specs/260-release-026/delivery.json +19 -0
  29. package/.duaer/specs/260-release-026/spec.md +12 -0
  30. package/.duaer/specs/260-release-026/tasks.md +3 -0
  31. package/.duaer/specs/261-fde-baseline-sign/delivery.json +10 -0
  32. package/.duaer/specs/261-fde-baseline-sign/spec.md +37 -0
  33. package/.duaer/specs/261-fde-baseline-sign/tasks.md +8 -0
  34. package/.duaer/specs/262-fde01-readme-docs/delivery.json +9 -0
  35. package/.duaer/specs/262-fde01-readme-docs/spec.md +23 -0
  36. package/.duaer/specs/262-fde01-readme-docs/tasks.md +5 -0
  37. package/.duaer/specs/263-arch-edge-via/delivery.json +9 -0
  38. package/.duaer/specs/263-arch-edge-via/spec.md +25 -0
  39. package/.duaer/specs/263-arch-edge-via/tasks.md +5 -0
  40. package/.duaer/specs/264-baseline-field-guide/delivery.json +10 -0
  41. package/.duaer/specs/264-baseline-field-guide/spec.md +23 -0
  42. package/.duaer/specs/264-baseline-field-guide/tasks.md +5 -0
  43. package/.duaer/specs/265-baseline-chat-passthrough/delivery.json +9 -0
  44. package/.duaer/specs/265-baseline-chat-passthrough/spec.md +22 -0
  45. package/.duaer/specs/265-baseline-chat-passthrough/tasks.md +4 -0
  46. package/.duaer/specs/266-fde02-api-contract/delivery.json +10 -0
  47. package/.duaer/specs/266-fde02-api-contract/spec.md +28 -0
  48. package/.duaer/specs/266-fde02-api-contract/tasks.md +7 -0
  49. package/.duaer/specs/267-baseline-restore/delivery.json +9 -0
  50. package/.duaer/specs/267-baseline-restore/spec.md +24 -0
  51. package/.duaer/specs/267-baseline-restore/tasks.md +5 -0
  52. package/.duaer/specs/268-fde07-uat/delivery.json +9 -0
  53. package/.duaer/specs/268-fde07-uat/spec.md +30 -0
  54. package/.duaer/specs/268-fde07-uat/tasks.md +5 -0
  55. package/.duaer/specs/269-release-027/spec.md +12 -0
  56. package/.duaer/specs/269-release-027/tasks.md +4 -0
  57. package/ADOPT.md +7 -4
  58. package/AGENTS.md +2 -2
  59. package/CHANGELOG.md +84 -0
  60. package/README.md +50 -38
  61. package/README.zh-CN.md +26 -25
  62. package/bin/duaer-live.mjs +347 -85
  63. package/bin/live-archify.mjs +85 -0
  64. package/bin/live-bug-context.mjs +1 -1
  65. package/bin/live-deliverables.mjs +54 -1
  66. package/bin/live-modules.mjs +63 -2
  67. package/bin/live-project-chat.mjs +18 -1
  68. package/bin/live-verify-gate.mjs +2 -2
  69. package/docs/agent/e2e-test-plan.md +22 -0
  70. package/docs/agent/live-desk.md +27 -7
  71. package/docs/agent/worker-models.md +7 -5
  72. package/docs/agent/worker-models.zh-CN.md +5 -3
  73. package/package.json +5 -5
  74. package/web/live-dev/api-contract.mjs +50 -0
  75. package/web/live-dev/app.js +664 -21
  76. package/web/live-dev/baseline.mjs +71 -0
  77. package/web/live-dev/confirm-card.mjs +19 -0
  78. package/web/live-dev/dispatch-center.html +25 -1
  79. package/web/live-dev/dispatch-center.js +113 -16
  80. package/web/live-dev/employee-catalog.mjs +2 -2
  81. package/web/live-dev/i18n-de.js +60 -8
  82. package/web/live-dev/i18n-es.js +60 -8
  83. package/web/live-dev/i18n-fr.js +60 -8
  84. package/web/live-dev/i18n-ja.js +60 -8
  85. package/web/live-dev/i18n-ko.js +60 -8
  86. package/web/live-dev/i18n-pt-BR.js +60 -8
  87. package/web/live-dev/i18n-ru.js +60 -8
  88. package/web/live-dev/i18n-vi.js +60 -8
  89. package/web/live-dev/i18n-zh-TW.js +62 -10
  90. package/web/live-dev/i18n.js +126 -21
  91. package/web/live-dev/index.html +97 -10
  92. package/web/live-dev/styles.css +63 -3
  93. package/web/live-dev/uat-pack.mjs +21 -0
@@ -13,7 +13,7 @@ AI-generated pages must not contain redundant explanatory text.
13
13
  Visible live-desk / FDE copy that names the product surface must include the
14
14
  **Duaer** brand (or **Duaer-spec FDE** where that full mark is already used).
15
15
 
16
- - Do not write anonymous「台面」/desk” alone when referring to this product’s
17
- chat surface or model setup — prefer「Duaer 台面」/ “Duaer desk
16
+ - Do not write anonymous「控制台」/console” alone when referring to this product’s
17
+ chat surface or model setup — prefer「Duaer 控制台」/ “Duaer console
18
18
  - Keep helper text short; branding is a name signal, not a slogan paragraph
19
19
  - Applies to i18n strings, HTML fallbacks, empty states, and setup/settings copy
@@ -13,10 +13,10 @@ AI-generated pages must not contain redundant explanatory text.
13
13
 
14
14
  ## Duaer brand (site-wide)
15
15
 
16
- Visible live-desk / FDE copy that names the product surface must include the
16
+ Visible live-console / FDE copy that names the product surface must include the
17
17
  **Duaer** brand (or **Duaer-spec FDE** where that full mark is already used).
18
18
 
19
- - Do not write anonymous「台面」/desk” alone when referring to this product’s
20
- chat surface or model setup — prefer「Duaer 台面」/ “Duaer desk
19
+ - Do not write anonymous「控制台」/console” alone when referring to this product’s
20
+ chat surface or model setup — prefer「Duaer 控制台」/ “Duaer console
21
21
  - Keep helper text short; branding is a name signal, not a slogan paragraph
22
22
  - Applies to i18n strings, HTML fallbacks, empty states, and setup/settings copy
@@ -1,11 +1,11 @@
1
1
  ---
2
- description: FDE live desk is only http://127.0.0.1:8787 — never alternate ports
2
+ description: FDE live console is only http://127.0.0.1:8787 — never alternate ports
3
3
  alwaysApply: true
4
4
  ---
5
5
 
6
- # FDE desk port (8787 only)
6
+ # FDE console port (8787 only)
7
7
 
8
- The Duaer-spec FDE desk has **one** URL:
8
+ The Duaer-spec FDE console has **one** URL:
9
9
 
10
10
  `http://127.0.0.1:8787`
11
11
 
@@ -16,16 +16,16 @@ Managed by LaunchAgent `com.duaer.live8787`.
16
16
  - Check / restart with `launchctl kickstart -k "gui/$(id -u)/com.duaer.live8787"`
17
17
  - Verify with `curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8787/`
18
18
  - After merge handoff, restart that LaunchAgent only (see `.duaer/handoff.json`)
19
- - Open architecture / 派工图 via desk `POST /api/open-external` (OS browser on :8787)
19
+ - Open architecture / 派工图 via console `POST /api/open-external` (OS browser on :8787)
20
20
 
21
21
  ## Do not
22
22
 
23
23
  - Start `node bin/duaer-live.mjs` on any port other than **8787**
24
- - Start a second desk when 8787 is already listening
25
- - Use Cursor Browser / Simple Browser / browser MCP to open the desk or
24
+ - Start a second console when 8787 is already listening
25
+ - Use Cursor Browser / Simple Browser / browser MCP to open the console or
26
26
  architecture present pages — Cursor proxies those as random high ports
27
27
  (`:62489`, `:64074`, …). That is **not** a second FDE server.
28
- - Treat product preview ports (3000, 8081, …) as the FDE desk
28
+ - Treat product preview ports (3000, 8081, …) as the FDE console
29
29
 
30
30
  Interactive `duaer live` may still open the OS browser once; LaunchAgent sets
31
31
  `DUAER_LIVE_NO_BROWSER=1` so kickstart does not spam tabs.
@@ -1,5 +1,5 @@
1
1
  {
2
- "feature": "252-release-0251",
3
- "specPath": ".duaer/specs/252-release-0251/spec.md",
4
- "source": "chat"
2
+ "feature": "269-release-027",
3
+ "branch": "chore/release-027",
4
+ "worktree": ".worktree/chore-release-027"
5
5
  }
@@ -0,0 +1,14 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-20T09:25:00.000Z",
4
+ "verification": {
5
+ "levels": ["docs"],
6
+ "commands": ["gh release view v0.25.1", "gh run list --workflow=npm-publish.yml"],
7
+ "result": "pass",
8
+ "notes": "GitHub Release v0.25.1 published; npm Trusted Publishing triggered"
9
+ },
10
+ "preview": {
11
+ "url": "https://github.com/fujiezee/duaer-spec/releases/tag/v0.25.1",
12
+ "label": "GitHub Release v0.25.1"
13
+ }
14
+ }
@@ -1,3 +1,3 @@
1
1
  - [x] T001 Bump package.json to 0.25.1 and fold CHANGELOG
2
2
  - [x] T002 Update README architecture note (en + zh-CN)
3
- - [ ] T003 Merge develop, promote main, push, GitHub release + npm
3
+ - [x] T003 Merge develop, promote main, push, GitHub release + npm
@@ -0,0 +1,9 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-20T09:35:00.000Z",
4
+ "verification": {
5
+ "levels": ["docs"],
6
+ "commands": ["docs-only review"],
7
+ "result": "pass"
8
+ }
9
+ }
@@ -0,0 +1,25 @@
1
+ # Docs: Cursor + Claude Code primary; no professional workflow required
2
+
3
+ ## Goal
4
+
5
+ User-facing docs lead with **Cursor** and **Claude Code** as the supported
6
+ way to use Duaer. Copy must say the human does **not** need to learn Spec
7
+ phases, slash commands, or a professional delivery process — install once,
8
+ then talk in normal language.
9
+
10
+ ## In scope
11
+
12
+ - `README.md` / `README.zh-CN.md` hero and “what you get” host bullets
13
+ - Light note in `ADOPT.md` / worker-models if they over-list hosts as “supported”
14
+ - CHANGELOG Unreleased
15
+
16
+ ## Out of scope
17
+
18
+ - Removing init adapters for other hosts (still installed; not the pitch)
19
+ - Product code / FDE UI copy unless README already covers it
20
+
21
+ ## Acceptance
22
+
23
+ 1. Hero no longer pitches the long host list as the primary support claim.
24
+ 2. Explicit: Cursor + Claude Code; no need to understand professional workflow.
25
+ 3. English docs stay CJK-free; Chinese README may keep English product names.
@@ -0,0 +1,3 @@
1
+ - [x] T001 Rewrite README.md + README.zh-CN.md hero / host bullets
2
+ - [x] T002 Align ADOPT.md / worker-models support wording if needed
3
+ - [x] T003 CHANGELOG Unreleased; stamp delivery
@@ -0,0 +1,13 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-20T09:40:00.000Z",
4
+ "verification": {
5
+ "levels": ["L0", "L1", "L3"],
6
+ "commands": [
7
+ "node --test test/duaer-fde-brand.test.mjs",
8
+ "npm test",
9
+ "npm run test:live"
10
+ ],
11
+ "result": "pass"
12
+ }
13
+ }
@@ -0,0 +1,27 @@
1
+ # Rename product surface「台面」→「控制台」
2
+
3
+ ## Goal
4
+
5
+ User-visible Chinese copy must say **控制台** (not 台面) for the FDE product
6
+ surface. English parallel: **console** (not desk) in the same user-facing spots.
7
+ Brand form: **Duaer 控制台** / **Duaer console**.
8
+
9
+ ## In scope
10
+
11
+ - live-dev i18n (zh-CN + en + locales that say desk/台面)
12
+ - HTML fallbacks, employee-catalog, duaer-live user messages, README.zh-CN,
13
+ worker-models.zh-CN, brand rules (AGENTS / ai-ui-copy), brand tests
14
+ - README.md “live desk” → “console” where it names the product surface
15
+
16
+ ## Out of scope
17
+
18
+ - Renaming DOM ids (`#desk`), `deskKind`, `live-desk.md` filename, or historical
19
+ Brief folders
20
+ - Rewriting entire CHANGELOG history
21
+
22
+ ## Acceptance
23
+
24
+ 1. No user-facing「台面」in zh i18n / README.zh-CN for the product surface.
25
+ 2. Setup strings use「Duaer 控制台」/ “Duaer console”.
26
+ 3. Brand rules prefer 控制台 / console.
27
+ 4. Brand + live smoke tests updated and pass.
@@ -0,0 +1,4 @@
1
+ - [x] T001 i18n + HTML: 台面/desk → 控制台/console
2
+ - [x] T002 README / worker-models / brand rules
3
+ - [x] T003 Server/user prompts + employee-catalog
4
+ - [x] T004 Tests + CHANGELOG; stamp delivery
@@ -0,0 +1,13 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-20T09:50:00.000Z",
4
+ "verification": {
5
+ "levels": ["L0", "L1", "L3"],
6
+ "commands": [
7
+ "node --test test/arch-fullscreen.test.mjs test/task-graph.test.mjs",
8
+ "npm test",
9
+ "npm run test:live"
10
+ ],
11
+ "result": "pass"
12
+ }
13
+ }
@@ -0,0 +1,16 @@
1
+ # Feat: dispatch center — view system architecture per project
2
+
3
+ ## Goal
4
+
5
+ On the **调度中心** (dispatch center) page, each project can show its
6
+ **系统架构** (system architecture diagram), not only the task/dispatch graph.
7
+
8
+ ## Acceptance
9
+
10
+ 1. Dispatch center has a view switch: 派工图 | 系统架构 (per selected project).
11
+ 2. Architecture view loads that project’s saved `architecture.url` from
12
+ `/api/projects/chat`; empty state when missing.
13
+ 3. Switching projects updates both views for the selected project.
14
+ 4. Architecture can open fullscreen via the same open-external path as the
15
+ console (optional button or click).
16
+ 5. i18n (zh + en minimum), live-desk / E2E row, L0–L3 smoke markers pass.
@@ -0,0 +1,4 @@
1
+ - [x] T001 HTML/CSS: stage view tabs (graph | architecture)
2
+ - [x] T002 dispatch-center.js: load & mount project architecture.url
3
+ - [x] T003 i18n + docs/E2E + tests
4
+ - [x] T004 Stamp delivery
@@ -0,0 +1,13 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-20T10:00:00.000Z",
4
+ "verification": {
5
+ "levels": ["L0", "L1", "L3"],
6
+ "commands": [
7
+ "node --check web/live-dev/app.js",
8
+ "node --test test/live-i18n-common.test.mjs test/live-i18n-ja.test.mjs",
9
+ "npm run test:live"
10
+ ],
11
+ "result": "pass"
12
+ }
13
+ }
@@ -0,0 +1,15 @@
1
+ # Feat: chat voice input next to Send
2
+
3
+ ## Goal
4
+
5
+ Operators can **record speech** beside Send to collect requirements by talking.
6
+ Transcript lands in the composer (editable), then Send as usual.
7
+
8
+ ## Acceptance
9
+
10
+ 1. Composer has a voice control next to Send (label via i18n).
11
+ 2. Uses browser SpeechRecognition when available; unsupported / denied shows a
12
+ short bot or aria notice — no silent fail.
13
+ 3. Listening state is visible; interim/final text appends into `#input`.
14
+ 4. Voice respects the same enable rules as Send (ready + project + not busy).
15
+ 5. README (en/zh) + live-desk note the voice path; E2E row; L0/L3 smoke pass.
@@ -0,0 +1,6 @@
1
+ # Tasks — 256-chat-voice
2
+
3
+ - [x] T001 HTML/CSS: voice button in composer
4
+ - [x] T002 app.js: SpeechRecognition wire + enable sync
5
+ - [x] T003 i18n (zh/en + locales)
6
+ - [x] T004 Docs + E2E + tests; stamp delivery
@@ -0,0 +1,9 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-20T10:05:00.000Z",
4
+ "verification": {
5
+ "levels": ["L0", "L3"],
6
+ "commands": ["node --check web/live-dev/app.js", "npm run test:live"],
7
+ "result": "pass"
8
+ }
9
+ }
@@ -0,0 +1,13 @@
1
+ # Fix: compact composer voice control
2
+
3
+ ## Goal
4
+
5
+ Composer Record + Send sit compact beside the input; the textarea stays on one
6
+ row and is not pushed down or squeezed away.
7
+
8
+ ## Acceptance
9
+
10
+ 1. Composer is one compact row: input + small Record + Send (or input + stacked
11
+ compact actions) without the textarea dropping below the buttons.
12
+ 2. Voice button uses tighter padding / type; listening state still visible.
13
+ 3. L0 + L3 smoke markers still pass; E2E note if layout contract changes.
@@ -0,0 +1,4 @@
1
+ # Tasks — 257-composer-voice-compact
2
+
3
+ - [x] T001 Fix composer CSS/HTML for compact voice+send beside input
4
+ - [x] T002 Smoke assert + brief stamp; merge develop
@@ -0,0 +1,14 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-20T10:20:00.000Z",
4
+ "verification": {
5
+ "levels": ["L0", "L1", "L3"],
6
+ "commands": [
7
+ "node --check bin/duaer-live.mjs",
8
+ "node --check web/live-dev/app.js",
9
+ "node --test test/stt-transcribe-url.test.mjs test/live-i18n-common.test.mjs test/live-i18n-ja.test.mjs",
10
+ "npm run test:live"
11
+ ],
12
+ "result": "pass"
13
+ }
14
+ }
@@ -0,0 +1,16 @@
1
+ # Feat: speech-to-text model for composer Record
2
+
3
+ ## Goal
4
+
5
+ After Record stops, decode speech to text via a configurable STT model in
6
+ Settings (alongside the console chat model). Transcript lands in the composer.
7
+
8
+ ## Acceptance
9
+
10
+ 1. Settings has an STT / speech model block (Base URL, API Key, Model) saved in
11
+ live config; OpenAI-compatible `/audio/transcriptions` (e.g. whisper-1).
12
+ 2. Record uses MediaRecorder when STT is configured; stop → `/api/transcribe` →
13
+ text in `#input`. Visible recognizing state; errors are not silent.
14
+ 3. Without STT config, browser SpeechRecognition remains a fallback (or a short
15
+ bot hint to configure STT).
16
+ 4. Docs (README / live-desk) + E2E + L0/L3 smoke pass.
@@ -0,0 +1,5 @@
1
+ # Tasks — 258-chat-stt
2
+
3
+ - [x] T001 Config + Settings STT fields + /api/transcribe
4
+ - [x] T002 MediaRecorder → transcribe into composer
5
+ - [x] T003 i18n + docs + tests; stamp; merge develop
@@ -0,0 +1,13 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-20T10:25:00.000Z",
4
+ "verification": {
5
+ "levels": ["L0", "L1", "L3"],
6
+ "commands": [
7
+ "node --check web/live-dev/app.js",
8
+ "node --test test/live-i18n-common.test.mjs",
9
+ "npm run test:live"
10
+ ],
11
+ "result": "pass"
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ # Fix: Record without STT opens Settings
2
+
3
+ ## Goal
4
+
5
+ Clicking Record with no speech model configured guides the operator to Settings
6
+ instead of falling back to browser speech.
7
+
8
+ ## Acceptance
9
+
10
+ 1. If `sttReady` is false, Record shows a short bot notice and opens Settings
11
+ (speech model block).
12
+ 2. Recording / transcribe only runs when STT is configured.
13
+ 3. L0 + L3 smoke still pass.
@@ -0,0 +1,4 @@
1
+ # Tasks — 259-voice-guide-stt
2
+
3
+ - [x] T001 Gate Record → open Settings when STT missing
4
+ - [x] T002 Smoke/docs tweak; stamp; merge
@@ -0,0 +1,19 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-20T14:14:57.110Z",
4
+ "verification": {
5
+ "levels": [
6
+ "docs"
7
+ ],
8
+ "commands": [
9
+ "gh workflow run npm-publish.yml --ref main",
10
+ "npm view duaer-spec version"
11
+ ],
12
+ "result": "pass",
13
+ "notes": "npm duaer-spec@0.26.0 published via Trusted Publishing after Duaer repo URL fix"
14
+ },
15
+ "preview": {
16
+ "url": "https://www.npmjs.com/package/duaer-spec/v/0.26.0",
17
+ "label": "npm duaer-spec@0.26.0"
18
+ }
19
+ }
@@ -0,0 +1,12 @@
1
+ # Feature Specification: Release 0.26.0
2
+
3
+ ## Goal
4
+
5
+ Ship 0.26.0: STT / composer Record, dispatch architecture view, console rename,
6
+ Cursor+Claude docs lead; promote develop → main; GitHub Release; npm Trusted
7
+ Publishing.
8
+
9
+ ## Acceptance
10
+
11
+ 1. `package.json` is `0.26.0`; CHANGELOG has `0.26.0` (Unreleased empty).
12
+ 2. Tag `v0.26.0` on main; GitHub Release published; npm shows `0.26.0`.
@@ -0,0 +1,3 @@
1
+ - [x] T001 Bump package.json to 0.26.0 and fold CHANGELOG
2
+ - [x] T002 Merge develop, promote main, push, GitHub release
3
+ - [x] T003 npm 0.26.0 published (Trusted Publishing + Duaer provenance URL)
@@ -0,0 +1,10 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-21T00:20:00.000Z",
4
+ "summary": "FDE-01: confirm card baseline fields, signed fingerprint gate before kickoff, change order + deliverables.",
5
+ "verification": {
6
+ "L0": "node --check bin/duaer-live.mjs web/live-dev/app.js web/live-dev/baseline.mjs bin/live-modules.mjs — pass",
7
+ "L1": "npm test — 225 pass (incl. baseline-sign)",
8
+ "L3": "npm run test:live — pass"
9
+ }
10
+ }
@@ -0,0 +1,37 @@
1
+ # Feature Specification: FDE-01 scope + acceptance baseline sign gate
2
+
3
+ ## Goal
4
+
5
+ Enforce a signed scope/acceptance baseline before kickoff (联调), per WeCom
6
+ FDE pain FDE-01: no unsigned baseline may enter dispatch; post-sign scope
7
+ changes require an explicit change order and re-sign.
8
+
9
+ ## In scope
10
+
11
+ - Confirm card fields: device matrix, critical paths, exception cases (feature)
12
+ - Project baseline sign (signer + time + fingerprint of confirmed modules)
13
+ - Kickoff / dispatch hard-blocked until baseline signed and fingerprint matches
14
+ - Change order: reason → unlock modules for re-confirm → clear sign → re-sign
15
+ - Deliverables page shows baseline + change history
16
+ - Docs / E2E / tests
17
+
18
+ ## Out of scope
19
+
20
+ - Real e-sign / PKI
21
+ - Automatic schedule recalculation
22
+ - Cloud browser matrix execution
23
+ - Full RACI (FDE-10)
24
+
25
+ ## Acceptance
26
+
27
+ 1. Feature confirm without device matrix / critical paths / exception cases fails local validate
28
+ 2. Unsigned baseline: 「写入 Brief 并启动」disabled or blocked with clear copy
29
+ 3. After sign, kickoff allowed when fingerprint matches confirmed modules
30
+ 4. Opening a change order with a reason clears the sign and returns modules to re-confirm
31
+ 5. Deliverables HTML shows signer, signed time, and change reasons when present
32
+ 6. `npm test` and `npm run test:live` pass
33
+
34
+ ## Assumptions
35
+
36
+ - Bug desk skips the three new field requirements but still needs baseline sign before dispatch
37
+ - Worktree: `.worktree/feat-fde-baseline-sign` · Brief: `.duaer/specs/261-fde-baseline-sign/`
@@ -0,0 +1,8 @@
1
+ # Tasks: FDE-01 baseline sign
2
+
3
+ - [x] T001 Clip card + session baseline helpers (`baseline.mjs` / modules / chat)
4
+ - [x] T002 Confirm card UI fields + i18n (device / paths / exceptions)
5
+ - [x] T003 Baseline sign + change-order UI in dispatch; gate doDispatch
6
+ - [x] T004 Server validate + dispatch reject unsigned / stale fingerprint
7
+ - [x] T005 Deliverables page + live-desk / E2E / CHANGELOG
8
+ - [x] T006 L0/L1/L3 verify; stamp delivery
@@ -0,0 +1,9 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-21T00:25:00.000Z",
4
+ "summary": "Document FDE-01 baseline sign in README zh-CN and en.",
5
+ "verification": {
6
+ "waiver": "docs-only",
7
+ "note": "README + CHANGELOG only; CJK scan on README.md clean"
8
+ }
9
+ }
@@ -0,0 +1,23 @@
1
+ # Feature Specification: Document FDE-01 in README
2
+
3
+ ## Goal
4
+
5
+ Update user-facing README (zh-CN + en) so FDE-01 baseline fields and sign
6
+ gate match the live console.
7
+
8
+ ## In scope
9
+
10
+ - `README.zh-CN.md` and `README.md` capability bullets + FDE flow steps
11
+ - Brief / delivery stamp
12
+
13
+ ## Out of scope
14
+
15
+ - Product code / i18n / ADR
16
+ - Push / release
17
+
18
+ ## Acceptance
19
+
20
+ 1. zh-CN README mentions device matrix / critical paths / exception cases on feature confirm
21
+ 2. Both READMEs mention signed baseline before kickoff and change-order re-sign
22
+ 3. English README has no CJK
23
+ 4. Docs-only waiver in delivery verification
@@ -0,0 +1,5 @@
1
+ # Tasks: Document FDE-01 in README
2
+
3
+ - [x] T001 Update README.zh-CN.md capability + flow
4
+ - [x] T002 Update README.md capability + flow
5
+ - [x] T003 Stamp delivery (docs-only waiver)
@@ -0,0 +1,9 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-21T00:35:00.000Z",
4
+ "summary": "Auto-detour architecture edges that would fail Archify clean-flow/edge-through-node.",
5
+ "verification": {
6
+ "L0": "node --check bin/live-archify.mjs — pass",
7
+ "L1": "node --test test/live-archify.test.mjs — 14 pass"
8
+ }
9
+ }
@@ -0,0 +1,25 @@
1
+ # Feature Specification: Auto-route architecture edges that cross nodes
2
+
3
+ ## Goal
4
+
5
+ When Archify rejects architecture IR with `clean-flow/edge-through-node`
6
+ (long same-row reverse edges from LLM layout), duaer-live auto-detours those
7
+ edges with `fromSide`/`toSide`/`via` so render succeeds.
8
+
9
+ ## In scope
10
+
11
+ - `routeCrossingEdges` in `bin/live-archify.mjs` (called from layout)
12
+ - Unit test using the failing PPT IR (state→gen)
13
+ - CHANGELOG / brief note in live-desk if needed
14
+
15
+ ## Out of scope
16
+
17
+ - Changing Archify itself
18
+ - Relayouting all LLM positions from scratch
19
+ - Showcase quality profile
20
+
21
+ ## Acceptance
22
+
23
+ 1. Saved IR `state`→`gen` (crosses user/ui/check/doc) renders via Archify without error
24
+ 2. Neighbor edges without intermediates keep no forced via
25
+ 3. `npm test` live-archify tests pass
@@ -0,0 +1,5 @@
1
+ # Tasks: Auto-route crossing architecture edges
2
+
3
+ - [x] T001 Implement `routeCrossingEdges` + wire into layout / viewBox
4
+ - [x] T002 Unit test for PPT IR state→gen case
5
+ - [x] T003 CHANGELOG; verify; stamp delivery
@@ -0,0 +1,10 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-21T00:40:00.000Z",
4
+ "summary": "Guide chat and placeholders to fill FDE-01 baseline confirm fields.",
5
+ "verification": {
6
+ "L0": "node --check bin/duaer-live.mjs web/live-dev/app.js — pass",
7
+ "L1": "node --test test/live-i18n-common.test.mjs — pass",
8
+ "L3": "npm run test:live — pass"
9
+ }
10
+ }
@@ -0,0 +1,23 @@
1
+ # Feature Specification: Guide filling FDE-01 baseline fields
2
+
3
+ ## Goal
4
+
5
+ Chat and confirm UX must guide (and preferably fill) device matrix, critical
6
+ paths, and exception cases — not leave them as empty「待确认」forever.
7
+
8
+ ## In scope
9
+
10
+ - Feature SYSTEM / ACCEPT / FIX / REVISE prompts include the three fields
11
+ - Field-specific placeholders (examples) in UI + i18n
12
+ - Smoke assert prompts mention the fields
13
+
14
+ ## Out of scope
15
+
16
+ - Bug desk (still skips the three fields)
17
+ - Changing validate rules
18
+
19
+ ## Acceptance
20
+
21
+ 1. `SYSTEM_PROMPT` / accept / fix prompts list `deviceMatrix` / `criticalPaths` / `exceptionCases`
22
+ 2. Feature confirm textareas use example placeholders (not bare「待确认」)
23
+ 3. `npm test` + `npm run test:live` pass
@@ -0,0 +1,5 @@
1
+ # Tasks: Guide filling FDE-01 baseline fields
2
+
3
+ - [x] T001 Update chat / accept / fix / revise prompts
4
+ - [x] T002 Per-field placeholders + i18n locales
5
+ - [x] T003 Smoke assert; stamp delivery
@@ -0,0 +1,9 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-21T00:45:00.000Z",
4
+ "summary": "Pass deviceMatrix/criticalPaths/exceptionCases through chat parse and SSE done.",
5
+ "verification": {
6
+ "L0": "node --check bin/duaer-live.mjs — pass",
7
+ "L3": "npm run test:live — pass"
8
+ }
9
+ }
@@ -0,0 +1,22 @@
1
+ # Feature Specification: Pass baseline fields through chat parse/SSE
2
+
3
+ ## Goal
4
+
5
+ When the model returns deviceMatrix / criticalPaths / exceptionCases in chat
6
+ JSON, they must reach the middle confirm card (not be stripped by
7
+ parseChatResult / chatDoneSsePayload).
8
+
9
+ ## In scope
10
+
11
+ - parseChatResult + chatDoneSsePayload passthrough (top-level + modules[])
12
+ - Unit / smoke coverage
13
+
14
+ ## Out of scope
15
+
16
+ - Prompt wording (already done in 264)
17
+
18
+ ## Acceptance
19
+
20
+ 1. Parsed chat JSON with baseline fields retains them in the done payload shape
21
+ 2. Middle card merge path receives the three keys from SSE done
22
+ 3. `npm run test:live` + targeted unit pass
@@ -0,0 +1,4 @@
1
+ # Tasks: Pass baseline fields through chat parse/SSE
2
+
3
+ - [x] T001 Fix parseChatResult + chatDoneSsePayload
4
+ - [x] T002 Unit test; smoke marker; stamp delivery