From e9767b1f79358332be262c2cbcdfb580d281f9eb Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 24 Aug 2026 22:43:05 +0000 Subject: [PATCH 1/2] prompt: complete intake-declared-difficulty (PyAutoBrain#274) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PyAutoBrain#275 and PyAutoMind#308 are merged, so the task leaves active/: the dated record folds in the prompt and records the family lesson (the same "declared beats derived" bug in three conductors, with a fourth found while fixing it — the reason the rule moved into the sizing faculty rather than being re-implemented a third time). Index and dashboard regenerated. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_012RXdgVSW8bUhVdEXEz6AAJ --- active.md | 22 --- active/intake_ignores_declared_difficulty.md | 61 -------- .../2026/08/intake-declared-difficulty.md | 140 ++++++++++++++++++ complete/index.md | 3 +- dashboard.html | 17 +-- dashboard.md | 20 +-- 6 files changed, 156 insertions(+), 107 deletions(-) delete mode 100644 active/intake_ignores_declared_difficulty.md create mode 100644 complete/2026/08/intake-declared-difficulty.md diff --git a/active.md b/active.md index c810a577..fb25a165 100644 --- a/active.md +++ b/active.md @@ -1,27 +1,5 @@ # Active Tasks -## intake-declared-difficulty -- issue: https://github.com/PyAutoLabs/PyAutoBrain/issues/274 (issued 2026-08-24) -- issued: 2026-08-24 -- prompt: active/intake_ignores_declared_difficulty.md -- status: library-dev -- worktree: none — remote web session (`web-github`), work done in the session clones -- repos: - - PyAutoBrain: claude/intake-declared-difficulty-icstba - - PyAutoMind: claude/intake-declared-difficulty-icstba -- summary: | - Third instance of one family: a conductor deriving from prose while ignoring a - declared header key (1 = feature ranker, fixed #217; 2 = the Bug Agent's Type: - leg, fixed in this pass; 3 = intake's Difficulty:). Per the prompt, the - precedence rule moves INTO the sizing faculty — one `effective_difficulty` - both conductors call — rather than being re-implemented per conductor: - declared wins, derived level + score reported alongside on disagreement. - Intake also reads a declaration out of unstructured raw text (the ideas.md - "Difficulty large, supervised." idiom), keeps it out of the derived - title/slug, and honours a declared `Type:` over prose classification. - The prompt file on main (c1927d5) is authoritative; the session's earlier - reconstruction of it was dropped in the merge. - ## transformed-message-factor-gradient-unpack - issue: https://github.com/PyAutoLabs/PyAutoFit/issues/1501 (issued 2026-08-19) - issued: 2026-08-19 diff --git a/active/intake_ignores_declared_difficulty.md b/active/intake_ignores_declared_difficulty.md deleted file mode 100644 index d957001a..00000000 --- a/active/intake_ignores_declared_difficulty.md +++ /dev/null @@ -1,61 +0,0 @@ -# Intake discards a declared Difficulty and persists its own derived one - -Type: bug -Target: pyautobrain -Repos: -- PyAutoBrain -Difficulty: medium -Autonomy: safe -Priority: normal -Status: formalised -Issued: 2026-08-24 - -@PyAutoBrain's Intake Agent never reads the `Difficulty:` a raw input declares. -`analyse()` hand-builds the prompt-shaped dict it hands the sizing faculty: - - agents/conductors/intake/_intake.py:268 - p = {"text": text, "repos": repos, "words": len(text.split()), - "target": target, "work_type": work_type} - level, score, factors = estimate_difficulty(p) - -That dict omits `declared_header(text)`, which the file-loading path in -`agents/faculties/sizing/_sizing.py:369` does fold in. So `estimate_difficulty` -runs with no declared key present, nothing reconciles derived against declared, -and `_intake.py:320` then writes the derived level into the header — silently -replacing what the input asked for. - -Reproduced 2026-08-24 while filing the arXiv-inbox-tier prompt: raw text -declaring `Difficulty: medium` classified as `too-large` (score 11), unchanged -when the full header block was prepended. The header had to be hand-corrected -after `--apply`. - -This matters because the derived score weights prompt *length*. A prompt is long -when it carries a design and the sibling tasks' traps, not when the work is -large — the exact inversion `complete/2026/08/feature-ranker-ignores-header-keys.md` -already records ("length is a bad size proxy … that is what a declared -`Difficulty:` is for"). A declared key is the documented escape hatch, and on -this path it does nothing. - -Third instance of one family — a conductor deriving from prose while ignoring a -declared header key: - -1. the Feature Agent ranker — fixed, PyAutoBrain#217. -2. the Bug Agent classifying on prose keywords over a declared `Type: bug` — - recorded in that same completion record and still unfiled. -3. this one. - -Worth fixing (2) in the same pass, and considering whether the reconciliation -belongs in the sizing faculty itself — one place both conductors already call — -rather than being re-implemented per conductor. Decide the precedence rule -explicitly: declared wins, or declared wins with the derived score reported -alongside when they disagree (the latter keeps the heuristic honest and visible). - - - -## Filing note (same session) - -Intake classified *this* prompt as `feature`, from prose, despite the input -naming itself a bug throughout — so the work-type leg of the same family fired -while the difficulty leg was being written up. The file was re-homed to -`draft/bug/pyautobrain/` and its `Type:` corrected by hand. Two legs of one -conductor, one root cause: derive from prose, never look at what was declared. diff --git a/complete/2026/08/intake-declared-difficulty.md b/complete/2026/08/intake-declared-difficulty.md new file mode 100644 index 00000000..cb27edbf --- /dev/null +++ b/complete/2026/08/intake-declared-difficulty.md @@ -0,0 +1,140 @@ +## intake-declared-difficulty +- issue: https://github.com/PyAutoLabs/PyAutoBrain/issues/274 +- completed: 2026-08-24 +- brain-pr: https://github.com/PyAutoLabs/PyAutoBrain/pull/275 (MERGED as 979fac5; pytest 3.12 + 3.13 green, 491 passed, tenant-firewall leg green) +- mind-pr: https://github.com/PyAutoLabs/PyAutoMind/pull/308 (MERGED as 243a871; lifecycle state only) +- prompt: active/intake_ignores_declared_difficulty.md (folded below) +- summary: the precedence rule "a DECLARED header key beats a value derived from + prose" now lives ONCE, in the sizing faculty, instead of being re-implemented + per conductor. `_sizing.effective_difficulty` (moved out of `_feature.py`) is + the rule: declared wins, and the derived level + score come back alongside so a + disagreement is REPORTED rather than silently resolved. `declared_header` also + reads `Type:` and `Autonomy:`; new `declared_inline` reads the same keys out of + unheadered conception prose. Intake and the Bug Agent now go through it. +- root cause, stated exactly: `_intake.analyse()` hand-built the prompt-shaped + dict it passes the faculty and omitted the `declared_header(text)` keys that + `parse_prompt` (the FILE-loading path) does fold in. So `estimate_difficulty` + ran with no declared key present, nothing reconciled derived against declared, + and the derived level was written into the header — silently replacing what the + input asked for. The reported case: raw text declaring `Difficulty: medium` + filed as `too-large` (score 11), unchanged when the full header block was + prepended, hand-corrected after `--apply`. +- THE LESSON, which is why the rule moved: this was the THIRD instance of one + family and a FOURTH was found while fixing it. (1) the Feature Agent's ranker + — fixed 2026-08-10, PyAutoBrain#217, by adding a local `effective_difficulty`; + (2) Intake's `Difficulty:`; (3) Intake's work-type classifier, which called the + bug prompt for THIS bug `feature` while the difficulty leg was being written + up; (4) the Bug Agent, sizing through raw `estimate_difficulty` and re-homing + on prose keywords over a declared `Type: bug` — nobody had filed that one. One + heuristic with N reconciliations is N chances to forget one, and two of the + three forgot. Fixing #217 locally is what let (2)–(4) survive. +- length is a bad size proxy (recorded AGAIN, second time): the derived score + weights prompt length, and a prompt is long when it carries a design and the + sibling tasks' traps, not when the work is large. That inversion is already on + the record in `feature-ranker-ignores-header-keys.md`; a declared `Difficulty:` + is the documented escape hatch for it, and on the intake path it did nothing. +- TRAP, inherited and re-earned: the fenced-block skip is load-bearing, not + tidiness — the bug prompt for this fix QUOTES `Difficulty:` header lines in a + ```-block and in backticks, so a naive scan makes the bug report re-size + itself. `declared_header` already skipped fences (the #217 trap); the new + `declared_inline` masks fenced blocks AND inline code spans to spaces before + matching, preserving offsets so the title-stripping stays aligned. +- second-order trap found by the tests: a declared value must not leak into the + DERIVED TITLE. "Fix the docstring. Difficulty: large." titled the task after + its own difficulty declaration and carried `large` into the slug — the + filename. `strip_declarations` removes the clause for title derivation only; + the prompt body stays verbatim (word-vomit is intent). +- a defect report legitimately says "refactor" and "documentation": that is why + the Bug Agent's `re_home_check` now returns None for a declared `Type: bug` + rather than weighing prose keywords against it. Note the sharp edge — the + literal string "bug" in a `Type: bug` line trips the agent's own `defect` + keyword hit, which masked the misbehaviour in a first draft of the test. +- verified on the live prompt: `intake classify --file` on this task's own prompt + now reports `Work-type: bug (declared)` and `Difficulty: medium (declared; + heuristic derived medium)`; before the fix it reported `feature` and re-sized. + `pyauto-brain feature`/`bug` report the declared level with the derived one + beside it. +- tests: `tests/test_declared_header_precedence.py` (15) is named for the FAMILY, + not the instance — rule-level tests plus the reported reproduction, the + prepended-header case, the title/slug leak, declared `Type:` at both intake and + the Bug Agent's re-home check, and "no declaration -> still derives". The old + per-instance test file written earlier in the session was dropped. +- gate note (`web-github`): PyAutoHeart is not among this session's repos, so the + Heart leg could not run. `ship_library`'s documented fallback applied — the + repo's own suite as the gate — and CI ran both pytest legs plus the tenant + firewall on the PR. +- process note worth keeping: the session was launched with a prompt path that + did not exist yet, wrote its own reconstruction of the prompt, and only later + found the real one pushed to `main` (c1927d5). The real prompt scoped the work + differently — it named `declared_header`, asked whether the rule belonged in + the faculty, and asked for leg (2) in the same pass — and the reconstruction + had reasoned the opposite way (per-conductor, faculty stays a pure estimator). + The merge kept main's text and dropped the reconstruction. Read the filed + prompt before designing; a plausible reconstruction of a task is not the task. +- scope: this branch is wider than one leg, deliberately, because the prompt asked + for (2) in the same pass — one root cause, one shared rule; splitting would have + meant two PRs editing the same function. + +## Original prompt + +# Intake discards a declared Difficulty and persists its own derived one + +Type: bug +Target: pyautobrain +Repos: +- PyAutoBrain +Difficulty: medium +Autonomy: safe +Priority: normal +Status: formalised +Issued: 2026-08-24 + +@PyAutoBrain's Intake Agent never reads the `Difficulty:` a raw input declares. +`analyse()` hand-builds the prompt-shaped dict it hands the sizing faculty: + + agents/conductors/intake/_intake.py:268 + p = {"text": text, "repos": repos, "words": len(text.split()), + "target": target, "work_type": work_type} + level, score, factors = estimate_difficulty(p) + +That dict omits `declared_header(text)`, which the file-loading path in +`agents/faculties/sizing/_sizing.py:369` does fold in. So `estimate_difficulty` +runs with no declared key present, nothing reconciles derived against declared, +and `_intake.py:320` then writes the derived level into the header — silently +replacing what the input asked for. + +Reproduced 2026-08-24 while filing the arXiv-inbox-tier prompt: raw text +declaring `Difficulty: medium` classified as `too-large` (score 11), unchanged +when the full header block was prepended. The header had to be hand-corrected +after `--apply`. + +This matters because the derived score weights prompt *length*. A prompt is long +when it carries a design and the sibling tasks' traps, not when the work is +large — the exact inversion `complete/2026/08/feature-ranker-ignores-header-keys.md` +already records ("length is a bad size proxy … that is what a declared +`Difficulty:` is for"). A declared key is the documented escape hatch, and on +this path it does nothing. + +Third instance of one family — a conductor deriving from prose while ignoring a +declared header key: + +1. the Feature Agent ranker — fixed, PyAutoBrain#217. +2. the Bug Agent classifying on prose keywords over a declared `Type: bug` — + recorded in that same completion record and still unfiled. +3. this one. + +Worth fixing (2) in the same pass, and considering whether the reconciliation +belongs in the sizing faculty itself — one place both conductors already call — +rather than being re-implemented per conductor. Decide the precedence rule +explicitly: declared wins, or declared wins with the derived score reported +alongside when they disagree (the latter keeps the heuristic honest and visible). + + + +## Filing note (same session) + +Intake classified *this* prompt as `feature`, from prose, despite the input +naming itself a bug throughout — so the work-type leg of the same family fired +while the difficulty leg was being written up. The file was re-homed to +`draft/bug/pyautobrain/` and its `Type:` corrected by hand. Two legs of one +conductor, one root cause: derive from prose, never look at what was declared. diff --git a/complete/index.md b/complete/index.md index 2e3fad43..b0a87134 100644 --- a/complete/index.md +++ b/complete/index.md @@ -6,7 +6,7 @@ Token-light navigation over the finished-work records (schema: only then grep a dated bucket. Curators: edit the band between the CURATED markers; everything below GENERATED is rebuilt. -1123 records across 7 buckets. +1124 records across 7 buckets. ## Highlights @@ -101,6 +101,7 @@ _(curate hard-won records here — survives regeneration.)_ - [imaging-mge-pytree-migration](2026/08/imaging-mge-pytree-migration.md) - [inference-method-cards-seed](2026/08/inference-method-cards-seed.md) - [inference-programme-ledger](2026/08/inference-programme-ledger.md) +- [intake-declared-difficulty](2026/08/intake-declared-difficulty.md) — the precedence rule "a DECLARED header key beats a value derived from - [interferometer-delaunay-flaky-fitexception](2026/08/interferometer-delaunay-flaky-fitexception.md) - [interferometer-delaunay-nonpd-fitexception](2026/08/interferometer-delaunay-nonpd-fitexception.md) - [interferometer-start-here-integrate-oom](2026/08/interferometer-start-here-integrate-oom.md) diff --git a/dashboard.html b/dashboard.html index 204763e8..da5f262f 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-24. 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 callissue #1501 — issued 2026-08-19HOLD — do not start dev. Fix-or-delete hangs off the PyAutoFit#1498 logpdf-contract

-

Parked markdown version

3 task(s) @@ -437,12 +436,6 @@

Backlog 2026-08-24 -issued -Intake discards a declared Difficulty and persists its own derived one - - - -2026-08-24 filed Heart's local smoke runner cannot run any CTI workspace — no autocti… @@ -459,7 +452,7 @@

Backlog Phase 3: stop installing pynufft in Hands/Heart CI and PyAutoCTI… - + 2026-08-23 filed Brain board follow-ups: what real mornings surface @@ -699,6 +692,12 @@

Backlog aplt.Output stale-API drift in the remaining workspace repos + +2026-08-04 +filed +Nightly release has been blocked 8 nights running — triage the streak + +

Epics markdown version

diff --git a/dashboard.md b/dashboard.md index ca7f71f3..86668214 100644 --- a/dashboard.md +++ b/dashboard.md @@ -42,7 +42,7 @@ anything you could not verify. | Where | Count | |-------|------:| -| [In flight](#in-flight) (`active/`) | 2 | +| [In flight](#in-flight) (`active/`) | 1 | | [Parked](#parked) (`parked.md`) | 3 | | [Planned](#planned) (`planned.md`) | 5 | | [Backlog](#backlog) (`draft/`) | 140 | @@ -185,14 +185,6 @@ Issued — each has an open GitHub issue and usually a branch. The full record f
-
📋 Intake discards a declared Difficulty and persists its own derived oneissue #274 — issued 2026-08-24 — library-dev - -``` -/start_dev active/intake_ignores_declared_difficulty.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). @@ -1256,16 +1248,15 @@ The 50 newest things to happen to the work in hand, newest first — issued, par | 2026-08-24 | filed | Un-park multi_galaxy/features/scaling_relation/slam once a capped run… | | 2026-08-24 | filed | The weekly smoke run's timings land in results-* under no… | | 2026-08-24 | filed | Organ repo spellings split across two normalised keys | -| 2026-08-24 | issued | Intake discards a declared Difficulty and persists its own derived one | | 2026-08-24 | filed | Heart's local smoke runner cannot run any CTI workspace — no autocti… | | 2026-08-23 | filed | pynufft removal: unswept downstream residue (1 hard break + stale… | | 2026-08-23 | filed | Phase 3: stop installing pynufft in Hands/Heart CI and PyAutoCTI… | +| 2026-08-23 | filed | Brain board follow-ups: what real mornings surface |
… 10 more (40 left) | Date | Event | Task | |------|-------|------| -| 2026-08-23 | filed | Brain board follow-ups: what real mornings surface | | 2026-08-22 | filed | smoke_install.sh's stale jax<0.7 pin — CI is on the right jax… | | 2026-08-22 | filed | Untrack the generated FITS test artifacts in autoarray | | 2026-08-22 | filed | The reconstruction noise map describes a different estimator than the… | @@ -1275,12 +1266,12 @@ The 50 newest things to happen to the work in hand, newest first — issued, par | 2026-08-22 | filed | Bug: fix the tracer.fits existence guard in autolens_workspace… | | 2026-08-21 | filed | Rectangular mesh split: Bilinear (fast CPU default) vs RTU… | | 2026-08-20 | filed | Numba CPU likelihood phase 2: kernel-CDF numba fast path (the 49-88%… | +| 2026-08-20 | filed | Numba CPU likelihood phase 1: batched MGE convolution +… |
… 10 more (30 left) | Date | Event | Task | |------|-------|------| -| 2026-08-20 | filed | Numba CPU likelihood phase 1: batched MGE convolution +… | | 2026-08-19 | filed | status.sh --repos sources a file that no longer exists | | 2026-08-19 | filed | jax 0.11 breaks beta/gamma message log_partition under jit… | | 2026-08-19 | filed | autolens_workspace_test jax_likelihood pins: 4 scripts fail smoke on… | @@ -1290,12 +1281,12 @@ The 50 newest things to happen to the work in hand, newest first — issued, par | 2026-08-19 | filed | Release board: local run_logs enrichment | | 2026-08-19 | filed | RTD organism docs currency: Nerves page, organ-count drift, hands.md… | | 2026-08-19 | filed | Deduplicate repos_sync.py's check/write pairs | +| 2026-08-19 | filed | Bug in autocti_workspace: the dataset_1d results/database example… |
… 10 more (20 left) | Date | Event | Task | |------|-------|------| -| 2026-08-19 | filed | Bug in autocti_workspace: the dataset_1d results/database example… | | 2026-08-18 | parked | single-source-density-design | | 2026-08-18 | parked | prior-message-collapse-design | | 2026-08-18 | filed | @PyAutoFit TransformedMessage.logpdf/pdf omit the transform… | @@ -1305,12 +1296,12 @@ The 50 newest things to happen to the work in hand, newest first — issued, par | 2026-08-14 | filed | Three jax_likelihood pins are stale by ~1.24e-4 and fail the smoke… | | 2026-08-09 | found | isothermal-ell-sph-oversampling-at-the-cusp | | 2026-08-08 | parked | pyautoreduce-slacs1430-acs-comparison | +| 2026-08-08 | filed | Regenerate autolens_workspace markdown/ so the MGE pages show… |
… 10 more (10 left) | Date | Event | Task | |------|-------|------| -| 2026-08-08 | filed | Regenerate autolens_workspace markdown/ so the MGE pages show… | | 2026-08-07 | filed | Regenerate setup_notebook-drifted notebooks in… | | 2026-08-06 | filed | Triage: Convolver "No blurring_image provided" warning in canonical… | | 2026-08-06 | filed | Rewrite PyAutoCTI docs/api — 55 of 89 autosummary entries are dead | @@ -1320,6 +1311,7 @@ The 50 newest things to happen to the work in hand, newest first — issued, par | 2026-08-04 | filed | cosmos_web_ring stores boolean masks as float64, wasting ~3.4 MB of… | | 2026-08-04 | filed | autolens_workspace_developer: broad stale-API rot (56 symbols, no CI) | | 2026-08-04 | filed | aplt.Output stale-API drift in the remaining workspace repos | +| 2026-08-04 | filed | Nightly release has been blocked 8 nights running — triage the streak |
From 6a3e6b12b48aec812baee02f34c3cb3943f7feb8 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 24 Aug 2026 22:44:52 +0000 Subject: [PATCH 2/2] lifecycle: regenerate complete/index.md over the merged records MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The merge brought main's tracer-fits-existence-guard record in beside this branch's, leaving the generated index one entry behind — the drift leg's failure. Regenerated, not hand-edited. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_012RXdgVSW8bUhVdEXEz6AAJ --- complete/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/complete/index.md b/complete/index.md index 0d4ff1d0..b0a02eff 100644 --- a/complete/index.md +++ b/complete/index.md @@ -6,7 +6,7 @@ Token-light navigation over the finished-work records (schema: only then grep a dated bucket. Curators: edit the band between the CURATED markers; everything below GENERATED is rebuilt. -1124 records across 7 buckets. +1125 records across 7 buckets. ## Highlights