PR #638 follow-ups: audit_sessions.py drift-classification edges nf-eigt ← Beads

closed priority 2 task unassigned

Twinned from https://github.com/cfsh/ninefold/issues/642 by tools/beads/import_github.py's reconcile pass.

Suggestions from ninefold-reviewer's review of #638. Neither blocks that PR — it is CONVERGED — and all three are advisory.

1. UNREGISTERED fires for a workspace that can never carry a board row

audit()'s final sweep reports every interactive agent that no located row claims, and UNREGISTERED is in DRIFT_KINDS.

PR #613 (merged onto main as ae548c0, three minutes after #638 was opened) made the reviewer run each review in a per-invocation worktree: dispatch.py's _tick() does os.chdir(tree) where tree is under worktree_dir() = ~/.ninefold-reviewer/worktrees/, and the claude -p child inherits that cwd. That path is ephemeral and per-invocation, so no board row can ever resolve to it — every in-flight review would add a drift item nobody can action, which is the exact property NOTE_KINDS' own comment says disqualifies a finding from the drift count (*"nobody can act on them and a report that cries drift every run is ignored"*).

Conditional, not certain: that chdir is gated on REVIEWER_SELF_SYNC, and this reviewer invocation's own cwd is still ~/nf/agents/ninefold-reviewer (the clone), so it may not fire on this box yet. Worth deciding before it does. The SUP_CRON carve-out already recognises this session class on the *supervisor* side; the workspace-pairing side has no equivalent — a cron-supervised agent that no row claims could be a CRON-SESSION note rather than UNREGISTERED drift. Same shape as the nf-office-ef question #638's body already raises.

2. clone_path() strips the leading /, so locate()'s absolute branch is unreachable

clone_path ends with text.strip().strip("/"), so a Clone cell holding /root/nf/devs/foo yields root/nf/devs/foo. That arrives at locate() as a *relative* path, matches under no root, and the row lands silently in NOT VISIBLE FROM THIS BOX — the bucket main_clone's own docstring names as "the one bucket that looks like a legitimate answer". locate()'s if os.path.isabs(relative) branch is therefore dead for POSIX paths.

Latent today: no row on #398 writes its first backticked span absolutely. LocateTest.test_an_absolute_path_is_not_joined_onto_a_root exercises locate() directly, so the clone_pathlocate seam is the untested part.

3. _names_this_box() is defeated by an FQDN nodename

host comes from os.uname().nodename and the test is host.lower() in _plain(row.clone).lower(). A box reporting nf-dev-sg.some.domain matches no Clone cell containing nf-dev-sg, and MISPLACED — the only way a row can be *wrong* about being remote — stops firing entirely, silently. Comparing the first dot-separated label would close it.

Dependencies

None.

Comments

No comments.

Add a comment