README: - Intro now describes the multi-host fleet + cross-host sample diversity as the primary workflow. - Tier 2 section: profile-driven workload table replaces the old "yes / dd" description. - New Tier 3 section: covers driver v2 dispatch + setup automation scripts. - Tier maturity table refreshed (1, 2 ✅; 3 ✅ code / ⏳ image; 4 🚧). - Telemetry-sources table moved into the per-tier story so the oracle-vs-feature split is visible from the top of the doc. - Status section restructured by section (Pipeline, Telemetry, Orchestrator + drivers, Fleet) instead of a flat list. Cross-links to the new Forgejo issues for the remaining gaps: #4 — Tier 4 MalwareBazaar fetcher #5 — source 3 (perf stat) #6 — bridge pcap per-episode wiring - Quick-start sections rewritten: 1) "fleet mode (the primary workflow)" with --capacity + --waves 2) "single episode, no fleet" covering both Tier 2 + Tier 3 3) "multi-host fleet — how cross-host diversity works" explains the deterministic per-(host, slot, ep) selection mechanism - Repo-layout table updated to include shipper/, scripts/, AGENTS.md, and the workloads/fleet additions. - Deploying section: replaces the "TODO scaffolds" wording with the actual sudo install-receiver / install-lab-host / wg-pki bring-up flow that's running on the Pi today. AGENTS.md: adds a "don't put off the hard parts" convention as the first item under Other conventions, with explicit guidance on when "deferred-with-reason" is legitimate (genuine operator artifact missing) and the requirement to file an issue + automate the bring-up so it Just Works once the artifact lands. 86/86 tests still pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4 KiB
4 KiB
AGENTS.md — guidance for AI agents working on this repo
This project is part of the spectral lab (http://maxgit.wg/spectral/).
The conventions below also apply to sibling repos (wg-enroll,
wg-pki, caddy, iptmonads, matrix, forgejo, vault,
openclaw-deploy).
File an issue when you hit a problem
When you run into an issue you cannot fully resolve in the current turn, file it as a Forgejo issue on the relevant repo before moving on. Do not silently log a TODO comment, leave a partial workaround, or assume someone else will remember. The issue tracker is the durable record.
This applies to:
- a build / test / typecheck failure you can't fix in scope
- a bug you discover but aren't tasked with fixing
- a missing dep, missing config, or env-only failure that blocks E2E
- a design gap you've worked around but want a follow-up to fix properly
- a scope-out you made (e.g. "deferred Tier 4 sample fetch") that needs an owner so it doesn't get lost
Don't file an issue when:
- the user is in the conversation and you can just tell them
- it's already filed (search first:
GET /api/v1/repos/<owner>/<repo>/issues?state=open&q=<keyword>) - it's truly a non-issue (a one-line edit you're about to make this same turn)
How to file (Forgejo API)
The local Forgejo at http://10.100.0.1:3000 accepts API calls with a
token-bearer header:
curl -s -X POST \
-H "Authorization: token <TOKEN>" \
-H "Content-Type: application/json" \
http://10.100.0.1:3000/api/v1/repos/spectral/<repo>/issues \
-d '{
"title": "<short, action-oriented title>",
"body": "<context, repro, attempted fixes, suggested next step>"
}'
The token comes from the user's session — never embed one in code or commits.
What a good issue body contains
- Context — one sentence on what was being attempted.
- What happened — the actual error, log line, or unexpected behavior. Paste exact output.
- What was tried — every workaround you attempted and why it didn't stick.
- Suggested next step — the smallest change that would resolve it, if you have a guess. "Unknown" is a fine answer.
- Related — link the commit / PR / file:line where the issue surfaced.
What a good title looks like
| Bad | Good |
|---|---|
tests broken |
tests/test_episode.py: race when t_mono_origin_ns is set in run() not __init__ |
caddy thing |
Caddy: client_auth requires absolute path; relative trusted_ca_cert_file silently fails |
fix later |
shipper: 5xx backoff cap is 5min, doc says 1min — pick one |
After filing
- Reference the issue number in the next commit message:
Refs spectral/<repo>#<n>orCloses spectral/<repo>#<n>if your current change actually fixes it. - If the issue is on a different repo than the one you're committing
to, fully qualify:
spectral/wg-pki#3.
Other conventions
- Don't put off the hard parts. Frame "deferred-with-reason" only for genuine blockers (binary not present on this machine, external service unreachable). For anything you could do but find awkward — bridge setup, cross-arch quirks, fleet concurrency — do it. The user has flagged this twice when work was scoped down prematurely. When something genuinely is blocked by an operator artifact, file the Forgejo issue and automate the bring-up (e.g., installer script + sha256-verifying fetcher) so the moment the artifact lands it Just Works.
- Naming: never coin USB / device / service names on the user's behalf. Ask first. Reusing an old name is especially bad.
/etcconfigs:Readfirst, copy second. Never overwrite a/etc/...file from a template without checking what's actually there.- wg-enroll scope: creation-only. Don't add admin / service-activation features to it.
- Don't expand a project's binary name beyond its own boundary:
openclawis the queue/permissions binary inopenclaw-deploy. This repo iswg-enroll(or its caller). Don't conflate.