From d5d979ad7e849e2f9f7096d74478094c992477a1 Mon Sep 17 00:00:00 2001 From: Chris0Jeky Date: Thu, 10 Sep 2026 12:00:56 +0100 Subject: [PATCH 1/5] Keep reminder draft guards owned by their save request --- .../workspace/WorkspaceAttentionSettings.vue | 9 ++--- .../components/WorkspaceAttention.spec.ts | 34 +++++++++++++++++++ 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/frontend/taskdeck-web/src/components/workspace/WorkspaceAttentionSettings.vue b/frontend/taskdeck-web/src/components/workspace/WorkspaceAttentionSettings.vue index a0fb45d732..bd8fbc37b8 100644 --- a/frontend/taskdeck-web/src/components/workspace/WorkspaceAttentionSettings.vue +++ b/frontend/taskdeck-web/src/components/workspace/WorkspaceAttentionSettings.vue @@ -9,7 +9,7 @@ const restricted = ref(false) const zone = ref('UTC') const days = ref([1, 2, 3, 4, 5]) const start = ref('09:00'); const end = ref('17:00') -let savingEnablement = false +let savingEnablement: symbol | null = null const dayOptions = [{ value: 1, name: 'Monday' }, { value: 2, name: 'Tuesday' }, { value: 3, name: 'Wednesday' }, { value: 4, name: 'Thursday' }, { value: 5, name: 'Friday' }, { value: 6, name: 'Saturday' }, { value: 0, name: 'Sunday' }] const formatTime = (minutes: number) => `${String(Math.floor(minutes / 60)).padStart(2, '0')}:${String(minutes % 60).padStart(2, '0')}` @@ -17,7 +17,7 @@ const minutes = (value: string) => { const [hour, minute] = value.split(':').map watch(() => attention.settings, settings => { // An enable-only receipt must not replace an independent, unsaved hours draft. if (settings && savingEnablement) return - savingEnablement = false + savingEnablement = null const window = settings?.window restricted.value = !!window zone.value = window?.timeZoneId ?? 'UTC' @@ -29,9 +29,10 @@ const valid = computed(() => !restricted.value || (zone.value.trim().length > 0 function localZone() { zone.value = Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC' } async function saveEnabled(enabled: boolean) { if (attention.busy || !attention.settings) return - savingEnablement = true + const request = Symbol() + savingEnablement = request try { await attention.save(enabled) } - finally { savingEnablement = false } + finally { if (savingEnablement === request) savingEnablement = null } } function saveHours() { if (!attention.settings || !valid.value) return diff --git a/frontend/taskdeck-web/src/tests/components/WorkspaceAttention.spec.ts b/frontend/taskdeck-web/src/tests/components/WorkspaceAttention.spec.ts index dc324d7009..9e4c1f436b 100644 --- a/frontend/taskdeck-web/src/tests/components/WorkspaceAttention.spec.ts +++ b/frontend/taskdeck-web/src/tests/components/WorkspaceAttention.spec.ts @@ -86,6 +86,40 @@ describe('optional quiet reminders', () => { expect(useWorkspaceAttentionStore().settings?.enabled).toBe(true) }) + it.each(['resolve', 'reject'])('keeps the newer account save guarded when the old save settles by %s', async outcome => { + wrapper = mount(WorkspaceAttentionSettings); await flushPromises() + let completeOld!: (value: typeof settings) => void + let rejectOld!: (reason: Error) => void + vi.mocked(workspaceAttentionApi.save).mockReturnValueOnce(new Promise((resolve, reject) => { + completeOld = resolve; rejectOld = reject + })) + await wrapper.get('input').setValue(false); await flushPromises() + session.userId = 'different-owner'; await flushPromises() + const savedWindow = { timeZoneId: 'Europe/London', daysMask: 62, startMinute: 540, endMinute: 1020 } + vi.mocked(workspaceAttentionApi.get).mockResolvedValueOnce({ ...settings, revision: 10, window: savedWindow }) + await wrapper.get('button').trigger('click'); await flushPromises() + await wrapper.get('input[type=text]').setValue('America/New_York') + await wrapper.findAll('input[type=time]')[0]!.setValue('22:00') + await wrapper.findAll('input[type=time]')[1]!.setValue('02:00') + let completeNew!: (value: typeof settings & { window: typeof savedWindow }) => void + vi.mocked(workspaceAttentionApi.save).mockReturnValueOnce(new Promise(resolve => { completeNew = resolve })) + await wrapper.get('input').setValue(false); await flushPromises() + if (outcome === 'resolve') completeOld({ ...settings, enabled: false, revision: 2 }) + else rejectOld(new Error('Old account save response was lost')) + await flushPromises() + expect(useWorkspaceAttentionStore().busy).toBe(true) + expect(useWorkspaceAttentionStore().settings?.revision).toBe(10) + completeNew({ ...settings, enabled: false, revision: 11, window: savedWindow }); await flushPromises() + expect((wrapper.get('input[type=text]').element as HTMLInputElement).value).toBe('America/New_York') + expect((wrapper.findAll('input[type=time]')[0]!.element as HTMLInputElement).value).toBe('22:00') + expect((wrapper.findAll('input[type=time]')[1]!.element as HTMLInputElement).value).toBe('02:00') + const window = { timeZoneId: 'America/New_York', daysMask: 62, startMinute: 1320, endMinute: 120 } + vi.mocked(workspaceAttentionApi.save).mockResolvedValueOnce({ ...settings, enabled: false, revision: 12, window }) + await wrapper.get('form').trigger('submit'); await flushPromises() + expect(workspaceAttentionApi.save).toHaveBeenCalledTimes(3) + expect(workspaceAttentionApi.save).toHaveBeenLastCalledWith(11, false, window) + }) + it('saves an explicit weekly window and disables controls until its receipt arrives', async () => { wrapper = mount(WorkspaceAttentionSettings); await flushPromises() const restrict = wrapper.findAll('input[type=checkbox]')[1]! From 6bb5b1c9835c3706f27fc834ccf4b654232be345 Mon Sep 17 00:00:00 2001 From: Chris0Jeky Date: Thu, 10 Sep 2026 12:00:56 +0100 Subject: [PATCH 2/5] Record reminder save ownership qualification --- docs/IMPLEMENTATION_MASTERPLAN.md | 2 ++ docs/STATUS.md | 2 ++ docs/product/WORKSPACE_OVERHAUL_VALIDATION.md | 13 +++++++++++++ 3 files changed, 17 insertions(+) diff --git a/docs/IMPLEMENTATION_MASTERPLAN.md b/docs/IMPLEMENTATION_MASTERPLAN.md index 6b1e061132..13dece3acb 100644 --- a/docs/IMPLEMENTATION_MASTERPLAN.md +++ b/docs/IMPLEMENTATION_MASTERPLAN.md @@ -2,6 +2,8 @@ Last Updated: 2026-09-10 +Finish delivery of #2895 and its bounded #2896 reminder-save ownership follow-up. The latter replaces a component-wide boolean with a request identity so an older account's completion cannot discard a newer account's unsaved hours. Its reproduced interleavings, full frontend suite, typecheck/build and lint pass. Keep the final #2808 completion record tied to the merged delivery receipts. + The #2893/#2894 recovery follow-up is implemented in [PR #2895](https://github.com/Chris0Jeky/Taskdeck/pull/2895): preserve reminder drafts, report concurrent question writes accurately and align model payloads with the evidence preview. Keep the existing privacy/revision/usage boundaries, prove the reproduced cases and publish one reviewed follow-up. Local full suites, focused final payload checks, browser recovery and bounded independent review pass. Merged #2892 as 93eab3443 after required run 34453924959 passed at reviewed head 42965edde. The reminder-hours slice under #2808 delivers: optional named-zone weekly windows, explicit save/recovery, existing shared budgets and server-side eligibility. Local full backend/frontend, combined privacy/recovery and cross-browser proof pass. The final active-account write condition prevents erased private hours from being restored by an in-flight request. Old opted-in users retain unrestricted behavior; reminders remain default off. diff --git a/docs/STATUS.md b/docs/STATUS.md index af14cd7fb1..53758f4b4d 100644 --- a/docs/STATUS.md +++ b/docs/STATUS.md @@ -2,6 +2,8 @@ Last Updated: 2026-09-10 +Reminder save ownership (#2896): a delayed completion from a previous account can no longer release the guard for a newer account's enable save. Both success and failure interleavings were reproduced before repair; 22 targeted component cases and the full 6,438-test frontend suite pass, with three existing skips. Typecheck, production build and scoped lint pass. This is a focused follow-up to #2895; the delivery tracker records its hosted gate and merge receipt. + Final overhaul recovery follow-up (#2893/#2894, [PR #2895](https://github.com/Chris0Jeky/Taskdeck/pull/2895)): retain an unsaved hours draft across enable-only saves and confirmed validation rejections, distinguish competing question writes from source changes, and send the model exactly the previewed excerpt. Final frontend passes 6,436 tests with three existing skips; full backend passes 9,315 with 34 existing skips, followed by 17 API and 19 application tests for the final payload correction. Build/typecheck, scoped lint, browser recovery and bounded independent review pass. Required hosted runs 34458797270 and 34462673996 passed at reviewed heads f39cc6cf3 and d25edf2a5, including both operating-system suites and browser smoke. The PR records subsequent base qualification and the final merge receipt. The source and draft regressions were reproduced before repair; the validation ledger records their scope. Optional reminder hours (#2808, merged #2892): explicit weekday and time windows in an IANA zone, including overnight and daylight-saving behavior. Server checks precede question lookup and budget admission; preference edits preserve the shared UTC allowance, old-client toggles retain the window, and exports include it without a new migration. The slice passed 9,270 backend and 6,421 frontend tests, with 34/three existing skips respectively. After parent integration, 56 API tests, 56 component tests, typecheck/build and five Chromium journeys pass, including a reproduced and fixed account-erasure race. Firefox and mobile Grove/Grove Night evidence are recorded in the validation ledger. Required CI run 34453924959 passed at reviewed head 42965edde; #2892 merged as 93eab3443. [Policy](product/WORKSPACE_ATTENTION.md). diff --git a/docs/product/WORKSPACE_OVERHAUL_VALIDATION.md b/docs/product/WORKSPACE_OVERHAUL_VALIDATION.md index 9520a0044a..9125c4a680 100644 --- a/docs/product/WORKSPACE_OVERHAUL_VALIDATION.md +++ b/docs/product/WORKSPACE_OVERHAUL_VALIDATION.md @@ -1,5 +1,18 @@ # Workspace overhaul validation and follow-through +## Reminder save ownership follow-up (2026-09-10) + +Issue #2896 covers a late-review account-switch interleaving: account A's save is pending, account B +loads settings and starts another enable save, then A settles before B. Both resolved and rejected A +responses reproduced replacement of B's unsaved zone with its saved zone. A unique request identity +now lets only the owning completion release the component guard. Both regressions pass within 22 +attention component tests and assert an explicit later hours save using B's returned revision. + +Full frontend qualification passes 6,438 tests with three existing skips across 416 files; typecheck, +production build and scoped ESLint pass. The backend is unchanged. The deterministic component tests +exercise the actual shared store and account-generation checks; no new physical-device or live-provider +claim is made. The follow-up PR records its independent review and hosted delivery receipt. + ## Final recovery follow-up (2026-09-10) The hours draft regression failed in both enable-toggle directions before the repair. A confirmed From 589578300ad1b79f4d9520d0c59cf3c3438bb721 Mon Sep 17 00:00:00 2001 From: Chris0Jeky Date: Thu, 10 Sep 2026 12:44:20 +0100 Subject: [PATCH 3/5] Prepare v0.4 feature contracts and qualification sessions --- docs/IMPLEMENTATION_MASTERPLAN.md | 2 + docs/QA_STRATEGY.md | 5 + docs/STATUS.md | 2 + docs/product/FEATURE_CAPABILITIES.md | 92 ++++++++ docs/testing/V04_QUALIFICATION_PLAN.md | 285 +++++++++++++++++++++++++ docs/testing/V04_SESSION_TEMPLATE.md | 69 ++++++ docs/testing/v04-outcomes.csv | 45 ++++ 7 files changed, 500 insertions(+) create mode 100644 docs/product/FEATURE_CAPABILITIES.md create mode 100644 docs/testing/V04_QUALIFICATION_PLAN.md create mode 100644 docs/testing/V04_SESSION_TEMPLATE.md create mode 100644 docs/testing/v04-outcomes.csv diff --git a/docs/IMPLEMENTATION_MASTERPLAN.md b/docs/IMPLEMENTATION_MASTERPLAN.md index 686d913610..9be0189fe2 100644 --- a/docs/IMPLEMENTATION_MASTERPLAN.md +++ b/docs/IMPLEMENTATION_MASTERPLAN.md @@ -2,6 +2,8 @@ Last Updated: 2026-09-10 +Prepare v0.4 qualification through [#2898](https://github.com/Chris0Jeky/Taskdeck/issues/2898): maintain the [feature capability catalogue](product/FEATURE_CAPABILITIES.md), run the eleven linked session workstreams against pinned candidates, and record the 44 initial cases in the [qualification plan](testing/V04_QUALIFICATION_PLAN.md). Preparation is delivered separately from execution; all seeded outcomes remain NOT RUN. Reuse existing performance, visual-baseline, hosted, dogfooding and release owners, preserving their milestones and the existing release decision gates. + The #2893/#2894 recovery follow-up is implemented in [PR #2895](https://github.com/Chris0Jeky/Taskdeck/pull/2895): preserve reminder drafts, report concurrent question writes accurately and align model payloads with the evidence preview. Keep the existing privacy/revision/usage boundaries, prove the reproduced cases and publish one reviewed follow-up. Local full suites, focused final payload checks, browser recovery and bounded independent review pass. Merged #2892 as 93eab3443 after required run 34453924959 passed at reviewed head 42965edde. The reminder-hours slice under #2808 delivers: optional named-zone weekly windows, explicit save/recovery, existing shared budgets and server-side eligibility. Local full backend/frontend, combined privacy/recovery and cross-browser proof pass. The final active-account write condition prevents erased private hours from being restored by an in-flight request. Old opted-in users retain unrestricted behavior; reminders remain default off. diff --git a/docs/QA_STRATEGY.md b/docs/QA_STRATEGY.md index 54d708edf1..a8ade78814 100644 --- a/docs/QA_STRATEGY.md +++ b/docs/QA_STRATEGY.md @@ -1,5 +1,10 @@ # Taskdeck QA Strategy +For current v0.4 session planning, use the [qualification programme](testing/V04_QUALIFICATION_PLAN.md) +and [feature capability contracts](product/FEATURE_CAPABILITIES.md). The dated counts and maturity +assessment below are historical snapshots, not current release evidence; the programme records +candidate-specific results and explicitly separates unrun, blocked and passed cases. + **Date:** 2026-04-16 **Last Updated:** 2026-08-01 **Scope:** Comprehensive quality assurance plan covering the full test pyramid, regression strategy, release gating, and continuous quality improvement diff --git a/docs/STATUS.md b/docs/STATUS.md index 2d0e3abd60..6209986c8f 100644 --- a/docs/STATUS.md +++ b/docs/STATUS.md @@ -2,6 +2,8 @@ Last Updated: 2026-09-10 +v0.4 QA preparation ([#2898](https://github.com/Chris0Jeky/Taskdeck/issues/2898)): eleven session issues now define 44 initial cases covering feature truth, core-loop authority, experience comparison, accessibility, work-model interactions, private sources, audio/questions, reminders, portability, hosted operations and Fabric contracts. All are milestone v0.4, Project Pending, Priority III. The [capability catalogue](product/FEATURE_CAPABILITIES.md), [qualification plan](testing/V04_QUALIFICATION_PLAN.md) and session/result templates distinguish implemented behavior, limits and future work. These are prepared cases, all NOT RUN; existing overhaul verification is separate from future release acceptance. + Final overhaul recovery follow-up (#2893/#2894, [PR #2895](https://github.com/Chris0Jeky/Taskdeck/pull/2895)): retain an unsaved hours draft across enable-only saves and confirmed validation rejections, distinguish competing question writes from source changes, and send the model exactly the previewed excerpt. Final frontend passes 6,436 tests with three existing skips; full backend passes 9,315 with 34 existing skips, followed by 17 API and 19 application tests for the final payload correction. Build/typecheck, scoped lint, browser recovery and bounded independent review pass. Required hosted runs 34458797270 and 34462673996 passed at reviewed heads f39cc6cf3 and d25edf2a5, including both operating-system suites and browser smoke. The PR records subsequent base qualification and the final merge receipt. The source and draft regressions were reproduced before repair; the validation ledger records their scope. Optional reminder hours (#2808, merged #2892): explicit weekday and time windows in an IANA zone, including overnight and daylight-saving behavior. Server checks precede question lookup and budget admission; preference edits preserve the shared UTC allowance, old-client toggles retain the window, and exports include it without a new migration. The slice passed 9,270 backend and 6,421 frontend tests, with 34/three existing skips respectively. After parent integration, 56 API tests, 56 component tests, typecheck/build and five Chromium journeys pass, including a reproduced and fixed account-erasure race. Firefox and mobile Grove/Grove Night evidence are recorded in the validation ledger. Required CI run 34453924959 passed at reviewed head 42965edde; #2892 merged as 93eab3443. [Policy](product/WORKSPACE_ATTENTION.md). diff --git a/docs/product/FEATURE_CAPABILITIES.md b/docs/product/FEATURE_CAPABILITIES.md new file mode 100644 index 0000000000..c6db8038a4 --- /dev/null +++ b/docs/product/FEATURE_CAPABILITIES.md @@ -0,0 +1,92 @@ +# Feature capabilities and expectations + +Last Updated: 2026-09-10 + +This is a user-facing contract inventory for the v0.4 QA programme, not a claim that v0.4 has +shipped or that its sessions passed. Baseline: the overhaul integrated through PR #2895 on main +`b344a5a74`; the overlapping-account reminder fix is in PR #2897 and remains a separate delivery +receipt until merged. Reconcile this inventory against the exact candidate before a QA session. + +Use the [qualification plan](../testing/V04_QUALIFICATION_PLAN.md) for expected-result matrices +and the [overhaul guide](WORKSPACE_OVERHAUL.md) for detailed instructions. Delivery tests and their +limits live in the [validation ledger](WORKSPACE_OVERHAUL_VALIDATION.md). + +## How to read status + +| Status | Meaning | +| --- | --- | +| Implemented | A working integrated path exists, with the cited conditions and limits. This does not mean every device/provider combination is verified. | +| Experimental | Implemented behavior whose usefulness, presentation or policy still needs evaluation. It is not a simulated success path. | +| Optional / unconfigured | Real functionality requires explicit configuration, availability or consent. Disabled does not mean stubbed. | +| Test fixture / prototype | Simulated data or transport used to explore a design or prove a contract; it does not establish production-provider behavior. | +| Planned / deliberately deferred | An owning roadmap issue defines future work. Its milestone is a target, not evidence that implementation exists. | +| Outside the current contract | No current commitment here. This does not permanently reject the idea. | +| Stubbed | A visible behavior is simulated or incomplete in the product itself. Record the exact code and affected entry point before using this label. | + +## Working product paths + +| Feature and entry point | What to expect | Limits and interactions | Status / QA | +| --- | --- | --- | --- | +| Capture → Review → Apply | Saved input leads to a reviewable proposal. Inspect evidence, approve, then explicitly apply. The board changes at Apply. | Preview, experience changes and approval alone do not apply changes. Stale revisions and missing authority require recovery. UI, CLI and MCP must retain the same authority boundary. | Implemented; [QA-02](https://github.com/Chris0Jeky/Taskdeck/issues/2900). | +| Experience selector | Classic, Studio, Companion and Unified offer different entry points and navigation over the same task data. | Classic remains the default. Switches preserve the mounted route/open card and appropriate drafts; they do not change permissions, provider policy or proposal authority. | Implemented experiment; [QA-03](https://github.com/Chris0Jeky/Taskdeck/issues/2901). | +| Presentation and Appearance | Zen/Studio/Control adjust disclosure independently of experience. Grove/Grove Night add prototype-inspired palettes alongside Paper/Legacy and Auto. | Detail called Studio is separate from the Studio experience. Due/blocker/trust information must remain available. Visual preference and accessibility require direct evaluation. | Implemented; [QA-03](https://github.com/Chris0Jeky/Taskdeck/issues/2901), [QA-04](https://github.com/Chris0Jeky/Taskdeck/issues/2902). | +| Card → Open thinking deck | Ordered note, question, options, steps and thread layers, viewed as Stack or Path. | Shared board thinking is distinct from private answers. Saves use revisions. Creating real work from a step is an explicit action. | Implemented; [QA-05](https://github.com/Chris0Jeky/Taskdeck/issues/2903). | +| Create card from step | Choose title/destination and create a real linked card. Retrying reuses the saved link; displayed status comes from the card. | Removing a thinking layer never deletes its cards. WIP, archive and permission checks apply. A deleted target is unavailable, not silently recreated. | Implemented; [QA-05](https://github.com/Chris0Jeky/Taskdeck/issues/2903). | +| Explore dependencies | Explicit prerequisites appear in both directions; invalid cycles are rejected. | Same-board graph, separate revision, guarded import/remapping. Links do not automatically change deadlines, status or assignments. Broader typed work-item links remain a separate roadmap contract. | Implemented; [QA-05](https://github.com/Chris0Jeky/Taskdeck/issues/2903). | +| Studio Personal Plan / Focus | Private chosen cards and last-worked focus, with Board/List/Horizon views over the same references. | Make room and Plan tomorrow do not reschedule card due dates. Requires a connected backend; backend-less demos hide the private-plan controls. | Implemented; [QA-05](https://github.com/Chris0Jeky/Taskdeck/issues/2903). | +| Companion and source picker | Accountable chat uses explicitly chosen card/thinking/private-memory/original context, with persisted source receipts. | No implicit private retrieval. Changed sources or authority invalidate dispatch. Pending sends and unsaved thinking have continuity guards. Actual model output depends on the configured provider. | Implemented, provider-dependent; [QA-02](https://github.com/Chris0Jeky/Taskdeck/issues/2900), [QA-06](https://github.com/Chris0Jeky/Taskdeck/issues/2904). | +| Preview on board | A checked, read-only proposal layer marks affected saved objects in either board renderer; the authoritative diff describes proposed new objects. | Refresh checks the effective revision. Expiry, board changes or lost access remove stale markers. Open Review leads back to explicit approval and Apply. | Implemented; [QA-02](https://github.com/Chris0Jeky/Taskdeck/issues/2900). | +| Your private answer / Memory | Private answers, statements/assumptions/unknowns, corrections, originals and history. Archive/restore changes active visibility. | Board JSON excludes private answers. Account exports include private originals/history; erasure follows account ownership while preserving collaborators' records. Board-scoped private download is archival JSON, not an atomic backup/import. | Implemented; [QA-06](https://github.com/Chris0Jeky/Taskdeck/issues/2904), [QA-09](https://github.com/Chris0Jeky/Taskdeck/issues/2907). | +| Audio answer / original library | Explicit recording/file intake, immutable upload, playback/download and separate written versions. Confirmation creates a private answer. | Microphone access is requested through the browser. Original audio remains separate from written corrections. Retained archived/deleted-board originals do not reactivate a question or grant new answer authority. | Implemented; physical-device acceptance pending; [QA-07](https://github.com/Chris0Jeky/Taskdeck/issues/2905). | +| Transcription options | Inspect destination/model and consent to one request. Output remains provisional until reviewed and explicitly confirmed. Durable receipts support recovery. | Disabled by default, separate from chat provider. No automatic retry or local WhisperX pipeline is implied. Manual replay/write remains available when the route is unavailable. See [transcription policy](AUDIO_TRANSCRIPTION.md). | Optional experimental live-provider path; [QA-07](https://github.com/Chris0Jeky/Taskdeck/issues/2905). | +| Quiet insights → Analyze now | Explicit structural analysis of blocked work and unknown/needs-review memory, with dismiss/snooze/mute and revalidation. | Structural rules do not call a model, infer semantics or run global background scans. | Implemented; [QA-06](https://github.com/Chris0Jeky/Taskdeck/issues/2904). | +| Grounded questions | Select one card, preview the bounded excerpt, then request a few private questions backed by exact quotes. | Shares Chat quota/kill switch; stale source, denied access or unavailable provider causes a visible refusal. No board write or automatic resend. See [observation policy](GROUNDED_OBSERVATIONS.md). | Experimental, provider-dependent; [QA-07](https://github.com/Chris0Jeky/Taskdeck/issues/2905). | +| Reminder settings | Default-off links to existing revalidated questions, optionally restricted to weekly hours in a named time zone. | Quiet-state suppression and a shared allowance apply. These are in-app reminders while the board is active, not OS notifications or closed-browser scheduling. See [attention policy](WORKSPACE_ATTENTION.md). | Implemented experiment; [QA-08](https://github.com/Chris0Jeky/Taskdeck/issues/2906). | +| Experiences → comparison | Record scenario/outcome, optional ease and notes. Export/import observations across builds with identity and configuration attribution. | Observations are session-only until exported. Import is explicit. No telemetry, random assignment or statistical A/B claim. | Implemented descriptive comparison; [QA-03](https://github.com/Chris0Jeky/Taskdeck/issues/2901). | + +## Numeric boundaries to recheck on the candidate + +These are current defaults/contracts, not performance targets. Configuration may narrow availability. +Record the effective value in the session before testing the boundary and one value on each side. + +| Surface | Current boundary | Source | +| --- | --- | --- | +| Thinking | 40 layers; 50 items per layer | [ThinkingDeck](../../backend/src/Taskdeck.Domain/Entities/ThinkingDeck.cs) | +| Private plan | 40 cards | [PersonalPlan](../../backend/src/Taskdeck.Domain/Entities/PersonalPlan.cs) | +| Dependencies | 500 same-board edges | [overhaul dependency contract](WORKSPACE_OVERHAUL.md) | +| Companion private sources | Five combined memories/originals | [overhaul source contract](WORKSPACE_OVERHAUL.md) | +| Audio originals | 60 seconds; 2 MiB; WebM/Ogg/WAV/MP3/MP4/M4A; up to 50 written versions per recording | [overhaul audio contract](WORKSPACE_OVERHAUL.md) | +| Transcription defaults | Five attempts and 10 MiB per owner/UTC day; 20 receipts per recording; two-minute publication deadline; 64 KiB response / 8,000 text characters | [settings](../../backend/src/Taskdeck.Application/Services/SpeechTranscriptionSettings.cs), [policy](AUDIO_TRANSCRIPTION.md) | +| Grounded questions | Up to three; categories next-step/outcome/dependency, at most one each; exact quote at most 400 characters; one-day freshness | [contract](../../backend/src/Taskdeck.Application/Services/WorkspaceObservationContract.cs), [policy](GROUNDED_OBSERVATIONS.md) | +| Reminder allowance | At most two claims per UTC day, at least two hours apart; visible/focused board polling no more often than five minutes | [attention policy](WORKSPACE_ATTENTION.md) | +| Reminder hours | Inclusive start, exclusive end; overnight belongs to its selected starting day in the saved IANA zone | [window](../../backend/src/Taskdeck.Domain/Entities/WorkspaceAttentionWindow.cs) | +| Comparison | Optional ease 1–5; notes 2,000 characters; 500 observations; 2 MiB import; v2/v3 accepted | [comparison store](../../frontend/taskdeck-web/src/store/workspaceExperimentStore.ts) | + +## Planned, deferred and intentionally absent + +| Area | Current expectation | Owning work / horizon | +| --- | --- | --- | +| Hosted open registration | Not established by a local build or the overhaul. Trusted hosting, threat model, identity, cost/abuse controls, backups and operational acceptance precede public registration. | [#2243](https://github.com/Chris0Jeky/Taskdeck/issues/2243), v0.4; [QA-10](https://github.com/Chris0Jeky/Taskdeck/issues/2908). Existing private-instance prerequisites retain their own milestones. | +| Expanded work model | Typed items/hierarchy, richer links, participants/assignments/estimates and custom fields must be checked against their own delivered slices. Existing card dependencies/private plans do not imply these are all complete. | [#2087](https://github.com/Chris0Jeky/Taskdeck/issues/2087), [#2092](https://github.com/Chris0Jeky/Taskdeck/issues/2092), [#2093](https://github.com/Chris0Jeky/Taskdeck/issues/2093), [#2094](https://github.com/Chris0Jeky/Taskdeck/issues/2094), v0.4. | +| Fabric foundations | Durable processing lifecycle, worker protocol/containment, representation migration and evidence anchors remain individually owned contracts. Native originals alone do not complete the general platform. | [#2254](https://github.com/Chris0Jeky/Taskdeck/issues/2254), children #2256–#2261/#2276, v0.4 foundation; [QA-11](https://github.com/Chris0Jeky/Taskdeck/issues/2909). | +| General semantic candidates and boardless recall | The selected-card grounded-question producer is not global/vector recall. | [#2262](https://github.com/Chris0Jeky/Taskdeck/issues/2262), [#2263](https://github.com/Chris0Jeky/Taskdeck/issues/2263), v0.5. | +| Packaged local speech / WhisperX / broad voice-note UX | Existing optional transcription does not supply one-click local speech or the general worker-based voice vertical. | [#2267](https://github.com/Chris0Jeky/Taskdeck/issues/2267), [#2268](https://github.com/Chris0Jeky/Taskdeck/issues/2268), [#2270](https://github.com/Chris0Jeky/Taskdeck/issues/2270), v0.5. | +| Policy routing, meeting understanding, runtime outcome dashboard and cloud speech benchmark | Separate later contracts; not inferred from presentation detail, selected context or manual comparison. | [#2264](https://github.com/Chris0Jeky/Taskdeck/issues/2264), [#2269](https://github.com/Chris0Jeky/Taskdeck/issues/2269), [#2271](https://github.com/Chris0Jeky/Taskdeck/issues/2271), [#2277](https://github.com/Chris0Jeky/Taskdeck/issues/2277), v0.6. | +| Source-storage import/restore | No general restore contract follows from private archival downloads. Use supported account/board exports and the actual instance backup runbook for their stated purposes. | Outside this overhaul contract; broader migration ownership includes [#2260](https://github.com/Chris0Jeky/Taskdeck/issues/2260). | +| Autonomous Apply / silent private retrieval / background question generation | Deliberately absent from these features. User intent and review-first authority remain explicit. | Delegated authority has its own separately gated [#2275](https://github.com/Chris0Jeky/Taskdeck/issues/2275); presentation controls do not enable it. | +| Randomized A/B platform, statistical winner, push reminders while closed | Not implemented or promised by the current comparison/reminder features. | Outside their current contract. | + +The supplied HTML prototypes simulate local state and model interactions. Repository mock providers +and synthetic browser fixtures are also simulations. Neither is evidence of a hidden production +stub. This inventory has not established a product stub in the integrated overhaul; the broader +route audit in [QA-01](https://github.com/Chris0Jeky/Taskdeck/issues/2899) must name any actual stub +with its exact code and visible consequence. Existing cohort/Ollama and dead-surface questions in +[OUTSTANDING_TASKS](../../OUTSTANDING_TASKS.md) require current verification, not inference from old titles. + +## What still needs actual use + +Automated passing tests establish their exercised contracts. They do not establish microphone +quality, screen-reader usability, physical keyboard behavior, live-model usefulness, subjective +non-intrusion, a preferred layout or readiness to expose an instance publicly. Record those outcomes +in the QA issues. Human release, signing, hosting and participant decisions remain in +[OUTSTANDING_TASKS](../../OUTSTANDING_TASKS.md); no checkbox is satisfied merely by this guide. diff --git a/docs/testing/V04_QUALIFICATION_PLAN.md b/docs/testing/V04_QUALIFICATION_PLAN.md new file mode 100644 index 0000000000..40df7e2a58 --- /dev/null +++ b/docs/testing/V04_QUALIFICATION_PLAN.md @@ -0,0 +1,285 @@ +# v0.4 qualification programme + +Last Updated: 2026-09-10 + +Tracker: [#2898](https://github.com/Chris0Jeky/Taskdeck/issues/2898). This document prepares future sessions; +all seeded outcome rows are NOT RUN. + +Read [feature capabilities](../product/FEATURE_CAPABILITIES.md) and use the +[session template](V04_SESSION_TEMPLATE.md). The [outcome ledger](v04-outcomes.csv) starts +with 44 cases and must be copied or versioned per candidate/session; do not overwrite failed evidence. + +## Outcome + +Prepare and execute a source-backed qualification programme for v0.4. A release reader should know what each feature actually does, how to use it, expected outcomes, tested combinations, limitations, and which promises are experimental, unavailable, stubbed, planned or deliberately deferred. + +This is new QA/documentation work requested on 2026-09-10, separate from implementation delivery #2808. Creating issues or writing matrices does not mean the sessions passed. Existing release authority and the four v0.4 gates remain unchanged; milestone placement alone does not declare a new release blocker. + +## Shared execution contract + +Every case records: case ID; full commit/tag and artifact digest; deployment/configuration; browser/OS/device; synthetic fixture revision; account/role; experience/detail/theme; prerequisites; numbered actions; expected UI and persisted state; expected request/side effects (including zero writes/egress where applicable); actual result; PASS/FAIL/BLOCKED/NOT RUN/NOT APPLICABLE; evidence; defect link and retest SHA. NOT APPLICABLE needs a stated contract reason. Unrun cells never count as passes. + +Fixtures use owner A, collaborating editor B, viewer C and unrelated account D; active, empty and archived boards; normal/due/blocked/completed cards; a pending proposal; private memory/originals; and a named reset procedure. Do not use production data or publish participant recordings, tokens or private answers. Counts, revisions and source hashes are observed from the fixture and recorded before each scenario. + +## Sequence + +1. Freeze the feature contract and fixture/case inventory on the candidate. +2. Run deterministic API/component/browser invariants and failure-path tests. +3. Run cross-browser/device/accessibility and moderated UX sessions on the same candidate. +4. Exercise upgrade/restore, hosted isolation/operations and relevant Fabric/work-model integrations as their implementations land. +5. Reconcile observed outcomes, defects, remaining human acceptance and release claims. Retest changed seams; reuse evidence only when its input/contract is unchanged. + +## Existing owners reused + +- #2237 owns performance measurements/threshold derivation; consume its baseline instead of inventing timing promises. +- #1363/#2764 own visual baseline infrastructure/residuals; #1949 owns affordance guards. +- #2243 owns hosted-beta implementation; #1644 and the beta threat model own browser authentication posture. +- #2334 owns clean-from-tag release qualification; #1271 owns actual 10-working-day personal dogfooding and #1325 the friends/family beta path. No agent report substitutes for human use. +- #1308 owns opt-in telemetry; comparison sessions add no implicit collection. + +## Completion + +- [ ] Linked session issues have executable matrices, fixture/reset instructions and source-linked expected values. +- [ ] Capability catalogue includes implemented, experimental, unavailable/unconfigured, verified stubs, planned/deferred and outside-current-contract categories without conflating them. +- [ ] Candidate result ledger links actual evidence for every required case and explicitly dispositions every uncovered combination. +- [ ] Confirmed trust/data-loss/security defects are fixed and retested or prevent the affected release claim; remaining findings have owners and explicit disposition under existing release policy. +- [ ] Actual participant/device/provider/hosted results are distinguished from synthetic proof; maintainer release acceptance remains explicit. + +## Session backlog + +- [ ] #2899 — [v0.4 QA-01] Publish the feature contract and capability status catalogue +- [ ] #2900 — [v0.4 QA-02] Rehearse capture, review and explicit apply across UI, CLI and MCP +- [ ] #2901 — [v0.4 QA-03] Compare Classic, Studio, Companion and Unified through task-based UX sessions +- [ ] #2902 — [v0.4 QA-04] Run keyboard, screen-reader, mobile and theme accessibility sessions +- [ ] #2903 — [v0.4 QA-05] Validate thinking, Studio continuity and work-model interactions +- [ ] #2904 — [v0.4 QA-06] Verify private answers, memory, original sources and account lifecycle isolation +- [ ] #2905 — [v0.4 QA-07] Qualify audio intake, transcription consent and grounded-question usefulness +- [ ] #2906 — [v0.4 QA-08] Exercise reminders, quiet states and overlapping request recovery +- [ ] #2907 — [v0.4 QA-09] Rehearse upgrades, backup restore and portable data compatibility +- [ ] #2908 — [v0.4 QA-10] Run hosted-beta isolation, onboarding and operations acceptance drills +- [ ] #2909 — [v0.4 QA-11] Qualify Fabric processing and evidence contracts as v0.4 slices land + + All new qualification issues target milestone v0.4; existing v0.3 prerequisites and v0.5/v0.6 feature work keep their current milestones. + +## Initial session matrices + +### [v0.4 QA-01] Publish the feature contract and capability status catalogue + +Issue: [#2899](https://github.com/Chris0Jeky/Taskdeck/issues/2899). + +#### Outcome matrix + +| Case | Setup and action | Expected outcome | +| --- | --- | --- | +| CAT-01 | Walk each advertised route/control with its documented prerequisites | A real consequence or explicit unavailable/disabled reason; no inert enabled control. Record the request and persisted consequence. | +| CAT-02 | Compare guide claims with code, feature flags and latest delivery receipts | Each claim has a source, candidate SHA, availability condition, known limit and proving case. | +| CAT-03 | Inspect disabled providers, demo builds and experimental features | Unconfigured is distinct from stubbed; synthetic transport is test evidence, not a production provider. Mark a stub only with exact code evidence. | +| CAT-04 | Reconcile v0.4 work-model/Fabric and later voice/semantic roadmap | Planned work retains its owning issue and actual milestone; no earlier release promise is inferred from shared terminology. | + +#### Session design and limits + +Deliver docs/product/FEATURE_CAPABILITIES.md with user entry points, examples, expected state changes, permission/privacy boundaries, persistence/export behavior, errors/recovery, limits, confidence/evidence, dependencies and planned/not-planned disposition. Audit current documentation claims without copying historical suite counts or QA maturity scores as present evidence. “Not planned” means no current committed scope, not a permanent product rejection. + +Use the parent’s synthetic A/B/C/D account fixture and evidence contract. Record exact candidate/configuration, baseline counts/revisions, ordered actions, actual UI/request/persisted effects and the case result. Expected values above are acceptance targets grounded in named contracts; revalidate constants against the candidate and explicitly document any approved contract change. + + +### [v0.4 QA-02] Rehearse capture, review and explicit apply across UI, CLI and MCP + +Issue: [#2900](https://github.com/Chris0Jeky/Taskdeck/issues/2900). + +#### Outcome matrix + +| Case | Setup and action | Expected outcome | +| --- | --- | --- | +| CORE-01 | Capture one known task and request a proposal | Capture is durable; proposal is reviewable; board card count remains N until explicit Apply. | +| CORE-02 | Preview, approve, then apply the one-create proposal | Preview and approval leave N cards; successful explicit Apply gives N+1 with correct text/destination and linked audit/provenance. | +| CORE-03 | Reject, lose permission, archive board or change proposal revision before apply | No unauthorized/stale board mutation; visible recovery explains refresh/review; no silent reapproval or resend. | +| CORE-04 | Repeat apply after a lost receipt through supported UI/CLI/MCP routes | Resolve the saved outcome using the documented idempotency contract; no second created card; record actual error/receipt shape. | + +#### Session design and limits + +Use the same synthetic input and proposal operations across interfaces; include credential absent/invalid/expired and scoped-key read/write boundaries. Check keyboard review focus, stale deep links, readable decision feedback and return to the exact proposal. Inventory actual command names from the current CLI/MCP docs rather than inventing parallel APIs. Consumption of #1940/#2215 fixes is a dependency, not duplicate implementation. + +Use the parent’s synthetic A/B/C/D account fixture and evidence contract. Record exact candidate/configuration, baseline counts/revisions, ordered actions, actual UI/request/persisted effects and the case result. Expected values above are acceptance targets grounded in named contracts; revalidate constants against the candidate and explicitly document any approved contract change. + + +### [v0.4 QA-03] Compare Classic, Studio, Companion and Unified through task-based UX sessions + +Issue: [#2901](https://github.com/Chris0Jeky/Taskdeck/issues/2901). + +#### Outcome matrix + +| Case | Setup and action | Expected outcome | +| --- | --- | --- | +| UX-01 | Switch through all four experiences with an open card and unsaved capture/chat/thinking | Same account, route, card IDs and appropriate unsaved draft remain; zero proposal approval/apply or provider request solely from switching. | +| UX-02 | Repeat one capture-think-review-resume scenario in each experience | Expected task is completed with correct saved result; record time, misclicks, assistance, recovery attempts and participant explanation. | +| UX-03 | Change Zen/Studio/Control and Grove/Grove Night, including Auto appearance | Permission, due/blocker and trust information remain accessible; selected and resolved appearance attribution are accurate. | +| UX-04 | Record, export and import the same comparison observations twice | Stable IDs and configuration/build attribution survive; exact duplicates are skipped; conflicting IDs reject the batch rather than silently overwrite. | + +#### Session design and limits + +Cover all 4×3×2 named experience/detail/Grove combinations for deterministic shell invariants; cover supported Paper/Legacy renderer combinations and Auto resolution separately. Use representative deeper journeys plus documented pairwise choices instead of asserting every browser/data Cartesian product was tested. Rotate experience order across moderated sessions to reduce practice bias; report raw individual outcomes, no statistical significance or randomized-product A/B claim. Start with a pilot session, then reuse the corrected script with the agreed beta cohort (#1325). Participant numbers and recruitment remain recorded choices, not invented research evidence. + +Use the parent’s synthetic A/B/C/D account fixture and evidence contract. Record exact candidate/configuration, baseline counts/revisions, ordered actions, actual UI/request/persisted effects and the case result. Expected values above are acceptance targets grounded in named contracts; revalidate constants against the candidate and explicitly document any approved contract change. + + +### [v0.4 QA-04] Run keyboard, screen-reader, mobile and theme accessibility sessions + +Issue: [#2902](https://github.com/Chris0Jeky/Taskdeck/issues/2902). + +#### Outcome matrix + +| Case | Setup and action | Expected outcome | +| --- | --- | --- | +| A11Y-01 | Keyboard-only capture, card thinking, review, settings and nested confirmation | Every intended control is reachable and named; focus is visible; no trap; Escape/close returns focus to the invoking control where contracted. | +| A11Y-02 | Use a real screen reader for saving, validation, stale results and proposal decisions | Names/roles/state changes and errors are announced meaningfully; recovery does not depend solely on color or visual location. | +| A11Y-03 | Open card/nested confirmation with a physical mobile keyboard visible; rotate and zoom | Focused fields and primary actions remain reachable; no obscured confirmation or lost draft; inspect real iOS Safari and Android Chrome separately from emulation. | +| A11Y-04 | Audit Grove/Night, Paper/Legacy and reduced-motion/high-zoom states | Measure the applicable WCAG 2.2 AA criteria (4.5:1 normal text, 3:1 large text/non-text where applicable); record exceptions and actual measurements, not a blanket certification. | + +#### Session design and limits + +Record browser, OS, assistive technology, physical device, viewport, zoom, font size and input method. Check meaningful loading/empty/disabled/error states, touch targets, scroll containment, shortcut collisions and theme changes during dialogs. Automated axe and reviewed visual baselines support the session but do not replace it. Proposed AA acceptance is a QA target requiring measured disposition, not an assertion of current conformance. + +Use the parent’s synthetic A/B/C/D account fixture and evidence contract. Record exact candidate/configuration, baseline counts/revisions, ordered actions, actual UI/request/persisted effects and the case result. Expected values above are acceptance targets grounded in named contracts; revalidate constants against the candidate and explicitly document any approved contract change. + + +### [v0.4 QA-05] Validate thinking, Studio continuity and work-model interactions + +Issue: [#2903](https://github.com/Chris0Jeky/Taskdeck/issues/2903). + +#### Outcome matrix + +| Case | Setup and action | Expected outcome | +| --- | --- | --- | +| WORK-01 | Save a steps layer, create one linked card, retry and remove the original step | Exactly one card/link on retry; current status comes from the real card; removing the layer does not delete that card. | +| WORK-02 | Add a prerequisite, attempt a reverse edge/cycle, then export/import | Valid edge appears in both directions; invalid cycle causes zero graph mutation; import remaps endpoints within the new board. | +| WORK-03 | Choose private plan/Focus, switch Board/List/Horizon, use Make room, reload | Same real card references; plan/focus persists for its owner; Make room does not change card due dates or collaborators’ private plan. | +| WORK-04 | Exercise typed items/parent hierarchy/assignments/custom fields on a candidate that includes their owning implementation | Apply each owning issue’s exact contract, ID/permission/archive/import rules and migrations; otherwise record BLOCKED on that issue, not PASS or stubbed. | + +#### Session design and limits + +Include WIP-full destinations, read-only/archived boards, deleted child targets, two-tab revisions, lost save receipts and empty plans. Snapshot card count, IDs, due dates, graph revision and per-user plan before/after. The existing dependency graph limit is 500 edges; verify boundary behavior against the candidate constant before seeding 499/500/501 cases. Keep dependency edges distinct from the broader typed-link feature #2092. + +Use the parent’s synthetic A/B/C/D account fixture and evidence contract. Record exact candidate/configuration, baseline counts/revisions, ordered actions, actual UI/request/persisted effects and the case result. Expected values above are acceptance targets grounded in named contracts; revalidate constants against the candidate and explicitly document any approved contract change. + + +### [v0.4 QA-06] Verify private answers, memory, original sources and account lifecycle isolation + +Issue: [#2904](https://github.com/Chris0Jeky/Taskdeck/issues/2904). + +#### Outcome matrix + +| Case | Setup and action | Expected outcome | +| --- | --- | --- | +| PRIV-01 | A and B answer the same shared question; C/D inspect board routes and exports | Shared question may be visible by board permission; private answers/history never appear in another user’s response, board JSON or UI. | +| PRIV-02 | Correct/archive/restore memory and preserve an older original | Current value changes only as requested; immutable original and correction lineage remain readable by the owner; historical originals are clearly labelled. | +| PRIV-03 | Explicitly select a memory/original for Companion, then change source or permission before send | Only previewed selected content is eligible; stale/unauthorized content is rejected; no implicit private retrieval or model resend. | +| PRIV-04 | Export account, erase A in an isolated fixture during pending reads/writes | Owner’s private source graph, representations and receipts follow erasure policy; late work cannot resurrect it; B’s records survive. | + +#### Session design and limits + +Test account-switch stale success and failure responses, logout, board physical deletion versus archive, native and legacy preserved originals, both account export formats and the board-scoped private download. A board-scoped multi-read download is not an atomic backup or a supported restore format. Record before/after ownership counts and blob/source lineage; sanitize all evidence. + +Use the parent’s synthetic A/B/C/D account fixture and evidence contract. Record exact candidate/configuration, baseline counts/revisions, ordered actions, actual UI/request/persisted effects and the case result. Expected values above are acceptance targets grounded in named contracts; revalidate constants against the candidate and explicitly document any approved contract change. + + +### [v0.4 QA-07] Qualify audio intake, transcription consent and grounded-question usefulness + +Issue: [#2905](https://github.com/Chris0Jeky/Taskdeck/issues/2905). + +#### Outcome matrix + +| Case | Setup and action | Expected outcome | +| --- | --- | --- | +| AI-01 | Record/upload valid audio, deny microphone access, use text fallback and retry a lost upload receipt | Original playback/download is usable; permission failure offers an actionable path; stable retry does not duplicate the original. | +| AI-02 | Inspect destination/model, consent once, receive provisional transcript, review and confirm | No provider request before consent; source bytes and configured destination match; provisional text is not an answer until explicit confirmation; original remains unchanged. | +| AI-03 | Preview one card excerpt and request grounded questions | The model user content equals the previewed excerpt; bounded questions contain valid quoted evidence; stale evidence/permission/budget failures are explicit and do not auto-resend. | +| AI-04 | Run an agreed synthetic/redacted corpus through an explicitly configured live route | Record transcription errors, unsupported claims, useful/duplicate questions, corrections, latency and usage. Report actual outcomes and limitations; deterministic mocks alone cannot pass this row. | + +#### Session design and limits + +Include silence/noise, short/long supported clips, unsupported size/type, provider unavailable, timeout, cancellation, reload and account erasure interleavings. Read upload/duration/model-budget limits from current policy/config and record exact boundary values before execution. Grounded analysis currently produces up to three questions with one-day freshness; include 0/1/3/over-limit and stale cases. No credentials, purchases or private recordings are assumed. General local STT/WhisperX/semantic recall/cloud benchmark roadmap stays with its v0.5/v0.6 owners; existing optional remote transcription is not a stub for those broader promises. + +Use the parent’s synthetic A/B/C/D account fixture and evidence contract. Record exact candidate/configuration, baseline counts/revisions, ordered actions, actual UI/request/persisted effects and the case result. Expected values above are acceptance targets grounded in named contracts; revalidate constants against the candidate and explicitly document any approved contract change. + + +### [v0.4 QA-08] Exercise reminders, quiet states and overlapping request recovery + +Issue: [#2906](https://github.com/Chris0Jeky/Taskdeck/issues/2906). + +#### Outcome matrix + +| Case | Setup and action | Expected outcome | +| --- | --- | --- | +| ATT-01 | Use a new account and eligible existing question; leave reminders disabled | Zero reminder delivery and zero automatic model analysis. Opt-in is explicit. | +| ATT-02 | Enable reminders with typing/dialog/Focus/Zen/hidden-tab suppression; advance controlled clock | No interruption in quiet states; at most two deliveries per UTC day and at least two hours between eligible deliveries across sessions. | +| ATT-03 | Save named-zone weekday/overnight hours and test DST, UTC rollover and enable-only toggles | Window uses the configured IANA zone and starting day; toggles preserve saved window and unsaved edit draft; editing hours does not reset usage allowance. | +| ATT-04 | A save pending → switch to B → B edits/saves → A succeeds or fails → B finishes | A’s completion cannot clear B’s guard; B’s draft remains; an explicit hours save uses B’s current revision exactly once. | + +#### Session design and limits + +Also test confirmed validation rejection versus uncertain/lost response: a confirmed validation failure retains editable values; uncertain state requires explicit read/reload and does not silently replay the write. Include both settlement orders, multiple tabs, disable/mute/snooze, source deletion and permission loss. Record subjective annoyance/usefulness in actual sessions separately from eligibility-rule correctness; no claim of non-intrusion based on mocked timers. + +Use the parent’s synthetic A/B/C/D account fixture and evidence contract. Record exact candidate/configuration, baseline counts/revisions, ordered actions, actual UI/request/persisted effects and the case result. Expected values above are acceptance targets grounded in named contracts; revalidate constants against the candidate and explicitly document any approved contract change. + + +### [v0.4 QA-09] Rehearse upgrades, backup restore and portable data compatibility + +Issue: [#2907](https://github.com/Chris0Jeky/Taskdeck/issues/2907). + +#### Outcome matrix + +| Case | Setup and action | Expected outcome | +| --- | --- | --- | +| DATA-01 | Upgrade a copied supported prior-release fixture using UPGRADING.md | Migrations succeed or fail safely; card IDs/counts, private histories, links, plans, originals and receipts reconcile to the baseline. | +| DATA-02 | Restore a backup into an isolated instance using the existing runbook | Restored counts/content and decryptability match; measured RPO/RTO and artifact hashes are recorded; original instance is untouched. | +| DATA-03 | Import board exports with linked thinking/dependencies and comparison v2/v3 files | References remap within the new board; private answers stay excluded; duplicates/conflicting IDs follow the documented policy; unsupported formats fail visibly. | +| DATA-04 | Attempt corrupt/truncated/unsupported imports and interrupted migration/restore | No partial unauthorized graph or silent data discard; recovery follows the documented transaction/backup boundary. | + +#### Session design and limits + +Inventory supported predecessor tags and export schema versions from current compatibility docs; do not guess universal backwards compatibility. Include enabled and disabled optional providers, empty and representative large fixtures, audio blobs, archived/deleted source cases and account export formats. Board-scoped memory JSON is not atomic backup/import; source-storage restore not currently defined must be explicitly NOT APPLICABLE with the limitation cited. Measure performance through #2237, not a made-up release threshold. + +Use the parent’s synthetic A/B/C/D account fixture and evidence contract. Record exact candidate/configuration, baseline counts/revisions, ordered actions, actual UI/request/persisted effects and the case result. Expected values above are acceptance targets grounded in named contracts; revalidate constants against the candidate and explicitly document any approved contract change. + + +### [v0.4 QA-10] Run hosted-beta isolation, onboarding and operations acceptance drills + +Issue: [#2908](https://github.com/Chris0Jeky/Taskdeck/issues/2908). + +#### Outcome matrix + +| Case | Setup and action | Expected outcome | +| --- | --- | --- | +| HOST-01 | Fresh browser follows the enabled registration/invitation mode and first capture-review-apply | The documented user path works with clear setup/egress/cost disclosure; closed/invite-only modes reject unauthorized registration. | +| HOST-02 | A/B/D attempt cross-account object reads/writes, stale sessions and reconnect | No cross-account private data or authority leakage; expired/revoked credentials fail visibly; reconnect does not duplicate writes. | +| HOST-03 | Exercise configured rate/cost/size ceilings and provider/storage outage | Admission fails before prohibited work/charges; operator and user receive bounded useful signals; secrets and private payloads are absent from logs. | +| HOST-04 | Restore the isolated deployment and rehearse an incident/runbook handoff | Documented recovery succeeds within measured/accepted objectives; status/contact/ownership and rollback evidence are real. | + +#### Session design and limits + +Dependency gates are #2243 and its security/host/backup/identity prerequisites, including #1644 and the beta threat model; this issue does not implement or bypass them. Run privately with synthetic accounts first. Public registration, production data mutation, external spending and credentials require their existing explicit scope. Gate order remains Fabric persistence → processor containment → trusted hosted instance → public hosted beta. Include reverse-proxy HTTPS, browser reload, two-device sessions, security headers/cookies and accessible error states according to the current deployment contract. + +Use the parent’s synthetic A/B/C/D account fixture and evidence contract. Record exact candidate/configuration, baseline counts/revisions, ordered actions, actual UI/request/persisted effects and the case result. Expected values above are acceptance targets grounded in named contracts; revalidate constants against the candidate and explicitly document any approved contract change. + + +### [v0.4 QA-11] Qualify Fabric processing and evidence contracts as v0.4 slices land + +Issue: [#2909](https://github.com/Chris0Jeky/Taskdeck/issues/2909). + +#### Outcome matrix + +| Case | Setup and action | Expected outcome | +| --- | --- | --- | +| FAB-01 | Submit a supported source and execute the existing deterministic capability path | Capture/source/job/run/representation lineage is durable and queryable under the owning contract; duplicate admission does not create unintended duplicate work. | +| FAB-02 | Restart/timeout/cancel a processor; expire a lease; replay a receipt | State transitions, retry eligibility and visible recovery match the queue/worker contract; no ambiguous “success” or duplicate committed outcome. | +| FAB-03 | Feed maliciously oversized/compressed/unsupported input to the isolated processor harness | Configured resource/capability limits stop processing; no uncontrolled child process or forbidden filesystem/network effect. | +| FAB-04 | Inspect/export evidence anchors after representation migration or source deletion | Anchors resolve to the intended typed source/version or clearly report unavailability; private/account boundaries and documented retention remain intact. | + +#### Session design and limits + +Resolve exact limits, expected job states, exit codes and lease timing from CF-02..CF-07/CF-23 implementations at the pinned candidate. Missing implementations block their scenarios explicitly. Use the existing conformance harness, not a parallel worker architecture. IBlobStore abstraction does not imply object-store hosting is enabled; semantic candidates/resolver, local transcription, meeting understanding and policy routing keep their later milestones. Include compatibility consumers from capture, chat and evidence preview, while preserving explicit Review/Approve/Apply. + +Use the parent’s synthetic A/B/C/D account fixture and evidence contract. Record exact candidate/configuration, baseline counts/revisions, ordered actions, actual UI/request/persisted effects and the case result. Expected values above are acceptance targets grounded in named contracts; revalidate constants against the candidate and explicitly document any approved contract change. + + diff --git a/docs/testing/V04_SESSION_TEMPLATE.md b/docs/testing/V04_SESSION_TEMPLATE.md new file mode 100644 index 0000000000..4110857d3e --- /dev/null +++ b/docs/testing/V04_SESSION_TEMPLATE.md @@ -0,0 +1,69 @@ +# v0.4 QA session and result template + +Last Updated: 2026-09-10 + +Companion: [qualification plan](V04_QUALIFICATION_PLAN.md), +[feature contracts](../product/FEATURE_CAPABILITIES.md), +[existing manual rehearsal template](MANUAL_REHEARSAL_TEMPLATE.md). + +## Run identity + +- Session ID / date / operator / issue: +- Candidate full commit or tag / artifact digest / backend and frontend versions: +- Deployment (source / packaged Windows / self-host / controlled hosted): +- Browser and version / OS / physical device or emulation / assistive technology: +- Viewport / zoom / input method / experience / detail / selected and resolved theme: +- Provider mode (disabled / deterministic synthetic / configured live), model and effective limits: +- Fixture revision / account roles / board IDs / initial counts and revisions: +- Consent and evidence storage location (use synthetic or approved redacted data): +- Contract sources and any explicitly approved deviation from their expected behavior: + +## Preconditions and reset + +1. Pin and record the candidate. Use isolated data and the named fixture/reset command from the case. +2. Establish owner A, editor B, viewer C and unrelated D only where needed. Record actual permissions. +3. Record starting card/source counts, revisions, due dates, usage allowance and controlled clock. +4. Verify provider/configuration availability before a live case. Unavailable is BLOCKED, not a pass. +5. Restore the fixture between destructive/interference cases. Never reset a participant's real work. + +## Outcome matrix + +| Case / issue | Prerequisites and ordered actions | Expected UI | Expected persisted result | Expected requests / zero-effects | Actual observation | Result | Evidence / defect / retest | +| --- | --- | --- | --- | --- | --- | --- | --- | +| Example, not executed | Record steps | State the visible result | State count/revision/content | State allowed writes/egress and what must remain unchanged | Leave blank until run | NOT RUN | Candidate-bound evidence | + +Results: **PASS**, **FAIL**, **BLOCKED**, **NOT RUN**, **NOT APPLICABLE**. A blocked case names the +missing prerequisite and owner; not applicable cites a specific contract boundary. Neither counts +as a pass. Split partial results into individual cases instead of marking a mixed row successful. + +## UX observations + +Record task completion, elapsed time, assistance, mistaken actions, recovery attempts, participant +expectation and their explanation of the result. Separate observed behavior from interpretation. +Do not fabricate ease ratings or preference. Rotate experience order when comparing alternatives; +retain the same task fixture. A small qualitative session does not establish statistical superiority. + +Record whether the user can explain: what saved, what is shared/private, what a proposal will change, +whether a model was called, what an error means, and the next safe action. Note distracting reminders, +missing feedback, confusing labels and hidden controls even when the underlying API is correct. + +## Evidence and findings + +- Keep sanitized screenshots, trace/log excerpts, measured counts and request receipts bound to case ID. +- Avoid tokens, credentials, private answers, raw participant recordings and production datasets. +- File a reproducible defect: candidate, fixture, steps, expected/actual, direct user impact and evidence. +- Reuse an existing owning issue when the failure is already tracked; link this session's new evidence. +- Retest the repair on its actual candidate and the affected interaction. Do not silently replace a fail. +- Performance targets come from the approved measured baseline in #2237; record raw values beforehand. + +## Session closeout + +- Executed / pass / fail / blocked / not-run / not-applicable counts, with denominator and coverage gaps: +- Actual platforms/configurations and combinations excluded, with reason: +- Confirmed trust/security/data-loss defects and disposition under existing release policy: +- Other defects, owner, severity, planned fix or explicit acceptance: +- Changed feature claims/limitations and links to corrected documentation: +- Next session and unresolved human/device/provider/hosting acceptance: + +Do not infer release acceptance, production deployment authorization or participant preference. +The programme coordinates evidence; existing release and human decision gates remain authoritative. diff --git a/docs/testing/v04-outcomes.csv b/docs/testing/v04-outcomes.csv new file mode 100644 index 0000000000..34128002f7 --- /dev/null +++ b/docs/testing/v04-outcomes.csv @@ -0,0 +1,45 @@ +"case_id","issue","target_milestone","candidate_sha","session_id","setup_action","expected_result","actual_result","status","evidence","defect","retest_sha" +"CAT-01","2899","v0.4","","","Walk each advertised route/control with its documented prerequisites","A real consequence or explicit unavailable/disabled reason; no inert enabled control. Record the request and persisted consequence.","","NOT RUN","","","" +"CAT-02","2899","v0.4","","","Compare guide claims with code, feature flags and latest delivery receipts","Each claim has a source, candidate SHA, availability condition, known limit and proving case.","","NOT RUN","","","" +"CAT-03","2899","v0.4","","","Inspect disabled providers, demo builds and experimental features","Unconfigured is distinct from stubbed; synthetic transport is test evidence, not a production provider. Mark a stub only with exact code evidence.","","NOT RUN","","","" +"CAT-04","2899","v0.4","","","Reconcile v0.4 work-model/Fabric and later voice/semantic roadmap","Planned work retains its owning issue and actual milestone; no earlier release promise is inferred from shared terminology.","","NOT RUN","","","" +"CORE-01","2900","v0.4","","","Capture one known task and request a proposal","Capture is durable; proposal is reviewable; board card count remains N until explicit Apply.","","NOT RUN","","","" +"CORE-02","2900","v0.4","","","Preview, approve, then apply the one-create proposal","Preview and approval leave N cards; successful explicit Apply gives N+1 with correct text/destination and linked audit/provenance.","","NOT RUN","","","" +"CORE-03","2900","v0.4","","","Reject, lose permission, archive board or change proposal revision before apply","No unauthorized/stale board mutation; visible recovery explains refresh/review; no silent reapproval or resend.","","NOT RUN","","","" +"CORE-04","2900","v0.4","","","Repeat apply after a lost receipt through supported UI/CLI/MCP routes","Resolve the saved outcome using the documented idempotency contract; no second created card; record actual error/receipt shape.","","NOT RUN","","","" +"UX-01","2901","v0.4","","","Switch through all four experiences with an open card and unsaved capture/chat/thinking","Same account, route, card IDs and appropriate unsaved draft remain; zero proposal approval/apply or provider request solely from switching.","","NOT RUN","","","" +"UX-02","2901","v0.4","","","Repeat one capture-think-review-resume scenario in each experience","Expected task is completed with correct saved result; record time, misclicks, assistance, recovery attempts and participant explanation.","","NOT RUN","","","" +"UX-03","2901","v0.4","","","Change Zen/Studio/Control and Grove/Grove Night, including Auto appearance","Permission, due/blocker and trust information remain accessible; selected and resolved appearance attribution are accurate.","","NOT RUN","","","" +"UX-04","2901","v0.4","","","Record, export and import the same comparison observations twice","Stable IDs and configuration/build attribution survive; exact duplicates are skipped; conflicting IDs reject the batch rather than silently overwrite.","","NOT RUN","","","" +"A11Y-01","2902","v0.4","","","Keyboard-only capture, card thinking, review, settings and nested confirmation","Every intended control is reachable and named; focus is visible; no trap; Escape/close returns focus to the invoking control where contracted.","","NOT RUN","","","" +"A11Y-02","2902","v0.4","","","Use a real screen reader for saving, validation, stale results and proposal decisions","Names/roles/state changes and errors are announced meaningfully; recovery does not depend solely on color or visual location.","","NOT RUN","","","" +"A11Y-03","2902","v0.4","","","Open card/nested confirmation with a physical mobile keyboard visible; rotate and zoom","Focused fields and primary actions remain reachable; no obscured confirmation or lost draft; inspect real iOS Safari and Android Chrome separately from emulation.","","NOT RUN","","","" +"A11Y-04","2902","v0.4","","","Audit Grove/Night, Paper/Legacy and reduced-motion/high-zoom states","Measure the applicable WCAG 2.2 AA criteria (4.5:1 normal text, 3:1 large text/non-text where applicable); record exceptions and actual measurements, not a blanket certification.","","NOT RUN","","","" +"WORK-01","2903","v0.4","","","Save a steps layer, create one linked card, retry and remove the original step","Exactly one card/link on retry; current status comes from the real card; removing the layer does not delete that card.","","NOT RUN","","","" +"WORK-02","2903","v0.4","","","Add a prerequisite, attempt a reverse edge/cycle, then export/import","Valid edge appears in both directions; invalid cycle causes zero graph mutation; import remaps endpoints within the new board.","","NOT RUN","","","" +"WORK-03","2903","v0.4","","","Choose private plan/Focus, switch Board/List/Horizon, use Make room, reload","Same real card references; plan/focus persists for its owner; Make room does not change card due dates or collaborators’ private plan.","","NOT RUN","","","" +"WORK-04","2903","v0.4","","","Exercise typed items/parent hierarchy/assignments/custom fields on a candidate that includes their owning implementation","Apply each owning issue’s exact contract, ID/permission/archive/import rules and migrations; otherwise record BLOCKED on that issue, not PASS or stubbed.","","NOT RUN","","","" +"PRIV-01","2904","v0.4","","","A and B answer the same shared question; C/D inspect board routes and exports","Shared question may be visible by board permission; private answers/history never appear in another user’s response, board JSON or UI.","","NOT RUN","","","" +"PRIV-02","2904","v0.4","","","Correct/archive/restore memory and preserve an older original","Current value changes only as requested; immutable original and correction lineage remain readable by the owner; historical originals are clearly labelled.","","NOT RUN","","","" +"PRIV-03","2904","v0.4","","","Explicitly select a memory/original for Companion, then change source or permission before send","Only previewed selected content is eligible; stale/unauthorized content is rejected; no implicit private retrieval or model resend.","","NOT RUN","","","" +"PRIV-04","2904","v0.4","","","Export account, erase A in an isolated fixture during pending reads/writes","Owner’s private source graph, representations and receipts follow erasure policy; late work cannot resurrect it; B’s records survive.","","NOT RUN","","","" +"AI-01","2905","v0.4","","","Record/upload valid audio, deny microphone access, use text fallback and retry a lost upload receipt","Original playback/download is usable; permission failure offers an actionable path; stable retry does not duplicate the original.","","NOT RUN","","","" +"AI-02","2905","v0.4","","","Inspect destination/model, consent once, receive provisional transcript, review and confirm","No provider request before consent; source bytes and configured destination match; provisional text is not an answer until explicit confirmation; original remains unchanged.","","NOT RUN","","","" +"AI-03","2905","v0.4","","","Preview one card excerpt and request grounded questions","The model user content equals the previewed excerpt; bounded questions contain valid quoted evidence; stale evidence/permission/budget failures are explicit and do not auto-resend.","","NOT RUN","","","" +"AI-04","2905","v0.4","","","Run an agreed synthetic/redacted corpus through an explicitly configured live route","Record transcription errors, unsupported claims, useful/duplicate questions, corrections, latency and usage. Report actual outcomes and limitations; deterministic mocks alone cannot pass this row.","","NOT RUN","","","" +"ATT-01","2906","v0.4","","","Use a new account and eligible existing question; leave reminders disabled","Zero reminder delivery and zero automatic model analysis. Opt-in is explicit.","","NOT RUN","","","" +"ATT-02","2906","v0.4","","","Enable reminders with typing/dialog/Focus/Zen/hidden-tab suppression; advance controlled clock","No interruption in quiet states; at most two deliveries per UTC day and at least two hours between eligible deliveries across sessions.","","NOT RUN","","","" +"ATT-03","2906","v0.4","","","Save named-zone weekday/overnight hours and test DST, UTC rollover and enable-only toggles","Window uses the configured IANA zone and starting day; toggles preserve saved window and unsaved edit draft; editing hours does not reset usage allowance.","","NOT RUN","","","" +"ATT-04","2906","v0.4","","","A save pending → switch to B → B edits/saves → A succeeds or fails → B finishes","A’s completion cannot clear B’s guard; B’s draft remains; an explicit hours save uses B’s current revision exactly once.","","NOT RUN","","","" +"DATA-01","2907","v0.4","","","Upgrade a copied supported prior-release fixture using UPGRADING.md","Migrations succeed or fail safely; card IDs/counts, private histories, links, plans, originals and receipts reconcile to the baseline.","","NOT RUN","","","" +"DATA-02","2907","v0.4","","","Restore a backup into an isolated instance using the existing runbook","Restored counts/content and decryptability match; measured RPO/RTO and artifact hashes are recorded; original instance is untouched.","","NOT RUN","","","" +"DATA-03","2907","v0.4","","","Import board exports with linked thinking/dependencies and comparison v2/v3 files","References remap within the new board; private answers stay excluded; duplicates/conflicting IDs follow the documented policy; unsupported formats fail visibly.","","NOT RUN","","","" +"DATA-04","2907","v0.4","","","Attempt corrupt/truncated/unsupported imports and interrupted migration/restore","No partial unauthorized graph or silent data discard; recovery follows the documented transaction/backup boundary.","","NOT RUN","","","" +"HOST-01","2908","v0.4","","","Fresh browser follows the enabled registration/invitation mode and first capture-review-apply","The documented user path works with clear setup/egress/cost disclosure; closed/invite-only modes reject unauthorized registration.","","NOT RUN","","","" +"HOST-02","2908","v0.4","","","A/B/D attempt cross-account object reads/writes, stale sessions and reconnect","No cross-account private data or authority leakage; expired/revoked credentials fail visibly; reconnect does not duplicate writes.","","NOT RUN","","","" +"HOST-03","2908","v0.4","","","Exercise configured rate/cost/size ceilings and provider/storage outage","Admission fails before prohibited work/charges; operator and user receive bounded useful signals; secrets and private payloads are absent from logs.","","NOT RUN","","","" +"HOST-04","2908","v0.4","","","Restore the isolated deployment and rehearse an incident/runbook handoff","Documented recovery succeeds within measured/accepted objectives; status/contact/ownership and rollback evidence are real.","","NOT RUN","","","" +"FAB-01","2909","v0.4","","","Submit a supported source and execute the existing deterministic capability path","Capture/source/job/run/representation lineage is durable and queryable under the owning contract; duplicate admission does not create unintended duplicate work.","","NOT RUN","","","" +"FAB-02","2909","v0.4","","","Restart/timeout/cancel a processor; expire a lease; replay a receipt","State transitions, retry eligibility and visible recovery match the queue/worker contract; no ambiguous “success” or duplicate committed outcome.","","NOT RUN","","","" +"FAB-03","2909","v0.4","","","Feed maliciously oversized/compressed/unsupported input to the isolated processor harness","Configured resource/capability limits stop processing; no uncontrolled child process or forbidden filesystem/network effect.","","NOT RUN","","","" +"FAB-04","2909","v0.4","","","Inspect/export evidence anchors after representation migration or source deletion","Anchors resolve to the intended typed source/version or clearly report unavailability; private/account boundaries and documented retention remain intact.","","NOT RUN","","","" From 4bd2794d1202d8a034736a6a0e82f120ebc406a9 Mon Sep 17 00:00:00 2001 From: Chris0Jeky Date: Thu, 10 Sep 2026 12:55:41 +0100 Subject: [PATCH 4/5] Correct interface authority and audio QA expectations --- docs/product/FEATURE_CAPABILITIES.md | 26 +++++++++++++++++++------- docs/testing/V04_QUALIFICATION_PLAN.md | 12 +++++++----- docs/testing/v04-outcomes.csv | 6 +++--- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/docs/product/FEATURE_CAPABILITIES.md b/docs/product/FEATURE_CAPABILITIES.md index c6db8038a4..5b993a4435 100644 --- a/docs/product/FEATURE_CAPABILITIES.md +++ b/docs/product/FEATURE_CAPABILITIES.md @@ -27,7 +27,9 @@ limits live in the [validation ledger](WORKSPACE_OVERHAUL_VALIDATION.md). | Feature and entry point | What to expect | Limits and interactions | Status / QA | | --- | --- | --- | --- | -| Capture → Review → Apply | Saved input leads to a reviewable proposal. Inspect evidence, approve, then explicitly apply. The board changes at Apply. | Preview, experience changes and approval alone do not apply changes. Stale revisions and missing authority require recovery. UI, CLI and MCP must retain the same authority boundary. | Implemented; [QA-02](https://github.com/Chris0Jeky/Taskdeck/issues/2900). | +| UI/API Capture → Review → Apply | Saved input leads to a reviewable proposal. Inspect evidence, approve, then explicitly apply. The board changes at Apply. | Preview, experience changes and approval alone do not apply changes. Stale revisions and missing authority require recovery. This describes the UI/API proposal flow, not every CLI or MCP command. | Implemented; [QA-02](https://github.com/Chris0Jeky/Taskdeck/issues/2900). | +| CLI card commands | Card add/move/list commands use application services directly; an add is a direct mutation, not a pending proposal. | Do not assume UI review-first sequencing or authorization parity. Fresh-machine and claims-first hardening remains tracked in [#1131](https://github.com/Chris0Jeky/Taskdeck/issues/1131). Inspect the [handler](../../backend/src/Taskdeck.Cli/Commands/CardsCommandHandler.cs) and run against isolated data. | Implemented direct-command surface with known hardening work; [QA-02](https://github.com/Chris0Jeky/Taskdeck/issues/2900). | +| MCP proposal tools | Get/list proposal state and dismiss eligible proposals; use the supported proposing tools and hand off to UI/API review. | [ProposalTools](../../backend/src/Taskdeck.Api/Mcp/ProposalTools.cs) deliberately exposes no approve or apply operation. Test each tool's actual side effects; do not invent an MCP Apply retry. | Implemented bounded tool surface; [QA-02](https://github.com/Chris0Jeky/Taskdeck/issues/2900). | | Experience selector | Classic, Studio, Companion and Unified offer different entry points and navigation over the same task data. | Classic remains the default. Switches preserve the mounted route/open card and appropriate drafts; they do not change permissions, provider policy or proposal authority. | Implemented experiment; [QA-03](https://github.com/Chris0Jeky/Taskdeck/issues/2901). | | Presentation and Appearance | Zen/Studio/Control adjust disclosure independently of experience. Grove/Grove Night add prototype-inspired palettes alongside Paper/Legacy and Auto. | Detail called Studio is separate from the Studio experience. Due/blocker/trust information must remain available. Visual preference and accessibility require direct evaluation. | Implemented; [QA-03](https://github.com/Chris0Jeky/Taskdeck/issues/2901), [QA-04](https://github.com/Chris0Jeky/Taskdeck/issues/2902). | | Card → Open thinking deck | Ordered note, question, options, steps and thread layers, viewed as Stack or Path. | Shared board thinking is distinct from private answers. Saves use revisions. Creating real work from a step is an explicit action. | Implemented; [QA-05](https://github.com/Chris0Jeky/Taskdeck/issues/2903). | @@ -55,7 +57,7 @@ Record the effective value in the session before testing the boundary and one va | Private plan | 40 cards | [PersonalPlan](../../backend/src/Taskdeck.Domain/Entities/PersonalPlan.cs) | | Dependencies | 500 same-board edges | [overhaul dependency contract](WORKSPACE_OVERHAUL.md) | | Companion private sources | Five combined memories/originals | [overhaul source contract](WORKSPACE_OVERHAUL.md) | -| Audio originals | 60 seconds; 2 MiB; WebM/Ogg/WAV/MP3/MP4/M4A; up to 50 written versions per recording | [overhaul audio contract](WORKSPACE_OVERHAUL.md) | +| Audio originals | Browser microphone recording stops at 60 seconds. Selected uploads are bounded by 2 MiB and supported MIME type, with no server duration check; a valid longer low-bitrate upload is not a duration failure. WebM/Ogg/WAV/MP3/MP4/M4A; up to 50 written versions per recording. | [recorder](../../frontend/taskdeck-web/src/components/thinking/AudioAnswerRecorder.vue), [upload service](../../backend/src/Taskdeck.Application/Services/ThinkingAudioService.cs) | | Transcription defaults | Five attempts and 10 MiB per owner/UTC day; 20 receipts per recording; two-minute publication deadline; 64 KiB response / 8,000 text characters | [settings](../../backend/src/Taskdeck.Application/Services/SpeechTranscriptionSettings.cs), [policy](AUDIO_TRANSCRIPTION.md) | | Grounded questions | Up to three; categories next-step/outcome/dependency, at most one each; exact quote at most 400 characters; one-day freshness | [contract](../../backend/src/Taskdeck.Application/Services/WorkspaceObservationContract.cs), [policy](GROUNDED_OBSERVATIONS.md) | | Reminder allowance | At most two claims per UTC day, at least two hours apart; visible/focused board polling no more often than five minutes | [attention policy](WORKSPACE_ATTENTION.md) | @@ -76,12 +78,22 @@ Record the effective value in the session before testing the boundary and one va | Autonomous Apply / silent private retrieval / background question generation | Deliberately absent from these features. User intent and review-first authority remain explicit. | Delegated authority has its own separately gated [#2275](https://github.com/Chris0Jeky/Taskdeck/issues/2275); presentation controls do not enable it. | | Randomized A/B platform, statistical winner, push reminders while closed | Not implemented or promised by the current comparison/reminder features. | Outside their current contract. | +## Verified stub and simulated surfaces + +The authenticated `/workspace/metrics/cohorts` route loads the cohort dashboard when the +`newAutomation` feature is enabled (enabled by default). Its +[metrics endpoint](../../backend/src/Taskdeck.Api/Controllers/AutomationMetricsController.cs) +explicitly returns an empty cohort list until the metrics service exists. Date validation is real; +the empty result does not establish that there is no cohort activity. **Status: Stubbed**. +The source names #1142; current dead-surface disposition is also tracked in +[#1276](https://github.com/Chris0Jeky/Taskdeck/issues/1276). QA-01 must preserve an honest explanation +or record the owning implementation/removal decision before treating it as working analytics. + The supplied HTML prototypes simulate local state and model interactions. Repository mock providers -and synthetic browser fixtures are also simulations. Neither is evidence of a hidden production -stub. This inventory has not established a product stub in the integrated overhaul; the broader -route audit in [QA-01](https://github.com/Chris0Jeky/Taskdeck/issues/2899) must name any actual stub -with its exact code and visible consequence. Existing cohort/Ollama and dead-surface questions in -[OUTSTANDING_TASKS](../../OUTSTANDING_TASKS.md) require current verification, not inference from old titles. +and synthetic browser fixtures are also simulations, distinct from this reachable product stub. +The broader route audit in [QA-01](https://github.com/Chris0Jeky/Taskdeck/issues/2899) must name any +additional stub with exact code and visible consequence. Remaining Ollama/dead-surface questions in +[OUTSTANDING_TASKS](../../OUTSTANDING_TASKS.md) still require current verification. ## What still needs actual use diff --git a/docs/testing/V04_QUALIFICATION_PLAN.md b/docs/testing/V04_QUALIFICATION_PLAN.md index 40df7e2a58..6412f81116 100644 --- a/docs/testing/V04_QUALIFICATION_PLAN.md +++ b/docs/testing/V04_QUALIFICATION_PLAN.md @@ -78,6 +78,8 @@ Issue: [#2899](https://github.com/Chris0Jeky/Taskdeck/issues/2899). #### Session design and limits +Current verified stub to catalogue: /workspace/metrics/cohorts (newAutomation enabled by default) calls AutomationMetricsController.GetCohortMetrics, which validates date ranges but returns an empty cohort list until the service exists (source owner #1142; dead-surface disposition #1276). Do not treat that empty list as actual measured inactivity. + Deliver docs/product/FEATURE_CAPABILITIES.md with user entry points, examples, expected state changes, permission/privacy boundaries, persistence/export behavior, errors/recovery, limits, confidence/evidence, dependencies and planned/not-planned disposition. Audit current documentation claims without copying historical suite counts or QA maturity scores as present evidence. “Not planned” means no current committed scope, not a permanent product rejection. Use the parent’s synthetic A/B/C/D account fixture and evidence contract. Record exact candidate/configuration, baseline counts/revisions, ordered actions, actual UI/request/persisted effects and the case result. Expected values above are acceptance targets grounded in named contracts; revalidate constants against the candidate and explicitly document any approved contract change. @@ -91,14 +93,14 @@ Issue: [#2900](https://github.com/Chris0Jeky/Taskdeck/issues/2900). | Case | Setup and action | Expected outcome | | --- | --- | --- | -| CORE-01 | Capture one known task and request a proposal | Capture is durable; proposal is reviewable; board card count remains N until explicit Apply. | -| CORE-02 | Preview, approve, then apply the one-create proposal | Preview and approval leave N cards; successful explicit Apply gives N+1 with correct text/destination and linked audit/provenance. | +| CORE-01 | Capture one known task through the UI/API proposal flow and request a proposal | Capture is durable; proposal is reviewable; board card count remains N until explicit Apply. | +| CORE-02 | In UI/API, preview, approve, then explicitly apply the one-create proposal | Preview and approval leave N cards; successful explicit Apply gives N+1 with correct text/destination and linked audit/provenance. | | CORE-03 | Reject, lose permission, archive board or change proposal revision before apply | No unauthorized/stale board mutation; visible recovery explains refresh/review; no silent reapproval or resend. | -| CORE-04 | Repeat apply after a lost receipt through supported UI/CLI/MCP routes | Resolve the saved outcome using the documented idempotency contract; no second created card; record actual error/receipt shape. | +| CORE-04 | Repeat UI/API apply after a lost receipt; inspect the available CLI and MCP commands separately | UI/API retry resolves the saved outcome without a second created card. MCP proposal tools expose get/list/dismiss, not approve/apply. CLI card add/move directly call application services and require their own permission/retry expectations; do not replay an invented Apply operation. | #### Session design and limits -Use the same synthetic input and proposal operations across interfaces; include credential absent/invalid/expired and scoped-key read/write boundaries. Check keyboard review focus, stale deep links, readable decision feedback and return to the exact proposal. Inventory actual command names from the current CLI/MCP docs rather than inventing parallel APIs. Consumption of #1940/#2215 fixes is a dependency, not duplicate implementation. +Use the same synthetic task where interfaces support it, with separate expected side effects: UI/API proposal approval and apply; MCP proposal reads/dismiss and supported proposal-producing tools with UI/API review handoff; CLI card add/move direct mutations, with claims-first/fresh-machine hardening tracked in #1131. Do not describe CLI authority parity as already proven; include credential absent/invalid/expired and scoped-key read/write boundaries. Check keyboard review focus, stale deep links, readable decision feedback and return to the exact proposal. Inventory actual command names from the current CLI/MCP docs rather than inventing parallel APIs. Consumption of #1940/#2215 fixes is a dependency, not duplicate implementation. Use the parent’s synthetic A/B/C/D account fixture and evidence contract. Record exact candidate/configuration, baseline counts/revisions, ordered actions, actual UI/request/persisted effects and the case result. Expected values above are acceptance targets grounded in named contracts; revalidate constants against the candidate and explicitly document any approved contract change. @@ -198,7 +200,7 @@ Issue: [#2905](https://github.com/Chris0Jeky/Taskdeck/issues/2905). #### Session design and limits -Include silence/noise, short/long supported clips, unsupported size/type, provider unavailable, timeout, cancellation, reload and account erasure interleavings. Read upload/duration/model-budget limits from current policy/config and record exact boundary values before execution. Grounded analysis currently produces up to three questions with one-day freshness; include 0/1/3/over-limit and stale cases. No credentials, purchases or private recordings are assumed. General local STT/WhisperX/semantic recall/cloud benchmark roadmap stays with its v0.5/v0.6 owners; existing optional remote transcription is not a stub for those broader promises. +Include silence/noise, short/long supported clips, unsupported size/type, provider unavailable, timeout, cancellation, reload and account erasure interleavings. The browser microphone recorder stops at 60 seconds; selected files have supported-MIME and 2 MiB bounds but no server duration check. A valid longer low-bitrate upload is not a duration defect. Read the remaining model-budget/configuration limits from the candidate and record exact boundary values before execution. Grounded analysis currently produces up to three questions with one-day freshness; include 0/1/3/over-limit and stale cases. No credentials, purchases or private recordings are assumed. General local STT/WhisperX/semantic recall/cloud benchmark roadmap stays with its v0.5/v0.6 owners; existing optional remote transcription is not a stub for those broader promises. Use the parent’s synthetic A/B/C/D account fixture and evidence contract. Record exact candidate/configuration, baseline counts/revisions, ordered actions, actual UI/request/persisted effects and the case result. Expected values above are acceptance targets grounded in named contracts; revalidate constants against the candidate and explicitly document any approved contract change. diff --git a/docs/testing/v04-outcomes.csv b/docs/testing/v04-outcomes.csv index 34128002f7..ea1b4f1e25 100644 --- a/docs/testing/v04-outcomes.csv +++ b/docs/testing/v04-outcomes.csv @@ -3,10 +3,10 @@ "CAT-02","2899","v0.4","","","Compare guide claims with code, feature flags and latest delivery receipts","Each claim has a source, candidate SHA, availability condition, known limit and proving case.","","NOT RUN","","","" "CAT-03","2899","v0.4","","","Inspect disabled providers, demo builds and experimental features","Unconfigured is distinct from stubbed; synthetic transport is test evidence, not a production provider. Mark a stub only with exact code evidence.","","NOT RUN","","","" "CAT-04","2899","v0.4","","","Reconcile v0.4 work-model/Fabric and later voice/semantic roadmap","Planned work retains its owning issue and actual milestone; no earlier release promise is inferred from shared terminology.","","NOT RUN","","","" -"CORE-01","2900","v0.4","","","Capture one known task and request a proposal","Capture is durable; proposal is reviewable; board card count remains N until explicit Apply.","","NOT RUN","","","" -"CORE-02","2900","v0.4","","","Preview, approve, then apply the one-create proposal","Preview and approval leave N cards; successful explicit Apply gives N+1 with correct text/destination and linked audit/provenance.","","NOT RUN","","","" +"CORE-01","2900","v0.4","","","Capture one known task through the UI/API proposal flow and request a proposal","Capture is durable; proposal is reviewable; board card count remains N until explicit Apply.","","NOT RUN","","","" +"CORE-02","2900","v0.4","","","In UI/API, preview, approve, then explicitly apply the one-create proposal","Preview and approval leave N cards; successful explicit Apply gives N+1 with correct text/destination and linked audit/provenance.","","NOT RUN","","","" "CORE-03","2900","v0.4","","","Reject, lose permission, archive board or change proposal revision before apply","No unauthorized/stale board mutation; visible recovery explains refresh/review; no silent reapproval or resend.","","NOT RUN","","","" -"CORE-04","2900","v0.4","","","Repeat apply after a lost receipt through supported UI/CLI/MCP routes","Resolve the saved outcome using the documented idempotency contract; no second created card; record actual error/receipt shape.","","NOT RUN","","","" +"CORE-04","2900","v0.4","","","Repeat UI/API apply after a lost receipt; inspect the available CLI and MCP commands separately","UI/API retry resolves the saved outcome without a second created card. MCP proposal tools expose get/list/dismiss, not approve/apply. CLI card add/move directly call application services and require their own permission/retry expectations; do not replay an invented Apply operation.","","NOT RUN","","","" "UX-01","2901","v0.4","","","Switch through all four experiences with an open card and unsaved capture/chat/thinking","Same account, route, card IDs and appropriate unsaved draft remain; zero proposal approval/apply or provider request solely from switching.","","NOT RUN","","","" "UX-02","2901","v0.4","","","Repeat one capture-think-review-resume scenario in each experience","Expected task is completed with correct saved result; record time, misclicks, assistance, recovery attempts and participant explanation.","","NOT RUN","","","" "UX-03","2901","v0.4","","","Change Zen/Studio/Control and Grove/Grove Night, including Auto appearance","Permission, due/blocker and trust information remain accessible; selected and resolved appearance attribution are accurate.","","NOT RUN","","","" From 884871a6415704c2376c1e6229df7223512c4e96 Mon Sep 17 00:00:00 2001 From: Chris0Jeky Date: Thu, 10 Sep 2026 15:36:22 +0100 Subject: [PATCH 5/5] docs: state the audio representation cap as a shared 50-slot pool WriteAsync refuses a Save once 49 representations exist for the capture, reserving the 50th slot for ConfirmAsync, and provisional transcriptions share the same pool. The boundary row said 50 written versions, which would have QA report a conforming refusal as a failure. --- docs/product/FEATURE_CAPABILITIES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/product/FEATURE_CAPABILITIES.md b/docs/product/FEATURE_CAPABILITIES.md index 5b993a4435..04eef9dd00 100644 --- a/docs/product/FEATURE_CAPABILITIES.md +++ b/docs/product/FEATURE_CAPABILITIES.md @@ -57,7 +57,7 @@ Record the effective value in the session before testing the boundary and one va | Private plan | 40 cards | [PersonalPlan](../../backend/src/Taskdeck.Domain/Entities/PersonalPlan.cs) | | Dependencies | 500 same-board edges | [overhaul dependency contract](WORKSPACE_OVERHAUL.md) | | Companion private sources | Five combined memories/originals | [overhaul source contract](WORKSPACE_OVERHAUL.md) | -| Audio originals | Browser microphone recording stops at 60 seconds. Selected uploads are bounded by 2 MiB and supported MIME type, with no server duration check; a valid longer low-bitrate upload is not a duration failure. WebM/Ogg/WAV/MP3/MP4/M4A; up to 50 written versions per recording. | [recorder](../../frontend/taskdeck-web/src/components/thinking/AudioAnswerRecorder.vue), [upload service](../../backend/src/Taskdeck.Application/Services/ThinkingAudioService.cs) | +| Audio originals | Browser microphone recording stops at 60 seconds. Selected uploads are bounded by 2 MiB and supported MIME type, with no server duration check; a valid longer low-bitrate upload is not a duration failure. WebM/Ogg/WAV/MP3/MP4/M4A; at most 50 stored representations per recording, shared by provisional transcriptions, written versions and the confirmation. A Save is refused once 49 already exist, so the 50th slot stays available for confirmation; a refusal at that point is the contract, not a defect. | [recorder](../../frontend/taskdeck-web/src/components/thinking/AudioAnswerRecorder.vue), [upload service](../../backend/src/Taskdeck.Application/Services/ThinkingAudioService.cs) | | Transcription defaults | Five attempts and 10 MiB per owner/UTC day; 20 receipts per recording; two-minute publication deadline; 64 KiB response / 8,000 text characters | [settings](../../backend/src/Taskdeck.Application/Services/SpeechTranscriptionSettings.cs), [policy](AUDIO_TRANSCRIPTION.md) | | Grounded questions | Up to three; categories next-step/outcome/dependency, at most one each; exact quote at most 400 characters; one-day freshness | [contract](../../backend/src/Taskdeck.Application/Services/WorkspaceObservationContract.cs), [policy](GROUNDED_OBSERVATIONS.md) | | Reminder allowance | At most two claims per UTC day, at least two hours apart; visible/focused board polling no more often than five minutes | [attention policy](WORKSPACE_ATTENTION.md) |