Skip to content

Make node-reported NetGuard reality durable but non-authoritative - #27

Draft
lr00rl wants to merge 2 commits into
integrationfrom
feat/hephaestus-task0017-netguard-reality-api
Draft

Make node-reported NetGuard reality durable but non-authoritative#27
lr00rl wants to merge 2 commits into
integrationfrom
feat/hephaestus-task0017-netguard-reality-api

Conversation

@lr00rl

@lr00rl lr00rl commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements TASK-0017 G3c server reality persistence/API under api-contract §2:

  • Adds GuardRealitySnapshots as the latest normalized node reality snapshot collection in the server store.
  • Adds POST /api/agent/guard-reality with bearer-bound node identity, forward-compatible agent JSON decode, normalization/limits, future timestamp clamp, stale-write conflicts, and audit counts only.
  • Adds GET /api/netguard/reality with per-visible-node summaries, opaque cursor pagination, detail reads, unknown|fresh|stale status, and 404 for missing/unauthorized detail.
  • Keeps the path observational only: no policy mutation, approvals, task enqueueing, apply, SDK/proto, dashboard, or node-agent polling changes.

Verification

  • go test ./internal/store ./internal/server -run 'TestGuardReality|TestNetGuardReality'
  • go test ./...
  • go vet ./...
  • git diff --cached --check
  • lattice-olympus/rules/checks/redaction-scan.sh

Coordination

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
@lr00rl

lr00rl commented Jul 31, 2026

Copy link
Copy Markdown
Contributor Author

Zeus exact-head r1 verdict on c719ca36aa30ff0f6f3267d1bdb6bd4abd3666ef: REQUEST CHANGES.

Merge blockers:

  1. failed persistence mutates live reality and identical retry can falsely return success;
  2. JSON↔bbolt migration silently drops the reality collection;
  3. snapshot lifecycle is not bound to hard-delete/re-enrollment identity generation.

Also close the required node_id 400-vs-401 error contract and nil/empty canonical equality gap. Exact-head CI and targeted suites are green, but three planted regressions reproduced the first, third, and error-contract failures.

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 [ack].

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.
@lr00rl

lr00rl commented Aug 1, 2026

Copy link
Copy Markdown
Contributor Author

Zeus exact-head r2 verdict on cacb1c318917b1fb662fc70fe75bd3b40d14d574: REQUEST CHANGES.

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 ReadyCheck() remains healthy. A planted exact-head test predicted one failure and observed exactly that green readiness.

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 [ack].

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant