Commit Graph

4782 Commits

Author SHA1 Message Date
pulse-triage[bot] 384dc53608 Keep repeated Proxmox cluster labels provider-scoped
A cluster name is an operator-selected display label, not global machine identity. Two independently configured estates using the same label could share one linked agent and then collapse into one presentation row after delayed cluster detection. Require node identity, exact endpoint, or host corroboration across provider instances instead.

Refs #1753

Change-source: pulse-maintainer
2026-09-03 23:41:31 +01:00
pulse-triage[bot] 9d1deb2a0a Allow TrueNAS CORE 12 legacy REST negotiation
CORE 12 reports versions such as TrueNAS-12.0-U5, which the legacy transport gate did not recognise. Admit that bounded version family and retain redirect negotiation coverage for both supported CORE generations.

Change-source: pulse-maintainer
2026-09-03 21:57:07 +01:00
Richard Courtman a70c96c8a3 Make telemetry consent a setup choice and retire the payload banner
The setup wizard's telemetry card only ever offered a way out: it led
with "enabled by default", gave no reason the data exists, and told the
reader to set PULSE_TELEMETRY=false before starting a process that had
already sent its first ping two minutes after boot. The payload-update
banner paired "we now collect more" with a one-click Disable button, was
keyed to schema v2 from July and never re-triggered across fifteen later
bumps, and its text was rewritten in August so anyone who had dismissed
it never saw the new wording. Nothing on either surface said what the
data is for or what it is never used for. No GitHub issue or discussion
has ever complained about the default-on posture, so the defensive
framing was answering a question nobody asked while quietly nudging
people to opt out.

Setup now leads with what the daily summary is for (development effort
follows real use; the features and platforms the operator relies on get
priority), names concrete exclusions (hostnames, credentials, IP
addresses), states what it is never used for (not sold or shared, not
used for advertising, not linked to a Pulse account or license), and
puts a real Usage statistics toggle on the admin-account step. The
toggle defaults to on and, when switched off, is applied through the
canonical system-settings endpoint once the admin token exists, so there
is no setup-only side channel and the account is created either way.
Neither setup screen tells the reader how to turn it off; the switch is
the control. The env-var instruction moves to PRIVACY.md where a reader
can still act on it, alongside a note that the first ping fires about
two minutes after start.

The payload-update banner is retired along with its telemetryAction deep
link that changed the preference on arrival. Payload changes are now
disclosed in a dated changelog in PRIVACY.md (back-filled from schema v2
to v17 from the telemetry package's own version notes) and in release
notes; an in-app notice is reserved for a change in kind. PRIVACY.md
gains a "What it is not used for" section whose statements are facts
about the license-server path, which never joins telemetry rows to
license or customer records; the contract treats any change to that path
as a change in kind. Settings leads with what the data is for and makes
Preview payload the primary action, because the exact runtime payload is
the disclosure an operator can verify. The security-privacy,
deployment-installability, and frontend-primitives contracts record the
new rules. Telemetry and i18n proof tests pin the setup choice, the
purpose-first and never-sold wording in every locale, and the changelog
row for the current schema so a future bump cannot land undisclosed.

Demand ledger: repos/pulse-pro FEATURE_REQUESTS.md "Telemetry consent as
a real setup choice" (named bet, pulse-pro PR #40). Supersedes the
three-commit branch behind Pulse PR #1873, rebuilt on current main.
2026-09-02 19:04:54 +01:00
pulse-triage[bot] 0a08c01132 Merge reviewed release convergence reconciliation
Retain the exact delivery-trust candidate commit and integrate its current-control retry and scheduled reconciliation behavior on canonical main.

Change-source: pulse-maintainer
2026-09-02 13:28:10 +01:00
pulse-triage[bot] f74de141b4 Reconcile convergence with current controls
GitHub reruns preserve the failed workflow SHA, so a repaired convergence control cannot resolve an already committed release. A missed workflow_run event can also leave mutable aliases stranded without another attempt.

Change-source: pulse-maintainer
2026-09-02 13:11:04 +01:00
rcourtman ff1d584a42 Merge pull request #1864 from rcourtman/claude/patrol-telemetry-provider-cost-v4
Add schema v17 Patrol provider, cost, autonomy, and outcome telemetry
2026-09-02 12:48:28 +01:00
rcourtman eecf45fafd Email the Patrol weekly summary as a report schedule kind
The customers most likely to lapse are the ones who stopped opening Pulse,
so the in-app "This week" card cannot reach them. Report schedules gain a
kind: the default resources kind is the existing PDF or CSV performance
report, and patrol_digest emails the same weekly "what Patrol did for you"
rollup the Patrol page shows, in plain language, for the whole workspace.
It reuses the existing scheduler, cadence, recipients, tenant email config,
and Pro advanced-reporting entitlement rather than adding a second
scheduler. Digest schedules are weekly and email-only; the server fixes
scope, format, and attachments, and a run with no AI service, no Patrol, or
no email destination records a last_error that names the missing piece
instead of sending an empty week. Nothing is written to disk.

The digest assembly moves from the HTTP handler into
AISettingsHandler.BuildPatrolDigest so the schedule runner and the
endpoint share one code path. docs/MSP.md documents the kind for
providers; the Settings > Reporting "Report type" selector follows in a
separate change once it has a Pro-licensed browser pass.
2026-09-02 11:15:22 +01:00
rcourtman 3420fcdee4 Add schema v17 Patrol provider, cost, autonomy, and outcome telemetry
The 2026-09-01 Patrol assessment could not answer four questions from
telemetry: what share of Patrol installs run local versus cloud models,
what Patrol costs an install per month (issue 1789 estimates ~104k input
tokens per full run at ~5.5 runs a day, above the Pro fee on non-Flash
tiers), how the 240 of 255 fleet investigations that produced no plan
actually ended, and which effective Patrol mode an install runs.

Schema v17 adds closed buckets only. ai_provider_class classifies the
Patrol model route (none, local, cloud_byok, cloud_subscription,
hosted_quickstart, unknown) with a syntactic private-host check on custom
OpenAI-compatible endpoints; it never resolves DNS or carries a provider,
model, endpoint, or account. pulse_intelligence_patrol_autonomy_level is
the effective level after licence and Autopilot gating. The two token
fields bucket the existing local usage ledger's Patrol events, so exact
counts and prices stay on the install. Thirteen investigation outcome
counters partition the findings already counted as investigated, one
bucket per finding, adding no finding, resource, or session identity.

The strings are never omitted, so an empty value can only mean a pre-v17
sender; the receiver stores those as unknown. PRIVACY.md, its shipped
mirror, the Settings preview interface, and the security-privacy and
api-contracts subsystem notes carry the disclosure, and the coverage gap
is registered in status.json.

The agent-lifecycle and storage-recovery contracts name internal/api under
their extension points, so both record that this telemetry is adjacent
adoption analytics and never agent or storage state. The stable E2E tier
pins the public schema version, so the disclosure spec moves to 17, and
the Settings preview interface change carries a browser receipt from a
scratch build of this tree at 1280x800 and 390x844. status.json also drops
an identical duplicate of the ai-provider-guided-setup coverage-gap record
that two merges each appended, which the private governance audit rejects.

The bucket for a legacy config still pointing at the retired Pulse-hosted
route is named hosted_legacy: the shipped privacy document discloses the
vocabulary verbatim and the frontend copy contract keeps that document
free of the retired hosted quickstart wording, so the telemetry package
now pins the vocabulary at the source.
2026-09-02 11:09:25 +01:00
rcourtman b5f694b216 Merge pull request #1860 from rcourtman/claude/patrol-value-digest-card-r2
Show what Patrol did this week on the Patrol page
2026-09-02 10:52:02 +01:00
rcourtman 5476288a4e Merge pull request #1840 from rcourtman/claude/helm-publish-checkout-order
Fix the release preflight worker and Helm publish, and map v6.4.3 to release/v6.4
2026-09-02 10:10:19 +01:00
rcourtman 123e342c6c Show what Patrol did this week on the Patrol page
A paying customer had no place in Pulse that added up Patrol's work: runs
were per run, findings per finding, actions under Actions, spend on the AI
cost dashboard. The Activity tab now opens with a "This week" card that
reads GET /api/ai/patrol/digest and shows six things in plain language:
Patrol runs, new issues and how many are still open, issues resolved,
investigations, fixes run, and estimated spend. Tile copy is mode-aware, so
a watch-only install reads that nothing was investigated because Patrol is
watch only, and the card links to Actions only when Patrol-origin fixes are
waiting for approval.

The card never recomputes counts client-side and keeps forensic vocabulary
out; a failed load says the summary is unavailable rather than showing
zeros, and a truncated run history says since when the numbers hold. The
page header already states the Patrol mode sentence, so the card does not
repeat it. Second slice of the "Patrol weekly digest" named bet in the
pulse-pro demand ledger; browser proof in browser-verification.json covers
the Activity tab at 1280 and 375 pixels against an isolated mock-mode
backend.
2026-09-02 09:57:22 +01:00
pulse-triage[bot] facee87bb4 Merge pull request #1852 from rcourtman/maintainer/20260902T060320Z
Fix empty-slot alerts and make keyboard navigation accessible
2026-09-02 09:52:36 +01:00
rcourtman 22b9abf231 Fix the release preflight worker and Helm publish, and map v6.4.3 to release/v6.4
Three defects that the v6.4.3-rc.1 cut exposed, each with its contract note
and proof:

1. scripts/release-preflight-worker.sh published the smoke stack on host port
   7655 and probed it directly. pulse-dev also hosts the maintainer's dogfood
   Pulse instance on 127.0.0.1:7655 and a second instance on 17655, so the
   release smoke failed to start after every other stage had passed on the
   qualified head. The worker now honours PULSE_RELEASE_PREFLIGHT_E2E_PORT,
   otherwise takes the first candidate host port pair it verifies free and
   fails fast when none is, probes health and update status on that port, and
   hands Playwright the same base URL.

2. .github/workflows/publish-helm-chart.yml resolved the chart version before
   checking out the repository, but de41ea1883 made that step call
   scripts/write_github_output.py, so every chart publish since failed with
   "can't open file". Run 33580123246 hit it after all other staging passed;
   the checkout now precedes the resolver.

3. docs/release-control/control_plane.json maps the 6.4.3 version prefix to
   release/v6.4. Run 33579042375, dispatched from main, failed inside the
   compiler dispatch because main advanced one minute after the pipeline
   pinned its source SHA; with pull requests landing every few minutes a
   candidate cannot hold its SHA between prepare and compile. release/v6.4
   was created from main at the exact-SHA-qualified commit 56e51e622e and
   carries these same fixes; v6.4.3-rc.1 published from it.

The deployment-installability contract records the worker port and toolchain
rules and the Helm checkout order; release_preflight_test.py and
build_release_assets_test.go pin them.
2026-09-02 09:32:40 +01:00
pulse-triage[bot] 6ab16f9f35 Merge current Pulse upstream for publication
Preserve the reviewed command-palette browser receipt as the current singleton receipt while retaining the upstream Patrol setup proof in its unchanged parent history.

Change-source: pulse-maintainer
2026-09-02 08:56:06 +01:00
rcourtman 8ea94d792b Add the Patrol weekly digest endpoint
Nothing in Pulse showed a paying customer what Patrol had done for them:
about 164 runs a month per install, findings raised, investigations and
fixes, and none of it summarised. GET /api/ai/patrol/digest rolls the last
N days (default 7, max 30) up from records Pulse already keeps: run
history, the findings store, Patrol-origin action audits, and the usage
cost store. It adds no telemetry and persists nothing. The payload
reports when the bounded run history no longer covers the window and when
model pricing is unknown, rather than quietly under-counting.

This is the first slice of the "Patrol weekly digest" named bet in the
pulse-pro demand ledger; the in-app "This week" card follows once its
browser pass is recorded. docs/PATROL_WEEKLY_DIGEST.md holds the design
note and the honest limits of each line.

status.json registers the patrol-value-visibility coverage gap, the
candidate lane, and its work claim. It also drops the second, identical
copy of the ai-provider-guided-setup coverage gap that landed with #1853;
the duplicate id fails the status audit on main for every pull request.
2026-09-02 08:53:50 +01:00
pulse-triage[bot] 6c5af82b52 Merge reviewed command palette accessibility fix
Change-source: pulse-maintainer
2026-09-02 08:32:12 +01:00
pulse-triage[bot] 23a59f17a1 Fix command palette active option accessibility
Keep DOM focus on the command search input while exposing the visually
selected result through combobox active-descendant semantics. Remove results
from the Tab sequence, keep keyboard selection visible in long lists, and
cover populated and empty states.

Change-source: pulse-maintainer
2026-09-02 08:16:13 +01:00
rcourtman ac328e1eee Guide the Patrol model choice with cost preview and budget pause
Forty-two percent of paying installs never get Patrol running, and the
support and issue evidence says the wall is model choice and cost: a
prospect asked which models Pulse recommends before trying, a Pro customer
picked Flash-Lite to save money and Patrol then could not file verdicts,
and a mispriced Opus row tripped the 20 USD budget so the circuit breaker
disabled Patrol with nothing but a log line (#1789).

Answer both questions at the point of choice. The Patrol and shared
default model pickers pin guided models in a "Suggested for Patrol"
section with recommended / suggested / caution markers and a one-line
reason: the Ollama preflight blessing is the only recommended entry,
Gemini Flash-Lite the only caution, and cloud starting points are labelled
price-driven and unqualified until this install's own readiness pass
upgrades them to "Verified on this install". A server-computed cost
preview sits under the model choice: monthly estimate from Pulse's price
table, the schedule, and the install's own median full run once three
priced runs exist (a measured 104,528-in / 4,491-out run otherwise), with
the assumption stated and a token explained once, plus 30-day spend
against budget. Each schedule preset is priced in the Schedule select.

When a per-token model is picked while the schedule is still the 6-hour
default, the cost model proposes the slowest preset that keeps scheduled
runs under half the budget (20 USD reference when none is set) and says
what the slower check costs in detection delay; a schedule the install
already chose is never changed.

A used-up budget is now a spending decision, not a provider fault: the
budget refusal is a typed sentinel with the figures, classified as the
budget_exhausted cause, excluded from circuit-breaker accounting, and
promoted into the Patrol block state, so the Patrol page shows "Patrol
paused" with the spend and limit and a "Raise the cost budget" action
instead of "Check Patrol model".
2026-09-02 07:55:42 +01:00
rcourtman a10c175f31 Fold alert-mirroring findings, collapse flapping, surface lasting decisions
Two users (discussions #1623, #1699) could not find Patrol's durable
outcomes: the Needs attention detail offered only Acknowledge and
Suppress, and Remember as expected, Dismiss: Not an issue, Dismiss:
Later, and Create rule sat two levels below it. The same screenshot
showed an alert with eleven open/resolved transitions in a day listed as
eleven timeline rows, and Patrol findings restating an active alert
appearing beside it. Telemetry shows most findings are seen and ignored.

Backend: findings_alert_mirror.go is the single matcher for a finding
that restates an active alert (explicit alert identifier, or same
canonical resource plus the same condition class). Patrol stamps
mirrors_alert_id/mirrors_alert_type after every real and demo cycle and
clears them when the alert resolves; the finding is kept, not dropped.
The storm throttler now also owns flap detection: four or more
open/resolved transitions in 24h mark a finding flapping, and the store
maintains one collapsed lifecycle row with the count instead of a row per
transition, hydrating the window from persisted lifecycle after restart.
The attention projection applies the same threshold to alert timelines
and exposes a flapping summary while keeping the full timeline.

Frontend: the attention detail gains a Lasting decisions section that
offers the four Patrol decisions on the finding mirroring the alert, each
with one line saying what it does and how long it lasts, an inline
confirmation, and a remembered-decision state with Reopen. An alert with
no mirrored finding says Patrol has nothing to remember and points at
alert thresholds. Flapping items carry one label and a summarised
timeline with every transition under an expansion. FindingsPanel demotes
active alert-mirroring findings into a collapsed group. The Patrol
surface loads dismissed findings so remembered decisions are visible.
2026-09-02 07:02:51 +01:00
pulse-triage[bot] d680c339d9 Require accessible names for shared dialogs
Make the shared Dialog prop contract require exactly one accessible-name strategy so new modal call sites cannot silently omit screen-reader context. Record the canonical primitive contract, preserve existing runtime behavior, and cover both valid strategies plus invalid unnamed and ambiguous props.

Change-source: pulse-maintainer
2026-09-02 04:40:19 +01:00
pulse-triage[bot] 9edc8bcea3 Merge captured Pulse upstream
Incorporate the batch-start upstream rootful qualification fixes without re-parenting canonical maintainer commits.

Change-source: pulse-maintainer
2026-09-02 03:48:55 +01:00
rcourtman e93ee38084 Tighten rootful runtime cleanup proof
Rootful evidence must reject non-running systemd states and prove no unrelated container runtime survives. Require exact manager state, mask distro containerd, recheck readiness after scenarios, and remove the complete Podman socket boundary.
2026-09-02 02:52:13 +01:00
rcourtman e836dfda13 Fix rootful qualification readiness
The disposable host reached multi-user.target in a degraded state because distro Podman housekeeping used overlay storage inside the outer container. Mask unused units, force VFS for explicit daemons, and fail closed on systemd unit failures so retained rootful evidence remains trustworthy.
2026-09-02 02:43:30 +01:00
pulse-triage[bot] f503b13442 Bind release dispatches to the admitted commit
A workflow dispatch by branch can resolve after that branch moves, allowing an unreviewed tip to enter the release pipeline. Require every publishing dispatch to name its expected source SHA and make the workflow reject a different source or workflow commit before checkout.

Change-source: pulse-maintainer
(cherry picked from commit a461fc9c0a)
2026-09-02 02:28:14 +01:00
rcourtman 419a368323 Merge pull request #1828 from rcourtman/topic/transparency-delivery
Describe how changes land and ship, and hold human commits to the standard
2026-09-02 02:22:14 +01:00
rcourtman 56e51e622e Merge pull request #1825 from rcourtman/topic/release-train
Adopt the release train: promote the soaked candidate, not the branch tip
2026-09-02 02:08:32 +01:00
rcourtman 5f0a487404 Merge pull request #1823 from rcourtman/pulse/secure-runtime-rootful-qualification
Add rootful runtime qualification packet
2026-09-02 01:48:16 +01:00
rcourtman 6d0ce0b45e Describe how changes land and ship, and hold human commits to the standard
The transparency page told evaluators that routine changes may merge
without line-by-line review, but not what governs a landing or a
release, so the commit stream was the only evidence and it read badly
(discussion #1539, the release-reliability ledger entry). The page now
states the delivery contract in public terms: every writer lands through
a pull request that auto-merges on green required checks with no bypass,
the maintainer's pull requests carry outcome, reason, and validation, and
releases run on a train with a soaked, exact-content candidate, with the
rules in RELEASE_PROMOTION_POLICY.md. The shipped docs mirror is updated
with it.

The maintainer's candidate preflight already refuses a commit without a
body or with a subject over 72 characters. The new husky commit-msg hook
holds human and interactive-agent commits in this checkout to the same
standard, exempting merge, fixup, squash, and revert messages.
2026-09-02 01:17:38 +01:00
rcourtman df7ad9be43 Adopt the release train: promote the soaked candidate, not the branch tip
Stable promotions built whatever the dispatch branch was at that second.
The resolver checked that HEAD descends from the promoted release
candidate but never that its content matches, so v6.4.0 shipped 64
changed files, including product code, that v6.4.0-rc.12 had not
soaked. Every v6 version was mapped to main, which now moves every few
minutes under the autonomous maintainer, so each fix to a candidate
brought everything landed since and stable was never an exact soaked
commit. Five of six stable minor releases shipped under version-bound
owner exceptions that waived the soak.

From v6.5.0 the release train applies (RELEASE_PROMOTION_POLICY.md,
"Release Train"): a two-week train sized to measured velocity, a
release/v6.N branch per train declared in the control plane so the
workflow refuses a dispatch from anywhere else, a stable promotion that
may differ from its candidate only in release metadata unless
hotfix_exception names active customer harm, and a seven day soak for
minor releases. The 6.4.x line stays on main so the v6.4.3-rc.1
candidate already prepared there is unaffected. The gap is registered
as coverage gap release-train-exact-candidate-promotion.
2026-09-02 01:17:38 +01:00
rcourtman 7996848b64 Submit advertised lifecycle actions through pulse_control, not prose
A paying operator asked the Assistant to reboot five Proxmox VMs matching
a name pattern (GitHub #1782, support mail 2026-08-26 and 2026-08-29). The
model resolved the VMs and then ended with a report that invented a
prerequisite: a QEMU guest agent on 6.3.2, a "discovery binding" on stable
6.4.0. It never planned the action. Three defects made the governed path
fail whenever the model did try it, and nothing refused the prose ending
when it did not:

- pulse_control handed the session-scoped id (vm:<node>:<vmid>) to the
  action lifecycle, whose registry keys on canonical unified ids, so a
  Proxmox guest plan could never resolve.
- pulse_control gated the action on the legacy per-executor action list,
  which never carried the canonical "reboot" capability Proxmox guests
  advertise, so "reboot" was refused as not permitted before planning.
- A reference absent from the session context was refused with "resource
  discovery is required" even when the unified inventory resolved it.

pulse_control now binds its target to the canonical unified resource
(session alias first, then a unique inventory match, refusing ambiguity
with candidate ids and naming the pulse_query recovery on a miss), passes
the canonical id to the planner, and answers "not available" only from
the resource's current advertised capabilities. The FSM ordering block
and the shared operating instructions state that a recoverable block is
not a limitation to report, and the instructions require the governed
action tool for advertised capabilities. The agentic loop adds a bounded
advertised-action gate: when the operator asked for a lifecycle action,
pulse_control was offered but never submitted, and a session-resolved
resource advertises the action, a tool-free final answer is refused once
with the exact per-target calls.

Covered by tools and loop unit tests (the #1782 transcript against a
scripted provider fails on the previous code with the two exact errors
above), a prompt-contract test, and the live eval scenario
ProxmoxBulkLifecycleActionScenario.
2026-09-02 00:19:08 +01:00
rcourtman 14a7d0bdaf Merge action-runner replay and Windows portability fixes 2026-09-02 00:16:26 +01:00
rcourtman d3ea482827 Merge branch 'main' into pulse/secure-runtime-rootful-qualification 2026-09-02 00:14:50 +01:00
rcourtman 2de076a9bc Merge main into claude/hostagent-replay-reconnect-wait
Pick up the browserslist advisory fix (#1827) so the required Frontend
dependency audit can pass on this pull request.
2026-09-02 00:14:41 +01:00
rcourtman 500cc1bf17 Harden rootful qualification evidence boundary 2026-09-01 23:53:36 +01:00
rcourtman c022a0dfe6 Raise browserslist above security advisory floor 2026-09-01 23:33:55 +01:00
rcourtman b1044cd8a4 Let replayed request ids wait for the in-flight handler instead of dropping
Since 60d0651a88 every typed request registers a per-connection cancellable
slot that its handler goroutine releases in a deferred cleanup after sending
its result. The server replays a request id when it wants the durable receipt
again, and that replay can reach the reader before the previous handler's
deferred release runs. launchCancellableRequest treated that as a duplicate
and dropped it, so the server waited out the operation's full timeout for a
result the agent already held. The Linux x64 native-verification leg failed
this way on 12 of the last 25 main runs, always on a "replay 1" dispatch of
host update, storage cleanup, or Docker lifecycle.

Give each slot a done channel that closes on release. A replay whose id is
still registered on the same connection now waits for that release and then
runs, answering from the durable receipt. Invalid ids and over-capacity
requests are still dropped. A unit test pins the wait-then-run behaviour and
the agent-lifecycle contract records the replay rule.
2026-09-01 23:22:55 +01:00
rcourtman 584cef81a1 Add rootful runtime qualification packet 2026-09-01 22:40:50 +01:00
pulse-triage[bot] 5fb7177b8a Require compiler dispatch run details
Change-source: pulse-maintainer
2026-09-01 22:26:46 +01:00
rcourtman 45dd45fe29 Record rootless runtime qualification evidence 2026-09-01 22:09:22 +01:00
rcourtman 62bfdbca7e Prepare v6.4.3-rc.1 release
Open the v6.4.3 candidate line from main. The v6.4.2 tag was staged on
2026-08-31 but never activated: its release run was cancelled after the
private Pro build failed the compiler memory gate, so the latest published
stable is still v6.4.1. This candidate carries the complete v6.4.2 change
set plus the corrections landed since that tag, including the stale PBS
Backup Running state (#1815), the Windows Unified Agent auto-update 404
(#1820), and shared-token same-hostname agent identity collapse (#1753).

Packet: VERSION, compose and install-docker defaults, Helm chart metadata,
release notes with a declined visual plan, changelog, pointer docs and
the shipped docs mirror, and the deployment-installability cutoff note.
Rollback target is v6.4.1 and the mobile decision is no-mobile-impact.

Tests: the packet tests now describe the 6.4.3 train, v6.4.2 is recorded
as an unpublished stable so it is never derived as the previous stable or
rollback target, and the Python v6.4.2 notes expectation matches the
phrase the notes actually use.
2026-09-01 21:37:41 +01:00
rcourtman 60041ad9e6 Validate each rootless socket identity 2026-09-01 21:26:49 +01:00
rcourtman b87ab75965 Limit planning status audit to tracked documents 2026-09-01 21:18:24 +01:00
rcourtman bc3dd3b704 Give rootless qualification hosts unique identities 2026-09-01 21:18:24 +01:00
rcourtman feff95934c Remove the Home tab and page, keep the fleet health verdict engine
The fleet health Home surface reached main on 2026-09-01 by implementing
a July agent-handoff spec with no demand-ledger entry. Exercised live on
the 1,510-resource mock estate it rendered 572 tiles on first paint with
275 in "Needs attention", 232 of them backup age, against two real
criticals; per-node storage mounts, disks, and swarm secrets appeared as
fleet members with no host context; and the critical node tile opened
its platform overview with the node below the fold. No stable release
carries it yet, so remove the route, navigation tab, page, i18n keys,
Assistant page context, route preload, and e2e cases now rather than
spend lane turns polishing an ungraded bet.

The server-side ResourceHealth verdict, its API projection, and the
/api/state/summary verdicts and attention extension stay: they are one
canonical health boundary that #1478 asked for and that any future
surface should read. The spec is parked with the 2026-09-01 review kept
as the design record.

Browser proof: desktop and 375px shells show no Home entry, /home renders
the not-found surface and its Go to workspace button lands on the
default workspace, the narrow More sheet lists Settings only, no console
errors or horizontal overflow.
2026-09-01 20:54:21 +01:00
rcourtman 2f8a4ec629 Require a Status line on planning documents
Any *_SPEC.md, *_PLAN.md, or *_CONTRACT.md under docs/ must now carry a
Status: line (or a ## Status section) in its header, enforced by the
pre-push lint. A spec, plan, or contract is a record of a decision, not
demand; the 2026-09-01 Home wall case showed what happens when a stale
handoff spec reads as a current signal. Subsystem contract markdown is
governed separately and is not scanned.

The commercial cancellation/reactivation e2e test plan gets the one
missing line so the existing set passes.
2026-09-01 20:52:25 +01:00
rcourtman f364cfc73b Reset Podman qualification storage on teardown 2026-09-01 20:49:43 +01:00
rcourtman 54cd77d3b1 Mark stale spec, plan, and contract docs with verified status
Repository specs, plans, and contracts are records of past decisions, not
demand. Each triaged document now carries a Status line that was checked
against the code and governance surfaces rather than against the document:

- VMware vCenter phase-1 onboarding, API runtime, resource projection, and
  alerts/assistant specs: IMPLEMENTED (shared floor shipped; live vCenter
  proof still outstanding).
- VMware execution plan and proof matrix: PARKED with a note that the
  first-lab-ready checkpoint was reached and the live proof has been
  blocked since 2026-03-30 with no ledger entry.
- Customer Account and Pulse Account portal specs: IMPLEMENTED at the L17
  RC floor; post-GA expansion is a lane follow-up, not a build signal.
- v6 bridge release foundation spec: SUPERSEDED by the resolved decision
  and lanes L18, L19, L20, and L22.
- Service assurance plan: slices A-E IMPLEMENTED, slices F-H PARKED.
- Availability history contract: IMPLEMENTED (history and fleet slices).
- Alert engine evolution: IMPLEMENTED; UI migration stays demand-gated.
- Legacy host classification audit: record; post-release queue PARKED.
- OIDC scope fix spec: closed record, fixes shipped in v6.0.4/v6.0.5.

Backup task timeline contract is left as ready for implementation because
its ledger entry is threshold-met. The HOME status wall spec, subsystem
contracts, and records are untouched.
2026-09-01 20:43:26 +01:00
rcourtman 832a4be9fd Record the 2026-09-01 Home wall review as binding spec revisions
Live exercise on the 1,510-resource mock estate showed the shipped Home
tab rendering 572 tiles on first paint with 275 in "Needs attention",
232 of them backup age, against two real criticals; per-node storage
mounts, disks, and swarm secrets rendered as fleet members with no host
context; and the critical node tile opened its platform overview with
the node below the fold. The implementation followed the July handoff
spec faithfully, so the fixes are recorded as spec revisions R1 to R6
(backup staleness out of attention, attention cap, fleet-member
granularity, host context, node deep links, plain-language reasons).

The default-route flip stays gated until R1 to R5 land and are
re-exercised in a browser. The spec now names its demand record in the
pulse-pro ledger and states that it is a decision record, not demand.
2026-09-01 20:35:47 +01:00
rcourtman fec53eb39e Wait for rootless runtime mounts to release 2026-09-01 20:26:46 +01:00
rcourtman 089ce2379d Clean runtime fixtures before qualification teardown 2026-09-01 20:13:15 +01:00