Skip to content

fix: remove hardcoded developer paths from shipped code - #14

Merged
abrichr merged 3 commits into
mainfrom
fix/hardcoded-founder-paths
Aug 27, 2026
Merged

fix: remove hardcoded developer paths from shipped code#14
abrichr merged 3 commits into
mainfrom
fix/hardcoded-founder-paths

Conversation

@abrichr

@abrichr abrichr commented Aug 27, 2026

Copy link
Copy Markdown
Member

This is a public repo, and a path under one developer's home directory was baked into library code, two tests, an example script, and a checked-in HTML artifact. PR #13 removed the two in the screenshot pipeline. This gets the rest.

The one that actually broke things

real_data_loader.py defaulted to /Users/abrichr/oa/src/openadapt-capture/turn-off-nightshift, so openadapt-viewer benchmark with no --data raised FileNotFoundError for everyone who isn't that developer.

Re-pointing that default at a sibling checkout would have looked like a fix and not been one. turn-off-nightshift/ is gitignored in openadapt-capture (.gitignore:56), so it's local data nobody else can obtain. There's no location the default could point to that would work. So the default is gone. Name a recording with --data, or set $OPENADAPT_CAPTURE_RECORDING. Missing config now prints one line and exits 1 instead of dumping a traceback.

The one that was quieter and worse

Key frames in episodes.json are stored relative to the checkout root, like ../openadapt-capture/<rec>/screenshots/step_0.png. The loader resolved them by prepending a literal /Users/abrichr/oa/src. Copy a recording anywhere else and all six screenshot paths came back pointing at a machine you don't have, with no error, because nothing checks that a screenshot path exists.

It now re-anchors on the capture directory the caller passed. I checked both directions:

  • Against the real recording in place: 6 frames, 0 missing, byte-identical paths to the old behaviour.
  • Against a copy under /private/tmp/.../fakeroot/: 6 frames, 0 missing. The old code returned /Users/abrichr/... here.

Deleting test_benchmark_refactored.html

I removed it rather than editing the paths inside it. It's generated by openadapt-viewer benchmark --output test_benchmark_refactored.html, no code reads it, and it embedded both the absolute paths and the step text of that private gitignored recording. .gitignore already excluded *_viewer.html; this one only survived because its name doesn't match the glob. It's ignored by name now.

verify_real_data.py is the only script that mentions it, and it already handles the file being absent without failing.

Say the word if you'd rather keep it and I'll regenerate it with portable paths instead.

Keeping it out

tests/test_no_hardcoded_paths.py fails the build if /Users/ or /home/ shows up in tracked code. I verified it fails on a planted violation, not just that it passes.

#13 merged while I was working on this, so the branch is rebased on it and the allowlist is now empty: the guard covers every tracked file with no exceptions. Re-verified by planting a violation in scripts/generate_for_web.sh, which the allowlist used to hide.

Markdown is out of scope here. About 50 status documents at the repo root still carry these paths. #15 sweeps them and drops that exemption.

Two variables, on purpose

$OPENADAPT_CAPTURE_DIR (PR #13, and tests/test_screenshot_generation.py here) names the openadapt-capture checkout that holds many recordings. $OPENADAPT_CAPTURE_RECORDING names one recording directory inside it. Overloading a single name with both meanings would have been a bug waiting to happen.

Found but not fixed

The loader reads capture.db with SELECT * FROM capture. openadapt-capture's recorder writes recording.db now (recorder.py:1292, recorder.py:2368), so this path loads pre-PR-#28 recordings only. That's a schema change, not a path fix, so I left it alone. Worth an issue.

Tests

CI is green on all five checks. pytest tests/ gives 145 passed, 46 skipped, and ruff check . passes. CLI verified end to end both with and without a recording configured.

Running pytest over the whole tree instead of tests/ turns up one more failure, test_minimal_viewer.py::test_viewer_html. It asserts on viewers/benchmark/minimal_viewer.html, which .gitignore:15 excludes, so it fails on any fresh clone. I reproduced it on a clean clone of main. CI only runs tests/, so it never sees it. Untouched here.

One thing worth calling out, since it's the kind of bug this PR is nominally about. The guard failed CI on first push because it flagged its own source, which has to spell out the prefixes it bans. It had passed locally only because the file was still untracked when I ran it, so git ls-files never returned it. Fixed in the second commit, and re-verified with planted violations in both src/ and tests/ with the file tracked.

This is a public repository, and a path under one developer's home directory
was baked into library code, tests, a test fixture and an example script.

The worst of them was in shipped code. `real_data_loader.py` defaulted to
`/Users/abrichr/oa/src/openadapt-capture/turn-off-nightshift`, so
`openadapt-viewer benchmark` with no `--data` raised FileNotFoundError for
every user who is not that developer. That directory is also gitignored in
openadapt-capture, so the default could never resolve for anyone else even
with both repositories checked out. Re-pointing it would have been theatre;
the default is gone instead.

A second path did real damage more quietly. Key frames in episodes.json are
stored relative to the checkout root, as `../openadapt-capture/<rec>/...`, and
the loader resolved them by prepending a literal `/Users/abrichr/oa/src`. Point
it at a recording anywhere else and every screenshot path came back pointing at
a machine you do not have. It now re-anchors on the capture directory the
caller actually passed, which resolves identically for that developer and
correctly for everyone else.

Callers name a recording by argument or through $OPENADAPT_CAPTURE_RECORDING.
That is deliberately a different variable from the $OPENADAPT_CAPTURE_DIR used
by the screenshot scripts, which names the capture checkout holding many
recordings, not one recording inside it.

test_benchmark_refactored.html is deleted rather than edited. It is generated
by `openadapt-viewer benchmark`, no code reads it, and it embedded both the
absolute paths and the step text of a private gitignored recording. .gitignore
already excluded `*_viewer.html`; this artifact only escaped because its name
did not match. It now matches.

tests/test_no_hardcoded_paths.py fails the build if such a path returns. Its
allowlist holds exactly the two files fixed in PR #13 and is checked for stale
entries, so it shrinks to nothing when that merges.

Not fixed here, and worth separate changes:

- The loader reads the legacy `capture.db` schema. openadapt-capture's recorder
  writes `recording.db` (recorder.py:1292), so this loads old recordings only.
- Roughly 50 status documents at the repository root still carry these paths.
  They are prose, not code, so the guard skips markdown.
The guard has to spell out the prefixes it bans, so it flagged its own source
and failed CI on all four matrix jobs.

It passed locally for the wrong reason: the file was still untracked when I ran
it, so `git ls-files` never returned it. Once committed it became tracked and
started matching. Skipping it by path is the fix, and the stale-entry test now
covers that path too, so a rename cannot leave the exclusion pointing at
nothing.

Re-verified by planting a violation in src/ and in tests/ with the file tracked
this time. Both fail the guard; a clean tree passes.
The two `scripts/` files it exempted are fixed on main, so the guard covers
every tracked file with no exceptions. Verified by planting a violation in
scripts/generate_for_web.sh, which the allowlist used to hide.
@abrichr
abrichr force-pushed the fix/hardcoded-founder-paths branch from ab3afec to a922ffb Compare August 27, 2026 18:35
@github-actions

Copy link
Copy Markdown
Contributor

📸 Generated Screenshots Preview

Screenshots have been generated. Download the artifacts to preview them.

Generated Files:

  • demo_new_controls.png (0.07 MB)
  • demo_new_events.png (0.04 MB)
  • demo_new_full.png (0.11 MB)
  • turn-off-nightshift_controls.png (0.15 MB)
  • turn-off-nightshift_events.png (0.13 MB)
  • turn-off-nightshift_full.png (0.23 MB)

🔗 Download screenshots artifact

@abrichr
abrichr merged commit ad12eba into main Aug 27, 2026
5 checks passed
@abrichr
abrichr deleted the fix/hardcoded-founder-paths branch August 27, 2026 19:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant