# Project export: Deadman

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: OpenAI Build Week
- Tagline: Deadman supervises autonomous coding loops: it detects stuck child processes, uses GPT-5.6 for bounded diagnosis, safely recovers proven descendants, verifies results, and logs incidents.
- Devpost: https://devpost.com/software/deadman
- GitHub: https://github.com/ManasShouche/deadman
- Video: https://www.youtube.com/embed/FMa71PaafNE?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 1 GitHub contributor(s) — ManasShouche (44 commits)

## Devpost submission (written by the team)

### Inspiration

Autonomous coding agents can work for long periods, but a single silent child process, wedged development server, or unbounded retry loop can stop all useful progress. The agent may still appear active while it is only waiting. Developers then return to a stalled session, wasted time, and no trustworthy way to recover it without killing the entire agent. We built Deadman around one question: how can an independent supervisor detect that an autonomous coding loop is genuinely stuck, recover only what is safe to recover, and prove that the intervention worked?

### What it does

Deadman is a local safety supervisor for Codex coding sessions. Its control loop is: Observe -> Detect -> Diagnose -> Recover -> Verify -> Report Deterministic code watches session events and operating-system process trees. When a detector finds a supported failure, Deadman sends GPT-5.6 a compact evidence packet. The model can recommend one typed action, but it receives no shell, filesystem, process-control, or session-control tools. Every recommendation must pass deterministic policy and process-ownership checks. Deadman can then terminate only a freshly proven descendant process, verify that the failure was resolved, and store the complete evidence chain in SQLite. If ownership or verification is uncertain, it refuses the action and escalates instead. Deadman supports several workflows: deadman run launches and supervises a non-interactive command such as codex exec --json. deadman agent launches an interactive Codex TUI inside a supervised PTY on macOS and Linux. deadman attach discovers and supervises a Codex TUI already running in another terminal in the same repository. deadman watch reads persisted Codex session evidence without controlling processes. deadman replay, deadman demo, and deadman report provide deterministic, credential-free evaluation paths. Automatic recovery is off by default. It must be explicitly enabled with --auto-recover.

### How we built it

We used Codex throughout both product design and implementation. A Codex web planning thread helped us explore the failure model, reject unsafe plugin-style control, and choose an independent supervisor architecture. The main Codex implementation thread then helped build and repeatedly test the adapters, detectors, typed diagnosis schema, policy engine, process executor, verification gates, SQLite incident state machine, CLI modes, replay fixtures, reports, and cross-platform behavior. The system is written in Python using Typer for the CLI, Rich for terminal output, Pydantic for strict model-response validation, SQLite for durable evidence, and psutil for process ownership and recovery. Live diagnosis uses the OpenAI Responses API with GPT-5.6. Deterministic replay and fixture diagnosis keep the core evaluation path usable without credentials. The architecture deliberately separates intelligence from authority. GPT-5.6 interprets bounded evidence and recommends an action. Deterministic code decides whether that action is permitted, executes it, and verifies the result.

### Challenges we ran into

The hardest problem was safe process identity. Early process classification could mistake the Codex root for a Python-related target when the prompt itself contained the word Python. We fixed this by classifying executable identity and proving ancestry from the live Codex root instead of relying on command text. Process ownership can also change between detection and recovery. A child may exit, become a zombie, or be reparented before Deadman acts. Deadman therefore rechecks ownership immediately before intervention. This occasionally produces an escalation instead of a recovery, but that is the correct outcome when safety cannot be proven. Interactive terminal supervision introduced additional challenges: PTY sizing, ANSI output, nested process trees, terminal passthrough, and keeping the Codex TUI alive after recovering its hung tool process. We also had to distinguish persisted session evidence from live process ownership. A session file is useful for observation, but it is not sufficient authority to terminate a process. Cross-platform support required a clear boundary. The core data model, replay, reporting, watch, attach, and managed run workflows support macOS, Linux, and Windows. The PTY-backed agent command remains macOS/Linux-only because Windows requires a separate ConPTY implementation.

### Accomplishments we're proud of

We demonstrated a real two-terminal recovery against a live Codex TUI. Codex started a silent Python parent and sleeping child. Deadman attached from another terminal, detected the hung process, obtained a typed diagnosis, proved ownership, terminated the two-process descendant tree, verified resolution, and recorded the incident while the Codex TUI remained open. We are equally proud of the refusal path. During a live package-install test, the target changed before intervention. Deadman refused to terminate it because it was no longer a proven descendant and recorded an escalated incident. Safe refusal is a product feature, not a failed demo. Other completed work includes: Strict evidence-reference validation and typed GPT-5.6 output. Automatic recovery disabled by default. Verification that can fail and force escalation. Durable incident timelines and terminal reports. Credential-free replay and demo workflows for judges. Live supervision of Codex sessions launched either by Deadman or independently. A test suite covering detection, policy, ownership, recovery, verification, persistence, CLI behavior, and platform boundaries.

### What we learned

An agent saying that it is working is not the same as measurable progress. Reliable supervision must use independent evidence from events, time thresholds, and the operating-system process tree. We also learned that diagnosis and authority should remain separate. A model is useful for interpreting evidence and selecting among constrained recovery strategies, but deterministic policy must retain control of every side effect. Finally, escalation is a valid recovery outcome. A supervisor that always acts is dangerous. A trustworthy supervisor must be able to say, "I detected a problem, but I cannot prove that this action is safe."

### What's next

The next version will add a dedicated progress ledger and live monitor UI for multiple concurrent Codex sessions, with signal thresholds, policy decisions, verification state, and incident timelines visible in one place. We also plan workload-aware timeout policies so long installs and builds are not treated like silent synthetic hangs. Further work includes committed failed-verification scenarios, richer postmortem generation, prevention-rule proposals after verified recovery, budget controls for long autonomous runs, and native Windows ConPTY support for interactive supervision. The long-term goal is for Deadman to become a dependable local control layer for long-running autonomous coding workflows: independent of the agent, conservative about authority, and accountable for every intervention.

## README (from the GitHub repository)

# Deadman

> The session died. The task did not.

**The problem:** you give a coding agent a long autonomous task and walk away — then it gets stuck. A hung child process, a wedged dev server, an infinite retry loop. You come back to a dead session and burned tokens, with no safe way to recover it. Deadman is the supervisor that watches the agent, catches the stall, and recovers it — safely enough to leave running unattended.

**How it works** — a six-step loop that is entirely deterministic except for one bounded model call:

```text
Observe → Detect → Diagnose → Recover → Verify → Report
                  (GPT-5.6, bounded)
```

Deterministic code watches the process tree and detects a stuck state. Only then does it hand GPT-5.6 a compact evidence packet — and the model can **recommend exactly one typed action, nothing else**. It never gets shell, files, PIDs, or your API keys. Deterministic code checks that recommendation against policy, executes only what's approved (**off by default**), verifies the outcome, and writes an auditable incident. **A model recommendation is never permission to act** — that separation is the whole point.

**See it work in 30 seconds — no Codex, no API key:**

```bash
git clone https://github.com/ManasShouche/deadman && cd deadman
./scripts/deadman demo      # runs three recorded failure→recovery scenarios offline
```

## What Can I Run?

| Need | Command | Can recover? | Best use |
| --- | --- | --- | --- |
| Supervise a non-interactive command that Deadman launches | `deadman run -- <command>` | Yes, with `--auto-recover` | `codex exec --json` and scripts |
| Launch and supervise the interactive Codex TUI | `deadman agent -- codex ...` | Yes, with `--auto-recover` | A new interactive Codex session |
| Supervise a Codex TUI already running in another terminal | `deadman attach` | Yes, with `--auto-recover` | Real two-terminal recovery |
| Read one persisted Codex session | `deadman watch` | No | Investigation and evidence only |
| Run credential-free shipped scenarios | `deadman replay <trace>` | Simulated only | Judge and offline testing |
| Run the three replay scenarios together | `deadman demo` | Simulated only | Fast offline smoke test |

`--auto-recover` is **off by default** for every command. Without it, Deadman records the signal, diagnosis, and policy result at the approval boundary instead of performing a recovery action.

## Judge Quickstart

```bash
git clone https://github.com/ManasShouche/deadman
cd deadman
./scripts/deadman config check
./scripts/live-attach-smoke
```

`./scripts/deadman` creates `.venv`, installs Deadman in editable mode, and forwards its arguments to the real CLI. The attach smoke is isolated, credential-free, and exercises live process discovery, hung-child detection, recovery, verification, and SQLite persistence.

For offline scenarios without Codex or an API key:

```bash
./scripts/deadman demo
./scripts/deadman replay scenarios/recordings/hung-process.jsonl
./scripts/deadman report repeated-failure
```

## Real Two-Terminal Recovery

This is the main live scenario. It uses a real interactive Codex TUI and Deadman attaches from a second terminal.

Terminal 1, in an isolated repository:

```bash
mkdir -p /private/tmp/deadman-real-attach
cd /private/tmp/deadman-real-attach
git init

codex --no-alt-screen --sandbox workspace-write --ask-for-approval never \
  "Do not edit files. Run this exact command and wait for it:\npython3 -c 'import subprocess; raise SystemExit(subprocess.Popen([\"sleep\", \"600\"]).wait())'\nDo not interrupt it yourself."
```

Wait until Codex reports that the background command is running. Then open Terminal 2 in the same repository:

```bash
cd /private/tmp/deadman-real-attach

/path/to/deadman/.venv/bin/deadman attach \
  --hung-timeout 20 \
  --auto-recover \
  --diagnosis fake
```

Replace `/path/to/deadman` with your clone path. Use `--diagnosis openai` only when `OPENAI_API_KEY` is configured and a live GPT-5.6 diagnosis is required. `fake` keeps this process-recovery test deterministic while still using the real Codex CLI and real OS process tree.

Expected result after about 20 seconds:

```text
Status       recovered
Signal       HUNG_PROCESS
Hung pid     <owned python or sleep pid>
Action       terminated descendant process tree (...)
Verification resolved
Final state  RESOLVED
```

Codex should stay open. Deadman never signals the selected Codex process itself; it can signal only a freshly proven descendant.

Inspect the recorded incident from Terminal 2:

```bash
sqlite3 .deadman/deadman.sqlite 'select id, state from incidents;'
sqlite3 .deadman/deadman.sqlite 'select count(*) from signals; select count(*) from diagnoses; select count(*) from action_results; select count(*) from verification_results;'
```

## Command Reference

All commands resolve the default database to `<git-root>/.deadman/deadman.sqlite`, not the shell's current directory. Startup always prints the resolved SQLite path and whether auto recovery is on.

### Anatomy of a supervised call

`run` and `agent` split into two halves at `--`: Deadman options on the left, the command Deadman launches on the right.

```text
deadman run  --hung-timeout 20 --auto-recover  --  codex exec --json --sandbox workspace-write "Fix the failing test"
             └────── Deadman options ─────────┘     └──────────────── Codex command (passed verbatim) ─────────────┘
```

Everything after `--` is passed to the child process as an argument array. Deadman never shell-interpolates it and never edits the prompt. `attach`, `watch`, `replay`, `demo`, and `report` take no `--` command — `attach`/`watch` find an existing Codex session, and the rest read shipped evidence.

The Codex flags used in the examples are Codex's own, not Deadman's:

| Codex token | What it does | Why Deadman examples use it |
| --- | --- | --- |
| `exec` | Codex's non-interactive mode: run one task, emit events, exit. | The surface `deadman run` supervises. |
| `--json` | Codex writes JSON Lines events to stdout. | Deadman's adapter parses these into normalized evidence. |
| `--sandbox read-only` \| `workspace-write` | Codex's own file-write sandbox level. | Deadman's guarded auto-resume requires one of these two (never full access). |
| `--ask-for-approval never` | Codex runs tool calls without pausing for interactive approval. | Lets a hung-command scenario reproduce deterministically. |
| `--no-alt-screen` | Codex renders inline instead of a full-screen TUI. | Keeps `deadman agent` PTY passthrough readable. |
| `"<prompt>"` | The natural-language task for Codex. | Passed verbatim as one argument; Deadman never interprets it. |

### `deadman run`

Use `run` when Deadman should start the command itself. It is the supported surface for non-interactive `codex exec --json` sessions.

```bash
deadman run [OPTIONS] -- <command> [command arguments]
```

Examples:

```bash
# Capture a normal JSONL Codex run.
deadman run -- codex exec --json --sandbox workspace-write "Fix the failing test"

# Detect a hung owned child after 20 seconds and recover it automatically.
deadman run --hung-timeout 20 --auto-recover -- \
  codex exec --json --sandbox workspace-write \
  "Run a command that starts a child process and waits forever"

# After verified recovery, resume the Codex exec session with grounded guidance.
deadman run --hung-timeout 60 --auto-recover --resume-after-recovery -- \
  codex exec --json --sandbox workspace-write "Fix the fixture task"
```

| Option | Meaning |
| --- | --- |
| `--database PATH` | Override the SQLite database path. |
| `--timeout SECONDS` | Stop the supervised command after this duration. |
| `--hung-timeout SECONDS` | Enable live hung-descendant detection after this idle time. |
| `--auto-recover` | Permit policy-approved recovery actions. Off by default. |
| `--diagnosis auto\|fake\|openai` | Use configured OpenAI, deterministic fixture diagnosis, or require OpenAI. |
| `--model MODEL` | Model for `--diagnosis op

[README truncated for size]

## Detected evidence (automated analysis)

Indexed codebase: 80 recognized source files, 345 KB.
- OpenAI (technology) — detected in the code
- Python (language) — detected in the code
- AI coding agent: Codex — evidence: config files committed to the repository

## Codebase structure (from repository index)

### Files (95 of 95)

```
.env.example
.github/workflows/ci.yml
.gitignore
AGENTS.md
apps/__init__.py
apps/cli/__init__.py
CODEX_LOG.md
deadman/__init__.py
deadman/adapter/__init__.py
deadman/adapter/jsonl.py
deadman/adapter/session.py
deadman/adapter/subprocess.py
deadman/agent.py
deadman/attach.py
deadman/config.py
deadman/detectors/__init__.py
deadman/detectors/hung_process.py
deadman/detectors/progress.py
deadman/detectors/replay.py
deadman/diagnosis/__init__.py
deadman/diagnosis/fake.py
deadman/diagnosis/openai_client.py
deadman/domain/__init__.py
deadman/domain/incident.py
deadman/domain/models.py
deadman/executor/__init__.py
deadman/executor/actions.py
deadman/incidents.py
deadman/monitor/__init__.py
deadman/monitor/descendants.py
deadman/monitor/process.py
deadman/monitor/workspace.py
deadman/paths.py
deadman/platforms.py
deadman/policy/__init__.py
deadman/policy/engine.py
deadman/recovery.py
deadman/report.py
deadman/run.py
deadman/store/__init__.py
deadman/store/sqlite.py
deadman/ui.py
deadman/verify/__init__.py
deadman/verify/replay.py
deadman/watch.py
DEVPOST_SUBMISSION.md
docs/architecture-decisions.md
docs/codex-event-contract.md
gate_a.txt
LICENSE
pyproject.toml
README.md
scenarios/README.md
scenarios/recordings/codex-session-cli-0.144.4.jsonl
scenarios/recordings/gate-a-codex-cli-0.144.4.capabilities.md
scenarios/recordings/gate-a-codex-cli-0.144.4.jsonl
scenarios/recordings/hung-process.capabilities.md
scenarios/recordings/hung-process.jsonl
scenarios/recordings/README.md
scenarios/recordings/repeated-failure.capabilities.md
scenarios/recordings/repeated-failure.jsonl
scenarios/recordings/session-handoff.capabilities.md
scenarios/recordings/session-handoff.jsonl
scripts/deadman
scripts/live-attach-smoke
scripts/live-diagnosis-check
scripts/live-tui-smoke
scripts/setup
spec.md
tests/test_adapter_jsonl.py
tests/test_adapter_subprocess.py
tests/test_agent.py
tests/test_attach.py
tests/test_cli_replay.py
tests/test_cli_run.py
tests/test_cli_watch.py
tests/test_cli.py
tests/test_config.py
tests/test_executor_actions.py
tests/test_gate_a_recording.py
tests/test_hung_process_detector.py
tests/test_incident_state.py
tests/test_incidents.py
tests/test_openai_diagnosis_client.py
tests/test_platforms.py
tests/test_policy_diagnosis.py
tests/test_process_monitor.py
tests/test_progress_detectors.py
tests/test_replay_pipeline.py
tests/test_run_pipeline.py
tests/test_session_adapter.py
tests/test_store_sqlite.py
tests/test_ui.py
tests/test_verify_replay.py
tests/test_workspace_fingerprint.py
```

### Dependencies

- pyproject.toml: mypy@>=1.10,<2, openai@>=2,<3, psutil@>=6,<8, pydantic@>=2.8,<3, pytest@>=8,<9, python-dotenv@>=1,<2, rich@>=13,<15, ruff@>=0.5,<1, typer@>=0.12,<1, types-psutil@>=7,<8

### Recent commits (newest first)

- Add healthy heartbeat status to attach supervisor
- Improve README introduction and quickstart
- Document Codex planning and implementation provenance
- Show diagnosis backend and preserve listening services
- Make PTY type checks platform neutral
- Normalize styled CLI output in tests
- Fix cross-platform CI assumptions
- Make supervision portable across platforms
- Document validation results and Codex implementation narrative
- Document supervised calls and diagnosis contracts
- Rewrite README around workflow-first CLI usage
- Add attach mode for recovering live Codex sessions
- Prevent interactive recovery from targeting Codex
- Terminate owned descendant process trees
- Track descendant baselines and persist recovery results
- Preserve terminal dimensions in agent PTY sessions
- Simplify fresh clone setup and harden project-root supervision
- Finalize Deadman MVP for judge testing
- Add live hung-child recovery to deadman run
- docs: finalize scope and Rust roadmap

## Key source files (fetched from GitHub, selected and truncated for size)

### AGENTS.md

```markdown
# Deadman contributor guide

## Architecture law

> Deterministic code observes events, detects pathological states, authorizes actions, executes approved actions, and verifies outcomes. GPT-5.6 receives a compact evidence packet and recommends only a typed action. The model never receives arbitrary shell, process, filesystem-write, or session-control tools.

## Working rules

- Treat `spec.md` as the source of truth. Build only the current delivery slice.
- Keep model output evidence-bound and validated. A model recommendation is never permission to perform an action.
- Default to escalation when process ownership, adapter capability, evidence, or policy is uncertain.
- Never shell-interpolate task text or model output. Process launches use argument arrays.
- Preserve malformed or unknown adapter events as evidence; do not silently discard them.
- Make small changes with focused tests. Run `pytest`, `ruff check .`, and `mypy .` before handing work off.
- Add a concise entry to `CODEX_LOG.md` for material implementation, validation, and human decisions.

## Current status

The repository now includes the deterministic MVP core: adapter evidence capture, replay fixtures, pure detectors, policy checks, bounded recovery executors, verification, SQLite persistence, terminal reports, and a live `deadman run` hung-child recovery path. New intervention behavior still needs a fixture and focused tests before being treated as supported.

```

### DEVPOST_SUBMISSION.md

```markdown
# Deadman

> The session died. The task didn't.

A local safety supervisor that watches an autonomous coding agent from outside the session, recovers only what it can prove is safe to touch, and records every intervention.

## Inspiration

Autonomous coding agents can work for long periods, but a single silent child process, wedged development server, or unbounded retry loop can stop all useful progress. The agent may still appear active while it is only waiting. Developers then return to a stalled session, wasted time, and no trustworthy way to recover it without killing the entire agent.

We built Deadman around one question: how can an independent supervisor detect that an autonomous coding loop is genuinely stuck, recover only what is safe to recover, and prove that the intervention worked?

## What it does

Deadman is a local safety supervisor for Codex coding sessions. Its control loop is:

**Observe -> Detect -> Diagnose -> Recover -> Verify -> Report**

Deterministic code watches session events and operating-system process trees. When a detector finds a supported failure, Deadman sends GPT-5.6 a compact evidence packet. The model can recommend one typed action, but it receives no shell, filesystem, process-control, or session-control tools.

Every recommendation must pass deterministic policy and process-ownership checks. Deadman can then terminate only a freshly proven descendant process, verify that the failure was resolved, and store the complete evidence chain in SQLite. If ownership or verification is uncertain, it refuses the action and escalates instead.

Deadman supports several workflows:

- `deadman run` launches and supervises a non-interactive command such as `codex exec --json`.
- `deadman agent` launches an interactive Codex TUI inside a supervised PTY on macOS and Linux.
- `deadman attach` discovers and supervises a Codex TUI already running in another terminal in the same repository.
- `deadman watch` reads persisted Codex session evidence without controlling processes.
- `deadman replay`, `deadman demo`, and `deadman report` provide deterministic, credential-free evaluation paths.

Automatic recovery is off by default. It must be explicitly enabled with `--auto-recover`.

## How we built it

We used Codex throughout both product design and implementation. A Codex web planning thread helped us explore the failure model, reject unsafe plugin-style control, and choose an independent supervisor architecture. The main Codex implementation thread then helped build and repeatedly test the adapters, detectors, typed diagnosis schema, policy engine, process executor, verification gates, SQLite incident state machine, CLI modes, replay fixtures, reports, and cross-platform behavior.

The system is written in Python using Typer for the CLI, Rich for terminal output, Pydantic for strict model-response validation, SQLite for durable evidence, and `psutil` for process ownership and recovery. Live diagnosis uses the OpenAI Responses API
[truncated — 6099 more characters]
```

### pyproject.toml

```
[build-system]
requires = ["setuptools>=68"]
build-backend = "setuptools.build_meta"

[project]
name = "deadman"
version = "0.0.0"
description = "A local recovery harness for Codex sessions."
readme = "README.md"
license = "MIT"
requires-python = ">=3.11"
dependencies = [
  "openai>=2,<3",
  "pydantic>=2.8,<3",
  "psutil>=6,<8",
  "python-dotenv>=1,<2",
  "rich>=13,<15",
  "typer>=0.12,<1",
]

[project.optional-dependencies]
dev = [
  "mypy>=1.10,<2",
  "pytest>=8,<9",
  "ruff>=0.5,<1",
  "types-psutil>=7,<8",
]

[project.scripts]
deadman = "apps.cli:main"

[tool.setuptools.packages.find]
include = ["apps*", "deadman*"]

[tool.pytest.ini_options]
testpaths = ["tests"]

[tool.ruff]
target-version = "py311"
line-length = 100

[tool.ruff.lint]
select = ["E", "F", "I"]

[tool.mypy]
python_version = "3.11"
strict = true
files = ["apps", "deadman", "tests"]

```

### apps/__init__.py

```python
"""Application entry points for Deadman."""

```

### deadman/__init__.py

```python
"""Deadman domain and runtime components."""

```

### tests/test_cli.py

```python
from typer.testing import CliRunner

from apps.cli import app


def test_baseline_cli_reports_unimplemented_status() -> None:
    result = CliRunner().invoke(app)

    assert result.exit_code == 0
    assert result.stdout == "Deadman is initialized. Feature commands are not implemented yet.\n"

```

### deadman/platforms.py

```python
"""Small platform capability checks for optional live supervision features."""

from __future__ import annotations

import os


def supports_pty_supervision(platform_name: str | None = None) -> bool:
    """Return whether the standard-library PTY supervisor is available."""

    return (platform_name or os.name) == "posix"


```

### tests/test_gate_a_recording.py

```python
import json
from pathlib import Path

RECORDING = Path("scenarios/recordings/gate-a-codex-cli-0.144.4.jsonl")


def test__recording_is_jsonl_with_observed_capabilities() -> None:
    events = [json.loads(line) for line in RECORDING.read_text().splitlines()]

    assert all(isinstance(event, dict) for event in events)
    assert any(event["type"] == "thread.started" and "thread_id" in event for event in events)
    assert any(event["type"] == "item.completed" for event in events)
    assert any("usage" in event for event in events if event["type"] == "turn.completed")

```

### tests/test_platforms.py

```python
from pathlib import Path

import pytest

from deadman import agent
from deadman.platforms import supports_pty_supervision


def test_pty_capability_is_explicit() -> None:
    assert supports_pty_supervision("posix")
    assert not supports_pty_supervision("nt")


def test_agent_explains_windows_fallback(
    monkeypatch: pytest.MonkeyPatch,
    tmp_path: Path,
) -> None:
    monkeypatch.setattr(agent, "supports_pty_supervision", lambda: False)

    with pytest.raises(RuntimeError, match="use deadman attach"):
        agent.run_agent_cli(("codex",), workspace=tmp_path)

```

### deadman/paths.py

```python
"""Path helpers shared by CLI entry points."""

from __future__ import annotations

from pathlib import Path


def project_root(path: Path) -> Path:
    """Return the nearest Git root, falling back to the resolved path."""

    current = path.resolve()
    if current.is_file():
        current = current.parent
    for candidate in (current, *current.parents):
        if (candidate / ".git").exists():
            return candidate
    return current


def default_database_path(path: Path) -> Path:
    """Return Deadman's default SQLite path for a workspace."""

    return project_root(path) / ".deadman" / "deadman.sqlite"

```

[68 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]