diff --git a/AUTONOMY.md b/AUTONOMY.md index be8e3c1..d47f630 100644 --- a/AUTONOMY.md +++ b/AUTONOMY.md @@ -50,13 +50,24 @@ A prompt's header never exceeds its work-type cap. The **effective level** is | Work-type | Cap | Why | |-----------|-----|-----| | `refactor`, `test`, `maintenance` | `safe` | behaviour-preserving by definition; tests + review are a near-complete gate | -| `feature`, `bug`, `docs` | `supervised` | until the calibration log justifies raising | +| `feature`, `docs` | `safe` at Difficulty ≤ `medium`; `supervised` at `large` and above | raised 2026-07-09 on calibration evidence (see "Calibration review — 2026-07-09") | +| `bug` | `supervised` | the log holds too few bug rows to justify raising (graduation rule below) | | `research`, `experiment` | `supervised` | output is judgment-shaped | | `release` | `human-required` | always; no autonomy level ships a release | Raising a cap is a doctrine edit to this page and must cite calibration-log evidence. +### Graduation and demotion + +A cap may rise one level only when the calibration log holds **≥ 10 clean +rows** for that work-type since the last doctrine edit — *clean* means outcome +`merged-unchanged`, or `amended` where the amendment was a human-directed +scope addition rather than a correction of the run's own work — and **zero +`rejected`** rows over the same window. Any `rejected` row demotes that +work-type's cap one level immediately, pending a review that cites the row. +Both directions are dated doctrine edits to the table above, citing rows. + ## Activation - Levels bind **only** when the human launches with an explicit `--auto`. @@ -118,13 +129,18 @@ applicability rule so "n/a" is a stated fact, never an assumption: 3. **Review** — review-faculty verdict **CLEAN** (`agents/faculties/review/AGENTS.md`). FINDINGS → resolve and re-review, or park to a human checkpoint; BLOCKED → park. -4. **Heart** — verdict **GREEN**, or **YELLOW whose reason set is contained - in the set the human acknowledged at launch**. Heart observes organism - state, not the branch (the audit confirmed its legs never see feature - branches), and chronic staleness reasons would otherwise dead-end all - autonomy. The acknowledgement binds to the *exact reason list* at launch, - for that launch only — any new reason, or RED, parks the run. Never - ambient, never carried across sessions. +4. **Heart** — verdict **GREEN** or **STALE**, or **YELLOW whose reason set is + contained in the set the human acknowledged at launch**. Heart observes + organism state, not the branch (the audit confirmed its legs never see + feature branches). **STALE** is Heart's freshness tier (evidence missing or + expired, nothing known-bad — `PyAutoHeart/heart/readiness.py`): it passes + this leg because an evidence gap is organism-scope, not branch-scope, and + legs 1–3 gate the branch itself; the PR body lists the stale reasons. + Releases are unaffected — they always require GREEN. A verdict from a Heart + without the tier behaves as before. For YELLOW, the acknowledgement binds + to the *exact reason list* at launch, for that launch only — any new + reason, or RED, parks the run. Never ambient, never carried across + sessions. A failed leg downgrades the run to a human checkpoint: state written to the issue, nothing force-shipped, never modify code to make a leg pass. @@ -142,6 +158,27 @@ Outcome ∈ `merged-unchanged` / `amended` / `rejected` / `parked`. This is the evidence base for raising or lowering caps — autonomy grows by demonstrated calibration, not by optimism. +### Calibration review — 2026-07-09 + +First review, over 59 rows (2026-07-08 → 2026-07-09): **zero `rejected`**; +26 runs reached merge — 23 `merged-unchanged`, 3 `amended`, and all three +amendments were human-directed scope additions mid-run, not corrections of the +run's own work. All 3 `safe`-level rows (refactors) merged unchanged through +the four-leg gate. Human ship sign-off added no delta in 23 of 26 merged +supervised runs — exactly the evidence the caps table anticipated. + +Result: `feature` and `docs` raised to `safe` at Difficulty ≤ `medium`. The +conception heuristic (`infer_autonomy`) already marks large, multi-repo and +architecturally risky prompts `supervised`, so the work-type cap was the +binding clamp for small/medium single-repo work; raising it makes the +already-conservative header effective. `bug` stays `supervised` — the window +holds almost no pure bug rows. + +One constant across all 59 rows: Heart never read GREEN — every shipped run +went out on an acked YELLOW. That is ack-fatigue risk, addressed by making +Heart's verdict distinguish stale evidence from bad evidence (the freshness +tier), never by weakening leg 4. + ## Hard invariants (every level, no exceptions) - **Merge and issue-close are human acts.** An explicit future flag may extend diff --git a/agents/conductors/intake/AGENTS.md b/agents/conductors/intake/AGENTS.md index 483f8f1..739b3db 100644 --- a/agents/conductors/intake/AGENTS.md +++ b/agents/conductors/intake/AGENTS.md @@ -60,6 +60,16 @@ Proposed path · Header (the block written verbatim) · Risks · Next action (`low|normal|high`) — the "can an agent safely handle this?" and "how urgent?" inputs, written into the header. +**`too-large` means decompose, never dispatch.** A prompt sized `too-large` is +not an executable unit of work — no conductor takes it to `start_dev` directly. +The route is a decomposition pass first: rewrite it as a sequenced series of +`small`/`medium` prompts, each with concrete acceptance criteria and stated +dependencies on its predecessors (the psf-oversampling series is the model: +one too-large idea → 8 phased prompts, all shipped). The original prompt +becomes the series' tracker or is retired. Decomposition is planning judgment — +it stays with the strongest available model; the resulting phases are what the +cheaper execution models run. + ## The header — extend the blessed convention, never YAML Writes the light header PyAutoMind blesses (`README.md` "Prompt file format"), diff --git a/agents/faculties/review/AGENTS.md b/agents/faculties/review/AGENTS.md index d140337..2abecb0 100644 --- a/agents/faculties/review/AGENTS.md +++ b/agents/faculties/review/AGENTS.md @@ -64,6 +64,33 @@ Exit codes: `0` surface produced · `4` no reviewable diff / could not resolve `5` bad usage. The script never exits non-zero for *findings* — findings are the agent's judgment, not the script's. +## Recurring-defect rubric (organism-specific) + +Checked on every review, alongside the generic correctness pass. These are the +defects that have actually recurred in this stack — each earned its line; +operational mechanics live in [`../../../skills/OPERATIONS.md`](../../../skills/OPERATIONS.md). + +- **Silent `None`-guards.** A guard that swallows bad input hides the bug — + the fix belongs at the producer; bad data must crash loudly. Flag any new + `if x is None: return …` that papers over an upstream defect. +- **JAX in library unit tests.** Library test suites are numpy-only; cross-xp + checks live in the `*_workspace_test` repos. Flag any `import jax` (or + jax-only fixture) added under a library's `test_*` tree. +- **Misplaced guard tests.** Install/smoke/cross-package JAX guards do not go + in library test dirs — they belong in `workspace_test` / `verify_install`. +- **Grown smoke lists.** `smoke_tests.txt` is a small curated subset; a diff + that adds entries to make a gate feel stronger is a finding, not a feature + (`AUTONOMY.md`, smoke leg). +- **Dishonest JAX benchmarks.** A perf claim measured through a single JIT + trace of `pure_callback`-bearing code is const-folded and inflated; require + vmap-based numbers. Likewise flag closures created per-call (JIT + cache-bust) presented as "fast". +- **Workspace-ship hygiene.** New output dirs need `.gitignore` cover; new + library `output.yaml` keys need mirroring into workspace configs; CRLF + files must keep their line endings (see OPERATIONS.md "Diff hygiene"). +- **Env mutation.** `os.environ` writes inside scripts where + `config/build/env_vars.yaml` is the override surface. + ## What this faculty must never do - Dispatch, mutate, fix, comment, or open PRs/issues — it only opines. diff --git a/agents/faculties/sizing/_sizing.py b/agents/faculties/sizing/_sizing.py index 9eec7ce..a6fbabe 100755 --- a/agents/faculties/sizing/_sizing.py +++ b/agents/faculties/sizing/_sizing.py @@ -19,6 +19,13 @@ off (mirrors PyAutoMind/ROUTING.md). It is intentionally dependency-free (stdlib only) and never writes anything. + +Calibration status: reviewed 2026-07-09 against the first 59 rows of +PyAutoMind/autonomy_log.md (AUTONOMY.md "Calibration review — 2026-07-09"). +The conception heuristics held — zero rejected outcomes; the work-type cap, +not this estimate, was the binding clamp — so the scoring below is unchanged. +`too-large` is a routing signal, not a difficulty grade: such prompts go to a +decomposition pass, never straight to dispatch (intake AGENTS.md). """ from __future__ import annotations diff --git a/agents/faculties/vitals/AGENTS.md b/agents/faculties/vitals/AGENTS.md index 205771f..40ecfea 100644 --- a/agents/faculties/vitals/AGENTS.md +++ b/agents/faculties/vitals/AGENTS.md @@ -68,8 +68,12 @@ faculty every cycle.) ```bash pyauto-heart readiness --json ``` - This returns `{ verdict, score, red_reasons[], yellow_reasons[], ts }`. The - `verdict` is Heart's decision — adopt it; do not re-derive it from raw checks. + This returns `{ verdict, score, red_reasons[], yellow_reasons[], + stale_reasons[], ts }`. The `verdict` is Heart's decision — adopt it; do not + re-derive it from raw checks. Verdicts are GREEN / STALE / YELLOW / RED; + STALE is the freshness tier (evidence missing or expired, nothing + known-bad — remedy is re-running the named checks). A verdict from an older + Heart without `stale_reasons` behaves as before (the tier is additive). If the command is unavailable, fall back to the persisted `~/.pyauto-heart/release_ready.json`; if neither exists, the verdict is **unknown -> treat as YELLOW** and recommend running `pyauto-heart tick`. diff --git a/agents/faculties/vitals/HEART_CAPABILITIES.md b/agents/faculties/vitals/HEART_CAPABILITIES.md index c0a5072..d01ead8 100644 --- a/agents/faculties/vitals/HEART_CAPABILITIES.md +++ b/agents/faculties/vitals/HEART_CAPABILITIES.md @@ -8,7 +8,7 @@ reimplement inside Brain. - `pyauto-heart tick` — refreshes the cached health snapshot. - `pyauto-heart status` — renders the cached state. -- `pyauto-heart readiness` — emits the authoritative GREEN / YELLOW / RED gate. +- `pyauto-heart readiness` — emits the authoritative GREEN / STALE / YELLOW / RED gate. - `pyauto-heart readiness --json` — machine-readable gate for agents/scripts. - `pyauto-heart dashboard [--oneline|--md|--html|--json|--badge]` — the ONE unified health board (verdict + every check + release-validation state); reads @@ -47,7 +47,8 @@ reimplement inside Brain. `validation_report.json` (`~/.pyauto-heart/validation_report.json`). - The report is a **hard readiness gate**: GREEN-for-release requires a fresh passing report whose `commit_shas` match the current `main` HEADs under the - `release` profile; absent/stale/SHA-mismatch/wrong-profile → YELLOW; a failed + `release` profile; absent/stale/SHA-mismatch/wrong-profile → STALE (an evidence gap: re-run + the rehearsal, don't fix code); a failed stage → RED. It is exposed as the `validate` capability + `validation_report` signal in Heart's `health_agent/capabilities.yaml`. - **Heart is ingest-and-judge only** — it never dispatches `release.yml` or @@ -102,8 +103,13 @@ logic, migrate that logic to PyAutoHeart and leave only delegation in PyAutoBuil - GREEN: Heart reports no blocking or cautionary issues. Build may proceed automatically if the calling agent requested execution. -- YELLOW: Heart reports warnings or unknowns. Work may proceed, but human review - is recommended before release/deployment. +- STALE: the freshness tier — nothing known-bad, but named evidence is missing + or expired. **Releases still require GREEN**: recommend re-running the named + checks (never code fixes), then re-read. The dev-ship gate (`AUTONOMY.md` + leg 4) treats STALE as passing — evidence gaps are organism-scope, not + branch-scope. +- YELLOW: Heart reports warnings on current evidence. Work may proceed, but + human review is recommended before release/deployment. - RED: Heart reports blocking issues. Build must not proceed automatically. The vitals faculty may explain, rank, and recommend actions from Heart output, but diff --git a/skills/OPERATIONS.md b/skills/OPERATIONS.md new file mode 100644 index 0000000..fb4cf60 --- /dev/null +++ b/skills/OPERATIONS.md @@ -0,0 +1,58 @@ +# Operational gotchas (canonical) + +Hard-won operational fixes that every agent — Claude, Codex, or otherwise — +needs and none can derive from the code. One entry per gotcha: the failure, +then the working move. Skills link here instead of restating; if you are +writing one of these workarounds into a skill body, stop and add it here. + +These were distilled 2026-07-09 from session-memory lessons that had never +been written into the repos. Add new entries the same way: when a workaround +gets rediscovered twice, it belongs here. + +## GitHub CLI fallbacks + +- **`gh pr create` fails on SSH remotes.** When `origin` is an SSH URL it can + refuse to resolve the repo. Fallback: + `gh api repos///pulls -f title=… -f head= -f base=main -f body=…` + then add labels with `gh api repos///issues//labels -f "labels[]=pending-release"`. +- **`gh issue close` is broken** (prints usage and fails). Comment first, then + `gh api -X PATCH repos///issues/ -f state=closed`. +- **`gh pr edit` fails on repos with classic Projects** (GraphQL `projectCards` + error aborts the whole edit). Use + `gh api -X PATCH repos///pulls/ -f body=…` instead. + +## Diff hygiene + +- **CRLF files exist in PyAutoArray.** A scripted `open()`/`write()` edit + normalises CRLF→LF and 10×'s the diff. Before scripted edits, check + `grep -c $'\r$' `; preserve the file's existing line endings. +- **Workspace ships can leak binary outputs.** New `images/`/output dirs are + not always gitignored. Pre-flight every workspace ship with + `git diff --stat` + `git status --short` and extend `.gitignore` before + committing, never after. + +## Config and environment + +- **Smoke/env overrides live in `config/build/env_vars.yaml`**, not in + `os.environ` mutations inside scripts. Fix the override file. +- **`PYAUTO_TEST_MODE` namespaces output under `output/test_mode/`.** Any + manually composed output path must include that segment or asserts read the + wrong tree. +- **autoconf lowercases YAML dict keys** (`muJy` → `mujy`). Keep config keys + and the registries that read them snake-case-lowercase from the start. +- **New library `output.yaml` keys need mirroring** into each workspace's + config copy — workspace configs override library defaults, so a key added + only in the library silently stays off for workspace users. +- **Tools under `admin_jammy` resolve through their symlink**: + `Path(__file__).resolve()` lands at the canonical checkout, not the + worktree you invoked from. Pass `--root` or use the cwd. + +## JAX measurement traps + +- **`pure_callback` constant-folds under a single JIT trace** — the callback + result gets baked in as an XLA constant and the op looks 20–30× faster than + it is. Benchmark through `vmap` (e.g. `fitness._vmap(jnp.array(params))`), + which is honest; never trust a single-JIT timing of callback-bearing code. +- **A closure created fresh per call cache-busts the JIT.** A new function + object is a new cache key, so every call recompiles. Cache the + (closure, solver) pair on the instance. diff --git a/skills/ship_library/reference.md b/skills/ship_library/reference.md index a95e391..a4fd724 100644 --- a/skills/ship_library/reference.md +++ b/skills/ship_library/reference.md @@ -91,6 +91,8 @@ Build/release step. Per repo, after the vitals faculty / Heart verdict is GREEN: `pending-release` is absent, stop and report — usually the label doesn't exist on the repo; fix with `bash admin_jammy/software/ensure_workspace_labels.sh` then `gh pr edit --add-label pending-release`. + If `gh pr create`/`gh pr edit` errors (SSH-URL origin, classic-Projects + GraphQL failure), use the `gh api` fallbacks in `skills/OPERATIONS.md`. 5. Return a structured summary: one line per repo with test pass/fail counts, commit SHA, and PR URL. diff --git a/skills/ship_workspace/reference.md b/skills/ship_workspace/reference.md index 8fa57a1..904edc9 100644 --- a/skills/ship_workspace/reference.md +++ b/skills/ship_workspace/reference.md @@ -41,6 +41,8 @@ step. Per workspace repo, after the readiness gate is GREEN: (paste the drafted body verbatim via HEREDOC). Verify the label landed (`gh pr view --json labels --jq '[.labels[].name]'`); if absent, fix with `ensure_workspace_labels.sh` + `gh pr edit --add-label pending-release`. + If `gh pr create`/`gh pr edit` errors (SSH-URL origin, classic-Projects + GraphQL failure), use the `gh api` fallbacks in `skills/OPERATIONS.md`. 5. If a library PR URL was passed in, cross-reference it: `gh pr comment --body "Workspace PR: "`. 6. Return a structured summary: one line per workspace with smoke pass/fail,