From d3a67ea763339f7f83e39aac3940158fe566469d Mon Sep 17 00:00:00 2001 From: Jammy2211 Date: Thu, 16 Jul 2026 09:50:42 +0100 Subject: [PATCH] refactor: read/write Mind completions via complete/ records (PyAutoLabs/PyAutoMind#81) - ship_library/ship_workspace: completion = draft rich body -> lifecycle.py record --from-file + index --apply + drop the active.md entry (no ledger append) - memory faculty digests complete/**/*.md records (excl. archive/index/AGENTS) instead of the retired complete.md - intake reconcile cross-refs record contents + H2 headers; census/docs wording - WORKFLOW.md, register_and_iterate, health, ORGANISM.md, organ docs updated Co-Authored-By: Claude Fable 5 --- AGENTS.md | 2 +- ORGANISM.md | 2 +- agents/conductors/intake/AGENTS.md | 4 +-- agents/conductors/intake/INTAKE_TAXONOMY.md | 2 +- agents/conductors/intake/_intake.py | 29 +++++++++++-------- agents/conductors/intake/intake.sh | 2 +- agents/faculties/memory/AGENTS.md | 8 ++--- agents/faculties/memory/_memory.py | 14 +++++++-- agents/faculties/memory/memory.sh | 2 +- docs/concepts/workflow.md | 6 ++-- docs/example.md | 2 +- docs/organs/memory.md | 2 +- docs/organs/mind.md | 4 +-- skills/WORKFLOW.md | 15 +++++----- skills/health/health.md | 2 +- skills/intake/intake.md | 2 +- .../register_and_iterate.md | 4 +-- skills/ship_library/reference.md | 20 ++++++------- skills/ship_library/ship_library.md | 5 ++-- skills/ship_workspace/reference.md | 16 +++++----- skills/ship_workspace/ship_workspace.md | 5 ++-- 21 files changed, 83 insertions(+), 65 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 3fa3628..a0918b8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -182,7 +182,7 @@ humans invoke identically, so behaviour isn't re-derived from prose each time. - **`agents/faculties/memory/`** — *recalls what the organism knows*: given a topic, returns a **cited digest** (ranked pages + snippets) over PyAutoMemory's sub-wikis, `autolens_assistant`'s skills/wiki, and Mind's - `complete.md` history. Grep-ranked at query time — no indexes, no layout + `complete/` records. Grep-ranked at query time — no indexes, no layout coupling, never a page dump; an empty digest is the honest answer. Privacy seam: PyAutoMemory citations never reach public user-facing output. - **`agents/faculties/samplers/`** — *the motor faculty*: expertise in how the diff --git a/ORGANISM.md b/ORGANISM.md index 2fe66c5..ca391f2 100644 --- a/ORGANISM.md +++ b/ORGANISM.md @@ -16,7 +16,7 @@ organs plan, build, test and release it, and you make every judgment call. | **Brain** | PyAutoBrain | Figures out *how* — reasoning, planning, decomposition, routing; hosts the specialist agents. Owns **no state, no health checks, no execution mechanics**. | | **Heart** | PyAutoHeart | Determines whether the organism is healthy. `pyauto-heart readiness` is the **authoritative** GREEN/YELLOW/RED "is it safe to release?" gate. An observer: never writes into other repos, never triggers Build. | | **Hands** | PyAutoBuild | Builds and releases — packaging, tagging, notebook generation, PyPI via `release.yml`. A pure executor: runs no readiness checks and never re-derives a gate decision. | -| **Memory** | PyAutoMemory | Long-term knowledge — *what the science says* (literature wikis, concepts, bibliographies). Operational history — *what the organism did* — lives in Mind (`complete.md`, issues), not here. | +| **Memory** | PyAutoMemory | Long-term knowledge — *what the science says* (literature wikis, concepts, bibliographies). Operational history — *what the organism did* — lives in Mind (the `complete/` records, issues), not here. | | **Gut** | PyAutoGut | Owns the lifecycle of *condemned self-material* — stale branches, stashes, dead code/tests. Holds each as a durable, recoverable git ref through a transit window and **voids** it on a sweep. The storage mirror of Memory (retention ↔ release); the hygiene conductor drives it, as vitals reads Heart. | The scientific libraries (PyAutoConf, PyAutoFit, PyAutoArray, PyAutoGalaxy, diff --git a/agents/conductors/intake/AGENTS.md b/agents/conductors/intake/AGENTS.md index be714d8..66e85d1 100644 --- a/agents/conductors/intake/AGENTS.md +++ b/agents/conductors/intake/AGENTS.md @@ -85,7 +85,7 @@ schema — light structure over free-form prose. | **census** | `intake census` | inventory every filed prompt (work-type/target/difficulty/status + hygiene flags); always read-only | | **dashboard** | `intake dashboard` | render the census as the Mind **backlog** page; `--apply` writes `PyAutoMind/dashboard.md` | | **formalise** | `intake formalise [prefix]` | retroactively header the prompts census flags — derive the missing fields, insert in place, prose untouched; `--apply` writes | -| **reconcile** | `intake reconcile [prefix]` | rank backlog prompts that look already-shipped (vs `complete.md` / `issued/`); always read-only — retiring stays human | +| **reconcile** | `intake reconcile [prefix]` | rank backlog prompts that look already-shipped (vs the `complete/` records / `active/`); always read-only — retiring stays human | Census/dashboard are the Mind *backlog* view — deliberately distinct from Heart's `/health status` health view (see "must never do"). The prompt-taxonomy @@ -101,7 +101,7 @@ moves or deletes a file. Reconcile exists because a prompt's `Status:` header is **not** a completeness signal — formalise preserves an existing Status verbatim, so shipped work can still read `Status: planned`. It cross-references each backlog prompt against -`complete.md` (path references + `## header` topic overlap), `issued/` +the `complete/` records (path references + `## header` topic overlap), `active/` basenames, and hand-set Status values, then ranks suspects (high/medium/low) with the evidence shown. The final verification — the target repo's git log / merged PRs — and the retirement itself stay human. diff --git a/agents/conductors/intake/INTAKE_TAXONOMY.md b/agents/conductors/intake/INTAKE_TAXONOMY.md index 885971c..f117bd4 100644 --- a/agents/conductors/intake/INTAKE_TAXONOMY.md +++ b/agents/conductors/intake/INTAKE_TAXONOMY.md @@ -125,7 +125,7 @@ only under `--apply` and re-runs are no-ops (nothing left missing). status went stale (a header `Status:` is display metadata — formalise preserves an existing value verbatim, so `Status: planned` can outlive the work by months). Per backlog prompt it collects four Mind-local signals — a -`complete.md` line referencing its path (follow-up/restore/parked wording +completion-record line referencing its path (follow-up/restore/parked wording downgrades it to likely-open), a duplicate basename in `issued/`, token overlap with a completed task's `## header`, and a hand-set Status — then ranks suspects high/medium/low with the evidence shown. Always read-only: the final diff --git a/agents/conductors/intake/_intake.py b/agents/conductors/intake/_intake.py index 7967e35..4089628 100755 --- a/agents/conductors/intake/_intake.py +++ b/agents/conductors/intake/_intake.py @@ -592,8 +592,8 @@ def emit_formalise(res: dict): "the a an of to in for and or is are be with on by via from into as at it " "this that use using make add new fix update support get set can we i you " "our my need should will when once each all its".split()) -# Wording in a complete.md reference line that marks the prompt as a deferred -# follow-up (still open) rather than the shipped task itself. +# Wording in a completion-record reference line that marks the prompt as a +# deferred follow-up (still open) rather than the shipped task itself. _FOLLOWUP_WORDS = ("follow", "restore", "parked", "remain", "blocked", "later", "next step", "next-step", "deferred") @@ -606,23 +606,28 @@ def _tokens(s: str) -> set: def reconcile(mind: Path, prefix: str = "") -> dict: """Rank backlog prompts that look already-shipped, for a human to retire. - Mind-local signals per prompt: a legacy complete.md line referencing its + Mind-local signals per prompt: a completion-record line referencing its path (follow-up wording downgrades it), a duplicate basename in `active/` or the `complete/` archive, token overlap with a completed task's header / archive record, and a hand-set Status the formalise pass deliberately preserved. Never writes anything. """ c = census(mind) - comp = mind / "complete.md" - comp_lines = (comp.read_text(encoding="utf-8", errors="replace").splitlines() - if comp.is_file() else []) - headers = [(ln[3:].strip(), _tokens(ln[3:].replace("-", " "))) - for ln in comp_lines if ln.startswith("## ")] comp_dir = mind / "complete" comp_files = ([p for p in comp_dir.rglob("*.md") - if "archive" not in p.parts and p.name != "AGENTS.md"] + if "archive" not in p.parts + and p.name not in ("AGENTS.md", "index.md")] if comp_dir.is_dir() else []) comp_names = {p.name for p in comp_files} + # reference lines + `## ` topic headers now live inside the dated + # records (the monolithic complete.md ledger was retired — issue #81) + comp_lines: list = [] + for p in comp_files: + comp_lines.extend( + p.read_text(encoding="utf-8", errors="replace").splitlines()) + headers = [(ln[3:].strip(), _tokens(ln[3:].replace("-", " "))) + for ln in comp_lines + if ln.startswith("## ") and ln[3:].strip() != "Original prompt"] headers += [(f"complete/{p.relative_to(comp_dir)}", _tokens(p.stem.replace("_", " "))) for p in comp_files] active = mind / "active" @@ -664,7 +669,7 @@ def reconcile(mind: Path, prefix: str = "") -> dict: if best[0] >= 0.40 or len(best[2]) >= 3: score = best[0] findings.append(("topic-overlap", - f"complete.md '## {best[1]}' " + f"completion record '{best[1]}' " f"(shared: {', '.join(sorted(best[2]))})")) if r["status"] not in ("-", "formalised"): @@ -697,8 +702,8 @@ def emit_reconcile(res: dict): print(f"== Intake reconcile: {len(res['suspects'])} suspect(s) of " f"{res['scanned']} scanned ==") if not res["suspects"]: - print(" backlog reconciles clean against the complete/ archive, " - "complete.md and active/.") + print(" backlog reconciles clean against the complete/ records " + "and active/.") for s in res["suspects"]: print(f"[{s['confidence']:>6}] {s['path']}") for f in s["findings"]: diff --git a/agents/conductors/intake/intake.sh b/agents/conductors/intake/intake.sh index 6f4fd42..ce4d688 100755 --- a/agents/conductors/intake/intake.sh +++ b/agents/conductors/intake/intake.sh @@ -25,7 +25,7 @@ # census flags (word-vomit is intent, not defect); # --apply writes the headers in place # intake reconcile [prefix] rank backlog prompts that look already-shipped -# (vs complete.md / issued/); always read-only — +# (vs the complete/ records / active/); always read-only — # retiring a prompt stays human # # Flags (place before the subcommand; both default OFF): diff --git a/agents/faculties/memory/AGENTS.md b/agents/faculties/memory/AGENTS.md index 141ec5b..068107e 100644 --- a/agents/faculties/memory/AGENTS.md +++ b/agents/faculties/memory/AGENTS.md @@ -4,7 +4,7 @@ > *consult*, not a front door you drive. It *recalls what the organism knows*: > given a topic or question, it returns a **cited digest** — pointers into > PyAutoMemory's sub-wikis, `autolens_assistant`'s skills/wiki pages, and -> Mind's operational history (`complete.md`) with matching snippets — and +> Mind's operational history (the `complete/` records) with matching snippets — and > stops. It never dispatches, never mutates, never bulk-loads a wiki into > context. @@ -23,7 +23,7 @@ synthesises. The digest is pointers + evidence, never wholesale content: memory.sh "delaunay regularization prior work" -> ranked pages (path · hit count · 1-2 matching snippet lines each) across: PyAutoMemory// · autolens_assistant/{skills,wiki}/ · - PyAutoMind/complete.md sections + PyAutoMind/complete/ records ``` - **No indexes, no embeddings, no new infra** — grep + the wikis' own @@ -31,8 +31,8 @@ memory.sh "delaunay regularization prior work" - **No layout coupling** — sub-wikis are discovered at query time (`*_wiki/` directories); when Memory grows a wiki, the faculty sees it with no edits (the standing "do not couple to Memory's internal layout" rule). -- Operational history stays Mind's: `complete.md` is *read* here as a recall - surface, but the boundary prose in ORGANISM.md is unchanged. +- Operational history stays Mind's: the `complete/` records are *read* here as + a recall surface, but the boundary prose in ORGANISM.md is unchanged. ## Privacy seam (hard rule) diff --git a/agents/faculties/memory/_memory.py b/agents/faculties/memory/_memory.py index fd022b6..1f4ff50 100755 --- a/agents/faculties/memory/_memory.py +++ b/agents/faculties/memory/_memory.py @@ -3,7 +3,7 @@ The **memory faculty** is a read-only opinion sink: given a topic/question, it greps the organism's knowledge surfaces — PyAutoMemory's sub-wikis, -autolens_assistant's skills/wiki pages, and Mind's complete.md history — and +autolens_assistant's skills/wiki pages, and Mind's complete/ records — and returns a **cited digest**: ranked pages with matching snippets. The consulting agent reads only the listed pages and synthesises; this script never dumps content, never writes, and builds no index. @@ -41,8 +41,16 @@ def surfaces(memory: Path | None, assistant: Path | None, mind: Path | None): if root.is_dir(): for f in root.rglob("*.md"): yield f"autolens_assistant/{sub}", assistant.parent, f - if mind and (mind / "complete.md").is_file(): - yield "PyAutoMind/complete.md", mind.parent, mind / "complete.md" + comp = mind / "complete" if mind else None + if comp and comp.is_dir(): + # the dated records are Mind's completion history (complete.md retired, + # issue #81); archive/ holds non-record material, index/AGENTS are meta + for f in comp.rglob("*.md"): + if f.name in ("index.md", "AGENTS.md"): + continue + if "archive" in f.relative_to(comp).parts: + continue + yield "PyAutoMind/complete", mind.parent, f def score_file(f: Path, terms: list[str]): diff --git a/agents/faculties/memory/memory.sh b/agents/faculties/memory/memory.sh index 94d96f0..032f8b5 100755 --- a/agents/faculties/memory/memory.sh +++ b/agents/faculties/memory/memory.sh @@ -3,7 +3,7 @@ # read-only reasoning capability). It recalls what the organism knows. # # Greps the knowledge surfaces — PyAutoMemory sub-wikis, autolens_assistant -# skills/wiki, PyAutoMind complete.md — and emits a cited digest (ranked pages +# skills/wiki, PyAutoMind complete/ records — and emits a cited digest (ranked pages # + matching snippets). The consulting agent reads only the listed pages and # synthesises. Read-only: never writes, never dumps whole pages, never invents # context when the surfaces are empty. Privacy seam: PyAutoMemory citations diff --git a/docs/concepts/workflow.md b/docs/concepts/workflow.md index 8409b6e..ed9b5d9 100644 --- a/docs/concepts/workflow.md +++ b/docs/concepts/workflow.md @@ -23,10 +23,10 @@ idea → prompt file → issue → worktree → PR(s) → merge → 4. **`ship_*`** gates the finish: test suites, the review faculty, and the Heart readiness verdict. GREEN ships; YELLOW needs an explicit human acknowledgement; RED stops. One PR per repo, always. -5. **Merge is always human.** After merge, the task entry moves from - `active.md` to `complete.md` — the organism's operational history. +5. **Merge is always human.** After merge, the task leaves `active.md` and a + dated `complete/` record is written — the organism's operational history. -The registry files (`active.md`, `planned.md`, `complete.md`) are shared +The registry files (`active.md`, `planned.md`, the `complete/` records) are shared state in the Mind repo, so any machine or session — laptop, web, CI — can read the current picture and resume an in-flight task with no handoff ceremony. diff --git a/docs/example.md b/docs/example.md index 101b2b1..c741593 100644 --- a/docs/example.md +++ b/docs/example.md @@ -38,7 +38,7 @@ Development touched PyAutoArray and PyAutoGalaxy; the ship gate ran both test suites, the review faculty, and Heart's verdict; one PR landed per repo; the workspaces then gained a demonstration script in a follow-up workspace task. The registry recorded every state transition, and the task -retired to `complete.md`. +retired to its dated `complete/` record. That is the whole pitch: the input was a paragraph of intent, and every step from there — planning, isolation, testing, gating, releasing, diff --git a/docs/organs/memory.md b/docs/organs/memory.md index 9e5479d..ca03738 100644 --- a/docs/organs/memory.md +++ b/docs/organs/memory.md @@ -13,7 +13,7 @@ Memory is **pull-only, on demand**. No agent loads it automatically; the Brain's memory faculty consults it when a task is scientific, returning a cited digest (pages + snippets) rather than bulk content. Operational history — what the organism *did* — deliberately lives in the Mind -(`complete.md`, issues), not here: Memory is what the domain says, Mind is +(the `complete/` records, issues), not here: Memory is what the domain says, Mind is what the organism did. ## The pieces diff --git a/docs/organs/mind.md b/docs/organs/mind.md index e842496..a253675 100644 --- a/docs/organs/mind.md +++ b/docs/organs/mind.md @@ -2,7 +2,7 @@ **What it owns:** intent and workflow state. Every task starts here as a plain-English markdown prompt; the registry files track what is in flight -(`active.md`), queued (`planned.md`) and done (`complete.md`); and +(`active.md`), queued (`planned.md`) and done (the dated `complete/` records); and `repos.yaml` — the **body map** — is the single source of repo identity for the whole organism. @@ -18,7 +18,7 @@ the whole organism. repo or domain. Prompts are free-form prose; an optional light header (`Type:` / `Difficulty:` / `Autonomy:` / `Priority:`) gives both humans and the Brain a glance-level summary. -- **The registry** (`active.md` / `planned.md` / `complete.md`) is the +- **The registry** (`active.md` / `planned.md` / the `complete/` records) is the shared task state — worktree claims, issue links, status, resume notes. It is what makes the workflow machine-independent. - **The body map** (`repos.yaml`) declares every repo's GitHub home, diff --git a/skills/WORKFLOW.md b/skills/WORKFLOW.md index 159bcf6..32949a4 100644 --- a/skills/WORKFLOW.md +++ b/skills/WORKFLOW.md @@ -11,7 +11,7 @@ the individual skill files can stay short. The organs and boundaries are defined once in [`../ORGANISM.md`](../ORGANISM.md). What the workflow skills need to know on top of that: Mind owns the workflow **state** (`active.md` / `planned.md` / -`complete.md`, the prompt taxonomy), and Build owns **no dev-workflow skills** +the `complete/` records, the prompt taxonomy), and Build owns **no dev-workflow skills** — it is the release/packaging executor only. A workflow skill reasons through **Brain**, gates ship through **Heart**, records @@ -97,7 +97,7 @@ execution tier — no manual model toggling. (`start_library`/`start_workspace`), release triage (`review_release`); identifying affected repos, drafting the commit message and full PR body (`## API Changes` / `## Scripts Changed`), workspace-impact analysis, the -library-first merge gate, the merge decision, `active.md` / `complete.md` +library-first merge gate, the merge decision, `active.md` / completion-record updates, and final issue comments. In `pre_build`: validating clean `main`, asking for the minor version, printing the summary. @@ -202,13 +202,14 @@ shared task state, so any environment reads it and continues an in-flight task. Workflow skills read and write Mind state via **workspace-root-relative** paths that resolve from any sibling repo: -- `PyAutoMind/active.md`, `PyAutoMind/planned.md`, `PyAutoMind/complete.md` (ledgers) -- Prompt **files** advance `draft/ → active/ → complete///` in lockstep - with the ledgers; `PyAutoMind/scripts/lifecycle.py` owns the moves (`move`) and - drift-checks them (`check`). See `PyAutoMind/complete/AGENTS.md` (issue #71). +- `PyAutoMind/active.md`, `PyAutoMind/planned.md` (live ledgers) +- Prompt **files** advance `draft/ → active/ → complete///`; the dated + record IS the completion ledger (`complete.md` retired 2026-07-16, issue #81). + `PyAutoMind/scripts/lifecycle.py` owns the writes (`record`, `move`) and + drift-checks them (`check`). See `PyAutoMind/complete/AGENTS.md` (issues #71/#81). - `source PyAutoMind/scripts/prompt_sync.sh` → `prompt_sync_push ""` (commit+push registry) -`active.md` task schema, `complete.md` schema, and the prompt taxonomy +`active.md` task schema, the completion-record schema, and the prompt taxonomy (`draft/feature//`, `draft/bug//`, …) are documented in `PyAutoMind/README.md`. **Under `draft/`, the first folder is the work type, the second is the target repo/domain.** diff --git a/skills/health/health.md b/skills/health/health.md index 8705ec5..462e624 100644 --- a/skills/health/health.md +++ b/skills/health/health.md @@ -11,7 +11,7 @@ Shared routing context: `PyAutoBrain/skills/COMMANDS.md`. |------------|--------------|---------------| | `/health` | The Brain **Health conductor** loop with you: assess (vitals → Heart) → triage → dispatch a validation leg → re-judge, until GREEN. | `bin/pyauto-brain health` | | `/health check` | One-shot **green-light sweep**: sync each repo's `main`, run library pytest + workspace smoke, report a pass/fail matrix. | `PyAutoHeart/skills/health_sweep/reference.md` | -| `/health status` | **Active-work dashboard**: what's in flight across the repos (reads `active.md` / `planned.md` / `complete.md`), conflicts, idle repos. | `PyAutoHeart/skills/pyauto-status/reference.md` | +| `/health status` | **Active-work dashboard**: what's in flight across the repos (reads `active.md` / `planned.md` / the `complete/` records), conflicts, idle repos. | `PyAutoHeart/skills/pyauto-status/reference.md` | | `/health full` | **Release-run dashboard**: what the last PyAutoBuild release-prep run produced (per-workspace pass/fail/timing, slowest scripts, failure tracebacks). | `PyAutoHeart/skills/pyauto-status-full/reference.md` | | `/health worktrees` | **Worktree/task dashboard**: every task worktree under `~/Code/PyAutoLabs-wt/`, cross-referenced with `active.md` — which parallel tasks are in flight and which repos each holds. | `PyAutoHeart/skills/worktree_status/reference.md` | diff --git a/skills/intake/intake.md b/skills/intake/intake.md index 2031ec7..dc16fb2 100644 --- a/skills/intake/intake.md +++ b/skills/intake/intake.md @@ -40,7 +40,7 @@ dev workflow (issue, branch, plan). Do not bypass the Brain. (then regenerate the dashboard). - `bin/pyauto-brain intake reconcile [prefix]` — ranks backlog (`draft/`) prompts that look already-shipped (cross-referenced against the `complete/` - archive — or the legacy `complete.md` until retired — and `active/`; a stale + records — the sole completion ledger since `complete.md` retired, #81 — and `active/`; a stale hand-set `Status:` is a signal, never proof). Always read-only: verify each suspect against the target repo's git log / merged PRs, then retire it to the `complete/` archive by hand (it is already done). diff --git a/skills/register_and_iterate/register_and_iterate.md b/skills/register_and_iterate/register_and_iterate.md index 5f74e1c..3852d53 100644 --- a/skills/register_and_iterate/register_and_iterate.md +++ b/skills/register_and_iterate/register_and_iterate.md @@ -58,8 +58,8 @@ derived task name is the filename stem with `_`→`-` ### 2. Check dependencies -Parse the prompt's `__Depends on__` section; verify each appears in -`PyAutoMind/complete.md`. If a dependency is missing, stop and tell the user +Parse the prompt's `__Depends on__` section; verify each has a completion +record under `PyAutoMind/complete/` (grep `complete/index.md`). If a dependency is missing, stop and tell the user which prompt to run first. **Do not** re-order the queue automatically. ### 3. Scaffold + iterate diff --git a/skills/ship_library/reference.md b/skills/ship_library/reference.md index d20c933..e8a0d72 100644 --- a/skills/ship_library/reference.md +++ b/skills/ship_library/reference.md @@ -132,19 +132,19 @@ Options (i) new scripts and (ii) migration both route to `/start_workspace`; **Progress (option i/ii) — workspace work to follow:** post a "Library PR Created" comment (PR URLs, "Next: /start_workspace", API-change summary), set the `active.md` status to `library-shipped, workspace-pending`, add `library-pr:`, -push Mind. Do **not** move to `complete.md`. +push Mind. Do **not** record completion yet. **Shipped (option iii passed):** offer to merge the library PR (`gh pr merge --merge --auto`), post a "Shipped" comment (PRs, summary, -optional session notes), then record completion in **both** lifecycle layers -(issue #71) — the ledger entry **and** the dated record, kept paired 1:1 by slug: -- **Ledger:** append the entry to `complete.md` (`## `, `issue`, - `completed: `, `library-pr:`) and drop it from `active.md`. -- **Record:** write the paired dated record and fold + remove the `active/` - prompt — - `python3 PyAutoMind/scripts/lifecycle.py record --date --prompt --apply` - (writes `complete///.md` from the just-appended `complete.md` - entry; `lifecycle.py check` enforces the record ↔ `complete.md` pairing). +optional session notes), then record completion — the dated record **is** the +ledger (issues #71/#81; the monolithic `complete.md` was retired 2026-07-16): +- **Draft the rich completion body** to a temp file — `## `, `issue`, + `completed: `, `library-pr:`, then the summary/traps/notes bullets. +- **Write the record** (folds + removes the `active/` prompt): + `python3 PyAutoMind/scripts/lifecycle.py record --date --from-file --prompt --apply` +- **Regenerate the index:** `python3 PyAutoMind/scripts/lifecycle.py index --apply` +- **Drop the task's `active.md` entry** (`lifecycle.py check` flags a finished + slug still present in `active.md`). Then push Mind with `prompt_sync_push "prompt: ship (#) → complete"`. diff --git a/skills/ship_library/ship_library.md b/skills/ship_library/ship_library.md index 9777e5a..f9b0183 100644 --- a/skills/ship_library/ship_library.md +++ b/skills/ship_library/ship_library.md @@ -95,8 +95,9 @@ Analyse downstream workspace impact and present data-driven options — see "Library PR Created" progress comment, set `active.md` to `library-shipped, workspace-pending`, add `library-pr:`, push Mind. - **(iii)** no workspace impact → run `/smoke_test` (with `activate.sh` sourced). - On pass, offer to merge the library PR, post a "Shipped" comment, move the task - to `complete.md`, push Mind. On fail, report and suggest `/start_workspace` + On pass, offer to merge the library PR, post a "Shipped" comment, write the + dated completion record (`lifecycle.py record`) and drop the `active.md` + entry, push Mind. On fail, report and suggest `/start_workspace` (likely option ii); do not merge, do not clean up `active.md`. Comment templates and Mind-state transitions are in [`reference.md`](reference.md) diff --git a/skills/ship_workspace/reference.md b/skills/ship_workspace/reference.md index dabcd49..d40f1f5 100644 --- a/skills/ship_workspace/reference.md +++ b/skills/ship_workspace/reference.md @@ -97,10 +97,10 @@ SHIP_EOF )" ``` -4. Record completion in **both** lifecycle layers (issue #71): the ledger entry - **and** the prompt file, in lockstep. +4. Record completion — the dated record **is** the ledger (issues #71/#81; the + monolithic `complete.md` was retired 2026-07-16). - **Ledger** — move the task from `active.md` to `complete.md`: + **Draft the rich completion body** to a temp file: ```markdown ## @@ -108,14 +108,16 @@ SHIP_EOF - completed: - library-pr: - workspace-pr: +- summary: ``` - **Record** — write the paired dated record from the just-appended - `complete.md` entry, folding + removing the `active/` prompt (kept paired 1:1 - by slug; `lifecycle.py check` enforces it): + **Write the record** (folds + removes the `active/` prompt), regenerate the + index, and drop the task's `active.md` entry (`lifecycle.py check` flags a + finished slug still present there): ```bash -python3 PyAutoMind/scripts/lifecycle.py record --date --prompt --apply +python3 PyAutoMind/scripts/lifecycle.py record --date --from-file --prompt --apply +python3 PyAutoMind/scripts/lifecycle.py index --apply ``` Push Mind: `prompt_sync_push "prompt: ship (#) → complete"`. diff --git a/skills/ship_workspace/ship_workspace.md b/skills/ship_workspace/ship_workspace.md index 13bbe29..7657f81 100644 --- a/skills/ship_workspace/ship_workspace.md +++ b/skills/ship_workspace/ship_workspace.md @@ -91,8 +91,9 @@ See [`reference.md`](reference.md) → "Library-first merge gate". ### 6. Complete the issue + Mind state -Detect the issue, generate a session summary, post a "Shipped" comment, move the -task from `active.md` to `complete.md`, and push Mind. Templates in +Detect the issue, generate a session summary, post a "Shipped" comment, write +the dated completion record (`lifecycle.py record`), drop the `active.md` +entry, and push Mind. Templates in [`reference.md`](reference.md) → "Issue completion + Mind state". ## Notes