From 57b8bf900460fab9731cb9a29e85336e715e0a0b Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 25 Aug 2026 13:17:07 +0000 Subject: [PATCH 1/4] =?UTF-8?q?prompt:=20file=20issue=20for=20inbox-board-?= =?UTF-8?q?staleness-signal=20(#58)=20=E2=86=92=20start=5Flibrary?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- active.md | 24 +++++++++++++++++ .../inbox_board_staleness_signal.md | 1 + dashboard.html | 14 +++++----- dashboard.md | 26 +++++++++---------- 4 files changed, 45 insertions(+), 20 deletions(-) rename {draft/feature/pyautomemory => active}/inbox_board_staleness_signal.md (99%) diff --git a/active.md b/active.md index fb25a1653..479c8eeb1 100644 --- a/active.md +++ b/active.md @@ -13,3 +13,27 @@ - registered: 2026-08-19 by the wake_up session — the issuing session (claude/autofit-priors-messages-audit-ylvenv) filed the prompt + issue but not this entry, tripping Lifecycle Drift on main. - repos-none-claimed: this entry claims NO repos — one line deliberately, not 2-space bullets. + +## inbox-board-staleness-signal +- issue: https://github.com/PyAutoLabs/PyAutoMemory/issues/58 +- issued: 2026-08-25 +- prompt: active/inbox_board_staleness_signal.md +- status: library-dev +- environment: web-github (no worktree — the session's clones: /home/user/pyautomemory, + /home/user/PyAutoMind) +- repos: + - PyAutoMemory: claude/inbox-board-staleness-signal-onzg34 + - PyAutoMind: claude/inbox-board-staleness-signal-onzg34 +- summary: | + Sixth in the paper-management line, split out of arxiv-inbox-pat-scope: the board's + empty arXiv inbox reads the same whether arXiv was quiet or the filing broke. + Fix is a `last digest: ` line in arxiv-inbox.md owned by inbox_actions.py + (no new state file), rendered on the board with the staleness warning computed + client-side — a render-time warning could never fire, since a broken digest means + no push and the published page freezes at its last good render. + PyAutoMind leg (beyond the prompt's stated scope, deliberate): arxiv_papers.yml must + stamp on quiet days too, or the stamp goes stale on exactly the days it should prove + were quiet. + Also clearing a pre-existing red on PyAutoMemory main — 498e1a8 added a tracked + .claude/ without adding it to ALLOWED_TOP_DIRS in validate_structure.py, so both + `make validate` and `make test` fail on arrival. diff --git a/draft/feature/pyautomemory/inbox_board_staleness_signal.md b/active/inbox_board_staleness_signal.md similarity index 99% rename from draft/feature/pyautomemory/inbox_board_staleness_signal.md rename to active/inbox_board_staleness_signal.md index 8dab29545..f6ca4c8f8 100644 --- a/draft/feature/pyautomemory/inbox_board_staleness_signal.md +++ b/active/inbox_board_staleness_signal.md @@ -9,6 +9,7 @@ Autonomy: supervised Priority: normal Status: formalised Filed: 2026-08-25 +Issued: 2026-08-25 Split out of `complete/2026/08/arxiv-inbox-pat-scope.md`, which fixed the filing bug but deliberately left this open. diff --git a/dashboard.html b/dashboard.html index bd589d400..89054631b 100644 --- a/dashboard.html +++ b/dashboard.html @@ -185,7 +185,7 @@

PyAutoMindDashboard

Intent. Priority. Flow.

Every task the Mind is holding. Tap a task's 📋 and its /start_dev command is on your clipboard — paste it into a Claude Code chat to route Claude straight to that task. Recent is the same work by date — what has been happening rather than what to do next.

- +

Last updated 2026-08-25. This page is generated from active/, draft/ and the registry files, so it is only as current as they are. dashboard_refresh.yml re-renders it on every push to main — that heals a stale page, but not a stale prompt: a task that shipped without its prompt advancing to complete/ keeps rendering here as pickable backlog. Reconciling those is the refresh below.

@PyAutoFit TransformedMessage.factor_gradient crashes on first call — issue #1501 — issued 2026-08-19 — HOLD — do not start dev. Fix-or-delete hangs off the PyAutoFit#1498 logpdf-contract

+

Parked markdown version

3 task(s) @@ -251,16 +252,15 @@

Planned

latent-nan-guard-honest-run — planned 2026-07-22

Backlog markdown version

-

141 filed prompts, not started — sorted most-pickable first (priority, then size). 25 of them belong to an epic and are listed only under Epics below.

+

140 filed prompts, not started — sorted most-pickable first (priority, then size). 25 of them belong to an epic and are listed only under Epics below.

-feature — 28 +feature — 27

Give PyAutoFit searches a seed — today no search can be made…✨ featureautofitmediumsupervisedmedium

Brain board follow-ups: what real mornings surface✨ featurepyautobrainsmallsupervisednormal

-

The knowledge board's empty inbox should distinguish quiet from broken✨ featurepyautomemorysmallsupervisednormal

Can create a list of InversionMatrix objects for each dataset✨ featureautoarraymediumsupervisednormal

Tune cluster-scale JOSS benchmarks toward their 5-minute targets✨ featureautolens_workspacemediumsupervisednormal

Token-light wiki index over the complete/ archive✨ featurepyautomindmediumsupervisednormal

@@ -400,9 +400,9 @@

Backlog 2026-08-25 -filed -The knowledge board's empty inbox should distinguish quiet from broken - +issued +The knowledge board's empty inbox should distinguish quiet from broken + 2026-08-24 diff --git a/dashboard.md b/dashboard.md index 3c755e37d..ddabb5c35 100644 --- a/dashboard.md +++ b/dashboard.md @@ -42,10 +42,10 @@ anything you could not verify. | Where | Count | |-------|------:| -| [In flight](#in-flight) (`active/`) | 1 | +| [In flight](#in-flight) (`active/`) | 2 | | [Parked](#parked) (`parked.md`) | 3 | | [Planned](#planned) (`planned.md`) | 5 | -| [Backlog](#backlog) (`draft/`) | 141 | +| [Backlog](#backlog) (`draft/`) | 140 | ## Start here @@ -177,6 +177,14 @@ Issued — each has an open GitHub issue and usually a branch. The full record f

+
📋 The knowledge board's empty inbox should distinguish quiet from broken — issue #58 — issued 2026-08-25 — library-dev + +``` +/start_dev active/inbox_board_staleness_signal.md +``` + +
+ ## Parked Started or scoped, not currently in flight — resume by moving the row back to `active.md`. Full detail in [`parked.md`](parked.md). @@ -261,10 +269,10 @@ Scoped but not started; some are not yet prompt files. Full detail in [`planned. ## Backlog -**141** filed prompts, not started. Each section is sorted most-pickable first (priority, then size). **25** of them belong to an epic and are listed only under [Epics](#epics) below. +**140** filed prompts, not started. Each section is sorted most-pickable first (priority, then size). **25** of them belong to an epic and are listed only under [Epics](#epics) below.
-feature — 28 +feature — 27
📋 Numba CPU likelihood phase 1: batched MGE convolution + operated-matrix caching — autoarray · medium · supervised · high @@ -314,14 +322,6 @@ Scoped but not started; some are not yet prompt files. Full detail in [`planned.
-
📋 The knowledge board's empty inbox should distinguish quiet from broken — pyautomemory · small · supervised · normal - -``` -/start_dev draft/feature/pyautomemory/inbox_board_staleness_signal.md -``` - -
-
📋 Can create a list of InversionMatrix objects for each dataset — autoarray · medium · supervised · normal ``` @@ -1242,7 +1242,7 @@ The 50 newest things to happen to the work in hand, newest first — issued, par | Date | Event | Task | |------|-------|------| -| 2026-08-25 | filed | The knowledge board's empty inbox should distinguish quiet from broken | +| 2026-08-25 | issued | The knowledge board's empty inbox should distinguish quiet from broken | | 2026-08-24 | filed | wiki-currency's --check-version gate rots on every library main merge | | 2026-08-24 | filed | interferometer/jax_grad/gradient.py: eager and jitted likelihoods… | | 2026-08-24 | filed | euclid: CRLF has reached the HPC submit scripts AGENTS.md warns about | From 1bc6a47aa48f1414bd1084c37f444e2369838e43 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 25 Aug 2026 13:25:05 +0000 Subject: [PATCH 2/4] feat: stamp the Memory inbox on quiet days, not just paper days MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The board half of PyAutoMemory#58 reads a `last digest: ` line to tell a quiet inbox from a broken one. That line is only worth anything if the digest writes it on days with nothing to file — otherwise it goes stale on exactly the days it exists to prove were quiet, and says "broken" about a working run. So the inbox step loses its `count != 0` guard and runs every weekday. To keep its preconditions honest, the empty-day heartbeat step now also writes arxiv_survivors.json as {"papers": []} — the same file the Claude step already writes on its own no-papers day. Every path produces one, so a MISSING survivors file in the inbox step stays what it has always been: a real failure, not an empty day. The step's other invariants are untouched. It still runs after the Slack POST, so a cross-repo auth or push failure cannot cost the morning's post; the missing-survivors and unset-PAT preconditions still warn and exit 0; a denied push still reddens the run (PR #317). Two consequences worth naming: - a quiet day is now a one-line commit to PyAutoMemory rather than silence, which also re-renders the knowledge board daily. That is the point — it is the board's version of the #papers empty-day heartbeat. - the sweep now runs every weekday too, so a lapsed line no longer lingers through a quiet stretch waiting for the next paper day to evict it. Re-running the same day is still a no-op: the stamp is unchanged, the porcelain check sees nothing, and the step exits without a commit. Validated: YAML parses, every run block passes bash -n, and all four paths were rehearsed against a real PyAutoMemory checkout with the two shell blocks extracted verbatim from this file — quiet day same date (no commit), quiet day new date (heartbeat commit), paper day (paper lands below the stamp), and a quiet day sweeping lapsed papers. NOT fired live: claude-code-action refuses to run when this file differs from the default branch's copy and then exits success, so no branch dispatch can reach these steps. The scheduled run on main is the first genuine exercise. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Ex9YARe5kDjsT3Ug7LKQ1r --- .github/workflows/arxiv_papers.yml | 31 ++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/.github/workflows/arxiv_papers.yml b/.github/workflows/arxiv_papers.yml index 2feae5e17..eade35661 100644 --- a/.github/workflows/arxiv_papers.yml +++ b/.github/workflows/arxiv_papers.yml @@ -14,7 +14,11 @@ name: pyauto-arxiv-papers # 4–5 sentence summary, then a compact list of the rest. # Cadence: weekday mornings. Empty days STILL post a short "no new strong- # lensing papers today" heartbeat (user, 2026-07-13) — so silence in #papers -# always means a broken run, never a genuinely empty one. +# always means a broken run, never a genuinely empty one. The Memory inbox step +# at the bottom carries the same invariant onto the knowledge board: it runs on +# every weekday and stamps `last digest: ` even with nothing to file, so +# an empty board is a quiet day and a stale one is a broken run +# (PyAutoMemory#58). # # Timing: arXiv announces new astro-ph at 20:00 US Eastern, Sun–Thu, which is # ~01:00 UK (00:00 UTC in summer / 01:00 UTC in winter) — the papers are live in @@ -101,6 +105,12 @@ jobs: # spend no subscription usage, but still write the heartbeat payload so # the POST step below has something to send. uk_date is read from # arxiv_papers.json, which the fetch always writes even at count=0. + # + # It also writes an EMPTY arxiv_survivors.json — the same file the + # Claude step writes on its own no-papers day. Every path therefore + # produces one, so the inbox step below can run unconditionally and + # stamp the quiet day, and a MISSING survivors file there stays what it + # has always been: a real failure, not an empty day. if: ${{ steps.fetch.outputs.count == '0' }} run: | set -euo pipefail @@ -120,6 +130,8 @@ jobs: } with open("slack_payload.json", "w") as f: json.dump(payload, f, indent=2) + with open("arxiv_survivors.json", "w") as f: + json.dump({"papers": []}, f) print(f"Wrote no-papers heartbeat for {uk_date}.") PY @@ -291,6 +303,14 @@ jobs: # knowledge board renders them with one-tap add / intake / cite / dismiss # buttons and un-acted lines lapse after a week. # + # It runs on EVERY weekday, including days with nothing to file, because + # it also writes the inbox's `last digest: ` stamp — the board's + # equivalent of the #papers empty-day heartbeat. Without a stamp on quiet + # days the board cannot tell "arXiv was quiet" from "the filing broke and + # the papers were lost", which is the exact ambiguity that hid the + # 2026-08-25 PAT failure (PyAutoMemory#58). A quiet day is therefore a + # one-line commit, not silence. + # # This DELIBERATELY reverses the original "the digest never commits" # constraint (PyAutoMemory#35): the human gate moved from "paste the # block into a session" to "tap a button on the board", it did not go @@ -306,7 +326,6 @@ jobs: # all live in PyAutoMemory's scripts/inbox_actions.py — this step only # supplies the papers, so the line format is never re-expressed here. - name: File the survivors into the PyAutoMemory arXiv inbox - if: ${{ steps.fetch.outputs.count != '0' }} env: PAT: ${{ secrets.PAT_PYAUTOLABS }} run: | @@ -332,9 +351,13 @@ jobs: # reading queue, so a re-run (or a paper announced twice) adds nothing. added=$(python3 scripts/inbox_actions.py append \ --papers-file arxiv_survivors.json) + # Unconditional, and the whole reason this step no longer skips empty + # days: it records that the digest ran at all. inbox_actions.py owns + # the line, so the format is never re-expressed here. + stamped=$(python3 scripts/inbox_actions.py stamp) swept=$(python3 scripts/inbox_actions.py sweep) rm arxiv_survivors.json - echo "inbox: ${added}, ${swept}" + echo "inbox: ${added}, ${swept}, ${stamped}" if [ -z "$(git status --porcelain -- arxiv-inbox.md)" ]; then echo "inbox unchanged — nothing to commit." @@ -343,7 +366,7 @@ jobs: git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" git add arxiv-inbox.md - git commit -m "inbox: ${added}, ${swept} (arXiv digest ${uk_date})" + git commit -m "inbox: ${added}, ${swept}, ${stamped} (arXiv digest ${uk_date})" # The retry is for a concurrent-push race — the knowledge board and the # queue-action workflows commit to this same repo — so a rejected push # is worth a rebase and another go. An auth failure is NOT that: the From 7b9ab3f43ea5f910e161ff9e99db082122b6565d Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 25 Aug 2026 13:25:38 +0000 Subject: [PATCH 3/4] prompt: inbox-board-staleness-signal (#58) implemented + pushed, ready to ship --- active.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/active.md b/active.md index 479c8eeb1..372fc9e99 100644 --- a/active.md +++ b/active.md @@ -18,7 +18,7 @@ - issue: https://github.com/PyAutoLabs/PyAutoMemory/issues/58 - issued: 2026-08-25 - prompt: active/inbox_board_staleness_signal.md -- status: library-dev +- status: ready-to-ship — both legs implemented, tested and pushed; no PR opened yet - environment: web-github (no worktree — the session's clones: /home/user/pyautomemory, /home/user/PyAutoMind) - repos: @@ -37,3 +37,12 @@ Also clearing a pre-existing red on PyAutoMemory main — 498e1a8 added a tracked .claude/ without adding it to ALLOWED_TOP_DIRS in validate_structure.py, so both `make validate` and `make test` fail on arrival. + Done: PyAutoMemory 05aa803 (the allowlist red, separate commit) + a4c5b64 (stamp, + board, 23 new tests — 92 green, make validate green); PyAutoMind 1bc6a47a (the + workflow leg; YAML parses, every run block passes bash -n, 197 tests green). + All four digest paths rehearsed against a real PyAutoMemory checkout with the + shell blocks extracted verbatim from the workflow, and the shipped freshness JS + cross-checked against the Python over 30 consecutive stamp dates. + NOT fired live: claude-code-action refuses to run when arxiv_papers.yml differs + from the default branch's copy and then exits success, so no branch dispatch can + reach those steps — the scheduled run on main is the first genuine exercise. From cf30b8e74530f8dbce6437017b01b6431c7edc32 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 25 Aug 2026 13:31:15 +0000 Subject: [PATCH 4/4] mind: regenerate the dashboard after the active.md status update 7b9ab3f4 moved this task's active.md entry to ready-to-ship without regenerating the generated pages, so dashboard_refresh.yml reddened the PR. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Ex9YARe5kDjsT3Ug7LKQ1r --- dashboard.html | 2 +- dashboard.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dashboard.html b/dashboard.html index 89054631b..8a74e1fba 100644 --- a/dashboard.html +++ b/dashboard.html @@ -234,7 +234,7 @@

Quick wins (small enough, and safe enough to run unatte

In flight markdown version

Issued — each has an open GitHub issue and usually a branch.

@PyAutoFit TransformedMessage.factor_gradient crashes on first call — issue #1501 — issued 2026-08-19 — HOLD — do not start dev. Fix-or-delete hangs off the PyAutoFit#1498 logpdf-contract

- +

The knowledge board's empty inbox should distinguish quiet from broken — issue #58 — issued 2026-08-25 — ready-to-ship — both legs implemented, tested and pushed; no PR opened yet

Parked markdown version

3 task(s) diff --git a/dashboard.md b/dashboard.md index ddabb5c35..13a29ad29 100644 --- a/dashboard.md +++ b/dashboard.md @@ -177,7 +177,7 @@ Issued — each has an open GitHub issue and usually a branch. The full record f
-
📋 The knowledge board's empty inbox should distinguish quiet from broken — issue #58 — issued 2026-08-25 — library-dev +
📋 The knowledge board's empty inbox should distinguish quiet from broken — issue #58 — issued 2026-08-25 — ready-to-ship — both legs implemented, tested and pushed; no PR opened yet ``` /start_dev active/inbox_board_staleness_signal.md