Files
stack/packages/mosaic/framework/defaults/STANDARDS.md
T
Hermes Agent e3a0ee87b3 framework: make tool discoverability, workspace placement and model tiering mechanical
An undocumented tool is, from inside an agent session, indistinguishable from a
tool that was never written. The framework shipped 26 git wrappers and named 6 of
them in its resident index docs — 23% discoverability, with pr-review.sh among the
missing. The observable consequence was an agent obeying Constitution gate 7 as
best it could see it, reaching for raw curl, sending GitHub's APPROVE to a Gitea
host, and getting HTTP 200 with the review silently filed PENDING. Three times.
That is not a discipline failure and no amount of prose fixes it.

Four changes, each converting a rule that decayed into a mechanism that cannot:

- check-tools-index.sh (new, CI-blocking): every tool in an enforced suite must be
  named in a resident index doc, and every tool an index names must exist. The git
  suite is enforced now; other suites report coverage without failing, so the
  ratchet tightens one reviewed PR at a time instead of landing as one sweep. The
  enforced list is framework-owned rather than a marker inside operator-owned
  TOOLS.md — a doc marker would let an operator silence the gate on exactly the
  host where it matters most. Carries --self-test, because a checker that only
  ever passes is indistinguishable from one that is not running.

- TOOLS-REFERENCE.md: complete 28-entry git index, plus the APPROVED/APPROVE
  dialect note that explains why pr-review.sh is not a formality.

- mosaic-worktree.sh + wrapper-guard.sh (upstreamed): the rule "big work goes on a
  work filesystem" already existed in prose, and 255 GB accumulated in $HOME across
  842 directories anyway, under five simultaneous placement conventions on one
  host. The helper therefore exposes no placement decision — given a branch name,
  every path is derived from `git worktree list --porcelain`. Worktrees rather than
  clones because enumerability is the only thing that makes reclaim safe, and
  reclaim is by evidence (clean tree + no unpushed commits), never by size or age.
  The guard blocks three mechanically-detectable mistakes and nothing else:
  a checkout into $HOME, a raw provider-API write to an endpoint that has a
  wrapper, and the literal APPROVE event. Reads pass untouched.

- STANDARDS.md: model tiering as a standard, named by capability class so it
  survives a model generation. Start cheapest, escalate on evidence, benchmark
  before demoting a task class, and keep the class->model binding in operator
  config with the DB-backed config service as the end state.

Registering the guard in runtime/claude/settings.json is the point of upstreaming
it: ~/.claude/settings.json is a framework-managed copy, so a hand-added hook there
is destroyed by the next upgrade. In the template it survives, and it reaches every
host instead of one.
2026-08-12 16:51:17 -05:00

6.0 KiB

Mosaic Universal Agent Standards

This file is the canonical standards contract for agent sessions on this machine.

Master/slave model:

  • Master: ~/.config/mosaic (this framework)
  • Slave: each repo bootstrapped via mosaic-bootstrap-repo

Execution Model

  1. Load this file first.
  2. Load project-local AGENTS.md next.
  3. Respect repository-specific tooling and workflows.
  4. Use lifecycle scripts when available (scripts/agent/*.sh).
  5. Use shared tools/guides from ~/.config/mosaic as canonical references.

Non-Negotiables

  • Data files are authoritative; generated views are derived artifacts.
  • Pull before edits when collaborating in shared repos.
  • Run validation checks before claiming completion.
  • Apply quality tools from ~/.config/mosaic/tools/ when relevant (review, QA, git workflow).
  • For project-level mechanical enforcement templates, use ~/.config/mosaic/tools/quality/ via ~/.config/mosaic/bin/mosaic-quality-apply.
  • For runtime-agnostic delegation/orchestration, use ~/.config/mosaic/tools/orchestrator-matrix/ with repo-local .mosaic/orchestrator/ state.
  • Avoid hardcoded secrets and token leakage in remotes/commits.
  • Do not perform destructive git/file actions without explicit instruction.
  • Browser automation (Playwright, Cypress, Puppeteer) MUST run in headless mode. Never launch a visible browser — it collides with the user's display and active session.

Secrets handling (HARD RULE)

  • Vault is the canonical source-of-truth for every secret in every environment. No exceptions.
  • For k8s workloads, the default read path is External Secrets Operator → k8s Secret → env var (secretKeyRef). The app reads standard env vars; no Vault client in app code.
  • Direct-Vault clients in application code are opt-in only, justified per-app by a documented dynamic-secrets requirement (e.g., DB rotation, AWS STS). Default to ESO. Document the justification in the project's README under "Secrets architecture".
  • ${VAR:-default} fallback syntax in any deployment configuration (compose, k8s manifests, Helm values, env files committed to git) is forbidden for required values. Use ${VAR:?VAR is required} to fast-fail. Defaults are allowed only for true conveniences (e.g. ${PORT:-3000}) and MUST be tagged # safe-default: <reason> so a reviewer can confirm the intent.
  • .env files in production deployment paths are forbidden. .env.example and .env in local-dev paths are fine.
  • App startup MUST validate required secrets against a schema (zod / pydantic / equivalent) and exit non-zero on missing required values. Never run with defaulted weak fallbacks.
  • New apps: bootstrap checklist (see ~/.config/mosaic/guides/BOOTSTRAP.md) MUST include Vault path provisioning + ExternalSecret manifest + README declaring the Vault path and required keys.

Session Lifecycle Contract

  • Start: scripts/agent/session-start.sh
  • Priority scan: scripts/agent/critical.sh
  • End: scripts/agent/session-end.sh
  • Limitation logging helper: scripts/agent/log-limitation.sh "Title"

If a repo does not expose these scripts, run equivalent local workflow commands and document deviations.

Multi-Agent Safety

  • Coordinate through git pull/rebase discipline.
  • Do not auto-resolve data conflicts in shared state files.
  • Keep commits scoped to a single logical change set.

Model Tiering

Model choice is a standard, not a preference. Delegating a mechanical grep to a frontier reasoning model wastes budget; sending a security review to a cheap tier produces a review that passes and proves nothing. Both are defects.

Tiers are named by capability class, so the standard survives a model generation. An operator binds each class to a concrete model id.

Class Use for
search grep/glob, file location, status and health checks, one-line mechanical edits
build feature implementation, test writing, bugfixes, routine refactors
judge code review, planning, API/compat-sensitive changes
adversarial security review, ambiguous architecture, anything where a wrong "looks fine" is expensive

Rules:

  1. Start at the cheapest class that can do the task; escalate on evidence, not on nerves. Omitting a tier is not neutral — it inherits the caller's model, which is usually the most expensive one.
  2. Compat-sensitive work escalates one class. A change that must interoperate with an existing contract is judged, not just built.
  3. A tier assignment is benchmarked, not asserted. Move a task class to a cheaper tier only against a blind A/B on real work from this codebase, ranked by someone other than the author. "It seemed fine" is not evidence.
  4. Reviewer independence beats reviewer size. An adversarial verdict from the model that wrote the code is not a second opinion (see Constitution gate 16).

Where the binding lives

The class→model map is operator configuration, never framework source: model availability, cost, and quotas differ per operator and per host.

Resolution order, first hit wins:

  1. the config service (DB-backed, surfaced and editable in the Mosaic webUI)
  2. a local operator file (STANDARDS.local.md, or policy/ where the runtime injects it)
  3. the framework default — the class names above, with no binding

Only layer 1 is auditable across a fleet, so it is the target end state; layers 2 and 3 exist so a host with no config service still runs. A local override that silently disagrees with the config service is drift — the same failure class the tool-index gate exists to catch, and it belongs in mosaic doctor.

Prompting Contract

All runtime adapters should inject:

  • ~/.config/mosaic/STANDARDS.md
  • project AGENTS.md

before task execution.

Runtime-compatible guides and tools are hosted at:

  • ~/.config/mosaic/guides/
  • ~/.config/mosaic/tools/
  • ~/.config/mosaic/profiles/ (runtime-neutral domain/workflow/stack presets)
  • ~/.config/mosaic/runtime/ (runtime-specific overlays)
  • ~/.config/mosaic/skills-local/ (local private skills shared across runtimes)