Skip to content

fix(runtime): refuse a DATABASE_URL that splits state from OFFERU_DATA_DIR - #168

Open
avabbbb wants to merge 1 commit into
mainfrom
fix/runtime-db-path-guard
Open

avabbbb wants to merge 1 commit into
mainfrom
fix/runtime-db-path-guard

Conversation

@avabbbb

@avabbbb avabbbb commented Oct 27, 2026

Copy link
Copy Markdown
Owner

Problem

offeru start sets OFFERU_DATA_DIR, but entry.configure() used os.environ.setdefault("DATABASE_URL", ...). An inherited stale value, usually a relative sqlite:///./offeru.db from an old repo-root .env, wins. Sessions and config go to the data dir, while agent runs, actions and operation audit go to a DB in whatever directory the process started in. Nothing is deleted, but history and audit look lost. This came up during the agent E2E audit: the sessions of 5 runs had no matching rows in the data-dir DB, and the runs turned up in the launch directory's offeru.db.

Change

  • runtime_paths.database_location_problem(url, data_dir): flags a relative sqlite path or one outside the data dir. Postgres and :memory: are never flagged.
  • entry.configure(): refuses to start with a Chinese message naming the cause and the fix. OFFERU_ALLOW_EXTERNAL_DATABASE=1 keeps an external DB and prints a warning. With no inherited URL, behavior is unchanged (<data dir>/djm.db).
  • Diagnostics bundle: data_safety.database_location_mismatch is true, false, or null (null when no data dir is set). It carries the verdict only, never a path.

Not affected

  • CI build.yml starts backend/run_server.py (not app.entry), and release-lite.yml runs offeru start without DATABASE_URL.
  • Tests: conftest.py already clears DATABASE_URL.

Tests

  • New backend/tests/test_runtime_database_guard.py: 8 passed.
  • Related subset -k "entry or runtime or data_safety or diagnostics or database": 17 passed.
  • PII/secret scan of the diff: clean.

Follow-up (not in this PR): running app.main directly through uvicorn in dev doesn't go through entry.configure, so it is only covered by the diagnostics flag.

Rebased onto main (6ef9569) and reopened; supersedes closed #152.

Local backend tests: no new failures vs main (the 8 failing on main are 7 Windows-only test_boss_sync WinError 193 and the change-capture FK test fixed by #166).

…A_DIR

`offeru start` set OFFERU_DATA_DIR but kept any inherited DATABASE_URL via
setdefault. A stale relative URL from an old repo-root .env
(sqlite:///./offeru.db) sent agent runs, actions and audit logs to a DB in
the launch directory, while sessions and config went to the data dir. Later
it looked like run history and audit had been lost.

- runtime_paths: sqlite_path_from_url / database_location_problem flag a
  relative sqlite path or one outside the data dir (postgres and :memory:
  are never flagged)
- entry.configure: refuse to start with an actionable message;
  OFFERU_ALLOW_EXTERNAL_DATABASE=1 keeps an external DB with a warning
- diagnostics bundle: data_safety.database_location_mismatch (verdict only,
  no path)

CI is unaffected: build.yml starts backend/run_server.py, not app.entry,
and release-lite.yml runs `offeru start` without DATABASE_URL.

This branch has not been deployed

No deployments
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