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.
- package/.claude/rules/ai-ui-copy.md +2 -2
- package/.cursor/rules/ai-ui-copy.mdc +3 -3
- package/.cursor/rules/fde-8787-only.mdc +7 -7
- package/.duaer/active-job.json +3 -3
- package/.duaer/specs/252-release-0251/delivery.json +14 -0
- package/.duaer/specs/252-release-0251/tasks.md +1 -1
- package/.duaer/specs/253-docs-cursor-claude/delivery.json +9 -0
- package/.duaer/specs/253-docs-cursor-claude/spec.md +25 -0
- package/.duaer/specs/253-docs-cursor-claude/tasks.md +3 -0
- package/.duaer/specs/254-console-rename/delivery.json +13 -0
- package/.duaer/specs/254-console-rename/spec.md +27 -0
- package/.duaer/specs/254-console-rename/tasks.md +4 -0
- package/.duaer/specs/255-dispatch-arch-view/delivery.json +13 -0
- package/.duaer/specs/255-dispatch-arch-view/spec.md +16 -0
- package/.duaer/specs/255-dispatch-arch-view/tasks.md +4 -0
- package/.duaer/specs/256-chat-voice/delivery.json +13 -0
- package/.duaer/specs/256-chat-voice/spec.md +15 -0
- package/.duaer/specs/256-chat-voice/tasks.md +6 -0
- package/.duaer/specs/257-composer-voice-compact/delivery.json +9 -0
- package/.duaer/specs/257-composer-voice-compact/spec.md +13 -0
- package/.duaer/specs/257-composer-voice-compact/tasks.md +4 -0
- package/.duaer/specs/258-chat-stt/delivery.json +14 -0
- package/.duaer/specs/258-chat-stt/spec.md +16 -0
- package/.duaer/specs/258-chat-stt/tasks.md +5 -0
- package/.duaer/specs/259-voice-guide-stt/delivery.json +13 -0
- package/.duaer/specs/259-voice-guide-stt/spec.md +13 -0
- package/.duaer/specs/259-voice-guide-stt/tasks.md +4 -0
- package/.duaer/specs/260-release-026/delivery.json +19 -0
- package/.duaer/specs/260-release-026/spec.md +12 -0
- package/.duaer/specs/260-release-026/tasks.md +3 -0
- package/.duaer/specs/261-fde-baseline-sign/delivery.json +10 -0
- package/.duaer/specs/261-fde-baseline-sign/spec.md +37 -0
- package/.duaer/specs/261-fde-baseline-sign/tasks.md +8 -0
- package/.duaer/specs/262-fde01-readme-docs/delivery.json +9 -0
- package/.duaer/specs/262-fde01-readme-docs/spec.md +23 -0
- package/.duaer/specs/262-fde01-readme-docs/tasks.md +5 -0
- package/.duaer/specs/263-arch-edge-via/delivery.json +9 -0
- package/.duaer/specs/263-arch-edge-via/spec.md +25 -0
- package/.duaer/specs/263-arch-edge-via/tasks.md +5 -0
- package/.duaer/specs/264-baseline-field-guide/delivery.json +10 -0
- package/.duaer/specs/264-baseline-field-guide/spec.md +23 -0
- package/.duaer/specs/264-baseline-field-guide/tasks.md +5 -0
- package/.duaer/specs/265-baseline-chat-passthrough/delivery.json +9 -0
- package/.duaer/specs/265-baseline-chat-passthrough/spec.md +22 -0
- package/.duaer/specs/265-baseline-chat-passthrough/tasks.md +4 -0
- package/.duaer/specs/266-fde02-api-contract/delivery.json +10 -0
- package/.duaer/specs/266-fde02-api-contract/spec.md +28 -0
- package/.duaer/specs/266-fde02-api-contract/tasks.md +7 -0
- package/.duaer/specs/267-baseline-restore/delivery.json +9 -0
- package/.duaer/specs/267-baseline-restore/spec.md +24 -0
- package/.duaer/specs/267-baseline-restore/tasks.md +5 -0
- package/.duaer/specs/268-fde07-uat/delivery.json +9 -0
- package/.duaer/specs/268-fde07-uat/spec.md +30 -0
- package/.duaer/specs/268-fde07-uat/tasks.md +5 -0
- package/.duaer/specs/269-release-027/spec.md +12 -0
- package/.duaer/specs/269-release-027/tasks.md +4 -0
- package/ADOPT.md +7 -4
- package/AGENTS.md +2 -2
- package/CHANGELOG.md +84 -0
- package/README.md +50 -38
- package/README.zh-CN.md +26 -25
- package/bin/duaer-live.mjs +347 -85
- package/bin/live-archify.mjs +85 -0
- package/bin/live-bug-context.mjs +1 -1
- package/bin/live-deliverables.mjs +54 -1
- package/bin/live-modules.mjs +63 -2
- package/bin/live-project-chat.mjs +18 -1
- package/bin/live-verify-gate.mjs +2 -2
- package/docs/agent/e2e-test-plan.md +22 -0
- package/docs/agent/live-desk.md +27 -7
- package/docs/agent/worker-models.md +7 -5
- package/docs/agent/worker-models.zh-CN.md +5 -3
- package/package.json +5 -5
- package/web/live-dev/api-contract.mjs +50 -0
- package/web/live-dev/app.js +664 -21
- package/web/live-dev/baseline.mjs +71 -0
- package/web/live-dev/confirm-card.mjs +19 -0
- package/web/live-dev/dispatch-center.html +25 -1
- package/web/live-dev/dispatch-center.js +113 -16
- package/web/live-dev/employee-catalog.mjs +2 -2
- package/web/live-dev/i18n-de.js +60 -8
- package/web/live-dev/i18n-es.js +60 -8
- package/web/live-dev/i18n-fr.js +60 -8
- package/web/live-dev/i18n-ja.js +60 -8
- package/web/live-dev/i18n-ko.js +60 -8
- package/web/live-dev/i18n-pt-BR.js +60 -8
- package/web/live-dev/i18n-ru.js +60 -8
- package/web/live-dev/i18n-vi.js +60 -8
- package/web/live-dev/i18n-zh-TW.js +62 -10
- package/web/live-dev/i18n.js +126 -21
- package/web/live-dev/index.html +97 -10
- package/web/live-dev/styles.css +63 -3
- 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
|
|
17
|
-
chat surface or model setup — prefer「Duaer
|
|
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-
|
|
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
|
|
20
|
-
chat surface or model setup — prefer「Duaer
|
|
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
|
|
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
|
|
6
|
+
# FDE console port (8787 only)
|
|
7
7
|
|
|
8
|
-
The Duaer-spec FDE
|
|
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
|
|
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
|
|
25
|
-
- Use Cursor Browser / Simple Browser / browser MCP to open the
|
|
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
|
|
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.
|
package/.duaer/active-job.json
CHANGED
|
@@ -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
|
+
}
|
|
@@ -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,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,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,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,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,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,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,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,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,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,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,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,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
|