From 4d6057a10250fd3920b8ed5f558830c9c48580f3 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Sun, 4 Oct 2026 08:40:56 +0100 Subject: [PATCH] Integrate Insight inference campaigns and evidence organ --- .claude/hooks/session-start.sh | 4 +- AGENTS.md | 3 +- ORGANISM.md | 12 ++++-- README.md | 2 +- agents/_pyauto_root.py | 1 + bin/_pyauto_root.sh | 2 +- board/AGENTS.md | 2 +- board/_board.py | 19 +++++++++ board/_theme.py | 10 +++++ config/policy.yaml | 2 + docs/concepts/organism.md | 7 +-- docs/index.md | 3 +- docs/organs/insight.md | 47 +++++++++++++++++++++ docs/research/profiling_inference_organs.md | 11 +++++ skills/route/route.md | 1 + tests/test_board.py | 20 +++++++++ tests/test_board_theme.py | 4 +- tests/test_workspace_root.py | 5 +++ 18 files changed, 140 insertions(+), 15 deletions(-) create mode 100644 docs/organs/insight.md diff --git a/.claude/hooks/session-start.sh b/.claude/hooks/session-start.sh index 54a10fe..591c2d7 100755 --- a/.claude/hooks/session-start.sh +++ b/.claude/hooks/session-start.sh @@ -132,12 +132,12 @@ marked_root() { holds_an_organ() { [ -d "$1/PyAutoBrain" ] || [ -d "$1/PyAutoMind" ] || [ -d "$1/PyAutoCortex" ] \ || [ -d "$1/PyAutoMemory" ] || [ -d "$1/PyAutoEyes" ] || [ -d "$1/PyAutoHeart" ] \ - || [ -d "$1/PyAutoHands" ] || [ -d "$1/PyAutoPulse" ] || [ -d "$1/PyAutoNerves" ] \ + || [ -d "$1/PyAutoHands" ] || [ -d "$1/PyAutoPulse" ] || [ -d "$1/PyAutoInsight" ] || [ -d "$1/PyAutoNerves" ] \ || [ -d "$1/PyAutoGut" ] \ || [ -d "$1/organs/PyAutoBrain" ] || [ -d "$1/organs/PyAutoMind" ] \ || [ -d "$1/organs/PyAutoCortex" ] || [ -d "$1/organs/PyAutoMemory" ] \ || [ -d "$1/organs/PyAutoEyes" ] || [ -d "$1/organs/PyAutoHeart" ] \ - || [ -d "$1/organs/PyAutoHands" ] || [ -d "$1/organs/PyAutoPulse" ] \ + || [ -d "$1/organs/PyAutoHands" ] || [ -d "$1/organs/PyAutoPulse" ] || [ -d "$1/organs/PyAutoInsight" ] \ || [ -d "$1/organs/PyAutoNerves" ] || [ -d "$1/organs/PyAutoGut" ] } diff --git a/AGENTS.md b/AGENTS.md index 60fa1e9..752e21a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -24,7 +24,8 @@ Canonical boundaries live in `PyAutoBrain/ORGANISM.md`; the full body map | **Ears** | PyAutoEars | The Ears — the community listening organ: owns read-only public conversation collection, the versioned community snapshot contract, coverage receipts and the dashboard. GitHub conversations remain authoritative; Brain’s Community conductor owns judgement, reply drafts and development routing, and Mind owns task state. Never posts replies, labels or issues, exports raw transcripts or private sources, or treats unknown coverage as no work. | | **Heart** | PyAutoHeart | Health/readiness — the authoritative "is it safe to release?" verdict. | | **Hands** | PyAutoHands | Packaging, tagging, notebook generation, PyPI release execution. | -| **Pulse** | PyAutoPulse | The Pulse — where the organism feels how fast it runs: the cross-project profiling dashboard over the `_profiling` project repos (today autolens_profiling) — the instance registry, the versioned `profiling-summary` read contract (v1 live at `autolens_profiling/dashboard/summary.json`), the ingest receipts (resolved commit per project per render) and the Pages board. Validates the exchange contract only; never moves pins, combines unmatched timings, applies the compile threshold to runtime, computes an ecosystem-wide speed score or issues a Heart verdict, and never judges (the Brain's profiling conductor does); the project repos keep their producers, results, drift policy and their own Pages page. | +| **Pulse** | PyAutoPulse | The Pulse — where the organism feels how fast it runs: the cross-project profiling dashboard over the `_profiling` project repos (today autolens_profiling) — campaign intent and pending domain tasks, the instance registry, the versioned `profiling-summary` read contract (v1 live at `autolens_profiling/dashboard/summary.json`), the ingest receipts (resolved commit per project per render) and the Pages board. Validates the exchange contract only; never moves pins, combines unmatched timings, applies the compile threshold to runtime, computes an ecosystem-wide speed score or issues a Heart verdict, and never judges (the Brain's profiling conductor does); the project repos keep their producers, results, drift policy and their own Pages page. | +| **Insight** | PyAutoInsight | Owns inference campaign intent and pending domain tasks, the cross-project inference instance registry, versioned `inference-summary` read contract, ingest receipts and evidence dashboard. Projects own execution, producers and raw samples; Cortex owns scientific run records, observations and human conclusions; Mind owns bounded implementation lifecycle and repository claims. Never infers scientific acceptance from execution, ranks incompatible runs or submits compute on refresh. | | **Nerves** | PyAutoNerves | The Nerves — the configuration/serialization layer connecting workspace conventions to libraries (layered config, version handshake, test_mode), delivered as the `autonerves` package. | | **Gut** | PyAutoGut | Owns the lifecycle of condemned self-material (stale branches, stashes, dead code/tests): holds it as durable, recoverable git refs through a transit window and voids it on a sweep. The storage mirror of Memory (retention vs release). | diff --git a/ORGANISM.md b/ORGANISM.md index 71f5524..2d17e8a 100644 --- a/ORGANISM.md +++ b/ORGANISM.md @@ -20,7 +20,8 @@ organs plan, build, test and release it, and you make every judgment call. | **Ears** | PyAutoEars | The Ears — the community listening organ: owns read-only public conversation collection, the versioned community snapshot contract, coverage receipts and the dashboard. GitHub conversations remain authoritative; Brain’s Community conductor owns judgement, reply drafts and development routing, and Mind owns task state. Never posts replies, labels or issues, exports raw transcripts or private sources, or treats unknown coverage as no work. | | **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** | PyAutoHands | 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. | -| **Pulse** | PyAutoPulse | Feels *how fast the organism runs* across the `_profiling` project repos. Owns the profiling instance registry, the versioned `profiling-summary` read contract, the ingest receipts (resolved commit per project per render) and the cross-project board. Validates the exchange contract only; project repos own producers, results, pins, drift policy and their own Pages page. Never moves pins, combines unmatched timings, applies the compile threshold to runtime, computes an ecosystem-wide speed score or issues a readiness verdict; the Brain's profiling conductor (`triage`) is the only judge. | +| **Pulse** | PyAutoPulse | Feels *how fast the organism runs* across the `_profiling` project repos. Owns profiling campaign intent and pending domain tasks, the profiling instance registry, the versioned `profiling-summary` read contract, the ingest receipts (resolved commit per project per render) and the cross-project board. Validates the exchange contract only; project repos own producers, results, pins, drift policy and their own Pages page. Never moves pins, combines unmatched timings, applies the compile threshold to runtime, computes an ecosystem-wide speed score or issues a readiness verdict; the Brain's profiling conductor (`triage`) is the only judge. | +| **Insight** | PyAutoInsight | Owns inference campaign intent and pending domain tasks, the cross-project inference instance registry, versioned `inference-summary` read contract, ingest receipts and evidence dashboard. Projects own execution, producers and raw samples; Cortex owns scientific run records, observations and human conclusions; Mind owns bounded implementation lifecycle and repository claims. Never infers scientific acceptance from execution, ranks incompatible runs or submits compute on refresh. | | **Nerves** | PyAutoNerves | The configuration/serialization layer (`autonerves`) — layered config with overrides, the workspace↔library version handshake, `test_mode`, FITS/JSON I/O. Connects the organism's conventions to every library; the base layer the scientific libraries all import. | | **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. | @@ -119,8 +120,13 @@ cross-project board, while each profiling project keeps its producers, results and drift policy and the Brain's profiling conductor stays the only judge. Community listening is the **Ears** (PyAutoEars), the fifth: it owns the versioned public conversation snapshot, collection coverage receipts and board. GitHub owns conversations; Brain owns judgement and approved response routing; -Mind owns tasks. Unknown or stale coverage never becomes a no-work claim. A -dashboard alone does not +Mind owns tasks. Unknown or stale coverage never becomes a no-work claim. + +**Insight** (PyAutoInsight) owns inference campaign coordination and pending +domain tasks, plus its inference exchange contract, instance registry, receipts +and evidence board. It uses project drivers and existing Brain routes, with no +new conductor. Cortex remains authoritative for scientific records and +conclusions; Mind retains implementation lifecycle and claims. A dashboard alone does not waive the state-or-effects requirement for a new organ. The human interaction layer is the command surface (`/route` + the verb commands), which is part of Brain. diff --git a/README.md b/README.md index ffcea69..760ab3b 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ repository inventory and refuses conflicting user-owned destinations. The eleven organs the Brain coordinates — Brain (reasoning), Mind (intent), Cortex (learning what is true), Memory (knowledge), Eyes (seeing the -figures), Ears (community listening), Heart (health), Hands (release), Pulse (feeling how fast it runs), +figures), Ears (community listening), Heart (health), Hands (release), Pulse (feeling how fast it runs), Insight (inference campaigns and evidence), Nerves (configuration), Gut (shedding) — are defined once in [ORGANISM.md](ORGANISM.md), which this diff --git a/agents/_pyauto_root.py b/agents/_pyauto_root.py index 435d94e..3966b70 100644 --- a/agents/_pyauto_root.py +++ b/agents/_pyauto_root.py @@ -66,6 +66,7 @@ "PyAutoHeart", "PyAutoHands", "PyAutoPulse", + "PyAutoInsight", "PyAutoNerves", "PyAutoGut", ) diff --git a/bin/_pyauto_root.sh b/bin/_pyauto_root.sh index c1bdc2c..6c38f1e 100755 --- a/bin/_pyauto_root.sh +++ b/bin/_pyauto_root.sh @@ -85,7 +85,7 @@ _pyauto_marked_root() { _pyauto_is_root() { [ -d "$1/PyAutoMind" ] || [ -d "$1/PyAutoCortex" ] || [ -d "$1/PyAutoMemory" ] \ || [ -d "$1/PyAutoEars" ] || [ -d "$1/PyAutoEyes" ] || [ -d "$1/PyAutoHeart" ] || [ -d "$1/PyAutoHands" ] \ - || [ -d "$1/PyAutoPulse" ] || [ -d "$1/PyAutoNerves" ] || [ -d "$1/PyAutoGut" ] + || [ -d "$1/PyAutoPulse" ] || [ -d "$1/PyAutoInsight" ] || [ -d "$1/PyAutoNerves" ] || [ -d "$1/PyAutoGut" ] } # Assigns PYAUTO_ROOT and PYAUTO_ROOT_REASON rather than printing: one diff --git a/board/AGENTS.md b/board/AGENTS.md index 3377fad..b11c545 100644 --- a/board/AGENTS.md +++ b/board/AGENTS.md @@ -21,7 +21,7 @@ copy-for-Claude payload: | ⏱ Test performance | the Heart board's published `performance` block — rendered verbatim, never re-derived | each row's own prompt | | 🏷️ Version consistency | the coupled-set stamps (`board: version_stamps`) | `/bug version drift: …` | | 💬 Community | the Ears (`community scan`, reused wholesale) — every open conversation gets a row | `/community`, `/community triage ` | -| 🔄 Resume | the Mind's registry + generated counts; the Cortex, Eyes and Pulse strips (each organ's own `dashboard.md` head counts, display-only, never in `state.json`); pending-release PRs | `/start_dev …`, `/prm ` | +| 🔄 Resume | the Mind's registry + generated counts; the Cortex, Eyes, Pulse and Insight strips (each organ's own `dashboard.md` head counts, display-only, never in `state.json`); pending-release PRs | `/start_dev …`, `/prm ` | | 🧹 Upkeep | open-issue count; the cleanup doors | `/issue_cleanup`, `/hygiene`, `/repo_cleanup` | | 🧼 Hygiene | the hygiene conductor's own `--json` pre-scan, run IN this render (BOARD_HYGIENE_SCAN=1; brain_board.yml checks out the body-map scan set blobless+sparse first) — no machine involved | each row's own delegate door | | 🖥️ Dev box | `state/devbox_board.json` — worktree state (unpushed/dirty/stashes — the one thing only the dev box can see; its hygiene rows render only when no cloud scan ran), pushed by `board publish` (morning.sh's last step); age-stamped, stale at 48h, dropped after 7d | — | diff --git a/board/_board.py b/board/_board.py index a98ca60..8a5c926 100755 --- a/board/_board.py +++ b/board/_board.py @@ -742,6 +742,11 @@ def collect_pulse(repo="PyAutoPulse"): return _dashboard_counts(repo, head_only=True) +def collect_insight(repo="PyAutoInsight"): + """Display owner-generated head counts; no scientific judgment or feed duplication.""" + return _dashboard_counts(repo, head_only=True) + + def collect_open_issues(org, degraded): """Total open issues across the org — the /issue_cleanup pointer count (the audit itself stays that skill's confirmation-gated job).""" @@ -950,6 +955,7 @@ def collect(): cortex = collect_cortex() eyes = collect_eyes(board_family.get("eyes", "PyAutoEyes")) pulse = collect_pulse(board_family.get("pulse", "PyAutoPulse")) + insight = collect_insight(board_family.get("insight", "PyAutoInsight")) open_issues = collect_open_issues(org, degraded) boards = {name: f"{pages_base}/{repo}/" for name, repo in board_family.items()} @@ -971,6 +977,7 @@ def collect(): "cortex": cortex, "eyes": eyes, "pulse": pulse, + "insight": insight, "open_issues": open_issues, "hygiene": collect_hygiene(degraded), "devbox": collect_devbox(), @@ -1372,6 +1379,11 @@ def render_md(data): + " · ".join(f"{k.lower()} {n}" for k, n in data["pulse"].items()) + f" — [Pulse board]({data['boards'].get('pulse', '')})") + if data.get("insight"): + L.append("- Insight: " + + " · ".join(f"{k.lower()} {n}" + for k, n in data["insight"].items()) + + f" — [Insight board]({data['boards'].get('insight', '')})") for t in data["resume"]["tasks"]: L.append(f" - `Use the start-dev skill. {t['path']}` — {t['title'][:70]}") pending = data["resume"]["pending_prs"] @@ -1769,6 +1781,13 @@ def community_row(e, note, tone): "board \u2197" + pills(*[(f"{k.lower()} {n}", "" if i == 0 else "n") for i, (k, n) in enumerate(data["pulse"].items())]))) + if data.get("insight"): + insight_url = data["boards"].get("insight", "") + H.append(_plain( + f'Inference evidence on the Insight ' + "board \u2197" + + pills(*[(f"{k.lower()} {n}", "" if i == 0 else "n") + for i, (k, n) in enumerate(data["insight"].items())]))) for t in data["resume"]["tasks"]: # An in-flight task wears the header facets the Mind gave it, so it # looks like itself on both pages — same pills, same order. diff --git a/board/_theme.py b/board/_theme.py index 8f9ceb0..a49eafa 100644 --- a/board/_theme.py +++ b/board/_theme.py @@ -139,6 +139,12 @@ # only 3.1:1 on #0d1117, so each scheme gets its own ink off the same hue: # #6420e0 (7.4:1 on #fff) and #a27aff (6.1:1 on #0d1117). Bluer than the # Memory violet, as the two logos are. + "insight": { + "organ": "Insight", + "tagline": "Infer. Inspect. Understand.", + "ink_light": "#995500", "ink_dark": "#ffc163", "glow": "#ffb347", + "hero": ("#392600", "#000000"), + }, "nerves": { "organ": "Nerves", "tagline": "Signal. Connect. Understand.", @@ -366,6 +372,10 @@ # Nerves — a neuron: branching dendrites round a nucleated soma, a # myelinated axon running right into node-tipped terminals, and the # signal arcs either side of it, inside a closed ring, as on the logo. + "insight": ( + '' + '' + ), "nerves": ( '' '' diff --git a/config/policy.yaml b/config/policy.yaml index 4d9ce41..3abfe44 100644 --- a/config/policy.yaml +++ b/config/policy.yaml @@ -128,6 +128,7 @@ test_witness: pyautoeyes: PyAutoEyes/tests pyautoears: PyAutoEars/tests pyautopulse: PyAutoPulse/tests + pyautoinsight: PyAutoInsight/tests # PyAutoGut has no test suite — deliberately absent, so the conductor's # "strengthen tests first" advice is correct there rather than noise. @@ -177,6 +178,7 @@ board: heart: PyAutoHeart hands: PyAutoHands pulse: PyAutoPulse + insight: PyAutoInsight nerves: PyAutoNerves gut: PyAutoGut organism: PyAutoScientist diff --git a/docs/concepts/organism.md b/docs/concepts/organism.md index 87c8ab1..b6e561f 100644 --- a/docs/concepts/organism.md +++ b/docs/concepts/organism.md @@ -18,6 +18,7 @@ it and adds the framework/instance distinction an adopter needs. | **Heart** | PyAutoHeart | Decides whether the organism is *healthy*. `pyauto-heart readiness` is the authoritative GREEN/YELLOW/RED release gate. An observer: never writes into other repos, never triggers a build. | | **Hands** | PyAutoHands | *Does* — packaging, tagging, notebook generation, PyPI releases. A pure executor: never re-derives a gate decision. | | **Pulse** | PyAutoPulse | *Feels* — the cross-project profiling registry, the versioned `profiling-summary` read contract, ingest receipts and dashboard. Project repos produce and hold timings; Pulse validates the exchange and links to them. The Brain's profiling conductor handles judgment. | +| **Insight** | PyAutoInsight | Coordinates inference campaign intent and domain tasks; owns the inference summary contract, registry, receipts and evidence board. Projects execute and retain samples; Cortex records scientific conclusions; Mind holds implementation lifecycle and claims. | | **Nerves** | PyAutoNerves | *Connects* — the configuration/serialization layer (`autonerves`): layered config, the workspace↔library version handshake, `test_mode`, FITS/JSON I/O. The base layer every library imports. | | **Gut** | PyAutoGut | *Sheds* — the lifecycle of condemned self-material (stale branches, stashes, dead code/tests): holds each as a durable, recoverable git ref through a transit window, then **voids** it on a sweep. The storage mirror of Memory (retention ↔ release); the hygiene conductor drives it, as vitals reads Heart. | @@ -36,7 +37,7 @@ is the container, and a workspace is one familiar kind of project. These roles do not replace the {doc}`repository categories <../satellites>` or change their workflow and release gates. Profiling, inference and visualization -repos illustrate the project role; Eyes and Pulse provide cross-project organ +repos illustrate the project role; Eyes, Pulse and Insight provide cross-project organ views over the visualization and profiling projects. The project-to-organ boundary is described in {doc}`../organs/eyes` and {doc}`../organs/pulse`. @@ -60,10 +61,10 @@ The organs split on one line that matters for adoption: pipelines. Domain facts appear only in declared config surfaces (tables and policy files, not logic), and a drift check — the {ref}`tenant firewall ` — keeps it that way. -- **Instance organs — Mind, Cortex, Memory, Eyes, Ears, Pulse, Gut.** Committed +- **Instance organs — Mind, Cortex, Memory, Eyes, Ears, Pulse, Insight, Gut.** Committed state, ledgers, knowledge, visualization and profiling registries and shed material. These are *inherently yours*: an adopter never forks the upstream - Mind, Cortex, Memory, Eyes, Ears, Pulse or Gut content, they create their own repos with the same documented + Mind, Cortex, Memory, Eyes, Ears, Pulse, Insight or Gut content, they create their own repos with the same documented shape. One more principle worth knowing before you read anything else: diff --git a/docs/index.md b/docs/index.md index d81991a..1767744 100644 --- a/docs/index.md +++ b/docs/index.md @@ -3,7 +3,7 @@ PyAutoScientist is a working, opinionated reference implementation of an **AI-agent development organism** for human-led, natural-language software development: a set of ten git repositories — Brain, Mind, Cortex, Memory, -Eyes, Ears, Heart, Hands, Pulse, Nerves, Gut — through which you lead a multi-repo project in +Eyes, Ears, Heart, Hands, Pulse, Insight, Nerves, Gut — through which you lead a multi-repo project in plain English. You describe what you want; AI agents plan, implement, test, gate and release it; you make every judgment call. @@ -62,6 +62,7 @@ organs/ears organs/heart organs/build organs/pulse +organs/insight organs/gut ``` diff --git a/docs/organs/insight.md b/docs/organs/insight.md new file mode 100644 index 0000000..d108aac --- /dev/null +++ b/docs/organs/insight.md @@ -0,0 +1,47 @@ +# Insight — PyAutoInsight + +[Dashboard](https://pyautolabs.github.io/PyAutoInsight/) · [Repository](https://github.com/PyAutoLabs/PyAutoInsight) + +Insight coordinates inference campaigns and pending domain tasks through one +editable all-inference check-in prompt, campaign table and task list. Results, +diagnostics, provenance and coverage follow below. A tracked campaign is not a +claim that a compute job is running. + +It owns the instance registry, versioned `inference-summary` exchange contract, +ingest receipts, last-good evidence snapshots and cross-project dashboard. +`autolens_inference` is the initial real producer; a fixture tests another +producer without claiming another adoption. Producers retain their dashboards, +execution drivers, results and raw samples. Organ and project feed identities +remain separate; the cockpit reads only the organ feed. + +## Ownership and routing + +Start with `PyAutoInsight/CHECKIN.md`, adding campaign focus or ideas before or +after the prompt without dropping the overall sweep. Verified updates and their +sources are recorded durably in Insight. Refreshing evidence neither records a +human check-in nor changes task or scientific status. Copy controls execute +nothing and confer no compute approval. + +Cortex remains authoritative for scientific run records, observations and human +conclusions. Mind retains bounded implementation PR lifecycle and repository +claims. Insight links both rather than maintaining independently editable copies. +Use existing project drivers, Brain faculties and development routes; there is +no inference conductor and the retired inference programme stays retired. + +## Reading evidence + +Integrity, freshness, execution status and scientific qualification are separate. +Unknown provenance stays unknown. Cached evidence retains its source age. +Failed seeds, partial pipelines and missing diagnostics or archives remain +visible. Comparison groups are producer-declared; incompatible runs are never +ranked. Overlapping stage times are not blindly summed. Heart alone owns release +readiness; Insight never turns process completion into scientific success. + +## Design history + +The 1 October proposal `research/profiling_inference_organs.md` established the +project/organ split. The 2–3 October Pulse implementation expanded ownership to +campaign intent and pending domain tasks. Insight follows that later model, +including migration mappings and the single-chat control room, rather than the +original evidence-only boundary. The human selected PyAutoInsight on 4 October +2026; canonical order is immediately after Pulse. diff --git a/docs/research/profiling_inference_organs.md b/docs/research/profiling_inference_organs.md index 8202c81..9fbae72 100644 --- a/docs/research/profiling_inference_organs.md +++ b/docs/research/profiling_inference_organs.md @@ -269,3 +269,14 @@ proposal uses public repository contracts as its inspectable evidence. [inference]: https://github.com/PyAutoLabs/autolens_inference/blob/656c348fe39e0acca7e6e92fe1f0fb3f55060dc6/AGENTS.md [cortex]: https://github.com/PyAutoLabs/PyAutoCortex/blob/b66d7fd0a20197d0283da8b802059654e891a3ec/REFERENCE.md [board]: https://github.com/PyAutoLabs/PyAutoBrain/blob/6ea15719854f19a3c9a8f2d0c828fbfdfbc8e3cc/board/state_schema.json + +## Implementation reconciliation — 4 October 2026 + +The human selected **PyAutoInsight**, key `insight`, for inference. The 2–3 +October Pulse campaign control room supersedes the evidence-only intent split +in this original proposal: Pulse and Insight own their domain campaign intent +and pending tasks. Mind retains bounded implementation PR lifecycle and claims; +Cortex retains authoritative scientific run records, observations and human +conclusions. Project producers and execution drivers remain project-owned. +Insight follows this boundary with no new conductor and no revival of the +retired inference programme. See [Insight](../organs/insight.md). diff --git a/skills/route/route.md b/skills/route/route.md index 644bfa9..106fc5c 100644 --- a/skills/route/route.md +++ b/skills/route/route.md @@ -23,6 +23,7 @@ Infer the work-type from the request using the taxonomy in | The request is about… | Route to | |-----------------------|----------| +| inference campaign updates, direction or ideas | `PyAutoInsight/CHECKIN.md`; retain the overall sweep when focusing a campaign | | a new capability, or "what should I work on next" | `/feature` | | building, shipping, releasing, publishing | `/build` | | failing tests, readiness, "is it safe / green?" | `/health` | diff --git a/tests/test_board.py b/tests/test_board.py index c54edd0..a55542c 100644 --- a/tests/test_board.py +++ b/tests/test_board.py @@ -40,6 +40,7 @@ # The Pulse organ's own counts (the head of its dashboard.md), None when # no Pulse is checked out. "pulse", + "insight", } AUTONOMY_LOG = """\ @@ -1169,3 +1170,22 @@ def test_monitoring_headline_keeps_release_verdict_separate(tmp_path): assert "Monitoring score" in page assert "72/100" in page assert "pyauto-brain health --scope dashboard" in page + + +def test_insight_strip_reads_owner_counts_without_duplicating_science(tmp_path): + stub = _fabricate(tmp_path, _default_fixtures()) + insight = tmp_path / "PyAutoInsight" + insight.mkdir() + (insight / "dashboard.md").write_text( + "# Insight\n\n| [Projects](#results) | 2 |\n| [Failed](#results) | 1 |\n\n" + "## Results\n| alpha_inference | 999 |\n") + result = _run(["--json"], tmp_path, stub) + assert result.returncode == 0, result.stderr + surface = json.loads(result.stdout) + assert surface["insight"] == {"Projects": 2, "Failed": 1} + assert surface["boards"]["insight"].endswith("/PyAutoInsight/") + page = _run(["--html"], tmp_path, stub) + assert "Insight board" in page.stdout + (insight / "dashboard.md").unlink() + result = _run(["--json"], tmp_path, stub) + assert json.loads(result.stdout)["insight"] is None diff --git a/tests/test_board_theme.py b/tests/test_board_theme.py index 129db96..bdd743e 100644 --- a/tests/test_board_theme.py +++ b/tests/test_board_theme.py @@ -203,7 +203,7 @@ def test_board_links_reads_the_declared_family_in_file_order(): # the order `config/policy.yaml` declares — the ruled organ order. links = _theme.board_links("https://example.invalid") assert list(links) == ["brain", "mind", "cortex", "memory", "eyes", "ears", - "heart", "hands", "pulse", "nerves", "gut", "organism"] + "heart", "hands", "pulse", "insight", "nerves", "gut", "organism"] assert list(links) == POLICY_BOARDS assert links["cortex"] == "https://example.invalid/PyAutoCortex/" @@ -226,7 +226,7 @@ def test_board_links_renders_the_family_footer_end_to_end(): _theme.board_links("https://example.invalid", "heart"), "heart") order = re.findall(r'data-organ="(\w+)"', footer) assert order == ["brain", "mind", "cortex", "memory", "eyes", "ears", "hands", - "pulse", "nerves", "gut", "organism"] + "pulse", "insight", "nerves", "gut", "organism"] def test_board_links_returns_nothing_when_the_config_is_unreadable(): diff --git a/tests/test_workspace_root.py b/tests/test_workspace_root.py index 8388fc5..d39e6c0 100644 --- a/tests/test_workspace_root.py +++ b/tests/test_workspace_root.py @@ -308,3 +308,8 @@ def test_env_override_is_honoured_and_the_marker_only_changes_the_reason(tmp_pat # Either way it beats the marker this checkout actually sits under. assert elsewhere != root + + +def test_insight_only_sibling_marks_workspace_in_both_resolvers(tmp_path): + root, brain = _fake_workspace(tmp_path, also=("PyAutoInsight",), marker=False) + assert _both_resolvers_say(brain) == (root, "beside this checkout")