From 242a6d96599d0d5fe76d09c5d65f7714501a9719 Mon Sep 17 00:00:00 2001 From: autonomic-bot Date: Mon, 10 Aug 2026 15:41:48 +0000 Subject: [PATCH] report: clear+re-pin the session id at launch (fixes un-watchdogged report runs) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Regression from the 2026-08-04 session-pinning work: lu._session_id() prefers the pin file, but launch-report.py never cleared or re-established it. A surviving pin from a PREVIOUS report run points at a session whose last message already carries RECIPE REPORT COMPLETE, so the shared watchdog evaluates _completed()=True and exits within one poll ('run completed — exiting'), leaving the CURRENT run unwatched. Observed live: the 2026-08-07 finish-run's report step was watched by a watchdog that quit after 3 minutes against an Aug-4 pin, then the report session ended early with nothing to resume it. start() now archives stale titles, clears the pin, snapshots existing ids, and re-pins the new session after launch — the same contract launch-upgrader.start() already follows. Scopes the shared helpers via UPGRADER_SESSION=. --- cc-ci-plan/launch-report.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/cc-ci-plan/launch-report.py b/cc-ci-plan/launch-report.py index 0f9bf7f..3b9b9cd 100755 --- a/cc-ci-plan/launch-report.py +++ b/cc-ci-plan/launch-report.py @@ -73,14 +73,30 @@ def start(mode, date): # Unique-name invariant (same as upgrader/supervisor): archive-rename every older session # titled SESSION so the one this launch creates is the ONLY 'cc-ci-report' in the web UI. # Archived names start with 'archive-' (operator convention 2026-08-04). + # + # AND clear the stale session PIN. The pin file is what the shared watchdog resolves via + # lu._session_id(); if a PREVIOUS run's pin survives, the watchdog inspects that old (already + # DONE_MARKER-bearing) session, declares "run completed" and exits within one poll — leaving + # the new run unwatched. That regression silently un-watchdogged the 2026-08-07 finish-run's + # report step (pin dated 2026-08-04). The pin is re-established after launch, below. + _lu = None + _prev_ids = set() try: + os.environ["UPGRADER_SESSION"] = SESSION # scope the shared helpers to THIS session name import importlib.util as _ilu _spec = _ilu.spec_from_file_location( "launch_upgrader", os.path.join(os.path.dirname(os.path.realpath(__file__)), "launch-upgrader.py")) _lu = _ilu.module_from_spec(_spec); _spec.loader.exec_module(_lu) _lu._archive_stale_titles(SESSION) + _rows = _lu._server_get("/session") or [] + _rows = _rows if isinstance(_rows, list) else _rows.get("data", []) + _prev_ids = {s.get("id") for s in _rows} + try: + _lu.STATE_SID_FILE.unlink() + except OSError: + pass except Exception as e: - log(f" (archive-rename skipped: {e})") + log(f" (archive-rename/pin-clear skipped: {e})") kf = Path(LOG_DIR) / f".kickoff-{SESSION}.txt" kf.write_text(build_kickoff(date)) @@ -102,6 +118,10 @@ def start(mode, date): log(f"starting {SESSION} (backend={BACKEND}, tier={TIER}, model={MODEL}, date={date or 'today'})") subprocess.run(["tmux", "new-session", "-d", "-s", SESSION, "-c", cwd, cmd]) subprocess.run(["tmux", "pipe-pane", "-o", "-t", SESSION, f"cat >> '{LOG_DIR}/{SESSION}.log'"]) + if BACKEND == "opencode" and _lu is not None: + # Re-establish the pin on THIS run's session, so the watchdog (spawned below) resolves the + # new session rather than falling back to a title lookup or a stale pin. + _lu._pin_new_session(_prev_ids) if BACKEND == "opencode": if OPENCODE_SHARE: log(f" attached to {OPENCODE_SERVER} → http://oc.commoninternet.net +public --share link")