Files
stack/packages/mosaic/framework/defaults/STANDARDS.md
T
Hermes Agent 8a901cc19a
ci/woodpecker/pr/ci Pipeline was canceled
guard: read command position, refuse unreadable URLs, survive pipefail
Round two of the same independent review. Three findings, all real, and the
first two share a root cause: the guard was reading command TEXT as though it
were a command.

1. Splitting the endpoint token itself defeats fragment matching outright —
   `a=/api/v1/repos/o/r/iss; b=ues/1/comments` leaves no fragment contiguous.
   Round one fixed one spelling of this and the reviewer produced the general
   form immediately. It is not winnable by more fragments: the endpoint does
   not exist until the shell expands it, and this hook runs first. So the guard
   stops pretending to read it. A write whose URL contains an expansion, on a
   visibly forge-shaped command, is now BLOCKED as unreadable — because "I
   could not find an endpoint" must not mean "there is no endpoint". Opaque
   URLs that are not forge-shaped (webhooks, artifact stores) still pass.

2. The broadened body detection false-blocked ordinary work: `grep -R "curl -d
   https://.../issues" docs/`, `echo "curl -d ..." > note.txt`, printing an
   example from python. Talking about a call is not making one, and this is the
   direction that actually kills a control — an over-blocking hook gets turned
   off, and an off hook permits everything. The client must now appear at
   COMMAND POSITION: line start or after a shell operator, optionally behind
   VAR=value. In every false positive it sat behind a quote instead. Quotes are
   deliberately NOT stripped before matching; real calls quote their URLs.

3. `wt_precious()` aborted `cmd_rm` under `set -euo pipefail`: `grep -v` exits 1
   when it filters everything out, which is exactly the disposable-only case,
   so a SAFE worktree failed to remove with no message. Fixed, and the same
   defect was latent one step upstream in `wt_dirty()`, where `head -200`
   SIGPIPEs git on any worktree with 201 changed files. The cap is gone —
   counting is cheap and the cap only ever truncated output that is no longer
   printed.

Seven new fixtures pin all of it, in both directions. 27/27.
2026-08-12 17:26:09 -05:00

6.3 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)