Make node-reported NetGuard reality durable but non-authoritative - #27
Conversation
The server now accepts bounded GuardNodeReality reports from authenticated nodes, normalizes them before storage, and serves only visibility-filtered summaries/details for operators. The write path remains observational: it records latest accepted reality and audit counts, but does not mutate policy, tasks, approvals, or apply state. Constraint: api-contract §2 requires bearer-bound node identity, bounded normalized reports, latest-only stale-write conflicts, summary/detail visibility filtering, and a hard low-trust/no-apply boundary Rejected: Persist raw agent reports | raw request bytes and bearer material are explicitly forbidden from GuardRealitySnapshots Rejected: Add a public delete/mutation API | TASK-0017 only needs latest observed reality persistence and reads Confidence: high Scope-risk: moderate Directive: Keep GuardRealitySnapshots observational; do not let this endpoint mutate NetGuard policy or enqueue/apply work without a new signed contract Tested: go test ./internal/store ./internal/server -run 'TestGuardReality|TestNetGuardReality' Tested: go test ./... Tested: go vet ./... Tested: git diff --cached --check Tested: lattice-olympus/rules/checks/redaction-scan.sh Not-tested: Live node-agent posting and dashboard consumer integration; both are outside TASK-0017
|
Zeus exact-head r1 verdict on Merge blockers:
Also close the required Full persisted verdict and r2 evidence request: https://github.com/LatticeNet/lattice-olympus/blob/main/messages/inbox/hephaestus/20260731-1717Z-zeus-task0017-r1-verdict.md Keep PR #27 draft until an exact-tested r2 receives |
Reality reports are low-trust, but their acceptance semantics must still be transactional. Stage snapshots before publishing them, distinguish pre-rename failures from committed durability warnings, fence writes by the authenticated node identity generation, and carry the collection through migration and node deletion. Constraint: A 500 must leave the prior snapshot intact, while a completed rename must not be reported as rejected merely because parent-directory sync degraded. Constraint: Same node IDs may be re-enrolled with a new immutable Lattice identity generation. Rejected: Publish the candidate map before Save | failed persistence exposed a rejected snapshot and made retry falsely idempotent. Rejected: Fence snapshots by node ID alone | delete and same-ID re-enrollment can cross identity generations. Confidence: high Scope-risk: moderate Directive: Treat post-rename directory-sync errors as committed durability warnings; keep live and reopened state convergent and surface the degradation through telemetry and logs. Tested: gofmt-clean; targeted failure, migration, cascade, generation, envelope, and canonicalization tests; go test ./...; go vet ./...; docker-defaults; go test -race -cover ./... (server 412.090s 70.0%, store 10.941s 61.0%); diff-check; redaction scan. Not-tested: Physical power-loss behavior after rename on production filesystems.
|
Zeus exact-head r2 verdict on All five r1 correctness findings are closed. Code/spec/security lane = APPROVE; architecture lane = WATCH. One MEDIUM remains: after a committed parent-directory fsync failure, the handler truthfully preserves the rename-as-commit 200/live/reopened behavior, but degradation is only a warning plus generic counter and r3 should add sticky durability-health set/stay/clear behavior inside the existing store/server surface while preserving the current commit point and response semantics. The pre-existing agent-auth timing debt remains explicitly out of scope. Full persisted verdict: https://github.com/LatticeNet/lattice-olympus/blob/main/messages/inbox/hephaestus/20260801-1551Z-zeus-task0017-r2-verdict.md Keep PR #27 draft until an exact-tested r3 receives |
A rename can commit the accepted state before parent-directory fsync fails. Remember that unresolved durability condition in the Store so readiness remains unhealthy across idempotent and failed retries, then clear it only when a later committed write confirms the parent sync. Constraint: Preserve the r2 commit point, accepted response, warning, telemetry, and live/reopened/retry convergence Rejected: Retry persistence for equal snapshots | changes established idempotent write behavior and is not required to keep health sticky Confidence: high Scope-risk: narrow Directive: Do not clear durabilityDegraded from readiness checks or pre-commit failure paths; only a committed write with successful parent sync may clear it Tested: Targeted set/stay/clear tests normal and race; go test ./... -count=1; go test -race -cover ./...; go vet ./...; Docker defaults; gofmt; diff check; staged redaction Not-tested: Physical power-loss behavior on a production filesystem
|
[request-changes] r3 on exact head b180096. One HIGH blocker: the durability-degraded flag is process-local, so reopening after a rename-committed parent-directory sync failure reports healthy without any confirmed parent sync. A planted exact-head restart-readiness assertion failed as predicted; independent code-review and architecture lanes both blocked approval. Keep this PR Draft. r4 must prove reopened stay, idempotent-retry stay, and recovery only after an explicit successful parent-directory sync, while preserving the r2 commit/HTTP 200/warning/convergence semantics. Full persisted verdict: https://github.com/LatticeNet/lattice-olympus/blob/main/messages/inbox/hephaestus/20260803-1029Z-zeus-task0017-r3-verdict.md |
A readable state pathname after process restart does not prove the prior rename is crash-durable. Sync the existing state file's parent directory during open, retain degraded readiness when that confirmation fails, and allow the same restarted Store to recover only after a later confirmed sync. Constraint: Preserve the r2 rename commit point, accepted response, warning, telemetry, and data convergence plus r3 live-process health behavior Rejected: Persist a separate degradation marker | the marker introduces a second atomic durability lifecycle while startup parent sync directly confirms the required invariant Confidence: high Scope-risk: narrow Directive: Existing state opens must attempt parent-directory sync; absent state must not manufacture a confirmation event Tested: Injected absent/empty/populated startup sync counts; restart fail/idempotent stay/same-instance recovery/data convergence; targeted race; go test ./... -count=1; go test -race -cover ./...; go vet ./...; Docker defaults; gofmt; diff check; staged redaction; independent re-review ack Not-tested: Physical power-loss behavior and non-Darwin directory-fsync portability outside CI
|
[ack] r4 on exact head 48b5a41. The restart false-recovery HIGH is closed: existing state now requires an explicit startup parent-directory sync, failed sync stays sticky-unready across idempotent retry, and health returns only after a confirmed sync. Independent code review returned 0 findings/ACK; architecture returned CLEAR. Exact CI, target x10, race, package tests, and a planted one-failure negative control all agree. Proceed with final integration sync/gates and merge only this acknowledged content; no release/deploy/signing authorization. Persisted verdict: https://github.com/LatticeNet/lattice-olympus/blob/main/messages/inbox/hephaestus/20260803-1221Z-zeus-task0017-r4-verdict.md |
|
Landed on |
Summary
Implements TASK-0017 G3c server reality persistence/API under api-contract §2:
GuardRealitySnapshotsas the latest normalized node reality snapshot collection in the server store.POST /api/agent/guard-realitywith bearer-bound node identity, forward-compatible agent JSON decode, normalization/limits, future timestamp clamp, stale-write conflicts, and audit counts only.GET /api/netguard/realitywith per-visible-node summaries, opaque cursor pagination, detail reads,unknown|fresh|stalestatus, and 404 for missing/unauthorized detail.Verification
go test ./internal/store ./internal/server -run 'TestGuardReality|TestNetGuardReality'go test ./...go vet ./...git diff --cached --checklattice-olympus/rules/checks/redaction-scan.shCoordination
lattice-olympus/contract/CHANGELOG.mdrow feat: make plugin service backing an explicit signed declaration #8 is co-signed.GuardRealitySnapshots, TASK-0017, hephaestus in progress.