Hold — design discussion, not a task. This is a proposal for maintainer
discussion. Please do not implement it, decompose it into sub-issues, or relay it
to contributors until the design is settled. The hold label should stay applied.
Status: Proposal
Scope: hive.yaml schema, policy resolution, MITM proxy enforcement, dashboard
Out of scope (deferred): fully independent per-repo levels, per-repo governor cadence
Summary
Allow each repo in project.repos to run at its own ACMM level, bounded above by the hive-wide level. The hive level continues to drive the agent roster and becomes the ceiling for the hive; a new project.acmm_default sets the level for repos that do not declare one; a per-repo acmm overrides the default. The effective policy mode for every agent is resolved per (agent, repo). Enforcement lives in the deterministic layer (the MITM GitHub proxy and merge-gate scripts), not in agent prompts.
This is the smallest change that lets one hive manage repos at different maturity levels. Keeping the hive level as a ceiling, rather than letting repos exceed it, means roster reconciliation, the governor, and the single-number dashboard are untouched.
Motivation
The ACMM level is currently a property of the hive: applying a level reconciles the whole roster and sets one policy mode per agent. But the thing that earns a level is test coverage, and coverage is a per-repo fact. The ACMM Eval page already scores Codebase Readiness per repo. A hive with one repo at 85% coverage and another at 30% has no honest single level today; the operator either runs the whole fleet at the level the weakest repo justifies, or lets agents open PRs against a repo that has not built the safety net L3 is supposed to establish.
The current workaround is one hive per maturity level. That works for organizational boundaries (separate teams, separate trust domains) but is the wrong tool for a single operator with a handful of repos: it duplicates the Go process, dashboard, agent tmux sessions, and fixed-cadence inference spend, and it fragments the governor's view of workload.
Concrete cases:
- Mixed-maturity org. A team onboards ten repos. Three have coverage gates and CI; seven do not. Today the hive runs at L2 for all of them, and the three ready repos get no benefit from the hold-gated PRs they have earned.
- Ramping one repo at a time. An operator wants to take one repo through the L2 to L4 readiness work without the other repos in the hive receiving agent-filed issues.
- Low-attention repo at high autonomy. A repo that has earned L6 but is not under active development can be left on auto-merge while the operator's attention is elsewhere, with the rest of the hive staying at L5 or lower.
- Safe onboarding. A newly added repo should land at a conservative level by default, not at whatever the most trusted repo in the hive runs at.
Proposal
Schema
project:
org: my-org
acmm_default: 5 # optional; defaults to the hive level
repos:
- name: atomic-image-builder
acmm: 6
- name: arch-bootc
acmm: 2
- name: aurora-zfs-simple # no acmm: runs at acmm_default
primary_repo: atomic-image-builder
repos entries currently accept a bare string. The bare-string form stays valid and means "use acmm_default." A repo may also be an object with name (required) and acmm (optional, integer 1 to 6). Any other keys are rejected at config load so the schema is not silently misused.
acmm_default is optional. When absent it equals the hive level, so an existing config with no per-repo entries behaves exactly as today.
Semantics
hive_level is the level applied via the dashboard or config. It drives roster reconciliation exactly as today, and it is the ceiling: no repo runs above it.
effective_level(repo) = min(hive_level, repo.acmm) when acmm is set, otherwise min(hive_level, acmm_default).
- For a given agent and repo, the effective policy mode is the mode the policy matrix (
src/docs/acmm-policy-matrix.md) assigns that agent at effective_level(repo).
- A repo
acmm (or acmm_default) above hive_level is legal, clamps to the ceiling, and produces a config-load warning. Allowing it lets an operator pre-declare which repos are cleared for a higher level before raising the hive; warning on it keeps the clamp visible.
Why the ceiling is set independently rather than derived. It is the one check that does not depend on the per-repo resolution being correct. If the proxy cannot parse a repo from some endpoint path, or a gate script reads the wrong key, or a repo is added through a path that skips the default, the hive level is what the authorization falls back to. An operator who sets the ceiling no higher than a repo actually needs keeps that failsafe meaningful; a convention of always setting L6 discards it.
Worked example: an operator wants most repos at L5 and one repo on full auto-merge. Set hive_level: 6, acmm_default: 5, and acmm: 6 on the one repo. Repos added later land at L5.
Enforcement
The design rule Hive already follows applies here: if a human would give the same answer every time, it belongs in infrastructure, not in a prompt. Whether an agent may open a PR against a repo is such a decision.
Enforcement points, in order of importance:
- MITM GitHub proxy. The proxy currently authorizes agent GitHub calls against the hive-level policy mode for the calling agent. It needs to resolve the target repo from the request path and authorize against the effective mode for (agent, repo) instead. This is the load-bearing change; without it, a model swap or a loosely interpreted prompt bypasses the cap.
- Merge-gate and auto-merge scripts. These already run in repo context. They should read the effective level for the repo rather than the hive level when deciding whether a PR may be labeled for merge or merged.
- Task filtering. The deterministic pipeline that assembles an agent's work should not hand an agent a task on a repo where its effective mode does not permit the action the task requires. This is a quality-of-life change (avoids wasted inference on work the proxy will reject), not a security boundary.
- Agent prompt context. Agents should be told the effective level for the repo they are working, so they do not attempt actions that will be refused. This is informational only and must not be the only place the cap is checked.
Dashboard
- The sidebar ACMM badge continues to show
hive_level, labeled as the ceiling when any repo runs below it, with acmm_default shown alongside.
- The per-repo view (or the ACMM Eval page, which is already per-repo) shows the effective level and where it came from (explicit, default, or clamped).
- The level-change dialog lists each repo's effective level after the change, so an operator raising the hive to L6 sees which repos will actually move and which stay where they are.
Reconciliation
No change. The roster is a function of hive_level. An architect that exists because the hive is L5 is simply advisory-mode when it touches an L2 repo; it is not spun down.
What this deliberately does not do
- Repos above the hive level. The hive level remains the ceiling. Letting a repo exceed it would make the roster a union across repos and force decisions about which level cross-repo agents (strategist, architect planning across repos) run at. Since the operator controls the ceiling, this costs nothing in practice: set the hive to the highest level any repo needs and use
acmm_default to keep the rest lower. The only visible consequence is that the hive-level number reads as "maximum allowed" rather than "what everything runs at."
- Per-repo governor cadence. Cadence stays per agent and hive-wide. An agent running advisory on some repos will still wake on the hive-wide cadence; the cheap fix is task filtering so it has nothing to do there.
- Per-repo agent enablement. Disabling an agent for one repo is a different feature and should be its own proposal.
Migration and compatibility
- Existing configs with bare-string
repos entries and no acmm_default load unchanged; every repo runs at the hive level.
- Hives with no per-repo levels behave identically to today at every enforcement point.
hive.yaml download and backup include the new fields.
- The hub API, if it reports a hive's level, continues to report
hive_level.
Testing
- Config: bare string and object forms both load; unknown keys rejected;
acmm and acmm_default out of range rejected; values above the hive level clamp with a warning.
- Resolution: table-driven test of
effective_level over (hive_level, acmm_default, repo acmm) combinations, including absent values.
- Proxy: for each (agent, action) cell in the policy matrix, a request against a repo running below the hive level is refused when the effective mode does not permit it and allowed when it does. Table-driven over the matrix, not hand-picked cases.
- Merge gate: a PR on a repo at L5 is not auto-merged even when the hive is L6; a PR on the one repo at L6 is.
- Regression: a hive with no per-repo levels passes the existing ACMM level test suite unchanged.
Alternatives considered
- Multiple hives. Works today. Correct for separate trust domains; expensive and fragmenting for one operator. Also does not compose with the governor, which sees only its own hive's queue.
- Per-repo levels with no hive ceiling. Strictly more general, meaningfully more invasive (roster union, cross-repo agent semantics, dashboard rework), and it buys nothing the operator cannot get by raising the ceiling. Proposed as a follow-on only if a concrete need appears.
- Derive the hive level instead of setting it.
hive_level = max(effective levels), reconciling the roster to that. One fewer knob to keep in sync, no clamp warnings, no "why is my repo not at the level I set." Rejected for two reasons: it removes the hive-wide failsafe described under Semantics, since there is no longer an independently-set bound to fall back to when per-repo resolution fails; and it makes level changes an implicit consequence of editing a repo entry rather than a deliberate action behind the dashboard's confirmation dialog. Worth revisiting if the per-repo path proves reliable enough that the failsafe is dead weight.
- Cap-only (no
acmm_default). Simpler schema, but forces the hive level to double as the default for new repos, so a hive with one L6 repo would onboard every new repo at L6. Rejected as an unsafe default.
- Prompt-only enforcement. Rejected. Contradicts the deterministic-layer rule and has already been observed to fail in practice when an agent's model changes.
Open questions
- Does the proxy currently see the target repo for every authorized call, or are there endpoints (search, org-level listing) where the repo is not in the path? Those need a documented rule (authorize at the lowest effective level in the hive, or treat as read-only).
- Should per-repo
acmm be settable from the dashboard, or config-only for a first version? Config-only keeps the change small and matches how repos are declared today.
- Should the ACMM Eval page's Codebase Readiness score be offered as a suggested per-repo level, one click to apply? Useful, but optional and easy to add later.
- Should raising
hive_level via the dashboard also raise acmm_default, or leave it? Leaving it is safer and matches the "ceiling" reading; the dialog should say which it does.
Related
src/docs/acmm-policy-matrix.md (policy mode per agent per level)
- ACMM Eval / Codebase Readiness (already per-repo)
- Hive federation design (the multi-hive alternative)
Status: Proposal
Scope: hive.yaml schema, policy resolution, MITM proxy enforcement, dashboard
Out of scope (deferred): fully independent per-repo levels, per-repo governor cadence
Summary
Allow each repo in
project.reposto run at its own ACMM level, bounded above by the hive-wide level. The hive level continues to drive the agent roster and becomes the ceiling for the hive; a newproject.acmm_defaultsets the level for repos that do not declare one; a per-repoacmmoverrides the default. The effective policy mode for every agent is resolved per (agent, repo). Enforcement lives in the deterministic layer (the MITM GitHub proxy and merge-gate scripts), not in agent prompts.This is the smallest change that lets one hive manage repos at different maturity levels. Keeping the hive level as a ceiling, rather than letting repos exceed it, means roster reconciliation, the governor, and the single-number dashboard are untouched.
Motivation
The ACMM level is currently a property of the hive: applying a level reconciles the whole roster and sets one policy mode per agent. But the thing that earns a level is test coverage, and coverage is a per-repo fact. The ACMM Eval page already scores Codebase Readiness per repo. A hive with one repo at 85% coverage and another at 30% has no honest single level today; the operator either runs the whole fleet at the level the weakest repo justifies, or lets agents open PRs against a repo that has not built the safety net L3 is supposed to establish.
The current workaround is one hive per maturity level. That works for organizational boundaries (separate teams, separate trust domains) but is the wrong tool for a single operator with a handful of repos: it duplicates the Go process, dashboard, agent tmux sessions, and fixed-cadence inference spend, and it fragments the governor's view of workload.
Concrete cases:
Proposal
Schema
reposentries currently accept a bare string. The bare-string form stays valid and means "useacmm_default." A repo may also be an object withname(required) andacmm(optional, integer 1 to 6). Any other keys are rejected at config load so the schema is not silently misused.acmm_defaultis optional. When absent it equals the hive level, so an existing config with no per-repo entries behaves exactly as today.Semantics
hive_levelis the level applied via the dashboard or config. It drives roster reconciliation exactly as today, and it is the ceiling: no repo runs above it.effective_level(repo) = min(hive_level, repo.acmm)whenacmmis set, otherwisemin(hive_level, acmm_default).src/docs/acmm-policy-matrix.md) assigns that agent ateffective_level(repo).acmm(oracmm_default) abovehive_levelis legal, clamps to the ceiling, and produces a config-load warning. Allowing it lets an operator pre-declare which repos are cleared for a higher level before raising the hive; warning on it keeps the clamp visible.Why the ceiling is set independently rather than derived. It is the one check that does not depend on the per-repo resolution being correct. If the proxy cannot parse a repo from some endpoint path, or a gate script reads the wrong key, or a repo is added through a path that skips the default, the hive level is what the authorization falls back to. An operator who sets the ceiling no higher than a repo actually needs keeps that failsafe meaningful; a convention of always setting L6 discards it.
Worked example: an operator wants most repos at L5 and one repo on full auto-merge. Set
hive_level: 6,acmm_default: 5, andacmm: 6on the one repo. Repos added later land at L5.Enforcement
The design rule Hive already follows applies here: if a human would give the same answer every time, it belongs in infrastructure, not in a prompt. Whether an agent may open a PR against a repo is such a decision.
Enforcement points, in order of importance:
Dashboard
hive_level, labeled as the ceiling when any repo runs below it, withacmm_defaultshown alongside.Reconciliation
No change. The roster is a function of
hive_level. An architect that exists because the hive is L5 is simply advisory-mode when it touches an L2 repo; it is not spun down.What this deliberately does not do
acmm_defaultto keep the rest lower. The only visible consequence is that the hive-level number reads as "maximum allowed" rather than "what everything runs at."Migration and compatibility
reposentries and noacmm_defaultload unchanged; every repo runs at the hive level.hive.yamldownload and backup include the new fields.hive_level.Testing
acmmandacmm_defaultout of range rejected; values above the hive level clamp with a warning.effective_levelover (hive_level, acmm_default, repo acmm) combinations, including absent values.Alternatives considered
hive_level = max(effective levels), reconciling the roster to that. One fewer knob to keep in sync, no clamp warnings, no "why is my repo not at the level I set." Rejected for two reasons: it removes the hive-wide failsafe described under Semantics, since there is no longer an independently-set bound to fall back to when per-repo resolution fails; and it makes level changes an implicit consequence of editing a repo entry rather than a deliberate action behind the dashboard's confirmation dialog. Worth revisiting if the per-repo path proves reliable enough that the failsafe is dead weight.acmm_default). Simpler schema, but forces the hive level to double as the default for new repos, so a hive with one L6 repo would onboard every new repo at L6. Rejected as an unsafe default.Open questions
acmmbe settable from the dashboard, or config-only for a first version? Config-only keeps the change small and matches how repos are declared today.hive_levelvia the dashboard also raiseacmm_default, or leave it? Leaving it is safer and matches the "ceiling" reading; the dialog should say which it does.Related
src/docs/acmm-policy-matrix.md(policy mode per agent per level)