Imported from bketelsen/onionsoup (
AGENTS.md). Install upstream withnpx skills add bketelsen/onionsoup. Copyright stays with the author.
Onionsoup
Build focused OSS maintenance agents using AgentLayer. Keep one job per agent and prove it useful before adding coordination infrastructure. Start at docs/README.md for designs, contracts, evidence, and plans.
AGENTS.md is canonical. CLAUDE.md, GEMINI.md, and
.github/copilot-instructions.md link here; .claude/skills links to
.agents/skills/. Edit canonical files only and keep instructions tool-agnostic
(ADR-0002). The root skills
symlink preserves older references.
Skills (follow these for common tasks)
Read the applicable skill before doing that work:
- Define responsibility or handoffs: agent-contract.
- Develop prompts, tools, or context: agent-context.
- Implement execution, recovery, or human handoffs: agent-execution.
- Evaluate behavior, instrument runs, or decide readiness: agent-evaluation.
Additional skills for the twenty-factor follow-through:
- Publish a discoverable agent capability: agent-capabilities.
- Make a complete workflow inspectable: workflow-observability.
- Bound the whole workflow: workflow-budgets.
- Record a reproducible execution configuration: agent-release-manifest.
- Keep delegated authority explicit: agent-authority.
- Persist the workflow at real recovery boundaries: workflow-durability.
- Automate useful quality feedback: agent-quality-review.
- Share explicit repository knowledge: repository-knowledge.
Deferred capabilities remain deferred unless the task calls for them; loading a skill does not authorize new effects or infrastructure.
Start new skills from .agents/skills/TEMPLATE/SKILL.md.
Package organization
The first portable slice lives in packages/ with thin entrypoints in apps/.
Use declared @onionsoup/* exports between packages. Never import root src/ or
application code from a package. Root forwards preserve legacy imports; edit the
canonical package implementation. Keep remaining sandbox assets in place until a
qualified extraction moves them. See workspace contracts.
npm run build compiles deployable JavaScript; npm run verify includes package
boundary checks. ONIONSOUP_RELEASE_INSTALL=1 npm test proves a fresh portable
release install (requires dependency cache or registry access).
Code conventions (live — the code exists)
-
Select provider and model explicitly at the application edge; prefer Copilot and Codex subscriptions. See providers.ts.
-
Use
gpt-5.6-terrafor current development evaluations and new batches, as in evaluation-policy.ts. Keep historical comparisons readable; defer a new model-comparison harness. -
Separate request kind from bug readiness. Classification must not imply project acceptance or rejection. Preserve v1 results without relabeling them. See contracts.ts and triage.ts.
-
Dispatch code-location only for matching ready bug reports and a pinned Git commit. Read Git blobs through the bounded source adapter; do not execute target repository code. See location-agent.ts and location-source.ts.
-
Validate citations against inspected evidence, preserve explicit failed attempts, and use host-generated v2/v3 overviews. Keep legacy v1/v2 records readable. See location-contracts.ts and location-record.ts.
-
Prepare features separately from ready bugs and converge through the read-only proposal contract. Preserve reported/proposed scope, source limitations, unrecorded acceptance and unexecuted checks. Neither a ready proposal nor classification authorizes patches, tests or publication.
-
Compose agents through versioned artifacts and callable functions; retain parent run identities and provenance. See packet.ts.
-
Run
npm run verifyfor code or documentation changes. It checks documentation, types, and tests. Usenpm run demofor a credential-free AgentLayer smoke test. Scripted model tests do not establish task accuracy. -
Repository briefs use deterministic counts and explicit sample coverage. Theme agents partition supplied IDs; health/actions cite supplied evidence. Never equate a valid reference with semantic accuracy or authorize proposed actions. See repository brief and package boundaries.
The TrueNAS evidence adapter is separately read-only: force write flags/environment off, invoke only the reviewed health tool, keep credentials external, and persist only normalized count/coverage evidence. Scoped self-signed TLS exceptions require explicit host configuration. No homelab service mutation or model-provider transfer of raw NAS data is part of this phase.
The SSH container source permits only fixed Docker/Podman/Incus inventory commands for operator-configured hosts. Preserve strict host-key checks, no sudo/forwarding, explicit account/socket/cluster scope, and unavailable-versus-empty distinctions. Never add generic model-controlled SSH.
The k3s source and saved homelab brief use fixed
status projections. Only explicit host access: sudo permits noninteractive sudo
for those three k3s reads. Never expose generic SSH/kubectl, transfer kubeconfig,
read Secrets or invoke Argo sync/refresh. Keep readiness, health and sync separate;
preserve saved-source scope, age and missing coverage in composed briefs.
The workload triage contract additionally permits five fixed pod/Job/ReplicaSet/Deployment/Argo Workflow projections, including explicit configured sudo. Workflow references require the reviewed API identity; phase and completion time establish execution outcomes, never service health. Names belong only in the private lookup; models receive normalized facts and hashed IDs. Never clear failures on age alone or infer recovery from missing owners. MCP clients select configured target/job IDs, never commands, credentials or paths. Triage proposes investigation only; no service mutation, logs or event prose. The conversational proof delegates through the same MCP host with one investigation, one brief and fixed aggregate bounds. The persistent chat keeps generic sessions separate from the homelab profile. Its reviewed refresh IDs reuse the existing read-only collectors; selected-finding inspection returns normalized cited facts only. Persist session admissions before effects, re-inspect evidence for follow-ups, and never replay interrupted jobs automatically. Profile/config/model bindings are immutable per session; discovery and task prose cannot widen authority.
The shared job host admits only operator-registered capabilities over authenticated loopback HTTP. Preserve per-invoker ownership, persisted quotas, exact idempotency binding and interrupted-without-replay semantics. Clients cannot enroll code, widen grants, select host paths or request publication. The scheduled consumer retains its separate SMTP effect ledger and local relay.
Repository boundary
Keep credentials, private keys, raw runs, local clones, and dependencies out of Git. See .gitignore. Never log credentials. Run live evaluations only with a configured subscription; the local-provider exploration remains deferred.
Do not broaden readiness into general triage, debugging, or GitHub mutation. Code-location suggests grounded code/test starting points; it must not diagnose bugs, execute repository code, implement fixes, or mutate GitHub. The inbox and packet are consumers of these bounded agents, not new agent authorities. The operator console admits explicit host actions from configured jobs; browser input cannot select paths, credentials or commands. The owned fixture runner separately permits bounded isolated execution and scoped local candidates under explicit fixture authorization. Its patch/review agents have no shell or filesystem tools. Keep real OSS repair/execution deferred; owned-fixture publication uses the separate approved-bundle boundary below; a ready proposal does not grant those effects. Preserve original checks and bind candidate receipts to the exact applied diff and accepted base.
The factor mapping records consciously deferred capabilities. Public contracts are readiness, code-location, and investigation packets.
Documentation rules
Every new document starts from its category's TEMPLATE.md:
docs/adr/: why we decided. Accepted ADRs are immutable; reversals use a new ADR and mark the old one Superseded.docs/design/: how it fits together. Update living designs to match reality.docs/specs/: exact contracts. Behavioral changes accompany implementation.docs/plans/: order of work. Every phase has a demonstrable Done when.
Dated evaluation reports live in docs/plans/records/ as evidence appendices of
the evaluation plan. Preserve historical versions,
findings, and limitations; do not rewrite them as current qualification.
Cross-linking is mandatory
Maintain links in both directions when adding or changing documents:
- ADRs link the designs/specs they shape and prior ADRs they build on.
- Designs link their rationale ADRs, contract specs, and implementing roadmap phase.
- Specs link their motivating ADRs and the design showing where they fit.
- Every plan phase links the design/spec it implements. Resolved architectural questions become ADRs.
Use relative links with valid targets and section anchors. npm run check:docs
checks local links, the index, document placement, and instruction symlinks;
reviewers also verify that cross-links accurately explain the relationships.
Housekeeping
- Index every new document in docs/README.md.
- Record significant decisions in an ADR first, then update affected designs/specs.
- Use absolute dates in documentation.
- Edit the canonical
.agents/skills/files, not separate tool-specific copies.
Owned-fixture draft publication uses the separate publication contract: exact approved bundles, configured bketelsen/* targets, persisted effect intents and conservative reconciliation. Never publish to get-bb/bb. Agents have no publication tools; merging remains out of scope.
The owned-project profile separately permits publication-status filtering in bketelsen/onionsoup after a recorded accepted proposal. Preserve its three-file allowlist, frozen dependency/check profile and exact candidate commit; only the host provisions dependencies or executes checks. The separately authorized clippy-bubble-color-v1 Go trial uses the same
workflow with only main.go and README.md editable, pinned Go/modules and offline
host-owned checks; see ADR-0018.
Other real-project repair remains deferred. The resulting feature belongs in a draft PR, not silently on main.
The reusable repository profile permits accepted Go task artifacts through the same pipeline. Keep host profiles/checks separate from task prose, bind exact runtime/dependency/check digests before patching, and allow only append-only changes to existing target tests. New-file creation remains unqualified; TypeScript task qualification follows the explicit adapter and declared original-test coverage below.
Reusable TypeScript tasks use the same profile/job pipeline with node-typescript-v1.
Profiles pin Node/npm policy and selected original test files; host checks stay
outside worker context. Do not describe selected-file checks as a complete suite.
See repository profiles.