docs(agents): streamline instruction routing (#6358)

This commit is contained in:
Zhengchao An
2026-08-22 08:19:53 +08:00
committed by GitHub
parent 61b5edf16e
commit 37c5ce1399
32 changed files with 545 additions and 1254 deletions
@@ -0,0 +1,24 @@
# Compatibility Lens
- Internal metadata uses `metadata_compat` helpers for dual RustFS/MinIO keys,
including mixed casing and removal of both twins.
- Binary UUID metadata treats absent, empty, and nil as no value. Unversioned
remote tiers receive no `versionId`; versioned purge requests retain the real
version ID.
- `xl.meta` changes preserve supported header/meta versions, recompute
signatures, decode legacy fixtures, and remain readable by old RustFS/MinIO.
- Foreign/corrupt metadata validates parallel array lengths and missing fields;
it returns a decode error rather than indexing, panicking, or fabricating data.
- Do not “correct” byte-for-byte MinIO ports without legacy fixture evidence.
Bitrot framing, shard math, distribution, and inline prefixes are contracts.
- Client-visible metadata/events strip both internal prefixes
case-insensitively.
- Proto fields are appended, never reused/renumbered; FlatBuffers tables extend
compatibly and absent new fields fail closed where authorization/quorum is
involved.
- Replay real client request shapes and exact pagination boundaries for S3
handler changes.
- Bucket metadata/IAM/config parsing remains compatible with pinned real MinIO
fixtures and encrypted migration data.
- Compatibility shims use `RUSTFS_COMPAT_TODO(<task-id>)`, have a removal
condition, and default toward reading old data safely.
@@ -0,0 +1,23 @@
# Concurrency and Durability Lens
- For every changed lock, enumerate overlapping lock sets and construct the
ABBA interleaving. Multiple-lock order must be documented and consistent.
- Mark guard lifetimes and every `.await`, disk, and RPC call inside them.
Estimate contention and timeout behavior under concurrent requests.
- Object commits remain fenced if the distributed lock is lost after shard
writes and before metadata rename.
- For write/rename changes, trace `write tmp -> sync tmp -> rename -> sync parent
-> sync required ancestors`; simulate a crash after each step and honor the
configured durability gate.
- Multi-disk fan-out counts every result. Quorum-minus-one cannot become success;
heal remains best-effort per target where that is the established contract.
- At every new cancellable await between mutation and cleanup/commit, drop the
future and inspect leftover files, counters, permits, and replay state.
- Multipart operations on the same upload ID are serialized where required;
abort/complete/list races cannot delete parts before durable commit.
- Post-commit cleanup is best-effort, retry-safe, and cannot fail an already
committed write or delete the last surviving copy.
- Persisted read-modify-write uses serialization/CAS. Queue replay is crash-safe
and duplicate delivery has an idempotency contract.
- Streaming reconstruction failures after partial output surface as errors, not
successful EOF.
@@ -0,0 +1,29 @@
# Correctness Lens
Attack the changed behavior, not every subsystem in the repository.
- Trace new error paths to the caller. Inject the ignored/wildcard variants and
verify they cannot become success, not-found, or a plausible default.
- Exercise zero/empty/missing, maximum, and exact-boundary inputs for every
changed count, size, index, page limit, or optional value.
- For aggregation/quorum changes, test exactly quorum and quorum-minus-one with
mixed disk errors and nil/placeholder entries.
- For listing/pagination, test `n == max`, `n == max + 1`, delimiter folding,
continuation markers, and object/prefix name collisions.
- For EC/read/streaming changes, inject failure after partial output and verify
the client receives an error rather than a clean truncated body. Assert exact
bytes and length.
- For multipart/object commits, fail before/after rename and cleanup; committed
data must remain readable and pre-commit cleanup must not destroy parts.
- For version/index ordering, test `len - 1`, `len`, equal timestamps, missing
versions, and deterministic tie-breaking.
- For directory-object behavior, trace `__XLDIR__` at the store layer; branches
below the layer that sees trailing slashes are dead.
- For binary UUID metadata, absent, empty, and nil all mean no value. Never send
nil/empty `versionId` to an unversioned tier.
- For agent rules/skill routers, test a trigger matrix covering ordinary
inquiry, low-risk implementation, explicit review, high-risk code, PR
creation, release, and post-PR monitoring. Each case must select only the
intended workflow and retain required safety/authorization boundaries.
Null verdicts name only the probes relevant to the diff.
@@ -0,0 +1,20 @@
# Performance Lens
- For added clones/allocations on request/object/block paths, quantify copied
data and frequency. Recommend borrowing, move, `Bytes`/`Arc`, `Cow`, or
capacity reservation only for a concrete repeated cost.
- Route every new sync/flush through the durability-mode and bucket override
gates; mode `none` must not pay the new fsync.
- Keep blocking filesystem/CPU work off async runtime threads, but do not split
one small operation into many `spawn_blocking` round trips.
- Measure lock hold time across I/O and compare acquisition order for ABBA.
- Keep cleanup, extra stat/rename, and diagnostics out of the PUT commit critical
section when they need not be there.
- Detect per-item serial I/O/RPC in batch APIs and accidental quadratic scans;
use a gate or bounded concurrency when the concrete fan-out warrants it.
- Count buffer growth and byte copies in EC/bitrot paths; preserve pool gauge
balance and avoid repeated metadata decode/fetch per object.
- Repetitive success logs stay at `trace`; metrics/instrumentation on hot paths
require an existing gate.
- Claims of no impact on PUT/GET/commit/erasure paths need relevant benchmark or
A/B evidence, especially for 4 KiB objects.
@@ -0,0 +1,31 @@
# Security Lens
Use `security-advisory-lessons` only for a dedicated advisory/security audit.
For an ordinary matched diff, attack these boundaries:
- Admin routes: route registration, whitelist, handler authn, and the exact
`AdminAction` must agree. Read-only diagnostics still require admin authz.
- IAM/service accounts: treat parent, claims, keys, groups, status, and policy
names as attacker-controlled; prove ownership/root authority before writes.
- Protocol frontends: every changed/sibling command authorizes the matching S3
action before reaching storage.
- Secrets/signatures: use constant-time comparison, normalize public failures,
keep RPC/root/STS keys independent, and fail closed when secrets are absent.
- RPC: bind signatures to the exact method/path and timestamp; reject replay,
stale, malformed, truncated, and invalid-enum payloads without panic.
- Paths/object/archive entries: reject traversal, absolute/platform escapes,
and normalization differences between authz and storage.
- Copy/multipart/presigned POST: enforce source, destination, version-aware
actions, copy-source conditions, and every signed policy condition.
- Logging/errors: never expose credentials, tokens, expected signatures, raw
secret-bearing input, or merged configs—including via `Debug` and parse errors.
- Untrusted serde: reject unknown fields where compatible and validate
security-critical defaults/ranges before numeric conversion.
- SSE/browser/CORS/trusted proxy: inspect stored ciphertext and wrapper order;
isolate user content; never reflect credentialed arbitrary origins or trust
forwarded identity from direct clients.
- Object Lock: unreadable/fabricated/unparsable metadata fails closed across
foreground, lifecycle, scanner, and force-delete paths.
Security findings distinguish unauthenticated compromise from a
low-privileged authenticated bypass.
@@ -0,0 +1,22 @@
# Simplicity Lens
- Compare the production diff with the smallest equivalent local edit. Fewer
lines alone are not evidence; the replacement must preserve correctness,
compatibility, readability, and real boundaries.
- Search the touched crate, domain owner, `crates/utils`, `crates/common`, and
relevant dependencies for each new helper, constant, wrapper, or fixture.
- Reject forced reuse when normalization, error, deadline, or durability
semantics differ.
- Require a concrete trigger for every new defensive branch. Keep boundary
checks for disk/RPC/version data and checks immediately before destructive
actions.
- Flag one-caller helpers only when they merely forward or split a short linear
flow without adding domain naming, invariant isolation, or useful context.
- Ensure a replacement removes the superseded in-scope path or keeps one
canonical core behind a documented compatibility adapter.
- Remove narration/change-history comments; preserve concise safety, lock,
durability, and compatibility invariants.
- Treat tests, fixtures, generated code, and documentation separately from
production growth. Do not optimize away meaningful regression coverage.
A finding must include a concrete smaller design, not a style preference.
@@ -0,0 +1,24 @@
# Test-Coverage Lens
- For every behavior claim, name the focused test/check that fails if the
changed hunk is reverted. If none is practical, require the reason and
residual risk.
- Confirm tests exercise the real production path and assert returned values,
exact bytes, stored state, or the specific error variant—not only success,
`is_err()`, or no panic.
- For new flags/modes, verify each branch and ask which test fails if the branch
is inverted.
- For new error propagation, inject the failure and assert the caller observes
it; mentally replacing `?`/`return Err` with success must break a test.
- Streaming GET tests assert the complete body and length under degraded reads.
- Disk/wire-format tests use pinned foreign/legacy fixtures; same-code
round-trips are insufficient for compatibility.
- Concurrency tests use readiness polling, isolate global state, and avoid fixed
sleeps or unrealistically short timeouts. Use nextest groups when process-level
serialization is required.
- Internal metadata tests assert both RustFS and MinIO keys, not only read-back
through a helper that prefers one key.
- Boundary companions are distinct coverage: `n == max` vs `max + 1`, and
absent vs empty vs nil UUID.
- A focused test proves only the targets/features it builds. Add compilation or
Clippy only for uncovered changed targets.