mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-24 04:33:17 +00:00
Bound audit overhead and preserve the published release source mapping (#2412)
## What changed and why Reduce configuration-fetch audit overhead without hiding access events (#2320). The suppression tracker now remembers at most 4,096 organisation/agent pairs and uses an expiry index instead of repeated full-map scans. Existing agents keep daily suppression; unremembered agents at capacity are conservatively audited on every fetch. Token/configuration changes and every failure remain audited. No audit history is deleted. The Apprise confidentiality test now observes the autonomous queue dispatcher instead of starting a competing manual batch. Its lifecycle, retry, configuration and confidentiality assertions remain intact. Preserve the exact 6.4.6 release-line mapping for the already-published packet. The fallback to main incorrectly rejected its immutable source during convergence. This maps that version only, not future patches, and changes no candidate product source. ## Included source and upstream reconciliation Complete new publication range: `e6540da45da4de4bcb954463373d8ea9f196eb56..35d8c7c13d3665b2ffe2fe4fd61e8952c46e21b1`. - Reviewed Delivery correction: `3578b0044740087e7589f19bca450245f610aced`. - Reviewed Core changes: `e225bf2abcb4189dcedd457292248e72a945dc74` and `6ab5383412f156f286c38623f9b86f2b0d3151f0`, integrated by `94ce8496b7d79e9b77d43493adc432c954d5e8b7`. - Additive upstream merge: `35d8c7c13d3665b2ffe2fe4fd61e8952c46e21b1`, incorporating published Proxmox table repairs at `e6540da45da4de4bcb954463373d8ea9f196eb56`. Every reviewed commit identity and ancestry is preserved. No upstream frontend source or dependency manifest changes in this proposal. ## Validation and limits Recorded independent-review evidence: Core returned four complete source-proof receipts covering connected configuration-fetch/authorization tests, five race repeats, notifications correctness/races and ten queue-fixture repeats, vet/builds, 135 governance tests, 23 docs-sync tests and frontend production build/budgets. Its fixed controls retained a maximum of 4,096 keys versus 12,288 in the predecessor; saturated in-memory lookup measurements are not installed write-rate or CPU acceptance. Delivery returned a complete offline source proof of 947 release-control tests (8 skipped), with guest shutdown. The exact-version tests reject unrelated versions. These are reviewed owner returns, not new qualification executions by this publication gate. On the combined committed source, provenance, whitespace, ancestry, canonical completion, browser-verification scope, control-plane audit, all 62 shipped-document mirrors and the 211-file public-document check pass. Core runtime and Go manifests are byte-identical to the reviewed Core candidate; release-control source/policy is byte-identical to the reviewed Delivery candidate; frontend runtime and graph are byte-identical to current upstream. Sufficient heavy/browser evidence was therefore not replayed. Core used Go 1.26.7 rather than declared 1.26.8, with an explicit backend embed fixture and a separately proved frontend build. Required exact-head CI remains necessary before landing. This proposal does not establish installed outcomes, release readiness, successful convergence or stable delivery, and does not replace or recut the published v6.4.6 candidate. [How Pulse handles triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
This commit is contained in:
+10
-1
@@ -36,7 +36,16 @@ Pulse automatically captures the following events:
|
||||
| `agent_profile_assigned` | Agent profile assignments | Profile `production` assigned to agent |
|
||||
| `agent_profile_unassigned` | Agent profile removals | Profile removed from agent |
|
||||
| `user_roles_updated` | RBAC role assignments changed | Updated roles for user jane: [operator] |
|
||||
| `agent_config_fetch` | Every failed agent configuration fetch. A successful fetch is recorded on the agent's first delivery after Pulse starts, when its token or delivered configuration changes, and otherwise once a day; agents poll every minute, so repeat polls are not recorded | `agent_id=… token_id=… config=sha256:… reason=config_changed` |
|
||||
| `agent_config_fetch` | Every failed agent configuration fetch. A successful fetch is normally recorded on the agent's first delivery after Pulse starts, when its token or delivered configuration changes, and otherwise once a day; unchanged minute polls are suppressed while the agent is remembered (see below) | `agent_id=… token_id=… config=sha256:… reason=config_changed` |
|
||||
|
||||
Config-fetch suppression remembers up to 4,096 organisation/agent pairs per
|
||||
Pulse process. New agents can replace entries last recorded at least 24 hours
|
||||
ago; a forgotten agent's next successful fetch is recorded again. If all slots
|
||||
are recent, additional agents' successful fetches are recorded on every poll
|
||||
with `reason=capacity` until a slot expires. This keeps memory bounded without
|
||||
hiding access events or displacing recent agents' suppression. It does not
|
||||
limit enrolment or configuration delivery, and every failed fetch is still
|
||||
recorded. No existing audit rows are removed by this tracker.
|
||||
|
||||
Each event includes:
|
||||
- **Timestamp** (UTC)
|
||||
|
||||
@@ -33,6 +33,11 @@
|
||||
"prerelease_branch": "release/v6.4",
|
||||
"stable_branch": "release/v6.4"
|
||||
},
|
||||
{
|
||||
"version_prefix": "6.4.6",
|
||||
"prerelease_branch": "release/v6.4",
|
||||
"stable_branch": "release/v6.4"
|
||||
},
|
||||
{
|
||||
"version_prefix": "6.5.",
|
||||
"prerelease_branch": "release/v6.5",
|
||||
|
||||
@@ -36,6 +36,9 @@ model that active and future release profiles reuse.
|
||||
support after the active profile has moved on, that branch mapping must stay
|
||||
explicit in `control_plane.json` as a legacy release-line override rather
|
||||
than being inferred from the active profile or smuggled into one workflow.
|
||||
The selected and published `6.4.6` packet remains bound to `release/v6.4`
|
||||
for convergence and exact-RC promotion. Its complete-version override does
|
||||
not map future `6.4.7` or similarly prefixed `6.4.60` releases to that line.
|
||||
4. Profile changes must reuse the same control-plane machinery.
|
||||
Future releases should switch or add profiles rather than fork the guardrail
|
||||
system.
|
||||
|
||||
@@ -5336,8 +5336,11 @@ pending or unknown rather than in-sync.
|
||||
|
||||
Routine config polling is not a per-poll audit event:
|
||||
`/api/agents/agent/{id}/config` audits every failed fetch, and a successful one
|
||||
only on the agent's first delivery after start, a token or desired-config
|
||||
change, or once a day (see the API contract).
|
||||
normally on the agent's first delivery after start, a token or desired-config
|
||||
change, or once a day (see the API contract). Suppression is bounded to 4,096
|
||||
organisation/agent pairs. New keys replace only expired suppression entries;
|
||||
overflow deliveries are audited with `reason=capacity`, without evicting
|
||||
recent agents or restricting enrolment, config access, or command authority.
|
||||
That same canonical /api/auto-register path must also complete the live
|
||||
post-registration contract after persistence: it must trigger discovery refresh
|
||||
and emit the canonical `node_auto_registered` WebSocket payload instead of
|
||||
|
||||
@@ -8776,8 +8776,20 @@ unchanged delivery last recorded 24 hours earlier. Agents poll every minute,
|
||||
and auditing each poll made this event over 99.9% of audit rows. Recorded
|
||||
successes carry `config=<desiredConfig hash>` and
|
||||
`reason=first_since_start|token_changed|config_changed|daily` in their details.
|
||||
The suppression tracker remembers at most 4,096 organisation/agent pairs.
|
||||
An expiry index replaces only entries last audited at least 24 hours ago,
|
||||
with no full-map scan on new-key admission. Recent entries are never evicted
|
||||
by key churn, so their unchanged minute polls stay suppressed. If every slot
|
||||
is recent, unremembered agents' successful fetches are recorded on every poll
|
||||
with `reason=capacity` until an expired slot is available. This conservative
|
||||
overflow can produce extra audit writes but must never suppress access events,
|
||||
change config authorisation/delivery, or grow either map or expiry index beyond
|
||||
the limit. Token, config and daily changes update the entry's expiry position;
|
||||
concurrent and out-of-order observations preserve that index.
|
||||
`TestAgentConfigFetchAuditsNewDeliveriesAndEveryFailure` and
|
||||
`TestAgentConfigFetchAuditTrackerRecordsOnlyNewDeliveries` pin the rule.
|
||||
`TestAgentConfigFetchAuditTrackerRecordsOnlyNewDeliveries` pin the rule;
|
||||
`TestAgentConfigFetchAuditCapacityContract` and the tracker capacity, expiry,
|
||||
churn and concurrency controls pin bounded state and conservative overflow.
|
||||
Agent profile delete and unassign clients must now also route canonical `204`
|
||||
success handling through shared allowed-status helpers in
|
||||
`frontend-modern/src/api/responseUtils.ts` instead of open-coding local
|
||||
|
||||
@@ -2687,6 +2687,13 @@ vdev layout is reported` in
|
||||
|
||||
## Current State
|
||||
|
||||
The agent config-fetch audit suppression cache is bounded to 4,096
|
||||
organisation/agent pairs, independently of persisted security audit history.
|
||||
Expiry-index pruning forgets only suppression state, never audit rows or
|
||||
recovery evidence. Unremembered overflow deliveries remain auditable with
|
||||
`reason=capacity`; cache expiry, overflow, or restart is not a successful
|
||||
storage operation or a reason to delete historical events.
|
||||
|
||||
### Container diagnostics shares private bootstrap transport (1 October 2026)
|
||||
|
||||
Recovery-adjacent diagnostics now reuse the canonical complete installer
|
||||
|
||||
Reference in New Issue
Block a user