Commit graph

17119 commits

Author SHA1 Message Date
pulse-triage[bot]
720c0a7050
Bind organization overview and billing to their selected read (#3672)
Some checks are pending
Canonical Governance / governance (push) Waiting to run
Canonical Private Governance / private-governance (push) Waiting to run
Helm CI / Lint and Render Chart (push) Waiting to run
Patrol Qualification Regression / Catalog, scorer, and replay regression (push) Waiting to run
Provider MSP startup / Provider MSP production startup (push) Waiting to run
Core E2E Tests / Playwright Core E2E (shard 1/8) (push) Blocked by required conditions
Core E2E Tests / Playwright Core E2E (shard 2/8) (push) Blocked by required conditions
Core E2E Tests / Detect browser receipt-only changes (push) Waiting to run
Core E2E Tests / Offline Organization provisioning (push) Blocked by required conditions
Core E2E Tests / Playwright Core E2E (shard 3/8) (push) Blocked by required conditions
Core E2E Tests / E2E verdict (push) Blocked by required conditions
Unified Agent Native Verification / Linux ARM64 (push) Waiting to run
Unified Agent Native Verification / Linux x64 (push) Waiting to run
Unified Agent Native Verification / Windows x64 (push) Waiting to run
Unified Agent Native Verification / macOS ARM64 (push) Waiting to run
Unified Agent Native Verification / macOS Intel (push) Waiting to run
Public docs / Documentation recipes (0) (push) Waiting to run
Public docs / Documentation recipes (1) (push) Waiting to run
Public docs / Documentation recipes (2) (push) Waiting to run
Public docs / Documentation recipes (3) (push) Waiting to run
Public docs / check (push) Blocked by required conditions
Core E2E Tests / Playwright Core E2E (shard 4/8) (push) Blocked by required conditions
Core E2E Tests / Playwright Core E2E (shard 5/8) (push) Blocked by required conditions
Core E2E Tests / Playwright Core E2E (shard 6/8) (push) Blocked by required conditions
Core E2E Tests / Playwright Core E2E (shard 7/8) (push) Blocked by required conditions
Core E2E Tests / Playwright Core E2E (shard 8/8) (push) Blocked by required conditions
Core E2E Tests / Agent registration lifecycle (push) Blocked by required conditions
Core E2E Tests / Build source-bound E2E images once (push) Blocked by required conditions
Core E2E Tests / Validate E2E tier selection (push) Blocked by required conditions
Unified Agent Native Verification / FreeBSD cross-build contract (push) Waiting to run
**Bind organization overview and billing to their selected read**

Invalidate obsolete reads, clear unread tenant figures and offer
deliberate read-only recovery. Bind name changes to their accepted
organization and never repeat an unconfirmed write.

**Pin Overview's selected-read binding in its owning panel test**

The normal panel test now asserts that metadata and members share the
same expected organisation and cancellation signal. The runtime is
unchanged.

**Record inspected organisation read-lifetime browser proof**

Bind the verified panel and API-client bytes to desktop and narrow
browser interactions, including settled member rows after the saved
read. Keep the observed timeout and intermediate fixture failure in the
retained evidence rather than treating them as passing executions.

Contract-Neutral: Adds only the exact-source browser verification
receipt; no runtime or subsystem contract delta.

---
Fleet candidate `20261101T012022Z-web-product` from the `web-product`
lane. Reviewed tip `3e8b8af1b5` on `main`.

[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
2026-11-01 03:01:17 +00:00
pulse-triage[bot]
4d7a18df77
Retain token authority throughout protected progress reads (#3670)
**Retain token authority throughout protected progress reads**

Guard replayed, queued and live SSE bytes at the writer for update
progress, Patrol and deployment reads. Revalidate admitted credential,
principal, selected organisation and the route's existing scope,
retaining instance authority only where the route requires it. Close
silent withdrawn readers within 15 seconds and join guarded writes
before returning; do not cancel background jobs or change session/proxy
admission. Exercise the actual router and synthetic producers, durable
deletion, independent readers and preserved job state.

Contract-Neutral: Enforce existing read admission and confidentiality
boundaries throughout SSE lifetimes; no new route, payload, scope, role,
job policy or session/proxy contract.

**Sharpen withdrawn-stream assertions and writer cleanup proof**

Expect existing invalid runtime-role authentication to refuse with 401,
not a scope-level 403. Detect a disclosed canary immediately rather than
waiting for stream timeout, and prove closure joins an in-flight
broadcaster write and rejects subsequent queued writes. Runtime and
admission policy are unchanged.

**Seed an active synthetic phase before Patrol replay checks**

The initial read matrix timed out waiting for a snapshot because its
synthetic Patrol stream was idle; idle subscriptions correctly send no
snapshot. Seed an analysing phase without starting Patrol, and retain
the failed first run as failed fixture evidence. Keep the production
repair unchanged and make the active-write closure assertion wait for
its concurrent closer.

**Join session progress writes before returning the HTTP reader**

The full-router race matrix exposed the existing update broadcaster
flushing after a session handler returned. Apply writer lifetime closure
to every admitted identity, while retaining token-only authority refresh
and leaving session/proxy admission and periodic-authentication
behaviour unchanged. Add a deterministic no-token late-write regression;
retain the failed race run rather than changing its assertions or
shutdown timing.

Contract-Neutral: Enforce existing HTTP writer ownership and read
admission; no route, wire, scope, role, job policy or session/proxy
authentication change.

---
Fleet candidate `20261101T004941Z-core-runtime` from the `core-runtime`
lane. Reviewed tip `66349b52d6` on `main`.

[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
2026-11-01 02:54:03 +00:00
pulse-triage[bot]
88b763e061
Reuse parsed public documentation anchors within each scan (#3669)
Load each distinct Markdown target only on a cache miss, including empty
anchor sets. Preserve per-link validation and errors, and discard the
cache between checks. Regression controls cover repeated links, distinct
paths, file changes and existing anchor rules.

Contract-Neutral: Link rules, discovered documents, reported failures
and CI gates are unchanged; only repeated anchor parsing within one
check is removed.

---
Fleet candidate `20261101T020002Z-delivery-trust` from the
`delivery-trust` lane. Reviewed tip
`4d8602f226` on `main`.

[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
2026-11-01 02:44:44 +00:00
pulse-triage[bot]
3e8b8af1b5 Record inspected organisation read-lifetime browser proof
Bind the verified panel and API-client bytes to desktop and narrow browser interactions, including settled member rows after the saved read. Keep the observed timeout and intermediate fixture failure in the retained evidence rather than treating them as passing executions.

Contract-Neutral: Adds only the exact-source browser verification receipt; no runtime or subsystem contract delta.
Change-source: pulse-maintainer
2026-11-01 02:26:47 +00:00
rcourtman
5197f33b5e
fix(notifications): preserve queued work through restart (#3668)
Preserve accepted notification work and firing receipts through shutdown and restore shared delivery policy before queue replay.
2026-11-01 02:17:06 +00:00
pulse-triage[bot]
4d8602f226 Reuse parsed public documentation anchors within each scan
Load each distinct Markdown target only on a cache miss, including empty anchor sets. Preserve per-link validation and errors, and discard the cache between checks. Regression controls cover repeated links, distinct paths, file changes and existing anchor rules.

Contract-Neutral: Link rules, discovered documents, reported failures and CI gates are unchanged; only repeated anchor parsing within one check is removed.
Change-source: pulse-maintainer
2026-11-01 02:06:59 +00:00
pulse-triage[bot]
a10470c142 Pin Overview's selected-read binding in its owning panel test
The normal panel test now asserts that metadata and members share the same expected organisation and cancellation signal. The runtime is unchanged.

Change-source: pulse-maintainer
2026-11-01 01:51:38 +00:00
pulse-triage[bot]
66349b52d6 Join session progress writes before returning the HTTP reader
The full-router race matrix exposed the existing update broadcaster flushing after a session handler returned. Apply writer lifetime closure to every admitted identity, while retaining token-only authority refresh and leaving session/proxy admission and periodic-authentication behaviour unchanged. Add a deterministic no-token late-write regression; retain the failed race run rather than changing its assertions or shutdown timing.

Contract-Neutral: Enforce existing HTTP writer ownership and read admission; no route, wire, scope, role, job policy or session/proxy authentication change.
Change-source: pulse-maintainer
2026-11-01 01:45:35 +00:00
rcourtman
5d11f80d7d fix(notifications): preserve queued work through restart
Keep delivery permission and SQLite available until queue workers,
admitted writes and direct fallback sends finish. Leave unclaimed rows
pending so restart and reload retain delivery work and firing receipts.

Restore shared webhook policy before persistent work is activated, including
tenant queues. Reject unreadable policy before queue creation and preserve
deployment URL locks when restoring saved installation settings.

Cover admission, concurrent stops, operator pause, channel disable,
direct fallback, restart recovery and bootstrap policy with persistent tests.
Keep API coverage of later policy replacement and revocation.
2026-11-01 01:43:21 +00:00
pulse-triage[bot]
21687d251a Bind organization overview and billing to their selected read
Invalidate obsolete reads, clear unread tenant figures and offer deliberate read-only recovery. Bind name changes to their accepted organization and never repeat an unconfirmed write.

Change-source: pulse-maintainer
2026-11-01 01:26:34 +00:00
pulse-triage[bot]
35b81d9ebb Seed an active synthetic phase before Patrol replay checks
The initial read matrix timed out waiting for a snapshot because its synthetic Patrol stream was idle; idle subscriptions correctly send no snapshot. Seed an analysing phase without starting Patrol, and retain the failed first run as failed fixture evidence. Keep the production repair unchanged and make the active-write closure assertion wait for its concurrent closer.

Change-source: pulse-maintainer
2026-11-01 01:20:25 +00:00
pulse-triage[bot]
8540b67cd3
Avoid repeated package startup in workflow exit adapters (#3667)
Keep the real workflow commands, runner, selector, complete discovered
inventories and every individual failure control. Run only their
stdlib-only synthetic exit adapters with the suite interpreter in
isolated no-site mode and avoid importing pathlib in every child. Add a
registered check for that exact fixture interpreter contract.

Contract-Neutral: Test-fixture startup only; production commands,
coverage, deadlines, policy and application behaviour are unchanged.

---
Fleet candidate `20261101T003400Z-delivery-trust` from the
`delivery-trust` lane. Reviewed tip
`1d19effd9d` on `main`.

[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
2026-11-01 01:15:30 +00:00
pulse-triage[bot]
87e1c0e66b
Show truthful Docs load failures and preserve same-guide retry (#3666)
**Show truthful Docs load failures and preserve same-guide retry**

Complete the retained #3102 error and retry repair on current main
without restoring the abandoned startup implementation. Preserve the
newer repeated-fragment focus handler, distinguish denied or interrupted
reads from absence, and retain the focused retry control while its read
is pending. Keep upstream response bodies out of the page and cover
recovery with registered loading tests.

Contract-Neutral: Repairs existing Docs error and retry presentation
without changing routes, APIs, authorisation or canonical subsystem
contracts.

**Record inspected Docs error and focus composition proof**

Bind desktop Chromium and narrow touch WebKit checks to the unchanged
Docs repair and this commit's own parent. Retain the first partial pass
and timeout, then the corrected unfinished-case continuation without
replaying fulfilled checks. All twelve retained captures were inspected
with the native image viewer.

Contract-Neutral: Adds only the source-bound browser verification
receipt for the existing Docs repair; no runtime or contract change.

---
Fleet candidate `20261101T001552Z-web-product` from the `web-product`
lane. Reviewed tip `4cd77a1ec2` on `main`.

[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
2026-11-01 01:00:03 +00:00
pulse-triage[bot]
fc7d1756d2 Sharpen withdrawn-stream assertions and writer cleanup proof
Expect existing invalid runtime-role authentication to refuse with 401, not a scope-level 403. Detect a disclosed canary immediately rather than waiting for stream timeout, and prove closure joins an in-flight broadcaster write and rejects subsequent queued writes. Runtime and admission policy are unchanged.

Change-source: pulse-maintainer
2026-11-01 00:59:47 +00:00
pulse-triage[bot]
f34c5b1ead Retain token authority throughout protected progress reads
Guard replayed, queued and live SSE bytes at the writer for update progress, Patrol and deployment reads. Revalidate admitted credential, principal, selected organisation and the route's existing scope, retaining instance authority only where the route requires it. Close silent withdrawn readers within 15 seconds and join guarded writes before returning; do not cancel background jobs or change session/proxy admission. Exercise the actual router and synthetic producers, durable deletion, independent readers and preserved job state.

Contract-Neutral: Enforce existing read admission and confidentiality boundaries throughout SSE lifetimes; no new route, payload, scope, role, job policy or session/proxy contract.
Change-source: pulse-maintainer
2026-11-01 00:55:05 +00:00
pulse-triage[bot]
2876265055
Keep credentials out of support-bundle system summaries (#3665)
**Keep credentials out of support-bundle system summaries**

Replace full configuration and process-environment serialization with a
closed diagnostic projection. Preserve the private raw logs, existing
route gates and useful polling/TLS/credential-presence facts; accept
only bounded Go runtime tuning values from the environment. Share
configuration ownership with log-level updates and report actual runtime
identity.

**Import the support-bundle HTTP contract reader**

Correct the missing io test import found by source-551gerps before any
selected tests ran. Runtime source and the export design are unchanged.
Retain the failed compile as failed evidence.

**Exercise the support-bundle instance gate with a valid selection**

The first native matrix correctly refused a nonexistent tenant with 400
invalid_org before reaching administration. Use a multi-organisation
token that can select default but cannot act for the instance, so this
test reaches the intended unchanged 403 gate. The failed assertion
remains retained; no runtime or authority change.

---
Fleet candidate `20261031T233032Z-core-runtime` from the `core-runtime`
lane. Reviewed tip `1aba138297` on `main`.

[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
2026-11-01 00:45:08 +00:00
pulse-triage[bot]
1d19effd9d Avoid repeated package startup in workflow exit adapters
Keep the real workflow commands, runner, selector, complete discovered inventories and every individual failure control. Run only their stdlib-only synthetic exit adapters with the suite interpreter in isolated no-site mode and avoid importing pathlib in every child. Add a registered check for that exact fixture interpreter contract.

Contract-Neutral: Test-fixture startup only; production commands, coverage, deadlines, policy and application behaviour are unchanged.
Change-source: pulse-maintainer
2026-11-01 00:40:22 +00:00
pulse-triage[bot]
77a8b5ea2d
Name failed smoke suites and preserve their exit codes (#3664)
Keep complete sorted discovery, shard selection, child output, later
suites and the aggregate failure verdict. End failed smoke and
documentation runs with the exact selected suite names and observed exit
codes so long logs leave an actionable handoff.

Contract-Neutral: Diagnostic-only smoke-runner output; no inventory,
scheduling, test command, deadline, contract requirement or pass/fail
policy changes.

---
Fleet candidate `20261031T234025Z-delivery-trust` from the
`delivery-trust` lane. Reviewed tip
`af21a594f2` on `main`.

[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
2026-11-01 00:29:29 +00:00
pulse-triage[bot]
4cd77a1ec2 Record inspected Docs error and focus composition proof
Bind desktop Chromium and narrow touch WebKit checks to the unchanged Docs repair and this commit's own parent. Retain the first partial pass and timeout, then the corrected unfinished-case continuation without replaying fulfilled checks. All twelve retained captures were inspected with the native image viewer.

Contract-Neutral: Adds only the source-bound browser verification receipt for the existing Docs repair; no runtime or contract change.
Change-source: pulse-maintainer
2026-11-01 00:28:10 +00:00
pulse-triage[bot]
b5a27bbbce Show truthful Docs load failures and preserve same-guide retry
Complete the retained #3102 error and retry repair on current main without restoring the abandoned startup implementation. Preserve the newer repeated-fragment focus handler, distinguish denied or interrupted reads from absence, and retain the focused retry control while its read is pending. Keep upstream response bodies out of the page and cover recovery with registered loading tests.

Contract-Neutral: Repairs existing Docs error and retry presentation without changing routes, APIs, authorisation or canonical subsystem contracts.
Change-source: pulse-maintainer
2026-11-01 00:18:13 +00:00
pulse-triage[bot]
70a273cb37
Keep Docs and reconnect coverage faithful to their contracts (#3663)
Stop calling an HTTP 503 evidence of a missing guide in navigation
coverage. Wait for the retained-resource fixture's store acquisition
instead of DOM polling, preserve every existing state and API assertion
and the default timeout, and dispose test roots after failures. These
independent corrections do not restore the abandoned startup
cancellation implementation or claim a cause for historical timeouts.

Contract-Neutral: registered test expectations, fixture synchronisation
and test-root cleanup only; no runtime, endpoint, authority or rendered
behaviour change.

---
Fleet candidate `20261031T232026Z-web-product` from the `web-product`
lane. Reviewed tip `748678e7a8` on `main`.

[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
2026-11-01 00:09:09 +00:00
pulse-triage[bot]
1aba138297 Exercise the support-bundle instance gate with a valid selection
The first native matrix correctly refused a nonexistent tenant with 400 invalid_org before reaching administration. Use a multi-organisation token that can select default but cannot act for the instance, so this test reaches the intended unchanged 403 gate. The failed assertion remains retained; no runtime or authority change.

Change-source: pulse-maintainer
2026-10-31 23:57:10 +00:00
rcourtman
9fc72c42f8
Alert on a host sensor's temperature from its own threshold (#3661)
Second slice toward per-sensor alerts (#3565): the backend half. Stacked
on #3658, whose commit it contains; the diff to review is the top
commit.

## What changes

- A native temperature sensor raises an alert only when its own override
sets a threshold: `Overrides["agent:<host>/sensor:<hex>"].Temperature`,
where `<hex>` is the lower-case hex of the sensor ID's UTF-8 bytes, so
IDs that differ only by case stay apart after host child IDs and metric
names are lower-cased.
- No default, and nothing is inherited from the host's, a linked node's
or a guest's CPU temperature threshold. Fans raise nothing.
- Evaluation uses the canonical metric path: metric `temperature`,
resource type `agent-sensor` (added as a spec bridge type). Delays,
critical escalation, quiet hours and notifications behave as for other
temperatures, and `agent-sensor` delay/intent rules apply on top of the
agent ones. The message names the sensor ("TB0T temperature at 47.0°C").

## Hold versus resolve

There is no completeness state in the report yet, so absence isn't
evidence of removal:

- **Hold** (interrupt timing, keep a firing alert): invalid reading, no
value, configured sensor missing from the report, empty inventory,
telemetry expiry. The existing 24-hour stale sweep still resolves an
alert with no observation.
- **Resolve**: override removed, disabled or zeroed; host or all-agents
alerting off; host removed; confirmed offline.
- **Config save**: re-judges a firing sensor alert by its own threshold,
and drops pending runs whose policy the save switched off (threshold,
host Disabled including inherited links, all agents, global), using the
host link identity recorded with the run. `ClearActiveAlerts` and the
stale-map sweep drop that identity too.
- Alert history joins the machine (`historySubResourceOwner` gains
`sensor`). Patrol's alert review never auto-resolves these alerts,
because its snapshot carries no sensor reading.

## Known limits, recorded in the alerts contract

- Operator intent (maintenance, mute) still resolves under the child ID,
the same as every existing host child alert.
- Overrides are keyed by the reporting host ID and aren't migrated when
a host's identity is healed to a new ID.
- As for every host metric, a report in flight during a save can act on
the old policy until the next report.

## Not in this PR

No UI writes these overrides yet. The Alerts → Thresholds section, mock
inventory and browser pass are the next PR. The UI save path sends the
raw override map, so overrides set through the API survive saves from
the current UI.

## Testing

- `operational_contract_test.go`: collision-free IDs (case, punctuation,
non-ASCII), exclusive override resolution, the full gap × policy matrix
(35 cases), config-save hold, pending-grace reset for five policy-off
paths including `ClearActiveAlerts`, sensor delay policy. Spec
validation, history ownership and the Patrol guard each have a test.
- Negative controls: removing each fix (pending re-check, save resolver,
Patrol guard, gap hold, removal clear, host-policy re-check,
classification, clear guard) makes its test fail.
- Full `internal/alerts/...`, `internal/ai/...` and
`internal/unifiedresources` pass.

Refs #3565
2026-10-31 23:57:09 +00:00
pulse-triage[bot]
af21a594f2 Name failed smoke suites and preserve their exit codes
Keep complete sorted discovery, shard selection, child output, later suites and the aggregate failure verdict. End failed smoke and documentation runs with the exact selected suite names and observed exit codes so long logs leave an actionable handoff.

Contract-Neutral: Diagnostic-only smoke-runner output; no inventory, scheduling, test command, deadline, contract requirement or pass/fail policy changes.
Change-source: pulse-maintainer
2026-10-31 23:50:47 +00:00
pulse-triage[bot]
9fda1ebe03 Import the support-bundle HTTP contract reader
Correct the missing io test import found by source-551gerps before any selected tests ran. Runtime source and the export design are unchanged. Retain the failed compile as failed evidence.

Change-source: pulse-maintainer
2026-10-31 23:43:24 +00:00
pulse-triage[bot]
f4a14d2235 Keep credentials out of support-bundle system summaries
Replace full configuration and process-environment serialization with a closed diagnostic projection. Preserve the private raw logs, existing route gates and useful polling/TLS/credential-presence facts; accept only bounded Go runtime tuning values from the environment. Share configuration ownership with log-level updates and report actual runtime identity.

Change-source: pulse-maintainer
2026-10-31 23:36:03 +00:00
pulse-triage[bot]
748678e7a8 Keep Docs and reconnect coverage faithful to their contracts
Stop calling an HTTP 503 evidence of a missing guide in navigation coverage. Wait for the retained-resource fixture's store acquisition instead of DOM polling, preserve every existing state and API assertion and the default timeout, and dispose test roots after failures. These independent corrections do not restore the abandoned startup cancellation implementation or claim a cause for historical timeouts.

Contract-Neutral: registered test expectations, fixture synchronisation and test-root cleanup only; no runtime, endpoint, authority or rendered behaviour change.
Change-source: pulse-maintainer
2026-10-31 23:22:47 +00:00
pulse-triage[bot]
4d35b8b557
End withdrawn System Logs token reads and show connection loss (#3659)
**End withdrawn System Logs token reads and show connection loss**

Reuse current credential snapshots with the log route's settings-read
scope and instance authority before history, queued and live lines and
idle checks. Preserve independent readers and session/proxy admission.
Show native connecting, reconnecting and disconnected states in the
existing panel without confusing them with display pause.

Contract-Neutral: Enforces the existing instance-admin/settings:read log
route and unchanged SSE format; connection status corrects the existing
panel. No route, grant or public API shape changes.

**Keep the existing log-panel shell fixture connected**

The shell fixture replaces the full state hook, so include its new
native connection-state projection before running the existing
architecture suite. Production and exercised lifecycle sources remain
unchanged.

**Record native System Logs withdrawal browser verification**

Bind the production log consumer to the real registered route's admitted
SSE frame, persisted deletion EOF, denied reconnect and independent
reader. Retain 31 native browser checks and four inspected
desktop/narrow captures; source and fixture limits remain explicit.

**Keep log safety smoke checks aligned with connection tracking**

Check disposed and paused admission in the actual receive callback, with
connection state updated between them. Preserve all display-only helper
checks and reject removed/reordered guards. Require every negative
control to mutate the source, so an obsolete matcher cannot pass
silently.

---
Fleet candidate `20261031T214001Z-core-runtime` from the `core-runtime`
lane. Reviewed tip `e62320cd99` on `main`.

[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
2026-10-31 23:21:29 +00:00
pulse-triage[bot]
73a763c8c7
Separate ownership assertions from live source ingestion (#3660)
The 175-case lookup suite repeatedly reads and audits the same source
for static ownership expectations. Extract its existing evidence-loading
boundary and share a real, deep-copied fixture only in the
classification test class. Keep live freshness and invalid-source
controls separate and retain every existing assertion.

Contract-Neutral: Preserve live source selection, all ownership and
dependent-reference classification, verification requirements and CLI
output; no production cache or policy change.

---
Fleet candidate `20261031T223306Z-delivery-trust` from the
`delivery-trust` lane. Reviewed tip
`cb56236cbe` on `main`.

[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
2026-10-31 23:19:44 +00:00
rcourtman
92aae26d34 Alert on a host sensor's temperature from its own threshold
The battery sensor in #3565 (applesmc TB0T) needs an alert without a
custom-metrics script. The agent now reports every lm-sensors input
with a stable key, so a threshold can name one sensor.

A native temperature sensor raises an alert only when its own override
sets one: Overrides["agent:<host>/sensor:<hex>"].Temperature, where
<hex> is the lower-case hex of the sensor ID, so IDs that differ only
by case stay apart after host child IDs are lower-cased. There is no
default and nothing is inherited from the host's or a linked node's CPU
temperature. Evaluation uses the canonical metric path (metric
temperature, resource type agent-sensor, now a spec bridge type), so
delays, escalation, quiet hours and notifications behave as for other
temperatures.

The report carries no completeness state yet, so an invalid reading, a
missing sensor, an empty inventory or telemetry expiry hold a firing
alert instead of resolving it; the existing 24-hour stale sweep still
applies. Removing or disabling the override, host or agent alerting
off, host removal and a confirmed offline host resolve it. Config saves
re-judge it by its own threshold and drop pending runs whose policy the
save switched off, using the host link identity recorded with the run.
Alert history joins the machine, and Patrol never auto-resolves these
alerts because its snapshot holds no sensor reading.

No UI writes these overrides yet; the Thresholds section follows.

Refs #3565
2026-10-31 23:16:48 +00:00
rcourtman
43e5d06d73
Report every lm-sensors temperature and fan with a stable key (#3658)
First of four slices toward per-sensor history and alerts (#3565). This
one only adds data; nothing reads it yet.

## Why

Per-sensor thresholds, history and a CPU-source choice need to name one
hardware input reliably. The existing `temperatureCelsius` / `fanRpm` /
`additional` maps can't: their keys drop the chip's bus address and
lower-case the label, so two NVMe drives, two CPU sockets, or applesmc's
`TC1F` and `TC1f` collapse into one reading, and readings outside 0–150
°C disappear.

## What changes

- The agent also reports `sensors.native`: one entry per `tempN_input`
and `fanN_input` of every chip, keyed `<chip>/<channel>` (e.g.
`applesmc-isa-0300/temp1`), with the original label, kind, unit,
unconverted value and an `ok`/`invalid` status.
- Implausible readings (outside -55..150 °C, e.g. applesmc's -127 °C)
stay listed as `invalid` instead of vanishing; a stopped fan's 0 RPM is
a reading.
- A chip whose inputs leave the legacy maps empty still reports its
inventory (power collection keeps its existing gate).
- Sorted, deduplicated, bounded at 256 entries. Cluster peer results
leave it out.
- Ingest keeps an entry only when its ID is exactly `<chip>/<channel>`
for a canonical channel of the reported kind, derives the unit, and
recomputes the status with the same shared policy
(`sensors.NativeSensorStatus`), so the server's judgement doesn't depend
on the agent version.
- Carried through the host model, frontend state (`native: []` beside
`custom`/`gpu`), unified resources, clones and the read-state
projection.

## What doesn't change

- The legacy maps keep their keys, filters and every consumer.
- No alerts, thresholds, history, preferences, CPU-source choice or UI.
The TypeScript type lands with the first frontend consumer.
- The key is a host-scoped source key, not a physical-device identity.
The contract notes record what later slices need first: completeness
state before a missing entry can mean a removed sensor, and a
collision-free encoding before the ID becomes a lower-cased alert or
metric key.

## Testing

- Parser: full fixture, distinct identities for same-type chips and
case-only labels, plausibility band edges, non-canonical channels,
dedupe and bound.
- Agent: complete `Sensors` result from the real parser path,
inventory-only chips (with the power gate), peer omission.
- Ingest: malformed entries, agent-claimed `ok` on -127 °C, `ok` without
a value, server-side cap, frontend and read-state projections, pointer
isolation.
- Unified resources: adapter and clone isolation.
- Full `internal/sensors`, `pkg/agents/host`, `internal/hostagent`,
`internal/models`, `internal/unifiedresources`, `internal/monitoring`,
`internal/alerts` and `internal/api` packages pass.

Refs #3565
2026-10-31 23:09:50 +00:00
pulse-triage[bot]
cb56236cbe Separate ownership assertions from live source ingestion
The 175-case lookup suite repeatedly reads and audits the same source for static ownership expectations. Extract its existing evidence-loading boundary and share a real, deep-copied fixture only in the classification test class. Keep live freshness and invalid-source controls separate and retain every existing assertion.

Contract-Neutral: Preserve live source selection, all ownership and dependent-reference classification, verification requirements and CLI output; no production cache or policy change.
Change-source: pulse-maintainer
2026-10-31 22:44:35 +00:00
rcourtman
e31210deec Report every lm-sensors temperature and fan with a stable key
Per-sensor alerts, history and a CPU-source choice (#3565) need to name
one hardware input reliably, and the existing flat maps cannot: their
keys drop the chip's bus address and lower-case the label, so two NVMe
drives, two CPU sockets or applesmc's TC1F/TC1f collapse into one
reading, and readings outside 0-150 °C vanish.

The agent now also reports sensors.native: one entry per tempN_input
and fanN_input of every chip, keyed "<chip>/<channel>", with the
original label, kind, unit, unconverted value and an ok/invalid status.
Implausible readings such as applesmc's -127 °C stay listed as invalid
rather than disappearing, a stopped fan's 0 RPM is a reading, and a
chip whose inputs leave the legacy maps empty still reports. The list
is sorted, deduplicated and bounded at 256 entries; cluster peer
results leave it out.

Ingest accepts an entry only when its ID is exactly <chip>/<channel>
for a canonical channel of the reported kind, derives the unit, and
recomputes the status with the same shared plausibility policy, so the
server does not depend on the agent's judgement. The inventory is
carried through the host model, frontend state, unified resources,
clones and the read-state projection.

Nothing consumes it yet. The legacy maps keep their keys, filters and
consumers. The contract notes record what later slices must add first:
completeness state before a missing entry can mean a removed sensor,
and a collision-free encoding before the ID becomes a lower-cased
alert or metric key.

Refs #3565
2026-10-31 22:24:26 +00:00
pulse-triage[bot]
e62320cd99 Keep log safety smoke checks aligned with connection tracking
Check disposed and paused admission in the actual receive callback, with connection state updated between them. Preserve all display-only helper checks and reject removed/reordered guards. Require every negative control to mutate the source, so an obsolete matcher cannot pass silently.

Change-source: pulse-maintainer
2026-10-31 22:22:24 +00:00
pulse-triage[bot]
058abfdc74
Reuse the complete contract index within each source lookup (#3657)
The protected parser improvement still leaves lookup parsing every
contract twice: its path references and dependent-update classification
load the same working tree separately. Share the invocation-local
complete index, reread it on every new lookup, and never substitute
ambient contracts for an explicitly empty snapshot. Standalone
index/commit guards keep their exact selected-source reads and reject a
borrowed working-tree index in those modes. Add full current-reference
equivalence, changed/deleted source, empty-source and source-selection
controls.

Contract-Neutral: Preserve ownership, dependent references, verification
obligations and source-selection rules; reuse only the complete
working-tree index within one lookup and prevent empty-snapshot
fallback.

---
Fleet candidate `20261031T214001Z-delivery-trust` from the
`delivery-trust` lane. Reviewed tip
`c5d2cd0850` on `main`.

[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
2026-10-31 22:16:48 +00:00
pulse-triage[bot]
e2c2e0c81d Record native System Logs withdrawal browser verification
Bind the production log consumer to the real registered route's admitted SSE frame, persisted deletion EOF, denied reconnect and independent reader. Retain 31 native browser checks and four inspected desktop/narrow captures; source and fixture limits remain explicit.

Change-source: pulse-maintainer
2026-10-31 22:08:21 +00:00
pulse-triage[bot]
bbc4015cd7
Release v6.7.0-rc.1 (#3656)
Release preparation for `v6.7.0-rc.1`. After this merges, the release
workflow runs at this exact head
`73ad6c7f20`.
2026-10-31 22:07:25 +00:00
pulse-triage[bot]
a707900690 Keep the existing log-panel shell fixture connected
The shell fixture replaces the full state hook, so include its new native connection-state projection before running the existing architecture suite. Production and exercised lifecycle sources remain unchanged.

Change-source: pulse-maintainer
2026-10-31 21:49:40 +00:00
pulse-triage[bot]
e90486c479
Keep organization sharing bound to the selected read (#3655)
**Keep organization sharing bound to the selected read**

Discard partial and obsolete sharing reads before enabling changes. Bind
all four existing share actions to the selected organization and
principal, reconcile unconfirmed writes through a deliberate read, and
preserve drafts only within that selection. Keep session, role,
read-only and target-approval boundaries intact.

Contract-Neutral: Bind existing organization sharing reads and changes
to their current selection; API/schema, authorization, sharing roles and
target-approval contracts are unchanged.

**Require a current destination for retained sharing drafts**

When an organization disappears from the accepted directory, clear its
retained destination instead of submitting an invisible value or
silently selecting a peer. Preserve the resource draft and require an
explicit current destination before the existing share action can run.

Contract-Neutral: Require a current explicit destination in the existing
sharing form; endpoint/schema, authorization, sharing-role and
target-approval contracts are unchanged.

**Align sharing validation with its explicit safety state**

Use supported role-query options without weakening assertions. Retain
the first exact-source 24,029-test pass and build/budget failure; allow
512 reference bytes only for the lazy OrganizationSharingPanel chunk's
current-selection, read-reconciliation and no-replay safeguards. Keep
the 15 percent threshold, all other chunk references, total budgets and
preload policy unchanged. Runtime source and its browser receipts are
unchanged.

Contract-Neutral: Test typing and a bounded single lazy-chunk size
reference update for the existing sharing safety repair; runtime,
protocol, authorization and preload contracts are unchanged.

**Keep removed sharing destinations invalid across refreshes**

Retain destination reselection as draft state across repeated directory
reads and events, failed-read recovery and a returning old destination.
Only an explicit current choice releases it; changing the organisation
or principal still clears the complete draft. Add six behavioral
regressions and fresh desktop/touch browser proof without altering
sharing roles, authority or target approval.

Contract-Neutral: Preserve explicit destination consent in the existing
sharing draft; API/schema, authorisation, sharing-role and
target-approval contracts are unchanged.

**Restore heading focus on repeated documentation links**

Explicitly restore the existing fragment's focus and scroll when the URL
is unchanged, instead of relying on a reactive navigation effect that
cannot rerun. Keep async document loading, different fragments, modified
clicks and truthful errors intact. Exercise the shipped Troubleshooting
link, actual router and desktop/narrow pixels; retain the narrower
parent focus failure rather than claiming the separate off-screen
finding was reproduced.

Contract-Neutral: Restore repeated-fragment focus in the existing
documentation viewer; routes, documentation content, sanitisation and
loading/error contracts are unchanged.

---
Fleet candidate `20261031T204217Z-web-product` from the `web-product`
lane. Reviewed tip `9b03f9fa0f` on `main`.

[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
2026-10-31 21:49:00 +00:00
pulse-triage[bot]
73ad6c7f20 Prepare v6.7.0-rc.1
Release candidate cut from main at d0d26373f5. It carries every change merged since stable v6.6.0.

Contract-Neutral: Release-only v6.7.0-rc.1 version, release notes and distribution metadata; no public install or runtime contract changes.
Change-source: pulse-maintainer
2026-10-31 21:48:42 +00:00
pulse-triage[bot]
c5d2cd0850 Reuse the complete contract index within each source lookup
The protected parser improvement still leaves lookup parsing every contract twice: its path references and dependent-update classification load the same working tree separately. Share the invocation-local complete index, reread it on every new lookup, and never substitute ambient contracts for an explicitly empty snapshot. Standalone index/commit guards keep their exact selected-source reads and reject a borrowed working-tree index in those modes. Add full current-reference equivalence, changed/deleted source, empty-source and source-selection controls.

Contract-Neutral: Preserve ownership, dependent references, verification obligations and source-selection rules; reuse only the complete working-tree index within one lookup and prevent empty-snapshot fallback.
Change-source: pulse-maintainer
2026-10-31 21:47:23 +00:00
pulse-triage[bot]
b732ff2b40 End withdrawn System Logs token reads and show connection loss
Reuse current credential snapshots with the log route's settings-read scope and instance authority before history, queued and live lines and idle checks. Preserve independent readers and session/proxy admission. Show native connecting, reconnecting and disconnected states in the existing panel without confusing them with display pause.

Contract-Neutral: Enforces the existing instance-admin/settings:read log route and unchanged SSE format; connection status corrects the existing panel. No route, grant or public API shape changes.
Change-source: pulse-maintainer
2026-10-31 21:46:32 +00:00
rcourtman
9225b0dcf9
fix(alerts): share acknowledgement request ownership (#3654)
Keep each alert with one outstanding card, group or global
acknowledgement request in the shared realtime store. Busy state
survives an overview remount, overlapping actions leave already-owned
alerts with their original request, and partial group results report
both success and failure counts.

End request ownership and optimistic confirmation guards together when
the alert scope changes, including their timers. Late responses cannot
change or notify the next scope when identifiers are reused. A reconnect
within the same scope retains both. The system-alert test factory now
supplies the required owner through typed props.

Owning contract: `docs/release-control/v6/internal/subsystems/alerts.md`
(L6), with the shared realtime and frontend contracts updated.

Verification: current-main and retained-patch scope-switch regressions
reproduced, then corrected. The final alerts/store/page suite passed 92
files and 1,441 tests. Type checking, the full lint chain, production
build and normal commit/pre-push hooks pass. Playwright and pixel review
cover 72 captures of `/alerts/overview` at 1440x1000, 768x1000 and
390x844 using built production controls and private API/socket fixtures,
including partial results, retries, overlap, remounts, scope changes,
reconnects and adjacent overlays.

The initial whole-tree worker attempt and baseline failure probes are
retained separately. Full frontend proof remains required through all
four protected CI shards before landing. The [browser
receipt](f269623271/frontend-modern/browser-verification/ef19f599dcfea639.json)
binds to the exact runtime bytes.
2026-10-31 21:42:43 +00:00
pulse-triage[bot]
d0d26373f5
End dashboard token streams when their authority is withdrawn (#3652)
**End dashboard token streams when their authority is withdrawn**

Revalidate the admitted token before every websocket data frame, queued
flush and idle ping. Share the current-tenant snapshot validator without
mutating a returned HTTP request. Keep session, origin, licensing and
wanted monitoring reads unchanged; exercise real token deletion, client
cleanup and independent subscribers.

**Preserve the existing unknown-organization reconnect refusal**

The first race proof closed every withdrawn socket but the reconnect
assertion expected only 401 or 403. Normal middleware first resolves the
rebound token's nonexistent organization and returns 400 invalid_org.
Assert that exact existing refusal without changing runtime authority,
frames or status codes.

---
Fleet candidate `20261031T195231Z-core-runtime` from the `core-runtime`
lane. Reviewed tip `096f655034` on `main`.

[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
2026-10-31 21:25:17 +00:00
pulse-triage[bot]
984f00dfc7
Parse numbered contract items without repeated prefix scans (#3653)
Exact-main governance spent 168 seconds in subsystem lookup tests. A
source profile attributes most lookup time to constructing and probing
99 numbered-list prefixes per line. Use one bounded equivalent match,
preserving the existing 1..99 syntax, content and source offsets; retain
full-index differential and adversarial parser coverage.

Contract-Neutral: Preserve contract syntax, reference offsets, ownership
and verification requirements; only remove repeated prefix construction
and scanning.

---
Fleet candidate `20261031T204026Z-delivery-trust` from the
`delivery-trust` lane. Reviewed tip
`edd1e3e940` on `main`.

[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
2026-10-31 21:23:30 +00:00
rcourtman
f269623271 fix(alerts): share acknowledgement request ownership
Keep each alert with one unsettled request across card, group and global
actions, including overview remounts. Report both success and failure counts
for partial group results so failures can be retried without resending work.

End request ownership and acknowledgement confirmation guards together when
the alert scope changes. Preserve both during same-scope reconnects so late
responses and timers cannot alter alerts with reused identifiers.
2026-10-31 21:01:28 +00:00
pulse-triage[bot]
9b03f9fa0f Restore heading focus on repeated documentation links
Explicitly restore the existing fragment's focus and scroll when the URL is unchanged, instead of relying on a reactive navigation effect that cannot rerun. Keep async document loading, different fragments, modified clicks and truthful errors intact. Exercise the shipped Troubleshooting link, actual router and desktop/narrow pixels; retain the narrower parent focus failure rather than claiming the separate off-screen finding was reproduced.

Contract-Neutral: Restore repeated-fragment focus in the existing documentation viewer; routes, documentation content, sanitisation and loading/error contracts are unchanged.
Change-source: pulse-maintainer
2026-10-31 20:58:21 +00:00
pulse-triage[bot]
442ec68c84 Keep removed sharing destinations invalid across refreshes
Retain destination reselection as draft state across repeated directory reads and events, failed-read recovery and a returning old destination. Only an explicit current choice releases it; changing the organisation or principal still clears the complete draft. Add six behavioral regressions and fresh desktop/touch browser proof without altering sharing roles, authority or target approval.

Contract-Neutral: Preserve explicit destination consent in the existing sharing draft; API/schema, authorisation, sharing-role and target-approval contracts are unchanged.
Change-source: pulse-maintainer
2026-10-31 20:50:23 +00:00
pulse-triage[bot]
edd1e3e940 Parse numbered contract items without repeated prefix scans
Exact-main governance spent 168 seconds in subsystem lookup tests. A source profile attributes most lookup time to constructing and probing 99 numbered-list prefixes per line. Use one bounded equivalent match, preserving the existing 1..99 syntax, content and source offsets; retain full-index differential and adversarial parser coverage.

Contract-Neutral: Preserve contract syntax, reference offsets, ownership and verification requirements; only remove repeated prefix construction and scanning.
Change-source: pulse-maintainer
2026-10-31 20:48:20 +00:00
pulse-triage[bot]
8ea8b57201 Compose retained organization sharing candidate for review repair
Change-source: pulse-maintainer
2026-10-31 20:42:55 +00:00