Deep Work is a personal Windows 11 focus app. During a session it can block
configured websites through the Windows hosts file, abruptly terminate named
distraction apps, capture the monitors enumerated by mss plus camera index 0 when readable,
ask OpenAI vision models whether the visible work matches the stated task, and
speak feedback. A loopback-only Flask dashboard controls the session and shows
the current policy, timers, scheduler health, and accepted verdict history.
Screenshot from an isolated browser verification fixture with injected collaborators and synthetic session data; it is not evidence of live enforcement.
Caution
This project handles highly sensitive screen, webcam, task, and model-output
data. It also edits the hosts file and kills matching processes in its real
mode. Read Data, privacy, and cost and begin with
--dry-hosts. This is an enforcement aid, not a security boundary, and AI
verdicts are not ground truth.
The operating loop is:
- Define intent: enter one concrete work topic and explicitly allow only the website/app groups required for it.
- Enforce policy: reconcile the desired website policy into one fenced hosts-file section and repeatedly kill unallowed configured app processes.
- Observe: after the scheduler's fixed wait, capture each monitor enumerated by mss
plus one frame from camera index
0when that read succeeds; resize, label, vertically stitch, and save the new composite as a JPEG. - Evaluate evidence: append that JPEG to the same-context rolling window,
then send the available one-to-
PROGRESS_WINDOW_CAPTURESimages to OpenAI oldest first. Capture one judges current alignment; capture two onward can compare visible task-relevant change over time. - Respond and audit: if the monitoring context still matches, record the verdict in live state, then attempt its ordered session event and one spoken response. A persistence or feedback failure can leave the accepted verdict visible without a durable event or utterance. The latest verdict can be corrected without erasing the original model label.
- Change context deliberately: task access, temporary goal access, breaks, session replacement, and agentic mode update enforcement and invalidate incompatible rolling comparison context.
The app does not train or fine-tune a model. Its methodology is runtime observation plus prompted inference over a short rolling image history. The main evidence is the visible task state; timestamps, cursor motion, video frames, or posture changes alone are not treated as progress. The full evaluation contract and its static-work cases are in the user guide.
flowchart LR
User["User in browser"] --> UI["Flask dashboard<br/>127.0.0.1:UI_PORT"]
subgraph PC["Windows PC"]
Main["main.py<br/>startup and wiring"]
State["Locked session state"]
Scheduler["Three fixed-delay loops"]
Enforcer["Hosts reconciler<br/>and exact-name app killer"]
Productive["Productivity monitor"]
Agent["Agent watcher"]
Capture["Shared capture path<br/>mss + camera 0 + Pillow"]
Verdict["Accepted productivity verdict<br/>timeline + latest correction"]
AgentState["Busy/idle transition"]
Feedback["Durability-gated text feedback<br/>and FIFO speech"]
Local["logs/ and results/<br/>captures · LLM JSON · session JSONL · state"]
end
Main --> UI
Main --> Scheduler
UI --> State
State --> Enforcer
State --> Local
Scheduler --> Enforcer
Scheduler --> Productive
Scheduler --> Agent
Productive --> Capture
Agent --> Capture
Productive -->|"save after post-capture context check"| Local
Agent -->|"save current JPEG"| Local
Productive -->|"1–N chronological JPEGs + task context"| PVision["OpenAI Responses API<br/>original-detail productivity vision"]
Agent -->|"one low-detail JPEG"| AVision["OpenAI Responses API<br/>agent activity"]
PVision -->|"usable verdict + matching context"| Verdict
PVision -->|"returned response, including refusal"| Local
AVision -->|"usable verdict"| AgentState
AVision -->|"returned response, including refusal"| Local
Verdict --> State
AgentState --> State
Verdict --> Local
AgentState --> Local
Verdict --> Feedback
AgentState --> Feedback
Feedback -->|"optional context prompt"| Text["OpenAI Responses API<br/>message generation"]
Text --> Local
Text --> Feedback
Feedback -->|"configured online voice"| Speech["OpenAI Speech API"]
Feedback -->|"offline alternative"| SAPI["pyttsx3 / Windows SAPI"]
All application modules are under deepwork/; main.py remains the
phase-oriented composition wrapper. See Architecture
for module ownership, threads, locks, and transition details.
- Windows 11. Hosts editing, UAC relaunch, DirectShow camera capture, process policy, and audio playback are Windows-specific.
- Git for Windows.
- uv on
PATH. The checked-in.python-versionselects Python 3.13; uv can install that interpreter and creates the repository-local.venv. - Internet access and an OpenAI API key with access and API billing for the configured models. ChatGPT subscriptions and API billing are managed separately.
- Administrator approval only for real hosts-file enforcement.
- A webcam is optional: an unsuccessful read omits its panel. Audio is optional for enforcement, although speech failures are logged.
If Git or uv is missing, install them in PowerShell and open a new terminal:
winget install --id Git.Git -e --source winget
winget install --id astral-sh.uv -e --source winget
git --version
uv --versionRun these commands from the directory in which you want the checkout:
git clone https://github.com/BurnyCoder/deep-work-jarvis-waifu-supervisor.git deep-work
Set-Location deep-work
uv sync --locked
Copy-Item .env.example .env
notepad .envReplace sk-your-key-here in .env with the API key, and never commit or
paste the key into logs. python-dotenv accepts quoted and unquoted values; see
its file-format documentation.
For offline speech playback, also change TTS_ENGINE=pyttsx3; vision and text
generation still use OpenAI.
uv sync --locked verifies the checked-in lockfile and installs its exact
resolution into ./.venv. Run from the repository root because
projects.json, logs/, and results/ are current-directory-relative.
Existing process environment variables override matching .env values.
Check the local setup without using admin rights, capture hardware, or OpenAI:
uv lock --check
uv run python main.py --help
uv run pytestChoose a command with its side effects in mind:
| Command | What it runs | Important side effects |
|---|---|---|
uv run python main.py --dry-hosts --open-browser |
Dashboard and all scheduler loops; opens one browser tab after readiness | No UAC or hosts writes, but after Start it can kill apps, capture/upload images, call APIs, write artifacts, and speak |
uv run python main.py --dry-hosts |
Same dry-hosts application; open the logged URL yourself | Same non-host side effects as above |
uv run python main.py --smoke |
One direct smoke test capture → productivity analysis → possible speech attempt |
Uses real capture/OpenAI/audio and writes artifacts; no HTTP server, scheduler threads, hosts writes, app killing, agent watch, start event, or good-luck message |
uv run python main.py |
Full dashboard and enforcement | Requests UAC; after Start, writes the hosts file, kills configured apps, captures/uploads, calls APIs, stores, and speaks |
Start Deep Work.bat |
Self-elevating launcher for the full command with --open-browser |
Same effects as the full run; enforcement and monitoring side effects begin after Start |
--open-browser is opt-in for terminal runs. Otherwise, open the
control panel listening: URL printed in the terminal. The dashboard is
served by Werkzeug only on 127.0.0.1; it has no authentication or CSRF
protection and must not be exposed as a production or network service.
- Start with
uv run python main.py --dry-hosts --open-browser. This is a hosts-write rehearsal, not a general no-side-effects mode. - Enter a specific topic, select only required access groups, optionally select a saved project preset, and choose Start session.
- Watch the status cards. Scheduler intervals are fixed delays after a tick finishes, and starting a session does not restart their countdowns.
- Use temporary goal access for one concrete blocked subgoal. One grant may be active at a time; it can last 1–240 wall-clock minutes or until session end. It does not pause monitoring or spend social-break allowance.
- Start an away or social-media break when needed. A break pauses productivity monitoring. Task access stays active; active goal access is suspended while its timer continues.
- If the newest verdict is wrong, correct it on its history card. Only the latest current-session verdict is editable; the model label remains in the audit record and only a genuine label change adds a correction event/message.
- To turn enforcement off, enter the exact case-sensitive phrase
I will not stop cool deepwork session. For process exit, use Ctrl+C and allow normal cleanup to finish.
The canonical access catalog contains 14 groups:
- Web only: Reddit, YouTube, X / Twitter, Hacker News, LinkedIn, Bluesky, Substack, Facebook, LessWrong, EA Forum, and 4chan.
- Web + app: Discord opens its configured domains and spares
discord.exe. - App only: Telegram and Steam spare their configured exact process names.
Hosts policy enumerates explicit domains; it is not wildcard filtering. App policy kills case-insensitive exact process-name matches abruptly, without checking executable path or owner. See Using Deep Work for ON/OFF/BREAK behavior, allowance accounting, goal access, agentic mode, verdict corrections, and known input limitations.
The dashboard waits three seconds after each status request finishes before polling again while visible; slow requests extend that interval. It keeps the last good view through temporary failures. Domain counts describe desired policy, including in dry-hosts mode, rather than measured network blocking.
The committed .env.example is the copyable source of defaults:
| Variable | Default | Purpose |
|---|---|---|
OPENAI_API_KEY |
none | Required API credential |
VISION_MODEL |
gpt-6-luna |
Productivity vision model; must support detail="original" |
PROGRESS_REASONING_EFFORT |
medium |
Productivity response reasoning effort |
AGENT_VISION_MODEL |
gpt-6-luna |
Agent-activity vision model |
AGENT_REASONING_EFFORT |
medium |
Agent-activity reasoning effort |
TEXT_MODEL |
gpt-6-luna |
Feedback-message model |
TEXT_REASONING_EFFORT |
medium |
Feedback-message reasoning effort |
TTS_ENGINE |
openai |
Exact openai selects OpenAI speech; every other value currently falls back to pyttsx3 |
TTS_MODEL |
gpt-4o-mini-tts |
OpenAI speech model |
TTS_VOICE |
coral |
OpenAI speech voice |
CAPTURE_INTERVAL_S |
300 |
Seconds waited after a completed productivity tick before the next tick begins |
PROGRESS_WINDOW_CAPTURES |
5 |
Maximum retained same-context captures; minimum 2, comparison starts at capture 2 |
KILL_INTERVAL_S |
3 |
Fixed delay between enforcement ticks |
AGENT_CHECK_INTERVAL_S |
60 |
Fixed delay after each agent-watch tick, including an ineligible skipped tick |
DAILY_SOCIAL_CAP_MIN |
120 |
Local-date social-break reservation cap |
UI_PORT |
5000 |
Loopback dashboard port |
BATCH_SIZE is accepted only as a compatibility fallback when
PROGRESS_WINDOW_CAPTURES is absent. Numeric validation is sparse: use
integers, keep scheduler delays positive, keep the progress window at least 2,
use a nonnegative allowance, and choose a valid TCP port. Nonpositive delays
can cause tight loops and excessive API/CPU usage.
The three text/image workloads default to
GPT-6 Luna, which
supports image input, structured outputs, and the configured reasoning levels.
Existing .env model overrides take precedence over these defaults; update
all three model variables when upgrading an existing installation, then restart
the app. Keep any independently chosen reasoning settings.
Productivity requests use detail="original" for dense screen content, subject
to the selected model's support and sizing limits. Each source tile is already
resized to 960 pixels wide and the composite is JPEG-compressed, so it is not
native monitor resolution. Agent-watch requests use low detail. Verify model
replacements with the current
vision input guide
and the model-migration checks.
Create projects.json in the repository root to add reusable access groups:
{
"Documentation": ["youtube", "substack"],
"Community support": ["discord", "telegram"]
}The file is loaded once at startup. Names must be nonempty and values must be
arrays containing only canonical group keys. A selected preset is unioned with
the checked one-off groups. projects.json is not gitignored, so do not
put confidential project names in it unless you intend to track them.
| Path | Contents |
|---|---|
logs/deepwork_YYYYMMDD_HHMMSS.log |
Timestamped runtime log; complete textual LLM prompts and semantic outputs also appear uncut in the terminal |
results/captures/*.jpg |
Timestamped quality-80 stitched monitor/webcam composites |
results/llm/*.json |
Returned text, productivity-vision, and agent-watch responses, including refusals; vision records reference local capture paths instead of duplicating base64 |
results/sessions/YYYYMMDD.jsonl |
Append-only session, policy, break, agent, verdict, and correction events |
results/state.json |
Persisted allowance usage and topic history |
Live sessions, grants, verdict timelines, and scheduler state do not reload
after restart. Files are unencrypted, have no automatic rotation or pruning,
and can contain private data. .env, logs/, and results/ are
gitignored; never force-add them.
- A productivity request uploads the current rolling set of one through
PROGRESS_WINDOW_CAPTURESstitched JPEGs. Each can include every monitor and camera index0, plus the complete topic, permanent access groups, and any active goal-access goal/groups. Agent watching uploads one low-detail stitched JPEG per eligible check. Text-feedback requests upload a bounded current session summary, including at most five recent monitor observations. TTS_ENGINE=openaiuploads each utterance that reaches its speaker to the Speech API, streams a temporary WAV, plays it, and deletes it after successful playback; an exception can leave that temp file. pyttsx3 keeps synthesis/playback local.- The code does not pass
store=Falseto Responses calls. OpenAI says API data is not used to train its models unless an organization opts in, but default Responses application state is retained for at least 30 days and default abuse-monitoring logs may be retained for up to 30 days. Review the current OpenAI API data controls for account controls, endpoint details, and exceptions. - The application does not calculate cost. Rolling productivity requests resend retained images, agentic mode adds vision calls, some transitions/corrections add text calls, and OpenAI TTS adds speech calls. Check current model pricing and your API usage.
See Privacy, data, retention, and cost before using real personal or employer data.
Normal Disable from an active mode and registered shutdown after an active run
attempt serialized hosts cleanup. Cleanup is still best-effort: a hard kill,
power loss, or process crash can skip atexit; startup, Disable while already
OFF, and shutdown from an untouched OFF start do not proactively remove a stale
fence. Run only one instance because hosts and local state files have no
cross-process lock.
If a previous run left websites blocked:
- Exit every Deep Work instance.
- Open
C:\Windows\System32\drivers\etc\hostsas Administrator. - Remove the section from
# >>> deepwork block startthrough# <<< deepwork block end, inclusive. Preserve every other line. - Run
ipconfig /flushdnsin an elevated terminal.
Back up the file before editing. An unmatched start marker is especially dangerous because a later apply/clear treats everything after it as owned content. See Troubleshooting for startup, port, hosts, resolver, capture, audio, OpenAI, and artifact failures.
The repository's hardware/network/admin-free automated suite uses temporary files, generated images, fake clients, Flask requests, and thread coordination:
uv lock --check
uv run pytest
uv run python main.py --helpThat suite is not proof that Windows hosts edits, UAC, the local devices, the
network, model access, or nondeterministic model judgments work on a particular
machine. --smoke is the shortest real capture/API/audio path, while the
interactive --dry-hosts run exercises the UI and loops without hosts writes.
Use the bounded, side-effect-labeled checks in
Verification.
Dashboard JavaScript regressions also use Node.js's built-in test runner:
node --test tests/dashboard.test.cjs. Node.js 22 or later is a test-only
prerequisite; the application and Python tests do not require it. See the
independent fact-check record
for evidence, corrections, sources, and remaining verification limits.
The canonical documentation index routes detailed operating, architecture, privacy, startup, recovery, verification, verdict-correction, and maintainer information to one owning page. Follow those links when the concise overview here is not enough.
The code is the behavioral source of truth. Documentation claims in this repository are intended to describe the checked-in implementation, not a planned feature.
