Files
MoShiro/AGENTS.md
T
justme a9bf849697
ci/woodpecker/push/web-build Pipeline was successful
ci/woodpecker/push/verify Pipeline was successful
ci/woodpecker/push/e2e Pipeline was successful
docs: rewrite README and AGENTS.md etc..
2026-10-21 06:28:19 +08:00

79 lines
7.0 KiB
Markdown

# Agent Instructions
MoShiro is a self-hosted network path quality monitor. Probes (home broadband) and Agents (public VPS) run active measurements and record raw per-packet and per-event data. The Backend stores it, derives metrics, scores lines per service model, and serves a REST/SSE API to two web apps. Documentation is in Chinese under [`docs/`](docs/); source comments are mostly Chinese too. [`README.md`](README.md) is the entry point.
## Mental model
| Term | Meaning |
| --- | --- |
| Probe, Agent | Collector processes (NativeAOT, BCL only). The Probe always dials the Agent; both dial the Backend over `wss` |
| Line | One (Probe, Agent) pair, per IP family. Id `<agent_id>~<probe_id>`, IPv6 adds `~ipv6`; series key `line:<probe_id>` |
| Kind | A declared measurement method (`udp_echo`, `tcp_echo`, `connect`, ...) composed from building blocks. Defined once in `MoShiro.Protocol/Catalog/Kinds` |
| RawChunk | Self-describing columnar block, cut every 10 s, appended to segment files. The Backend never trusts node-reported statistics |
| Metric, Model | `MetricDef` is a one-line declaration over accumulators; models score metrics at query time. Both are recomputable from raw data |
| Plan | A sequence of on-demand test phases (for example `hy2_ladder`). Exists only in the Backend (`Application/Tests/Plans.cs`) |
| Fleet | Product-agnostic node framework under `backend/fleet/` (identity, enrollment, RPC, link, outbox, state sync) |
| Operator set | Passkey-signed trust root. Nodes pin its genesis fingerprint and owner at install time and verify the chain themselves |
## Invariants (violations fail the build or review)
- Nodes are pure collectors: no process start, dynamic loading, `HttpClient`, or file writes outside `Fleet.Hosting.ConfigStore` (`backend/BannedSymbols.Node.txt`). Do not add RPC methods that trigger non-measurement actions.
- `backend/fleet/**` must not reference `MoShiro.*` (`ArchitectureTests`). `MoShiro.Measurement` contains no service concepts such as REALITY or Hysteria2.
- Every RPC method is declared in a method table (`FleetMethodTable`, `MoShiroMethodTable`) with direction, type and roles. Add the declaration before the handler.
- `Backend.Api` must not reference `Storage`. Error-code to HTTP mapping happens once, in the Api layer.
- Server-sent parameters pass `ParamSpec` validation and then the node-local hard limits (`BudgetGuard`). Never bypass either.
- Public API responses contain no IP, city or ASN.
- Code style is enforced at build time (`.editorconfig`, `BannedSymbols.txt`, warnings as errors). Details in [`docs/dev/coding-style.md`](docs/dev/coding-style.md).
## Where to change what
| Task | Location |
| --- | --- |
| New measurement method | Kind declaration in `backend/shared/MoShiro.Protocol/Catalog/Kinds`; new building block only if needed in `MoShiro.Measurement/Blocks` plus `BlockCatalog` |
| New metric | `MetricDef` in `backend/src/MoShiro.Backend.Analysis/Metrics`, add to `MetricRegistry.All` and a preset if shown |
| New service model | `Analysis/Models` |
| New RPC method | `MoShiro.Protocol/Rpc` (params, `MoShiroMethodTable`), then `router.On(...)` in `AgentApp` or `ProbeApp`; Backend-side handlers register in `Backend.Gateway` (`FleetGateway`) |
| New REST endpoint | `Backend.Api/Public` or `Admin` (typed results, operationId, capability), contract DTO in `Api/Contracts`, then regenerate `backend/openapi/v1.json` and web types |
| New capability | `Capability` constants in `Backend.Application/Auth/Capabilities.cs`; every `/api/admin` endpoint must declare one |
| Schema change | Append a migration in `Storage.Sqlite/Schema.cs` and bump `CurrentVersion` |
| Install or update behaviour | `packaging/` (install scripts, Quadlet, compose, updater) and `docs/ops/deployment.md` |
| Web UI | `web/display` (anonymous read-only), `web/admin`, shared code in `web/shared`. Colors only in `web/shared/theme/tokens.css` |
## Documentation
Index: [`README.md`](README.md#文档). Prefer the code and `backend/openapi/v1.json` when they disagree with a document, and fix the document. Update docs in the same change as behaviour: `docs/design` (architecture, protocol, measurement, analysis, storage, query), `docs/security`, `docs/api`, `docs/ops`, `docs/dev`, and `docs/roadmap.md` for unimplemented work. Do not record dates or change history in docs.
## Workspace safety
- Inspect `git status` before editing. Preserve existing uncommitted changes; do not reset, clean, stash, or commit unrelated files.
- `main` is the only working branch. Commit to it directly; use a pull request when review is required.
- Never commit credentials, API keys, registry passwords, or generated runtime data. CI credentials are Woodpecker secrets (`zot_secret`, `gitea_token`, `release_signing_key`).
- The release signing private key must not enter the repository or the panel. Only the public key under `packaging/update/` is versioned.
## Build and test
Requirements: .NET SDK 10 (pinned by `global.json`) and Node.js with npm. NuGet versions are centralized in `Directory.Packages.props`.
| Task | Command |
| --- | --- |
| Build all .NET projects | `dotnet build MoShiro.slnx -c Release` |
| Backend tests | `cd backend && dotnet test --solution MoShiro.slnx -c Release` |
| Run Backend | `cd backend && dotnet run --project src/MoShiro.Backend -- --urls http://localhost:5000` |
| Web dependencies and build | `npm ci --prefix web && npm run build --prefix web` |
| Web dev servers | `npm run dev --prefix web` (ports are set in the Vite configs) |
| Style check | `npm run lint:css --prefix web` |
| Regenerate API types | `npm run gen:api --prefix web` |
First run of the Backend prints a claim code in its log; the admin UI asks for it. Slow end-to-end tests carry `[Trait("Category", "Slow")]`. After changing API contracts, update `backend/openapi/v1.json` and regenerate the web types. Run only the validation the task requires; do not start a full tag or release build unless requested.
## CI and releases
Triggers, tags and image paths are defined in `.woodpecker/*.yml` and [`docs/ops/deployment.md`](docs/ops/deployment.md). Verify them there before changing or describing them. The rules below are the stable contract.
- Every push to `main` runs the fast Backend tests and the web build. Both must pass before images are published.
- A commit message containing `[CI]` builds and pushes development images. `[CI SKIP]` skips the pipeline; `[SKIP TESTS]` skips only the Backend tests. Slow end-to-end tests run after image publication and do not block it.
- A tag `vMAJOR.MINOR.PATCH` runs the full cross-platform release pipeline. No version-bump commit is needed.
- Versions are produced by `ci/version.sh`. The `<Version>` in `backend/Directory.Build.props` and the `version` in `web` `package.json` files are placeholders (`0.0.0-dev`) and must not be edited.
- Development images use the `moshiro-dev/` repository path and release images use `moshiro/`. A development build must never overwrite a release tag such as `latest`.
- Release manifests are registered at `/api/release/offer`, which requires no token because the panel verifies the signature.