Evaluate a Tauri desktop app, gated on measured value over browser auto-open
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 初心者へのやさしさ
- 20/100
調査の方向性
Start with the D00 inputs and repository facts, then read the dependency graph and the D02, D03a, D04a, D04b, and D05 package steps. The initial five-day spike is limited to a Tauri prototype and core qualification cases; the broader plan includes design, security, cross-platform work, measurements, and release decisions. Done means the required package artifacts and evidence exist and their gates pass; each Stop clause names the decision owner.
索引モデルが issue の本文から書いたものです。
説明
Summary
Evaluate shipping CodeTrial as a desktop application, starting with a bounded
Tauri prototype on macOS. The browser deployment stays available throughout.
A desktop release ships only if a complete interview works reliably in the
system WebView and the desktop app shows measurable value over a simpler
alternative: the existing binary opening the browser automatically.
This is a proposal with an explicit stop at every stage, not a commitment to
ship. No prototype or benchmark has been run; every threshold below is a
proposed acceptance target.
Why Tauri first, and what is out of scope
- CodeTrial already ships as one Rust binary with embedded web assets, WASM,
and vendored dependencies. With no arguments it starts web mode and falls
back to setup when no config exists. It prints a URL; it does not open a
browser. Auto-open is therefore the baseline any desktop shell has to beat. - Tauri fits the Rust backend and can host the Axum service in-process. That
is design work (bootstrap, runtime, lifecycle), not an existing feature. - tinyjs would run the current binary as a sidecar, adding a JavaScript runtime
and child-process management. Tauri and tinyjs both use system WebViews, so
switching between them does not remove the main media-compatibility risk.
Revisit tinyjs only with measured gains (D13); no migration is planned. - Electron bundles Chromium, which reduces engine differences at the cost of a
much larger distribution and update burden. - Interviews still need LiveKit and Gemini; C, C++, and Java tests still use
Compiler Explorer. A desktop installer does not make interviews offline. - Initial desktop scope: managed startup, a dedicated window, optional
fullscreen, a report-ready notification, predictable shutdown. Not in scope:
a new frontend framework, interview protocol changes, replacing SQLite, a
framework-neutral plugin layer, or eye tracking (a separate, contract-gated
study in D12). - The desktop app still listens on loopback. Tauri uses WKWebView, WebView2,
and WebKitGTK; existing Chromium browser tests do not qualify any of them. - Fullscreen is presentation only. Native focus signals or gaze estimates must
not change scoring or imply misconduct (docs/observable-delivery-policy.md,
docs/integrity-evidence.md,docs/recording-contract.md). - Cloud cost: plan for 0% LiveKit or model savings at the same workload
(docs/provider-cost-and-degradation.md).
Release criteria
Ship only when the core qualification gates pass and at least one benefit is
measured: simpler unassisted use, a useful native integration, or a
performance gain against the auto-open baseline (at least 20% faster median
launch-to-lobby, p95 no more than 10% slower; memory and CPU no more than 10%
worse at equal workload). Ten failure-free qualification sessions are a
release checklist, not a reliability claim: they still allow about a 26%
per-session failure rate at one-sided 95% confidence.
Formulas, always on observed values:
- Time reduction:
(baseline s - desktop s) / baseline s. - Annual user time saved:
users * launches per year * seconds saved / 3600. - Memory reduction:
(baseline tree memory - desktop tree memory) / baseline tree memory, same accounting method and workload. - Economic return: annual time and support savings minus engineering,
signing, release, and maintenance cost, once labor rates are agreed.
Timing protocol: release builds of one revision on one machine, at least 30
cold and 30 warm launches per variant in random order, failures kept, OS and
WebView versions recorded. Browser resource cost is the incremental cost of
the interview tab and its processes, plus a dedicated-browser run.
How the tasks are written
Every work package has: Accountable (one person), Depends on, Inputs,
checkbox Steps (one verifiable action each), Done (numbers or named
artifacts), Evidence (where the sanitized record goes), and Stop (condition
and decider).
Conventions shared by all packages:
- Paths. Specifications go in proposed
docs/desktop/. Sanitized evidence goes
in proposeddocs/desktop/evidence/<package>/. Raw data containing device
identifiers, service usage, or participant information stays outside the
repository at a private location recorded in D00. Nothing public carries
credentials, session tokens, candidate content, or recordings
(CONTRIBUTING.md). - Evidence record. Each record starts with revision SHA, date, artifact
checksum, OS and WebView build, hardware, devices, accountable person, and
decider. Its body lists the steps run, the exact commands, expected versus
actual results, pass/fail/unsupported per case, and evidence links. Raw
measurements go in a sibling CSV. - Commands. Commands that exist today appear bare. Commands that a package
creates are marked# proposed:until they have run successfully. - Gate rule. A new script or self-test is either registered in
scripts/test.shas a named gate (Python suites use unittest through
unittest_gate tests/test_<name>.py, seescripts/test.sh:305-319) or is
declared out-of-gate with a reason. Any new crate states howfmt,clippy,
andcargo testreach it, because the gate only runs the root manifest
(scripts/test.sh:275-297) and the repository has no Cargo workspace. - Size rule. A package estimated at more than three engineering days, or
producing more than one kind of deliverable (spec, code, measurement, study),
is split. The packages below are already split on that basis. - Port. Desktop work and tests use
127.0.0.1:3101. Never port 3000.
Decision owners. Every Stop clause cites one of these roles:
| Role | Owns |
|---|---|
| Maintainer | Scope, budget, go/no-go, extensions, platform deferral, fallback |
| Security reviewer | Trust boundary, native bridge authorization, OAuth and secret policy |
| Test lead | Case definitions and pass/fail/unsupported rulings |
| Report owner | Any change that could lose or alter a saved report |
| Policy owner | Anything touching integrity evidence, recording, or candidate privacy |
Decision owners. Every Stop clause cites one of these roles:
| Role | Owns |
|---|---|
| Maintainer | Scope, budget, go/no-go, extensions, platform deferral, fallback |
| Security reviewer | Trust boundary, native bridge authorization, OAuth and secret policy |
| Test lead | Case definitions and pass/fail/unsupported rulings |
| Report owner | Any change that could lose or alter a saved report |
| Policy owner | Anything touching integrity evidence, recording, or candidate privacy |
Repository facts the tasks rely on
Checked at revision df69ac3:
run_web(src/main.rs:300) prints its readiness line atsrc/main.rs:363
andserve_setup(src/main.rs:512) atsrc/main.rs:532. Both print after
binding but beforeaxum::servestarts accepting, so a readiness line is
not proof that a page will load.primary_config_path(src/main.rs:785) searches./config/and./
before the executable directory.cold_start_config_path
(src/main.rs:1150) writes to./config/whenever
config/codetrial.env.exampleexists in the working directory.web_dir
defaults to a working-directory-relativeweb(src/config.rs:66), and
files on disk override the embedded assets one file at a time
(src/web/assets.rs). A Finder launch has an arbitrary working directory.web_error_log_path(src/main.rs:655) writescodetrial-error.loginto
exe_dir(). In a macOS bundle that directory is.app/Contents/MacOS.- The only Host check is
host_is_loopbackinsrc/web/setup.rs:76, and it
covers setup only. The main router validates neither Host nor Origin.
src/web/policy.rsbuilds CSP and security headers only. CSRF protection is
theSameSite=Laxsession cookie (src/web/auth.rs:548). random_token(bytes)insrc/accounts/sessions.rs:212is the existing
cryptographic token generator;ring0.17 is already a dependency.endInterview(reason)(web/interview.js:573) returns nothing and acts only
whenstate.phase === "live". Close handling therefore needs a completion
signal it does not have today.web/before-unload.jsis tested in
tests/browser/interview-lifecycle.test.js;web/report-recovery.jsin
tests/browser/report-recovery.test.js;web/history.jsin
tests/browser/history.test.js.- Unit tests attach with
#[path = "../tests/unit/<name>.rs"](for example
src/main.rs:1162,src/lib.rs:120). - rusqlite is built without its
backupfeature (Cargo.toml:37). - CI builds release binaries in the
buildmatrix
(.github/workflows/check.yml:612,macos-15andwindows-2025) and
publishes in thereleasejob (.github/workflows/check.yml:928). docs/integrity-evidence.md:129refuses gaze-direction inference. Any gaze
work is a contract question before it is an engineering question.
Plan
Dependency graph:
D00 -> D01 -> D02 -> D03a -> D04a -> D04b -> D05 (core C1-C7)
D04b -> D04c -> D05 (remaining cases)
D03a -> D03b (only if D00 requires import) -> D10b
D00 (scope) + D04b + D05 -> D06a / D06b / D06c (each only if required)
D03a + D05 -> D07
D04b + D05 + D07 -> D08
D01 + D05 + D07 + D08 -> D09a -> D09b
D00 (recruitment approval) + D09a -> D09c
D00 -> D10-prep (signing membership and credentials, in parallel)
D04c + D05..D09 + D10-prep -> D10a -> D10b -> D10c -> D11-win, D11-linux
D10c -> optional D12 (gaze, contract decision first) / optional D13 (tinyjs)
Five-day spike allocation (engineering days, not calendar days): D02 one day;
D03a plus D04a two days; D04b one day; D05 core cases C1-C7 one day. D03b,
D04c, the remaining D05 cases, and everything after are outside the box.
Work packages
D00 - Freeze scope, credentials, and the test matrix
- Accountable: maintainer. Depends on: none.
- Inputs:
README.md,docs/install.md,docs/interview-length.md,
docs/observable-delivery-policy.md,docs/integrity-evidence.md,
docs/recording-contract.md,docs/provider-cost-and-degradation.md. - Steps:
- Create proposed
docs/desktop/scope.md. Recordgit rev-parse HEAD, the
exact Tauri crate version (tauri = "=2.x.y"), the application
identifier,sw_versoutput,system_profiler SPHardwareDataType
summary, and the microphone, camera, and output device models. - Assign one person to each role in the decision-owner table.
- Mark each feature required, optional, or deferred, with a case ID and an
expected result: solo interview, preflight, Pyodide, JavaScript runner,
Compiler Explorer languages, face presence, avatar, whiteboard, replay,
export/download, GitHub OAuth, recording, Meet presentation, fullscreen,
report-ready notification. Default: solo, non-recorded, no OAuth. - Name the holder of each credential without its value: LiveKit URL, key,
and secret; Gemini key; GitHub OAuth client (only if OAuth is required);
recording service account (only if recording is required). - Decide Apple Developer Program membership: buy, defer, or no. Without it,
D10 ends at an ad-hoc local build and the release decision is no-go. - Size the live-service budget from planned session counts (D05 core, D09b
active runs, ten default-length sessions per configuration in D10c and
D11) and get a written USD ceiling from the maintainer. - Approve or reject the D09c usability study: participant count, consent
text, and compensation. Rejection removes D09c; D10 then relies on D09b
or a native-integration benefit. - Cap the number of declared device/OS configurations per platform.
- Record the private location for raw evidence.
- Create proposed
- Done:
docs/desktop/scope.mdhas no empty cell, no secret value, and a
maintainer sign-off line. - Evidence:
docs/desktop/scope.md. - Stop: missing credentials block only their live cases. The maintainer
resolves them within five working days or marks those cases deferred.
Required OAuth or recording makes the matching D06 package mandatory.
D01 - Establish an honest browser baseline
- Accountable: Rust developer. Depends on: D00.
- Inputs: Python 3, Cargo, one named browser, disposable config, database, and
browser-profile directories outside the repository. - Steps:
- Read
run_web,serve_setup,bind_web_listener(src/main.rs:242),
andis_cold_startinsrc/main.rs. Indocs/desktop/baseline.md,
record the two readiness lines, what runs between each line and
axum::serve, and the failure path (non-zero exit, stderr,
codetrial-error.log). - Run
cargo build --release --bin codetrial. - Create proposed
scripts/desktop_auto_open.py. It starts
target/release/codetrial webbound to127.0.0.1:3101as an owned child,
reads one readiness line with a timeout, then polls that URL until the
owned child answers HTTP, then opens exactly one tab in the dedicated
profile. On child exit or timeout it opens nothing. On browser launch
failure it prints the URL. On its own exit it terminates the child.
The setup-to-lobby handover reuses the same tab. - Create proposed
tests/test_desktop_auto_open.py(unittest) covering:
configured line, setup line, setup line followed by configured line
(one open), line printed but HTTP never answers (no open), exit before
readiness (no open), browser launch failure (URL printed). - Register it in
scripts/test.sh:
gate desktop-auto-open-tests unittest_gate "$ROOT/tests/test_desktop_auto_open.py". - Run
./scripts/test.sh. - Take three smoke timings per workflow (manual URL, auto-open) using the
metrics in Release criteria. The full trial is D09b.
- Read
- Done: step 6 passes; manual runs of configured, fresh-setup, bind
conflict, and invalid-config launches produce the expected tab counts
(1, 1, 0, 0). - Evidence:
docs/desktop/baseline.md,docs/desktop/evidence/D01/. - Stop: the maintainer reviews the smoke results. If auto-open meets the user
need and D00 lists no required native integration, the maintainer can
promote auto-open into the product as a separate change and stop here.
D02 - Specify desktop bootstrap, origin, and trust boundary
- Accountable: Rust developer, reviewed by the security reviewer.
Depends on: D01. Spike day 1. - Inputs: D01 trace.
- Steps:
- Read
run_web,serve_setup,web_server_config,initialize_accounts
(src/main.rs:907),published_secret_refusal, and dispatcher
construction insrc/main.rs; readsrc/dispatch.rs,src/web/mod.rs,
src/web/setup.rs,src/web/auth.rs, andsrc/web/policy.rs. - Create proposed
docs/desktop/bootstrap.mdwith:- a. A Rust interface for proposed
src/launch.rs: an explicit paths value
(config file, database, error log, optionalweb_dir), a start
function returning a running handle (bound address, async
shutdown()) plus a readiness event emitted afteraxum::servehas
started, and a typed start error. - b. The list of
src/main.rshelpers that move to the library and those
that stay CLI-only. - c. A state diagram: Idle, SetupServing, Configuring, Ready, Failed,
ShuttingDown, Stopped, with the setup-to-lobby handover on one
listener. - d. The runtime model: one Tokio runtime owned off the Tauri main thread;
noblock_onfrom the UI thread; no nested runtimes.
- a. A Rust interface for proposed
- Record one decision: in-process service or owned sidecar, with the files
each choice changes. Default: in-process. - Record the origin decision:
http://127.0.0.1:3101, single-instance lock
acquired before bind, second launch focuses the owner, a port conflict
fails visibly, never load a page from a port this process does not own.
Runlsof -iTCP:3101 -sTCP:LISTENon the target machines and record it. - Specify the desktop session secret:
random_token(32)from
src/accounts/sessions.rs, created exclusively, mode 0600, reused across
launches, fatal on unreadable or malformed content. - Write a route-by-route expected-status table for wrong Host, foreign
Origin, missing session, forged session, authorized setup, username login,
and account report access, covering setup and main service. Each row
names its D04c test. - Specify the cookie and CSP policy for desktop mode explicitly; do not
derive it by settingNODE_ENV=production.
- Read
- Done: the Rust developer and security reviewer sign
bootstrap.md. - Evidence:
docs/desktop/bootstrap.md. - Stop: if in-process reuse would change more than about 300 lines of
src/main.rsor any behavior covered bycargo test --test cli, the
maintainer chooses the sidecar design instead. No second configuration
pipeline.
D03a - Make bootstrap paths explicit
- Accountable: Rust developer. Depends on: D02. Spike day 2, shared with D04a.
- Inputs:
bootstrap.mdinterface. - Steps:
- Add the explicit paths value from D02 to the shared bootstrap. In desktop
mode, config, database (theCODETRIAL_DB_PATHequivalent), error log,
andweb_dircome only from that value. Desktop never calls
primary_config_path's working-directory search,
cold_start_config_path, orexe_dir(). - Keep CLI path semantics unchanged.
- Add proposed
tests/unit/launch.rs, attached fromsrc/launch.rswith
#[path]. Tests: with the working directory set to a temporary directory
holdingconfig/codetrial.env.local,config/codetrial.env.example, and
web/index.html, a desktop-mode start reads none of them; a failed
desktop start writes nothing beside the executable. - Run
cargo test --lib,cargo test --bin codetrial,
cargo test --test cli.
- Add the explicit paths value from D02 to the shared bootstrap. In desktop
- Done: step 4 passes; existing CLI tests are unchanged.
- Evidence:
docs/desktop/evidence/D03a/. - Stop: a CLI behavior change goes to the maintainer before merging.
D03b - Optional legacy import (only if D00 requires it)
- Accountable: Rust developer, reviewed by the report owner.
Depends on: D03a. Not part of the spike. - Steps:
- Choose the copy mechanism and record it: stopped-source file copy, or
VACUUM INTOfrom a read connection, or enabling rusqlite'sbackup
feature. Default:VACUUM INTO, which needs no new feature. - Import only from a source the user selects; never scan directories.
Copying a config file containing credentials needs a separate consent. - Show, before copying, that browser localStorage and anonymous-account
identity do not transfer. - Stage into an empty destination. Refuse to overwrite. Require
PRAGMA integrity_checkto returnokand source and staged row counts
to match for the account and report tables. Activate by rename. On
failure, leave source and destination unchanged and delete staging. - Test: overwrite refusal, corrupt source, uncheckpointed WAL data, denied
access, interrupted staging followed by retry. - Run
cargo test --libandcargo test --test web.
- Choose the copy mechanism and record it: stopped-source file copy, or
- Done: every step 5 case has a tested outcome; no original data is deleted.
- Evidence:
docs/desktop/evidence/D03b/. - Stop: the report owner blocks any path that can lose rows.
D04a - Extract the shared bootstrap
- Accountable: Rust developer. Depends on: D03a. Spike day 2.
- Steps:
- Create proposed
src/launch.rs, export it fromsrc/lib.rs, and move the
helpers listed inbootstrap.mdinto it.src/main.rscalls it; CLI
flags, setup handover, validation, and provider/account ordering stay the
same. - Emit the readiness event after
axum::servehas started, and implement
shutdown()with axum's graceful shutdown. - Run
cargo fmt --check,
cargo clippy --locked --all-targets -- -D warnings,
cargo test --lib,cargo test --bin codetrial,
cargo test --test cli,cargo test --test web, then./scripts/test.sh.
- Create proposed
- Done: step 3 passes; new tests in
tests/unit/launch.rscover readiness
after serve, start failure, and shutdown completing. - Evidence:
docs/desktop/evidence/D04a/. - Stop: see D02's stop clause.
D04b - Minimal Tauri shell
- Accountable: desktop developer. Depends on: D04a. Spike day 3.
- Steps:
- Record the crate placement in proposed
docs/desktop/development.md.
Default: a standalonesrc-tauri/crate with its ownCargo.lock, kept
out of the root lockfile and the Bullseye build, plus a macOS-only gate
line inscripts/test.sh:
gate desktop-check cargo check --locked --manifest-path "$ROOT/src-tauri/Cargo.toml".
Alternative: a workspace member. The maintainer decides. - Create
src-tauri/Cargo.toml,src-tauri/build.rs,
src-tauri/src/main.rs,src-tauri/tauri.conf.json,
src-tauri/Info.plist, andsrc-tauri/Entitlements.plistwith the
pinned version and the D00 identifier. - The window loads
http://127.0.0.1:3101/as a remote URL served by the
embedded Axum assets.frontendDistis unset or points only to a static
starting page. Do not bundleweb/a second time. - Resolve config, data, cache, and log directories with Tauri's path API and
pass them to the D03a paths value. Record the resolved macOS paths. - Set
NSCameraUsageDescriptionandNSMicrophoneUsageDescription; set
thecom.apple.security.device.cameraand
com.apple.security.device.audio-inputentitlements needed under the
hardened runtime. - First check, before anything else: confirm
getUserMediaworks in
WKWebView onhttp://127.0.0.1:3101. If not, stop and escalate, because
it invalidates the origin decision. - Start the service on the owned runtime; show the window only after the
readiness event; keep the native UI responsive during startup. - Add the single-instance plugin, acquired before bind.
- Write the exact install, build, and launch commands into
development.mdand run them from a clean checkout.
- Record the crate placement in proposed
- Done: 20 of 20 launches reach the lobby with a readiness event within 10
seconds; afterwardspgrep -f codetrialshows no orphan; a second launch
focuses the first; a port conflict, invalid config, and service failure each
show an error and load nothing. - Evidence:
docs/desktop/development.md,docs/desktop/evidence/D04b/. - Stop: a startup deadlock that persists through the spike, or step 6
failing, goes to the maintainer: sidecar fallback, extension, or stop.
D04c - Security implementation and adversarial tests
- Accountable: desktop developer, reviewed by the security reviewer.
Depends on: D04b. Must pass before any build leaves the developer's machine. - Steps:
- Implement the D02 secret file and the Host allowlist for setup and main
service in desktop mode. - Write explicit capability files granting only the required operations to
the named window and the exactremote.urlsloopback origin. Configure
application-command permissions separately from plugin permissions.
Initially grant no optional IPC. - Reject navigation and frames to other origins; if the service fails,
take the window away instead of reconnecting to a new port occupant. - Implement every row of the D02 status table as a test in
tests/web.rsortests/unit/launch.rs. - From an untrusted page and an untrusted frame, call each prohibited
bridge command and record that it is rejected. A missing frontend global
is not proof of denial. - Check that no secret appears in URLs, logs, or frontend storage.
- Run
./scripts/test.sh.
- Implement the D02 secret file and the Host allowlist for setup and main
- Done: every D02 row passes; step 5 records a rejection for each command.
- Evidence:
docs/desktop/evidence/D04c/. - Stop: the security reviewer blocks any bridge exposure. Release is blocked
until resolved.
D05 - Qualify core features in packaged WKWebView
- Accountable: test lead. Depends on: D04b (core), D04c (remaining cases),
D00 credentials and budget. Core cases are spike day 4-5. - Inputs: packaged app from the
development.mdprocedure, its checksum. - Steps:
- Record the environment in
docs/desktop/evidence/D05/environment.md. - Create
docs/desktop/evidence/D05/cases.csvwith columns case ID,
action, expected, actual, result (pass/fail/unsupported), duration,
diagnostic link. One row per D00 case. - Core cases, in order:
- C1 microphone and camera prompts appear; grant succeeds.
- C2 preflight completes (mic meter moves; face check runs or reports
unavailable). - C3 interviewer audio is heard; candidate speech is transcribed.
- C4 speaking over the interviewer interrupts it.
- C5 a Python test run through Pyodide passes.
- C6 ending the interview renders the report and its save is confirmed.
- C7 quit and relaunch; the report is listed in history.
- Remaining cases: JavaScript runner, Compiler Explorer languages if
enabled, face Worker/WASM, avatar render and cache, whiteboard input,
export/download, replay (only with an authorized fixture), denied
microphone, denied camera, unplug and replug, output selection or its
fallback, 30-second network drop, five minutes backgrounded, sleep/wake. - After any compatibility fix, run
node --test tests/browser/runners.test.js tests/browser/face-presence.test.js tests/browser/avatar-model.test.js tests/browser/history.test.js tests/browser/report-recovery.test.js
and add a regression test for the fix.
- Record the environment in
- Done: C1-C7 pass in the packaged app; every other case has a result, and
unsupported ones show defined UI behavior. Chromium and Node runs do not
certify WKWebView. - Evidence:
docs/desktop/evidence/D05/. - Stop: at the end of spike day 5, the maintainer records stop, an explicit
extension in days, or browser fallback. No optional integration starts
while C1-C7 fail.
D06a - OAuth (only if D00 requires it)
- Accountable: authentication developer, reviewed by the security reviewer.
Depends on: D04c, D05. - Steps:
- Read
login_handler,callback_handler, and the cookie helpers in
src/web/auth.rs,src/accounts/sessions.rs, and the login UI in
web/app.js. - In proposed
docs/desktop/support.md, record GitHub's current redirect
URI rules and embedded user-agent policy, with URLs and retrieval date,
and the chosen session handoff (for example system browser plus loopback
callback on port 3101). Keep any client secret out of the installer. - Implement after the security reviewer approves step 2.
- Test with a disposable OAuth app: cancellation, wrong state, replayed
callback, cold and warm launch, session established in the WebView.
- Read
- Done: step 4 passes. Evidence:
docs/desktop/evidence/D06a/. - Stop: unsupported redirect rules, embedded-login restrictions, or secret
distribution block account-enabled desktop release; the maintainer decides.
D06b - Recording (only if D00 requires it)
- Accountable: test lead with the policy owner. Depends on: D06a.
- Steps:
- Read
docs/recording-contract.md,src/web/recordings/mod.rs, and
scripts/recording-integration.sh; list the acceptance phases and their
credential prerequisites insupport.md. - Run those phases from the packaged app. Do not weaken the verified
identity requirement.
- Read
- Done: every listed phase passes. Evidence:
docs/desktop/evidence/D06b/. - Stop: the policy owner blocks any contract deviation.
D06c - Meet presentation (only if D00 requires it)
- Accountable: test lead. Depends on: D05.
- Steps:
- Run
docs/meet-tab-audio-manual-check.md, adapted to window or system
audio capture, with two participants, two endpoints, and headphones. - Record whether interviewer audio and candidate speech both reach the
remote participant, whether either is duplicated, whether echo is
audible over two minutes, and what is captured (window or whole system).
- Run
- Done: results recorded in that document's results format.
- Stop: if it fails, desktop shows that Meet presentation needs the browser,
with the browser route, before an unsupported flow starts.
For any deferred D06 feature, change web/app.js or web/interview.js to show
the limitation and the tested browser route, and test that UI.
D07 - Preserve report semantics through close and recovery
- Accountable: desktop developer, reviewed by the report owner.
Depends on: D03a, D05. - Steps:
- Read
endInterview,receiveReport,saveHistory, and
renderReportSaveStatusinweb/interview.js;web/before-unload.js;
web/report-recovery.js;saveReportHistoryandreportIsPersistedin
web/history.js. - Create proposed
docs/desktop/close-state-machine.mdmapping the actual
state.phasevalues and the paused, receiving, and save-result flags to
the close actions: close now, cancel, end and wait, export, or discard
explicitly. - Add the smallest completion signal the native close needs (for example
endInterviewreturning a promise that settles on the existing save
result), reusing the existing report deadlines and recovery UI. No second
report generator. - In the desktop host, intercept close and Quit, keep them idempotent
(repeated events share one pending operation), and await asynchronously
without blocking the native event loop. - Add browser tests covering idle, preflight, live, paused, ending, report
recovery, save failed, saved, and repeated close; extend
tests/browser/interview-lifecycle.test.jsand
tests/browser/report-recovery.test.js. - Run
node --test tests/browser/interview-lifecycle.test.js tests/browser/report-recovery.test.js tests/browser/history.test.js. - Packaged runs: each phase from step 5 crossed with close and Quit, plus
three rapid double-closes and three closes during a failed save (at least
20 runs). Then three forced kills during live and during ending.
- Read
- Done: no acknowledged save is lost; the camera indicator is off within five
seconds;pgrep -f codetrialshows no owned process after exit; forced
kills reopen with committed data intact. - Evidence:
close-state-machine.md,docs/desktop/evidence/D07/. - Stop: the report owner blocks save loss. Do not persist live session
snapshots or frozen prompts for crash recovery; a forced kill does not
promise an ungenerated report.
D08 - Add only the integrations D00 selected
- Accountable: frontend developer. Depends on: D04b, D05, D07.
- Steps:
- Create proposed
web/desktop.js: fullscreen and report-ready
notification, each a no-op whenwindow.__TAURI__is absent, with no
import that needs a frontend build step. - Load it from
web/interview.htmland call it fromweb/interview.js.
Updatetests/browser/dom-contract.test.jsif the DOM contract changes. - Add only the needed plugin permissions to the D04c capability files.
- Trigger the notification once per report, when
reportIsPersisted
reports a confirmed save. The body is generic, with no report content.
Clicking it focuses the interview window. Ask permission in context. - Add proposed
tests/browser/desktop.test.js: absent globals, denied
permission, duplicate save callbacks. Runnode --teston it. - Packaged runs: 20 fullscreen cycles during a live interview, and 20
notifications with permission granted and Do Not Disturb off. Record
denial and Do Not Disturb separately.
- Create proposed
- Done: fullscreen keeps media and phase in 20 of 20 runs; 20 of 20
notifications arrive within five seconds of the confirmed save. - Evidence:
docs/desktop/evidence/D08/. - Stop: an integration needing broad system permission or touching scoring
goes back to the maintainer before implementation.
D09a - Benchmark instrumentation
- Accountable: performance tester. Depends on: D01, D05, D07, D08.
- Steps:
- Create proposed
scripts/desktop_benchmark.pyfor three variants: V1
manual URL, V2 auto-open (D01), V3 Tauri app (D04b). It records monotonic
timestamps for launch, service ready, interactive lobby, preflight done,
and interviewer connected, on one clock. - Resource sampling: attributable process tree once per second, using the
platform's memory accounting, with shared-memory limits documented. - Create proposed
tests/test_desktop_benchmark.py(unittest) on fixed
fixtures: timestamp ordering, failed trials kept, nearest-rank
percentiles, bootstrap 95% confidence interval (10,000 resamples), and the
formulas in Release criteria. Register it as a gate.
- Create proposed
- Done:
./scripts/test.shpasses with the new gate. - Evidence:
docs/desktop/evidence/D09a/.
D09b - Performance and resource trials
- Accountable: performance tester. Depends on: D09a.
- Steps:
- In random order, 30 process-cold and 30 warm launches per variant. Run
any cache-cold study separately. - Three repetitions of five idle and ten active minutes per variant on a
fixed interview workload. - Store
launches.csv,resources.csv,environment.json; produce
analysis.mdwith proposed
python3 scripts/desktop_benchmark.py --recompute docs/desktop/evidence/D09b.
- In random order, 30 process-cold and 30 warm launches per variant. Run
- Done: every number in
analysis.mdreproduces from the raw CSV; timeouts
stay as failed trials. - Stop: if a confidence interval crosses a target, the maintainer approves a
bounded extra run count or the result is labeled inconclusive.
D09c - Usability study (only if D00 approved it)
- Accountable: usability tester. Depends on: D09a, D00 approval.
- Steps:
- At least 20 new users per workflow, assigned before testing, with equal
service access. - Success is reaching the interactive lobby unassisted. Record setup time,
permission time, failures, and assistance separately.
- At least 20 new users per workflow, assigned before testing, with equal
- Done: counts, medians, and confidence intervals reported; 19/20 is a sample
outcome, not a population rate. - Evidence: aggregates in
docs/desktop/evidence/D09c/; participant data in
the private location.
D09 decision: the maintainer records which benefit qualifies (D09b speed or
resources, D09c usability, or a D08 integration with a stated use). If none
does, recommend auto-open and stop release investment.
D10-prep - Signing access (parallel, after D00)
- Accountable: release engineer. Steps: complete Apple Developer Program
enrollment, issue a Developer ID Application certificate to a named holder,
create a notarytool keychain profile, and store CI secrets with a named
owner. Done: a test binary signs and notarizes. Stop: without membership,
D10 ends at an ad-hoc local build.
D10a - CI and versioning
- Accountable: release engineer. Depends on: D04c, D05-D09, D10-prep.
- Steps:
- Read the
buildmatrix andreleasejob in
.github/workflows/check.ymlanddocs/install.md. - Add a macOS desktop job to the build matrix without changing the CLI
artifacts or the rollinglatestrelease. - Publish desktop artifacts under their own immutable tags (for example
desktop-v0.1.0) with monotonic versions.
- Read the
- Done: CI produces the desktop artifact on a tag push; CLI releases are
unchanged.
D10b - Sign, notarize, and install
- Accountable: release engineer. Depends on: D10a.
- Steps:
- Write proposed
docs/desktop/release.mdwith tested build, sign,
notarize, staple, install, uninstall, and previous-version recovery
commands, including
# proposed: xcrun notarytool submit "$DESKTOP_ZIP" --keychain-profile "$PROFILE" --wait. - On the artifact, run
codesign --verify --deep --strict --verbose=2 "$DESKTOP_APP",
spctl --assess --type execute --verbose=2 "$DESKTOP_APP", and
xcrun stapler validate "$DESKTOP_APP", recording the real paths. - Download it with quarantine intact onto a clean macOS account; run fresh
setup, permissions, data paths, history, D03b import if in scope, and
CLI coexistence.
- Write proposed
- Done: all three checks pass;
spctlreports accepted; step 3 passes. - Evidence:
release.md,docs/desktop/evidence/D10b/, checksum.
D10c - Media qualification and release decision
- Accountable: test lead, then the maintainer. Depends on: D10b.
- Steps:
- Ten sessions of the configured default length (45 minutes today,
docs/interview-length.md) through report delivery, per declared
configuration, within the D00 budget. - Record disconnects, report persistence, device release, and service
spending per session. - Run
./scripts/test.shand disclose skipped lanes.
- Ten sessions of the configured default length (45 minutes today,
- Done: zero app-caused disconnects, missing reports, or device leaks;
a go/no-go record that cites the D09 benefit. - Evidence:
docs/desktop/evidence/D10c/. - Stop: unresolved save loss, bridge exposure, or a required unsupported
feature is a no-go. Auto-update is a separate future package; v1 ships
manual signed installers.
D11-win and D11-linux - Separate platform qualification
- Accountable: one platform developer per OS. Depends on: D10c.
- Steps (per OS):
- Create proposed
docs/desktop/windows.mdordocs/desktop/linux.md
naming OS and runtime versions (WebView2 bundled or bootstrapped; distro
and WebKitGTK version), architectures, devices, build host, installer
format, and signing choice. Unsigned Windows behavior is stated; a
certificate does not promise no SmartScreen prompt. - List the applicable D03a-D10c case IDs and justified exclusions.
- Split the work into one-to-three-day packages: paths and build, startup
and security, media and lifecycle, installer and recovery. - Run the build and install commands and record them.
- Run D05 C1-C7 and the remaining cases, D07, D08, D10b equivalents, ten
default-length sessions per declared configuration, and D09b.
- Create proposed
- Done: each platform has its own artifacts, commands, and support matrix.
macOS results do not count. - Stop: missing core media support blocks that platform only; the maintainer
defers it and the browser route remains.
D12 - Optional gaze feasibility study
- Accountable: policy owner first, then an ML engineer. Depends on: D10c and
a separately approved budget. - Steps:
- The policy owner records whether the proposed use is permitted under
docs/integrity-evidence.md(which refuses gaze-direction inference at
line 129) anddocs/observable-delivery-policy.md. If it is not, stop
here unless a contract revision is approved first. - Create proposed
docs/desktop/gaze-study.md: one output (head direction,
gaze direction, or screen coordinates), maximum error, minimum coverage,
tolerated false alerts per hour, cohort size, consent and withdrawal,
reference measurement, calibration, and retention. - Write the evaluation commands before collecting data.
- Compare web and native at the same sampling rate and accuracy; report
LiveKit published-track frame rate with and without the gaze pipeline
(five-minute runs, three repeats), latency, CPU, and energy.
- The policy owner records whether the proposed use is permitted under
- Done: every limit in step 2 has a pass/fail result; missing calibration or
samples stay neutral. - Evidence: aggregates in
docs/desktop/evidence/D12/. - Stop: the policy owner blocks prohibited inference; feasibility implies no
scoring or integrity integration.
D13 - Optional tinyjs reassessment
- Accountable: desktop maintainer. Depends on: D10c, D09b raw data, a
separately approved budget, and one numeric improvement hypothesis. - Steps:
- Create proposed
docs/desktop/tinyjs-reassessment.md: pinned tinyjs
version, platform support and security/update sources, chosen threshold,
a 24-month comparison horizon, and engineering-hour rates. - Package the same revision as an owned sidecar, keeping the D02 and D03a
origin, secret, and path rules; test shutdown and child ownership. - Run D05 C1-C7, D07, and D09b on equivalent hardware.
- Estimate one-time migration and recurring maintenance hours.
- Create proposed
- Done: a screening threshold (20% better startup or memory, or 30% smaller installed size, with no reliability regression) is met with
uncertainty, required cases pass, and savings exceed cost over 24 months. - Stop: no threshold-sized gain means keep Tauri and close the reassessment.
Existing checks
Runnable today:
cargo fmt --check
cargo clippy --locked --all-targets -- -D warnings
cargo test --lib
cargo test --bin codetrial
cargo test --test cli
cargo test --test web
node --test tests/browser/interview-lifecycle.test.js \
tests/browser/history.test.js tests/browser/report-recovery.test.js
./scripts/test.sh
Read scripts/server-check.sh and scripts/browser-check.sh before running
live checks: browser flow and agent modes need different credentials. Those
scripts qualify the browser and server; D05's packaged checks stay separate.
Read scripts/server-check.sh and scripts/browser-check.sh before live
checks; they qualify the browser and server, not the packaged WebView.
Proposed tooling (scripts/desktop_auto_open.py, scripts/desktop_benchmark.py,
src/launch.rs, src-tauri/, web/desktop.js) does not exist until its
package lands.
- 主要言語
- Rust
- スター
- 160
- フォーク
- 64
- 平均マージ
- 1日 9時間
- マージ済み PR(30日)
- 111
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
sysprog21/codetrial のほかの issue
-
Highlight the active line in the code editor対応中かも @ArthurArthurArthur0817 が 6 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
sysprog21/codetrial#247 · コメント 3 件 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
難易度 3/5 1〜2日 初心者へのやさしさ 62/100
sysprog21/codetrial#301 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
Standardize section header and toggle indicator styles for test panel対応中かも @kumi222 が今日担当しました。 オープン
sysprog21/codetrial#298 · コメント 2 件 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
Allow interview page to scroll vertically and horizontally when zoomed in対応中かも @Alan52254 が今日担当しました。 オープン
sysprog21/codetrial#296 · コメント 1 件 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
Allow candidates to toggle avatar visibility back on (Show/Hide Avatar)対応中かも @lakekenny が今日担当しました。 オープン
難易度 3/5 1〜2日 初心者へのやさしさ 45/100
sysprog21/codetrial#291 · コメント 3 件 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
sysprog21/codetrial の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
extendr/extendr.github.io#134 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
メンテナーはふだん 1 日以内に返信
-
enhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
bgreenwell/xleak#90 · リアクション 1 件 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
cloudflare/boring#530 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
project-robius/robrix#1154 ·
メンテナーはふだん 1 日以内に返信