Overview
The PyAutoMemory Dashboard shows per-section reading-queue counts only — there is no route from the board to an individual paper's page, and no per-paper action. This task grows the board into a real paper-management surface: browse every queued paper, link out to read it, and act on it with one-tap prefilled GitHub issue buttons — "read, don't file" (auto-marked DONE by a small Action) and "intake into memory" (the issue becomes the filing work item). Human-gated throughout: nothing changes state until the human submits the prefilled issue on GitHub.
Plan
- Parse individual papers (title, optional
— <arXiv id/URL> ref, DONE state) in board.py's queue collector.
- Dashboard lists each waiting paper under collapsible per-section blocks; titles link to the arXiv abstract page (ref present) or an arXiv title-search (bare title — today ~all 230 lines are bare).
- Two prefilled-issue action buttons per paper: ✅ read — don't file (label
queue-read) and 📥 intake into memory (label queue-intake).
- New
queue_actions.yml + scripts/queue_mark_done.py: for owner/collaborator-authored queue-read issues, prefix the queue line with DONE <date> — , commit (explicit-path staging), close the issue. Public repo → strangers' issues must never mutate the queue.
queue-intake issues stay open as filing work items (body carries the file-this-paper prompt); claude-action wiring can come later.
- Markdown render gets the same per-paper links; tests and the spawn DROP rule updated.
Detailed implementation plan
Affected Repositories
- PyAutoMemory (primary)
- PyAutoMind (one mechanical edit: spawn DROP rule)
Branch Survey
| Repository |
Current Branch |
Dirty? |
| ./PyAutoMemory |
main (synced) |
clean |
| ./PyAutoMind |
main (synced) |
clean |
Suggested branch: feature/dashboard-per-paper-actions
Worktree: ~/Code/PyAutoLabs-wt/dashboard-per-paper-actions/
Implementation Steps
scripts/board.py — collect(): queue loop returns papers: [{title, ref, done, done_date}] per section. Regexes: ^DONE (\d{4}-\d{2}-\d{2}) — (.*)$ for read lines; trailing — <ref> split where ref is an arXiv id (\d{4}\.\d{4,5}) or URL. Stays stdlib-only, fully local-parse.
scripts/board.py — new pure helpers: _paper_url(ref, title) → https://arxiv.org/abs/<id> / the URL as-is / https://arxiv.org/search/?searchtype=title&query=<quoted> fallback (urllib.parse.quote); _issue_link(...) → https://github.com/{owner}/{repo}/issues/new?title=…&body=…&labels=…. Issue bodies carry the section header + exact queue line (robust matching), and the intake body embeds the existing _read_prompt workflow specialised to that title. Repo identity keeps deriving from the git remote (spawn-template portability).
_render_html() — each queue section row becomes a <details> block: summary keeps the current Section — N waiting · M read text + the existing section 📋 (badge and headline text untouched — badge messages are a cross-board API); body lists waiting papers (linked title + the two action buttons), with DONE papers in a nested collapsed reading-history block.
_render_md() — same per-paper lists via <details> (GitHub renders these in markdown); --json includes the papers (titles/counts are the pinned privacy level — never claim text).
- New
.github/workflows/queue_actions.yml — on: issues: [opened]; job gated on label queue-read AND github.event.issue.author_association ∈ {OWNER, MEMBER, COLLABORATOR}; permissions: contents: write, issues: write; concurrency-serialised; runs scripts/queue_mark_done.py, commits reading-queue.md only (explicit path staging — never add -A), comments + closes the issue; on no-match comments and leaves the issue open.
- New
scripts/queue_mark_done.py — stdlib-only pure text transform: locate the exact title line in its section, prefix DONE <YYYY-MM-DD> — ; idempotent when already DONE.
tests/test_board.py — fixture queue gains a ref'd paper + a DONE line; pin the per-paper snapshot shape, both link forms, issue-link labels; privacy test still pins titles/counts only. New unit test for queue_mark_done.
PyAutoMind/scripts/spawn.py — add (".github/workflows/queue_actions.yml", "DROP") beside the knowledge_board.yml DROP (instance workflows break the fresh-repo invariant).
- Ship-time one-offs:
gh label create queue-read / queue-intake on PyAutoLabs/PyAutoMemory.
Key Files
PyAutoMemory/scripts/board.py — collector + all four renders
PyAutoMemory/reading-queue.md — format unchanged (already ## sections + DONE <date> — prefix)
PyAutoMemory/.github/workflows/queue_actions.yml — new issue-label Action
PyAutoMemory/scripts/queue_mark_done.py — new mark-DONE transform
PyAutoMemory/tests/test_board.py — pins
PyAutoMind/scripts/spawn.py — DROP rule
Testing
make validate + pytest tests/ in PyAutoMemory; render --html/--md/--json locally and eyeball the page; verify an issue link round-trips through queue_mark_done.py on a fixture queue.
Original Prompt
Click to expand starting prompt
Memory dashboard: per-paper browsing + one-tap read/intake actions
Type: feature
Target: pyautomemory
Repos:
- PyAutoMemory
Difficulty: medium
Autonomy: supervised
Priority: normal
Status: draft
Follow-up to the paper-management pipeline
(complete/2026/08/paper-management-pipeline.md, Memory #35/PR#37) and the
knowledge board (#32/PR#33). The dashboard at
https://pyautolabs.github.io/PyAutoMemory/ shows per-section waiting/read
counts only; the human wants to browse and act on the individual papers.
Original request (verbatim)
We did work on dashboards recently, the PyAutoMemory dashboard says how many
papers need reading but does not provide an easy route to getting to their
page to read them or go through the indviidual papers. There is a claude
copy button but ideally it'd allow me to nevigate through them all, I guess
each would have a claude copy button to say ive read them
doesn't even need to be a claude copy button I could imagine a button which
either says to intake it into memory or ive read it but i dont want it
added?
Agreed design (human chose: prefilled GitHub issues)
scripts/board.py (html render): expand each reading-queue section into a
collapsible per-paper list (<details> per section; 230 waiting papers must
stay navigable, DONE papers stay out of the way or in a collapsed history).
- Each paper title links out: arXiv abstract page when the queue line carries
— <arXiv id or URL>, otherwise an arXiv title-search link.
- Two action buttons per paper, both prefilled GitHub issue links
(issues/new?title=…&body=…&labels=…) so nothing changes state until the
human taps Submit on GitHub (human-gated, works from phone, no secrets in
the static page):
- "Read — don't file" → issue labelled for a small new Action in
PyAutoMemory that mechanically prefixes the queue line with
DONE <YYYY-MM-DD> — , commits, closes the issue.
- "Intake into memory" → issue stays open as the filing work item
(bibliography entry + wiki stub is agent work; claude-action wiring can
come later).
- Markdown render (
_site/dashboard.md) grows the same per-paper links in
plain form.
- Constraints: board.py stays stdlib-only and fully local-parse; contents
privacy pin is titles/counts only (already satisfied — titles are pinned as
allowed); validate_structure.py bans committed .html; the issue-label
Action must respect the never-rewrite-history and explicit-path-staging
rules; board.py travels into spawn templates, so it must keep deriving repo
identity from the checkout/git remote (issue-link URLs included).
Overview
The PyAutoMemory Dashboard shows per-section reading-queue counts only — there is no route from the board to an individual paper's page, and no per-paper action. This task grows the board into a real paper-management surface: browse every queued paper, link out to read it, and act on it with one-tap prefilled GitHub issue buttons — "read, don't file" (auto-marked DONE by a small Action) and "intake into memory" (the issue becomes the filing work item). Human-gated throughout: nothing changes state until the human submits the prefilled issue on GitHub.
Plan
— <arXiv id/URL>ref, DONE state) inboard.py's queue collector.queue-read) and 📥 intake into memory (labelqueue-intake).queue_actions.yml+scripts/queue_mark_done.py: for owner/collaborator-authoredqueue-readissues, prefix the queue line withDONE <date> —, commit (explicit-path staging), close the issue. Public repo → strangers' issues must never mutate the queue.queue-intakeissues stay open as filing work items (body carries the file-this-paper prompt); claude-action wiring can come later.Detailed implementation plan
Affected Repositories
Branch Survey
Suggested branch:
feature/dashboard-per-paper-actionsWorktree:
~/Code/PyAutoLabs-wt/dashboard-per-paper-actions/Implementation Steps
scripts/board.py—collect(): queue loop returnspapers: [{title, ref, done, done_date}]per section. Regexes:^DONE (\d{4}-\d{2}-\d{2}) — (.*)$for read lines; trailing— <ref>split where ref is an arXiv id (\d{4}\.\d{4,5}) or URL. Stays stdlib-only, fully local-parse.scripts/board.py— new pure helpers:_paper_url(ref, title)→https://arxiv.org/abs/<id>/ the URL as-is /https://arxiv.org/search/?searchtype=title&query=<quoted>fallback (urllib.parse.quote);_issue_link(...)→https://github.com/{owner}/{repo}/issues/new?title=…&body=…&labels=…. Issue bodies carry the section header + exact queue line (robust matching), and the intake body embeds the existing_read_promptworkflow specialised to that title. Repo identity keeps deriving from the git remote (spawn-template portability)._render_html()— each queue section row becomes a<details>block: summary keeps the currentSection — N waiting · M readtext + the existing section 📋 (badge and headline text untouched — badge messages are a cross-board API); body lists waiting papers (linked title + the two action buttons), with DONE papers in a nested collapsed reading-history block._render_md()— same per-paper lists via<details>(GitHub renders these in markdown);--jsonincludes the papers (titles/counts are the pinned privacy level — never claim text)..github/workflows/queue_actions.yml—on: issues: [opened]; job gated on labelqueue-readANDgithub.event.issue.author_association∈ {OWNER, MEMBER, COLLABORATOR};permissions: contents: write, issues: write; concurrency-serialised; runsscripts/queue_mark_done.py, commitsreading-queue.mdonly (explicit path staging — neveradd -A), comments + closes the issue; on no-match comments and leaves the issue open.scripts/queue_mark_done.py— stdlib-only pure text transform: locate the exact title line in its section, prefixDONE <YYYY-MM-DD> —; idempotent when already DONE.tests/test_board.py— fixture queue gains a ref'd paper + a DONE line; pin the per-paper snapshot shape, both link forms, issue-link labels; privacy test still pins titles/counts only. New unit test forqueue_mark_done.PyAutoMind/scripts/spawn.py— add(".github/workflows/queue_actions.yml", "DROP")beside theknowledge_board.ymlDROP (instance workflows break the fresh-repo invariant).gh label create queue-read/queue-intakeon PyAutoLabs/PyAutoMemory.Key Files
PyAutoMemory/scripts/board.py— collector + all four rendersPyAutoMemory/reading-queue.md— format unchanged (already##sections +DONE <date> —prefix)PyAutoMemory/.github/workflows/queue_actions.yml— new issue-label ActionPyAutoMemory/scripts/queue_mark_done.py— new mark-DONE transformPyAutoMemory/tests/test_board.py— pinsPyAutoMind/scripts/spawn.py— DROP ruleTesting
make validate+pytest tests/in PyAutoMemory; render--html/--md/--jsonlocally and eyeball the page; verify an issue link round-trips throughqueue_mark_done.pyon a fixture queue.Original Prompt
Click to expand starting prompt
Memory dashboard: per-paper browsing + one-tap read/intake actions
Type: feature
Target: pyautomemory
Repos:
Difficulty: medium
Autonomy: supervised
Priority: normal
Status: draft
Follow-up to the paper-management pipeline
(
complete/2026/08/paper-management-pipeline.md, Memory #35/PR#37) and theknowledge board (#32/PR#33). The dashboard at
https://pyautolabs.github.io/PyAutoMemory/ shows per-section waiting/read
counts only; the human wants to browse and act on the individual papers.
Original request (verbatim)
Agreed design (human chose: prefilled GitHub issues)
scripts/board.py(html render): expand each reading-queue section into acollapsible per-paper list (
<details>per section; 230 waiting papers muststay navigable, DONE papers stay out of the way or in a collapsed history).
— <arXiv id or URL>, otherwise an arXiv title-search link.(
issues/new?title=…&body=…&labels=…) so nothing changes state until thehuman taps Submit on GitHub (human-gated, works from phone, no secrets in
the static page):
PyAutoMemory that mechanically prefixes the queue line with
DONE <YYYY-MM-DD> —, commits, closes the issue.(bibliography entry + wiki stub is agent work; claude-action wiring can
come later).
_site/dashboard.md) grows the same per-paper links inplain form.
privacy pin is titles/counts only (already satisfied — titles are pinned as
allowed);
validate_structure.pybans committed.html; the issue-labelAction must respect the never-rewrite-history and explicit-path-staging
rules; board.py travels into spawn templates, so it must keep deriving repo
identity from the checkout/git remote (issue-link URLs included).