7.0 KiB
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/; source comments are mostly Chinese too. 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 outsideFleet.Hosting.ConfigStore(backend/BannedSymbols.Node.txt). Do not add RPC methods that trigger non-measurement actions. backend/fleet/**must not referenceMoShiro.*(ArchitectureTests).MoShiro.Measurementcontains 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.Apimust not referenceStorage. Error-code to HTTP mapping happens once, in the Api layer.- Server-sent parameters pass
ParamSpecvalidation 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 indocs/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. 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 statusbefore editing. Preserve existing uncommitted changes; do not reset, clean, stash, or commit unrelated files. mainis 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. Verify them there before changing or describing them. The rules below are the stable contract.
- Every push to
mainruns 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.PATCHruns the full cross-platform release pipeline. No version-bump commit is needed. - Versions are produced by
ci/version.sh. The<Version>inbackend/Directory.Build.propsand theversioninwebpackage.jsonfiles are placeholders (0.0.0-dev) and must not be edited. - Development images use the
moshiro-dev/repository path and release images usemoshiro/. A development build must never overwrite a release tag such aslatest. - Release manifests are registered at
/api/release/offer, which requires no token because the panel verifies the signature.