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

117 lines
6.3 KiB
Markdown

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