Skip to content

Fix all 12 verified defects from the second systematic bug scan - #47

Merged
hsliuustc0106 merged 2 commits into
mainfrom
fix/issue-45-scan2-fixes
Oct 3, 2026
Merged

hsliuustc0106 merged 2 commits into
mainfrom
fix/issue-45-scan2-fixes

Conversation

@hsliuustc0106

Copy link
Copy Markdown
Contributor

Fixes #45 — all 12 verified defects from the second systematic bug scan (decision log #36, teardown registry #37/#39, npm packaging #30/#41, DSH admission discipline).

Branch is rebased on current main (63d2f13, includes #41/#43).

Medium fixes

  1. Bounded per-poll decision history (core/runner.py, core/activity.py) — each task keeps its most recent OBSERVATION_RETENTION (20) check-observed entries, pruned after each record; decisions and delivery records are never pruned. A (task_id, kind, at) index keeps the excluded-kind queries (watch list, activity) on-index. Replaces the unbounded ~1.2MB/day/task growth; the design doc now records the retention policy.
  2. Activity-write isolation on all paths (core/runner.py) — _block and _schedule_retry now use the isolation-guarded record: a failing append no longer swallows the BLOCKED notification/state, and no longer double-counts consecutive_failures through the daemon.
  3. Inbox connection registered + failure-path unwinds (cli.py) — NativeNotifier.close joins the teardown registry (inbox-sink, reverse order preserved); registration happens per-resource as it is created, so a mid-wiring failure (e.g. provider setup raising) unwinds everything already opened; an outer idempotent unwind covers lease-entry failures.
  4. Record before egress (core/runner.py) — each event is recorded (carrying the occurrence identity the sink dedups on) before the optional summary request, and the supersession check precedes recording. Egress can no longer outrun the log (discipline 3); a run superseded during summarizing suppresses delivery but keeps the record of what the provider saw.
  5. No re-forwarded SIGINT (bin/nanodot.cjs) — the launcher swallows its own group-delivered SIGINT (the CLI already received it) instead of sending a second one that aborted the graceful teardown; SIGTERM forwarding is unchanged.

Low fixes

teardown.run() catches BaseException per step (a mid-unwind Ctrl-C costs one step, never the remaining stores); Python is probed in the caller environment instead of -I isolated mode (stray PYTHONHOME now fails probing with a clean message); the package-smoke allowlist permits the LICENSE npm always includes; discipline 3 is scoped to system-derived fields with --intent as the documented exception; README names tar as a setup requirement.

Verification

  • 552 pytest tests pass (546 baseline + 6 new: retention bounds, block/retry isolation, egress-after-record with a cancel-during-summarize provider, replay identity, BaseException unwind, wiring-failure unwind).
  • npm launcher tests 12/12 (2 new: a group-delivered SIGINT reaches the CLI exactly once via a detached process group; a broken-env interpreter fails probing cleanly). The fake-python discriminator moved from the -I flag to the probe's code string, rebased onto npm launcher: pin uv download integrity (no unpinned remote shell) #41/Verify uv download integrity; stop executing a downloaded script (#41) #43's fixture.
  • One pre-existing test updated for the deliberate contract change: a run superseded during summarizing now keeps its activity entries (egress already happened — the log must reconstruct it) while notification and the task write stay suppressed.
  • Package smoke and the first_pr_watch e2e demo pass.

Medium:
- Bound the per-poll decision history: keep the most recent
  OBSERVATION_RETENTION (20) check-observed entries per task, pruned
  after each record; decisions and delivery records are never pruned, and
  a (task_id, kind, at) index keeps the excluded-kind queries on-index
  (runner, activity)
- Apply activity-write isolation to the blocked/retry paths too: a
  failing append no longer swallows the BLOCKED notification/state or
  double-counts consecutive failures via the daemon (runner)
- Register the inbox sink's SQLite connection with the teardown registry,
  and register every resource as it is created so a mid-wiring failure
  still unwinds what already opened; the unwind also runs when lease
  entry itself fails (cli)
- Record before egress: an event is logged (with its occurrence
  identity) before the optional summary request, so nothing reaches a
  provider that the log cannot reconstruct (adapter-seam discipline 3);
  a run superseded while summarizing suppresses delivery, not the record
  (runner)
- Stop re-forwarding the terminal's group-delivered SIGINT from the npm
  launcher: the child already received it, and the second interrupt was
  aborting the graceful teardown (bin/nanodot.cjs)

Low:
- Teardown.run catches BaseException per step so a mid-unwind interrupt
  costs one step, never the remaining stores (teardown)
- Probe Python in the caller environment (not isolated mode): an
  interpreter broken by a stray PYTHONHOME now fails probing with a
  clean nanodot message instead of a raw fatal on every command
  (bin/nanodot.cjs)
- Package smoke allowlist permits the LICENSE file npm always includes
  (npm-tests)
- Discipline 3 wording scoped to system-derived fields, with the
  --intent sentence as the documented exception (adapter-seam.md)
- README names tar as a setup requirement alongside curl; decision-log.md
  documents the retention policy and replay identity (docs)

552 pytest tests pass (6 new); npm launcher tests 12/12 (2 new, one
rebased onto #41's fixture); package smoke and the e2e demo pass.
The bootstrap smoke intercepted the launcher's Python probes by their -I
flag; the probe now runs in the caller environment (#45 fix 9), so hide
the probe by its sys.version_info gate instead.
@hsliuustc0106
hsliuustc0106 merged commit 711b45c into main Oct 3, 2026
6 checks passed
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.

Bug scan 2: 5 medium / 7 low verified defects in decision log, teardown registry, npm packaging

1 participant