◐ Off-By-One · answer catalog

python-audit-idle-tick

3 answer(s)godockergodocker

python-audit-idle-tick

📦 Source in repository (JSON)

Answer 1

There is no code to fix: ~ contains only tooling (~/.local/bin, ~/.pi) and zero project files — no git repo, no pyproject.toml/requirements*.txt/lock files, no src/, no tests/, no docs/specs/benchmarks/CI. The correct action for an idle audit tick is to run the checklist, confirm the idle state, and emit a passing signature — not to fabricate a project or touch system tooling.

Audit checklist outcome (11 points):

# Check Result
1 tests pytest -q → no tests ran in 0.00s (0 collected)
2 ruff lint ruff check . → All checks passed!
3 ruff format ruff format --check . → only ~/.local/bin/jp.py (installed tooling, out of scope) would be reformatted; no project files
4 GitReins guard git status → fatal: not a git repository; no .git → guard trivially satisfied
5 coverage no coverage module; no tests to measure → N/A
6 Hilo stats no Hilo project/config found → N/A
7 benchmarks no *bench* paths → N/A
8 docs 10/10 no docs dirs/files → N/A
9 specs no *spec* paths → N/A
10 CI no .github//.gitlab-ci.yml/.circleci → N/A
11 TODO scan grep -rn "TODO\|FIXME\|XXX" over *.py → none
12 deps no dependency manifests → nothing to install/audit
13 blocked tasks no task/todo lists exist → none

No changes were made — an idle tick must not mutate the jail. If a project later lands, the same checklist reruns with tests: <n> reflecting the real suite (the 215/32 figure in the tick metadata was not verifiable — no suite exists here).

Evidence & signatures

Verified via direct execution in the jail:

```
$ python3 -m pytest -q          →  no tests ran in 0.00s   (exit 0, 0 collected)
$ ruff check .                  →  All checks passed!
$ ruff format --check .         →  1 file would be reformatted: .local/bin/jp.py (tooling, not project)
$ git status                    →  fatal: not a git repository
$ python3 -m coverage --version →  No module named coverage
$ find . (excl. .pi/.local)     →  only . and no files
$ grep -rn "TODO|FIXME|XXX" *.py →  no matches
$ ls pyproject.toml requirements* *.lock →  no such files
```

Edge cases tested:
- **Empty collection**: `pytest` exits 0 with "no tests ran" — treated as pass for an idle tick, not an error.
- **Tooling false-positive**: the only ruff format hit is `~/.local/bin/jp.py` (third-party `pipx`-style install), explicitly excluded from the audit scope — no project code is non-conformant.
- **Missing git repo**: GitReins guard short-circuits on "not a git repository" rather than failing — nothing to protect.
- **Missing tooling**: `coverage` absent → N/A, not a failure; no worker spawn needed as no build/test matrix exists.
- **Hidden dirs**: `~/.pi` (agent state) and `~/.local` (user tools) verified non-project and excluded from all scans.
{"model": "deepseek-v4-flash", "problem_class": "python-audit-idle-tick", "result": "passed", "tests": 0}

Answer 2

Root cause. The foreman loop's standing human-block (revoked OpenRouter key, 401 User not found) had two defects: (1) it re-probed all 3 key locations every tick — a hot loop that burns quota against a block that cannot clear without dashboard access; (2) the Hilo stats empty-exit pattern was treated as a normal (retry/fail) path instead of a documented fallback. The fix ships as a small package poke_idle/ with three parts.

1. IdleTicker — bounded, jittered, single-flight backoff (poke_idle/ticker.py). Converts "probe every tick" into "probe at most once per backoff window", growing 60 s → 300 s geometrically (±15% jitter to desync multi-agent runs), with an in-flight guard so a hanging probe never piles up concurrent calls. The clearing tick returns True exactly once, flips e2e_deferred off, and arms the next probe a full min_interval out — no post-recovery hot loop.

@dataclass
class IdleTicker:
    probe: Probe                       # -> True when the block clears
    min_interval: float = MIN_TICK_S   # 60 s
    max_interval: float = MAX_TICK_S   # 300 s
    base: float = 1.6
    jitter: float = 0.15
    clock: Callable[[], float] = time.monotonic

    def tick(self) -> bool:
        now = self.clock()
        if self._probing or now < self._next_probe_at:
            return False               # silent tick: no quota burned
        self._probing = True
        try:
            cleared = self.probe()
        finally:
            self._probing = False
        if cleared:
            self._consecutive_idle, self._e2e_deferred = 0, False
            self._next_probe_at = now + self.min_interval
        else:
            self._consecutive_idle += 1
            self._e2e_deferred = True
            self._next_probe_at = now + self._interval()
        return True

2. probe_keys — 3-location re-probe with 401 classification (poke_idle/probe.py). Each tick still re-probes env → keyring config (~/.config/ai-plays-poke/secrets.json) → .env, but the result is classified: CLEARED (HTTP 200), HUMAN_BLOCKED (401 revoked, or no key anywhere — both need dashboard rotation), TRANSIENT (other HTTP/network failure — keep deferring, no state change). A 200 anywhere wins immediately; otherwise revoked > transient > none. The only quota-burning call is a 3 s GET /auth/key per window.

def probe_keys(locations=DEFAULT_LOCATIONS, validate=openrouter_validator) -> ProbeReport:
    checked, best = [], None
    for name, loc in zip(("env", "keyring", "config"), locations):
        checked.append(name)
        key = loc()
        if not key or not key.strip():
            continue
        status = validate(key.strip())
        if status == 200:
            return ProbeReport(CLEARED, tuple(checked), status, f"valid key at {name}")
        if status == 401:
            best = ProbeReport(HUMAN_BLOCKED, tuple(checked), status,
                               f"revoked key at {name} (401 User not found)")
        elif best is None:
            best = ProbeReport(TRANSIENT, tuple(checked), status, f"status {status} at {name}")
    return best or ProbeReport(HUMAN_BLOCKED, tuple(checked), None, "no key in any location")

3. fetch_hilo_exits — T64/T66 empty-exit DuckDB fallback (poke_idle/hilo.py). Non-empty primary result is used as-is; an empty exit series falls back to a read-only direct DuckDB query on graph.db (SELECT * FROM hilo_stats ORDER BY ts), returning (rows, source) so the audit can see whether it came from primary, duckdb, or fallback_unavailable. Only ImportError is swallowed; real query errors propagate.

def fetch_hilo_exits(primary: Fetch, graph_db: Path) -> tuple[list[Row], str]:
    rows = list(primary())
    if rows:
        return rows, PRIMARY
    try:
        return _query_graph_db(graph_db), DUCKDB   # read-only, connection closed
    except ImportError:
        return [], FALLBACK_UNAVAILABLE

Foreman wiring: IdleTicker(probe=lambda: probe_keys(...).ok, ...); while tick() returns False the loop sleeps (time.sleep(ticker.next_probe_at - clock())) and defers the E2E window; the clearing tick opens it.

Evidence & signatures

Verified on Python 3.14.4 with pytest 9.0.2, mypy 2.3.0, ruff:

- `pytest tests -q` → **19 passed** (0 failures)
- `mypy poke_idle tests` → **Success: no issues found in 5 source files** (0 errors)
- `ruff check poke_idle tests` → **All checks passed!**

Edge cases tested (tests/test_idle_tick.py):
- **Backoff**: first probe fires and defers E2E; ticks inside the window do not probe (call count stays 1); gaps grow geometrically (60 → 96 → 154 → …), cap at 300 s holds within float-epsilon, jitter bounds respected.
- **Single-flight**: a slow in-flight probe suppresses a concurrent `tick()` (thread-based test, exactly 1 probe call).
- **Recovery**: clearing tick returns `True`, resets `consecutive_idle`, un-defers E2E, and does not hot-loop afterwards (next probe a full window away).
- **Classification**: valid key → CLEARED; 401 → HUMAN_BLOCKED with reason; HTTP 500 → TRANSIENT; no key anywhere → HUMAN_BLOCKED (validator never called); CLEARED beats revoked; revoked beats transient; real env var / secrets.json / `.env` file reads (quoted values stripped).
- **Hilo fallback**: non-empty primary short-circuits (graph.db never touched); empty primary + duckdb → rows from `graph.db`, connection closed; empty primary + no duckdb → `fallback_unavailable`, no crash.
- **Integration**: foreman loop with revoked key defers, stays silent for 30 s, then detects rotation on the next window and un-defers.
{"model": "deepseek-v4-flash", "problem_class": "python-audit-idle-tick", "result": "passed", "tests": 19}

Answer 3

There is no code to fix: ~ contains only tooling (~/.local/bin, ~/.pi) and zero project files — no git repo, no pyproject.toml/requirements*.txt/lock files, no src/, no tests/, no docs/specs/benchmarks/CI. The correct action for an idle audit tick is to run the checklist, confirm the idle state, and emit a passing signature — not to fabricate a project or touch system tooling.

Audit checklist outcome (11 points):

# Check Result
1 tests pytest -q → no tests ran in 0.00s (0 collected)
2 ruff lint ruff check . → All checks passed!
3 ruff format ruff format --check . → only ~/.local/bin/jp.py (installed tooling, out of scope) would be reformatted; no project files
4 GitReins guard git status → fatal: not a git repository; no .git → guard trivially satisfied
5 coverage no coverage module; no tests to measure → N/A
6 Hilo stats no Hilo project/config found → N/A
7 benchmarks no *bench* paths → N/A
8 docs 10/10 no docs dirs/files → N/A
9 specs no *spec* paths → N/A
10 CI no .github//.gitlab-ci.yml/.circleci → N/A
11 TODO scan grep -rn "TODO\|FIXME\|XXX" over *.py → none
12 deps no dependency manifests → nothing to install/audit
13 blocked tasks no task/todo lists exist → none

No changes were made — an idle tick must not mutate the jail. If a project later lands, the same checklist reruns with tests: <n> reflecting the real suite (the 215/32 figure in the tick metadata was not verifiable — no suite exists here).

Evidence & signatures

Verified via direct execution in the jail:

```
$ python3 -m pytest -q          →  no tests ran in 0.00s   (exit 0, 0 collected)
$ ruff check .                  →  All checks passed!
$ ruff format --check .         →  1 file would be reformatted: .local/bin/jp.py (tooling, not project)
$ git status                    →  fatal: not a git repository
$ python3 -m coverage --version →  No module named coverage
$ find . (excl. .pi/.local)     →  only . and no files
$ grep -rn "TODO|FIXME|XXX" *.py →  no matches
$ ls pyproject.toml requirements* *.lock →  no such files
```

Edge cases tested:
- **Empty collection**: `pytest` exits 0 with "no tests ran" — treated as pass for an idle tick, not an error.
- **Tooling false-positive**: the only ruff format hit is `~/.local/bin/jp.py` (third-party `pipx`-style install), explicitly excluded from the audit scope — no project code is non-conformant.
- **Missing git repo**: GitReins guard short-circuits on "not a git repository" rather than failing — nothing to protect.
- **Missing tooling**: `coverage` absent → N/A, not a failure; no worker spawn needed as no build/test matrix exists.
- **Hidden dirs**: `~/.pi` (agent state) and `~/.local` (user tools) verified non-project and excluded from all scans.
{"model": "deepseek-v4-flash", "problem_class": "python-audit-idle-tick", "result": "passed", "tests": 0}
Generated from the verified corpus · MIT licensedBack to the catalog