Commit Graph

2693 Commits

Author SHA1 Message Date
pulse-triage[bot] 071dadf1f7 Exercise balanced smoke selection through the workflow fixture
Copy the real selector and its timing hints into the existing whole-inventory workflow fixture. Verify sorted, disjoint complete coverage and inject a failure into each actual selected shard, keeping the required verdict fail closed instead of asserting the retired filename-parity placement.

Contract-Neutral: Consuming CI fixture alignment for whole-suite scheduling only; workflow admission, check names, runtime tests and acceptance remain unchanged.
Change-source: pulse-maintainer
2026-10-26 17:36:56 +00:00
pulse-triage[bot] db76f62798 Balance isolated smoke suites with measured scheduling hints
A complete passing PR run spent 318 and 567 seconds inside the two smoke inventories. Filename parity places the long deadline controls together. Partition every discovered suite by measured duration while preserving sorted per-shard execution, real deadlines, failure collection and the existing checks. New suites use a default weight; stale hints cannot add or omit coverage, and incomplete selection fails before execution.

Contract-Neutral: CI scheduling of unchanged complete script suites only; product, installer, release and verification acceptance contracts are unchanged.
Change-source: pulse-maintainer
2026-10-26 17:32:06 +00:00
pulse-triage[bot] 5cf7d82c6a Bound synchronous audit exports and summaries
Limit the actual query to 10001 rows and refuse selections over 10000 before verification or encoding. Preserve complete accepted results, selectors, signatures and access boundaries, and explain how to narrow a refused selection.

Change-source: pulse-maintainer
2026-10-26 16:06:56 +00:00
pulse-triage[bot] aaf38867e7 Recover lifecycle discovery from peer stream cancellation
The daily install/recovery rehearsal stopped before installation in run 40343060586 when GitHub cancelled a metadata stream. Retry only that exact transport-only exit, with fixed GET identities, deadlines and a finite budget; discard partial output and stop on refusals, malformed data, signals or unknown errors.

Exercise the actual workflow resolver with synthetic process outcomes and retain the existing signed installation, update and rollback contracts. This changes no release gate or deployment operation.

Change-source: pulse-maintainer
2026-10-26 14:57:25 +00:00
rcourtman d5604fe3df Confine release credentials to the release environment (#3303)
## What

Every job that reads a release, signing or registry credential now
declares
`environment: release`, and `scripts/check_workflow_trust.py` enforces
it.

- 20 jobs across `create-release`, `build-release-candidate`,
`publish-docker`,
  `promote-floating-tags`, `promote-private-pro-runtime`,
  `recover-release-activation`, `backfill-release-assets`,
  `retry-release-convergence`, `release-signing-preflight`,
  `signpath-test-signing` and `canonical-private-governance` declare
`environment: release`. `qualify-browser-update-release` declares
`infra` for
its tailnet credentials. `PULSE_LICENSE_PUBLIC_KEY` is a public key and
stays
  repository-wide.
- The checker reads job structure with a duplicate-key-rejecting YAML
loader
  and scans both raw text and decoded values for secret expressions
  (case-insensitive, across lines, quote-aware). It requires the literal
release environment for release credentials and a deployment environment
for demo/tailnet credentials (the demo workflow's runtime choice only in
its
own job). It refuses dynamic `secrets[...]` access and workflow-level
secret
env, and requires any push workflow that reads a secret to admit exactly
  `branches: [main]`.

## Why

Release secrets are repository-level today, so any workflow run on any
branch,
including a pushed proposal branch before review, can read them. The
release
train is switching to post-merge `release-dispatch/*` branches that only
the
release dispatcher App can create (ruleset-enforced). A `release`
environment
admitting only `main` and `release-dispatch/*` then keeps these
credentials
away from unmerged code.

## Merge order (draft until then)

Stacked on #3297. Do not merge until:
1. a beta has published through a `release-dispatch/*` dispatch, and
2. the `release` (branches `main`, `release-dispatch/*`) and `infra`
(`main`)
environments exist with branch-typed policies, so the first post-merge
run
   does not auto-create an unprotected environment.

Repository-level secret copies stay until no snapshot without these
declarations can still be dispatched or recovered.

## Validation

- Live tree passes the checker; `test_workflow_trust.py` 50 OK,
including new
cases for every rule and for bypasses found in review (lower-case names,
`}}` inside strings and YAML-escaped quotes, `release#x`, duplicate
keys,
  quoted `tags`/`inherit`, a push key hidden in a description, the demo
  expression outside its job).
- Eleven mutations, one per guard, each fail the tests.
- All 1301 `scripts/tests`, Go `scripts/installtests`, and
`release_promotion_policy_test.py` 74 OK (new proof test pins the
release
jobs' environment). Release-control discovery has 17 failures and 1
error
  that are identical on `main` and on this branch's base.
2026-10-26 14:22:52 +00:00
pulse-triage[bot] aef2f5be9c Keep non-root agent preflight outside saved installer trust
Fix the manual-recovery failure reported in Pulse #3331. Compare directory identity without entering the protected saved lifecycle directory, so a freshly authenticated temporary installer can finish preflight as the invoking user. Keep the saved installer's ownership, mode and checksum enforcement, including parent-directory aliases.

Contract-Neutral: Restores the existing non-root preflight and saved-installer integrity contracts; no privilege, credential, update-authorisation or rendered-interface contract changes.
Change-source: pulse-maintainer
2026-10-26 12:37:01 +00:00
pulse-triage[bot] 1df60af642 Scope TrueNAS release notes to the delivered fixes (#3332)
Separate disk-temperature and SCALE CPU fixes from the still-failing
CORE host CPU and memory reporting request. Preserve the rest of the
stable and RC.6 notes and cover both source copies in the existing
renderer suite.

Contract-Neutral: Published-note wording and its regression coverage
only; no runtime or subsystem contract changes.

---
Fleet candidate `20261026T105420Z-delivery-trust` from the
`delivery-trust` lane. Reviewed tip
`e0714ad8fee464087b154b9b8b204fb43e890517` on `main`.

[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
2026-10-26 12:17:57 +00:00
pulse-triage[bot] ed841e7ade Separate PMG decoding failures from gateway reachability (#3329)
Explain the queue-response failure reported on stable without treating
an unread dataset as an empty queue or an authentication failure. Keep
native queue monitoring and private, bounded evidence as the fallback
rather than DNS, privilege or mail mutations.

Contract-Neutral: Existing PMG help and safety regression coverage only;
no collector, API, schema, permission or navigation behaviour changes.

---
Fleet candidate `20261026T101040Z-product-intelligence` from the
`product-intelligence` lane. Reviewed tip
`34e3502630a46f5ff50f4f6d0f54a814751d49db` on `main`.

[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
2026-10-26 12:00:46 +00:00
pulse-triage[bot] a5659362bf Prepare v6.7.0-beta.1
Beta cut from main at 047313732c. It carries every change merged since stable v6.6.0.

Contract-Neutral: Release-only v6.7.0-beta.1 version, release notes and distribution metadata; no public install or runtime contract changes.
Change-source: pulse-maintainer
2026-10-26 11:11:36 +00:00
pulse-triage[bot] e0714ad8fe Scope TrueNAS release notes to the delivered fixes
Separate disk-temperature and SCALE CPU fixes from the still-failing CORE host CPU and memory reporting request. Preserve the rest of the stable and RC.6 notes and cover both source copies in the existing renderer suite.

Contract-Neutral: Published-note wording and its regression coverage only; no runtime or subsystem contract changes.
Change-source: pulse-maintainer
2026-10-26 11:03:27 +00:00
pulse-triage[bot] 34e3502630 Separate PMG decoding failures from gateway reachability
Explain the queue-response failure reported on stable without treating an unread dataset as an empty queue or an authentication failure. Keep native queue monitoring and private, bounded evidence as the fallback rather than DNS, privilege or mail mutations.

Contract-Neutral: Existing PMG help and safety regression coverage only; no collector, API, schema, permission or navigation behaviour changes.
Change-source: pulse-maintainer
2026-10-26 10:21:04 +00:00
pulse-triage[bot] 1aa9974ed2 Preserve existing Docker deployments during setup
The first-install generator replaced customised Compose files and overwrote its one recovery backup on every rerun. Refuse existing Compose paths before Docker or output writes, retain regular environment files, and prevent output clobbering. Report configuration preparation rather than an installation that was never run.

Contract-Neutral: Restore intended setup idempotency and saved-deployment preservation; no generated Compose schema, runtime policy, image default, upgrade API or lifecycle contract changes.
Change-source: pulse-maintainer
2026-10-26 09:44:50 +00:00
rcourtman 9406ceb23e Name workflow trust test inputs as references
CodeQL flagged the release_job helper as clear-text storage of a secret because its parameter was named secret. The value is only the ${{ secrets.NAME }} expression text written into a fixture workflow, never a credential, so the name now says that.
2026-10-26 08:47:48 +00:00
pulse-triage[bot] 3bb2c7e95d Pin installer help to its verified private-file guide
The returned candidate failed the existing branch-tip documentation guard in script smoke shard 0. Keep that guard intact, bind help to the inspected immutable guide, and test the real emitted URL as well as the private-file commands.

Contract-Neutral: CLI guidance and its regression only; installer flags, authentication, TLS, service lifecycle and runtime behaviour are unchanged.
Change-source: pulse-maintainer
2026-10-26 08:40:58 +00:00
pulse-triage[bot] 2b0b134dfa Keep agent installer guidance off token arguments and HTTP pipes
Recommend the existing inspected HTTPS/private-file route in shipped help and the source header. Exercise copied commands, saved-state updates and side-effect-free help with synthetic credentials.

Contract-Neutral: CLI guidance only; installer flags, authentication, TLS, service lifecycle and runtime behaviour are unchanged.
Change-source: pulse-maintainer
2026-10-26 07:37:06 +00:00
pulse-triage[bot] 665b18acad Stop container continuity reads at explicit access refusals
The scheduled scan at 41715cf2 retried a refused Docker Hub control-plane read four times, then attempted aliases through a second script. Stop explicit registry or attestation access refusals on the first response, retain the exact target and exit, and run aliases only after exact-container verification succeeds. Keep both registries, every digest and source-bound attestation mandatory; unrelated Helm evidence remains independent.

Contract-Neutral: Fail-closed refusal handling and diagnostic ordering only; public registry, digest, provenance and release activation requirements are unchanged.
Change-source: pulse-maintainer
2026-10-26 06:00:47 +00:00
rcourtman 69354b9d20 Confine release credentials to the release environment
Release, signing and registry secrets are repository-wide, so a workflow run
on any branch can read them, including a pushed proposal branch before any
review. The release train now dispatches on post-merge release-dispatch/*
branches that only the release dispatcher App can create, so these secrets
can move into a `release` environment that admits only main and those
branches.

Every job that reads the update signing key, Apple, SignPath or Windows
signing material, Docker Hub credentials or WORKFLOW_PAT now declares
`environment: release`; the browser update qualification job declares `infra`
for its tailnet credentials. The public license verification key is not a
credential and stays repository-wide.

check_workflow_trust.py enforces this. It reads job structure with a YAML
loader that rejects duplicate keys and scans expressions across lines,
comments and quoted `}}`, matching secret names case-insensitively. Release
credentials need the literal release environment, demo and tailnet
credentials need a deployment environment (the demo workflow's runtime choice
only in its own job), dynamic secrets[...] access and workflow-level secret
env are refused, and a push workflow that reads any secret must admit exactly
`branches: [main]`. A test that asserted an any-branch push workflow could
read WORKFLOW_PAT now asserts the opposite.
2026-10-26 00:30:23 +00:00
pulse-triage[bot] 9242018047 Preserve updater assets when repository configuration fails (#3299)
Return actual allocation, syntax, mode and rename failures before
publishing a configured updater. Prepare the rewrite beside its input
and leave the installed helper and units unchanged when configuration
cannot complete. Exercise the real rewriter and its containing asset
installer under the conditional callers that suppress errexit.

Contract-Neutral: Repairs the existing configured-helper and
failure-preservation guarantees without changing update consent, source
selection, service policy or deployment contracts.

---
Fleet candidate `20261025T214019Z-delivery-trust` from the
`delivery-trust` lane. Reviewed tip
`aa4f3bbf8db4e9ff1b055f391ef4ecf0d6fb9a0a` on `main`.

[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
2026-10-25 23:35:37 +00:00
rcourtman c157b921b0 Recover activation for release-train snapshot runs (#3297)
## What

`recover-release-activation.yml` now also admits failed
`create-release.yml`
runs dispatched from release-train snapshot refs
(`release-candidate/<packet>`
or `release-dispatch/<packet>`), not only from `main`.

A snapshot run is admitted only when main's `release_snapshot.py` proves
its
commit is the merged head of exactly one `release-candidate/<packet>`
release
PR. The source run's own `prepare` job ran that branch's code, so it is
not
trusted. Recovery now refuses to run unless dispatched on `main`,
fetches full
history for the ancestry check, and gains `pull-requests: read` for the
PR
lookups.

## Why

The release train has dispatched on `release-candidate/*` branches since
October, and will move to post-merge `release-dispatch/*` branches so
release
secrets can be confined to refs that exist only after merge. A train
release
that failed at activation could not use this recovery path at all.

## Stacking

This branch is built on #3295 (snapshot check accepts
`release-dispatch/*`
refs), whose commit is included here. The two PRs touch different files.

## Validation

- New executable test runs the recovery admission against stubbed GitHub
and
git: `main`, `release-candidate/*` and `release-dispatch/*` runs are
admitted;
lane branches, missing, unmerged or mismatched PRs, a different head
commit,
two matching PRs, malformed refs and a merge missing from main are
rejected.
- Mutations that each fail it: skipping the provenance check, and not
mapping
`release-dispatch/*` to its candidate head. Two more (admitting any
branch in
the run predicate, dropping the head-SHA filter in PR selection) are
caught
  by `release_snapshot.py`'s own checks instead.
- `release_promotion_policy_test.py` 73/73, `check_workflow_trust.py`
and its
  44 tests, `release_snapshot_test.py` 7/7, all on a full checkout.
2026-10-25 23:31:19 +00:00
pulse-triage[bot] af5b66dad8 Align triage disclosure with current release and retest policy (#3296)
**Align triage disclosure with current release and retest policy**

Correct the disclosure linked from every community reply and its shipped
Docs copy: weekly stable targets, daily betas instead of early candidate
cuts, and the stable publication clock when a same-fix preview retest
already exhausted unanswered contact. Correct the linked release guide
as well, preserving every-symptom resolution, safe retesting and
unchanged candidate soak. Add registered document and
production-renderer coverage.

Contract-Neutral: Public guidance now matches existing standing release
and contact policy; no runtime, release machinery, authority or
subsystem contract change.

**Explain CORE reporting rejection without repeated capture**

Distinguish the reported HTTP 400 query-schema failure from an invalid
API key, refreshed inventory and measured idle zeros. Link
missing-telemetry readers to the safe native Reporting fallback before
more capture, retaining the original report and upgrade relevance. Add
registered production-renderer regression coverage.

Contract-Neutral: Existing TrueNAS troubleshooting guidance only; no
API, collector, storage, permission or release contract change.

**Assert the native fragment contract for CORE help**

The first source proof caught a test-only assumption: fragment-only
links deliberately use native browser anchors, not the cross-document
router marker. Check that existing contract; the guide bytes are
unchanged. Retain the original failed proof.

Contract-Neutral: Correct a documentation test assertion; no runtime or
subsystem contract change.

**Format issue follow-through renderer tests for CI**

The reviewed help candidate failed the required full frontend formatting
check because its disclosure test file was not included in the focused
formatting command. Apply the configured style without changing
assertions, documentation or runtime behaviour.

Contract-Neutral: Test-only formatting; no rendered content, runtime or
subsystem contract changes.

**Finish formatting long disclosure assertions**

The full-tree check found additional over-width assertions beyond the
first scoped repair. Reflow the remaining expressions without changing
their tokens or documentation.

Contract-Neutral: Test expression layout only; assertions and runtime
behaviour are unchanged.

---
Fleet candidate `20261025T210853Z-product-intelligence` from the
`product-intelligence` lane. Reviewed tip
`b06f1584aa8da42d3effbae4c57e7b8c325c5d57` on `main`.

[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
2026-10-25 22:53:16 +00:00
rcourtman e2545bd34b Accept release-dispatch refs as post-merge snapshot dispatches (#3295)
## What

The release snapshot check
(`scripts/release_control/release_snapshot.py`)
now also accepts dispatches from `release-dispatch/<packet>` refs. Such
a
dispatch must name a merged PR whose head is
`release-candidate/<packet>` at
the dispatched commit. The other checks are unchanged: closed and
merged,
head SHA equals `GITHUB_SHA` and `GITHUB_WORKFLOW_SHA`, base is the
requested
source line, canonical repository, and both merge ancestry checks.
`release-candidate/*` dispatches keep working exactly as before.

## Why

Release, signing and registry secrets are repository-level today, so a
workflow run on any branch can read them. The planned fix moves them
into a
`release` environment that admits only `main` and post-merge dispatch
refs.
`release-candidate/*` cannot be that ref, because unmerged release PR
heads
live under the same name. This check has to accept the new namespace
first,
and every snapshot cut after this merges will carry it, before the host
dispatcher switches over.

This validates identity only. Restricting who can create or move
`release-dispatch/*` refs is a separate repository ruleset; the contract
in
`deployment-installability.md` says the namespace carries no extra trust
until that ruleset is active.

## Validation

- `release_snapshot_test.py`: 7/7, including new cases for the dispatch
  mapping, rejected head names (`release-candidate/other`,
  `release-dispatch/*`, `maintainer/*`), malformed dispatch names and
  unbound inputs, plus the end-to-end `main()` path for both namespaces.
- Mutation checks, each failing the tests: dispatch ref not mapped to
its
  candidate head; slashes admitted in dispatch names; dispatch ref not
  admitted by `source_branch`.
- `release_promotion_policy_test.py` behaves identically with and
without
  the change on the same partial tree; CI runs it in full.
2026-10-25 22:50:26 +00:00
rcourtman 54fd5f3aa2 Recover activation for release-train snapshot runs
Activation recovery only admitted failed create-release runs dispatched on
main, but the release train dispatches on release-candidate/* snapshot
branches, and will move to post-merge release-dispatch/* branches. A train
release that failed at activation could not use the recovery path.

Recovery now also admits runs from those refs, but only after main's
release_snapshot.py proves the run's commit is the merged head of exactly one
release-candidate/<packet> release PR. The source run's own prepare job ran
that branch's code, so it is not trusted. Recovery refuses to run unless
dispatched on main, fetches full history for the ancestry check, and gains
pull-requests: read for the PR lookups.
2026-10-25 22:36:09 +00:00
rcourtman 879de51e28 Accept release-dispatch refs as post-merge snapshot dispatches
Release secrets are repository-wide today, so any workflow on any branch can
read them. The plan is to move them into a `release` environment that admits
only `main` and post-merge dispatch refs. Today's dispatch refs cannot serve:
`release-candidate/*` also names unmerged release PR heads.

The snapshot check now also accepts `release-dispatch/<packet>`. It must name
a merged PR whose head is `release-candidate/<packet>` at the dispatched
commit, with the same source-line and ancestry checks as before. The
existing `release-candidate/*` dispatch keeps working, so the host dispatcher
can switch over later. Every snapshot cut after this lands carries the check.

This change validates identity only. Restricting who can create or move
`release-dispatch/*` refs is a separate repository ruleset, and the contract
says the namespace carries no extra trust until that ruleset is active.
2026-10-25 22:00:28 +00:00
pulse-triage[bot] aa4f3bbf8d Preserve updater assets when repository configuration fails
Return actual allocation, syntax, mode and rename failures before publishing a configured updater. Prepare the rewrite beside its input and leave the installed helper and units unchanged when configuration cannot complete. Exercise the real rewriter and its containing asset installer under the conditional callers that suppress errexit.

Contract-Neutral: Repairs the existing configured-helper and failure-preservation guarantees without changing update consent, source selection, service policy or deployment contracts.
Change-source: pulse-maintainer
2026-10-25 21:47:30 +00:00
rcourtman b3a27e2dd2 Sync issue labels with GITHUB_TOKEN, not the triage App key
The label sync was the only workflow that read PULSE_TRIAGE_APP_PRIVATE_KEY.
That key belongs to an App installation that can administer the repository,
and as a repository-level Actions secret any workflow run on any branch could
read it. Everything the helper does (read the issue, create, add and remove
labels) is covered by the run's own GITHUB_TOKEN with issues: write, so the
App key can now be deleted from Actions.

The policy test now requires issue-mutating workflows to use the scoped
GITHUB_TOKEN and to reference no secrets, and still requires the parser tests
to run before the label write. Silent labels are applied as
github-actions[bot]; AI_TRANSPARENCY.md says so.
2026-10-25 21:21:54 +00:00
pulse-triage[bot] 6d3315934b Merge retained CORE and triage help corrections for CI repair
Change-source: pulse-maintainer
2026-10-25 21:10:33 +00:00
pulse-triage[bot] 21a32dbf86 Fail closed when local pre-push source reads fail
Require complete Git scope, parent, trailer and file observations before checking committed source. Keep ordinary dirty-tree exits distinct from read errors, retain every failing canonical commit, and stop before expensive source checks when admission is already blocked. Fault-injection controls exercise empty and partial reads alongside the successful Go, type-check and browser-guard path.

Contract-Neutral: Local pre-push orchestration only; product contracts and the required source, audit and browser checks are unchanged.
Change-source: pulse-maintainer
2026-10-25 19:47:30 +00:00
pulse-triage[bot] 3fb0ec966f Merge commit 'f7cd68379b00266870a6345a9ebbd55fd5b75c40' into maintainer-async/20261025T184637Z-product-intelligence/pulse
Change-source: pulse-maintainer
2026-10-25 19:20:08 +00:00
pulse-triage[bot] c84e5143da Keep manual channel proof on the HTTPS transport envelope
Returned CI rejected the new curl protocol flags in the existing channel fixture. Admit only the exact HTTPS options and require both. Make the invalid-signature control prove it reached the real verifier instead of passing on a fixture error; retain all channel and no-download checks.

Change-source: pulse-maintainer
2026-10-25 16:56:36 +00:00
pulse-triage[bot] f7cd68379b Align triage disclosure with current release and retest policy
Correct the disclosure linked from every community reply and its shipped Docs copy: weekly stable targets, daily betas instead of early candidate cuts, and the stable publication clock when a same-fix preview retest already exhausted unanswered contact. Correct the linked release guide as well, preserving every-symptom resolution, safe retesting and unchanged candidate soak. Add registered document and production-renderer coverage.

Contract-Neutral: Public guidance now matches existing standing release and contact policy; no runtime, release machinery, authority or subsystem contract change.
Change-source: pulse-maintainer
2026-10-25 16:28:47 +00:00
pulse-triage[bot] 89c61b233c Keep signed manual update bootstraps on HTTPS
The generated manual helper currently permits an HTTPS asset redirect to plaintext HTTP, unlike the unattended downloader. Restrict initial and redirect protocols for both signed inputs, without weakening deadlines, signature verification or cleanup. Exercise the actual helper with real curl and authenticated local TLS, including downgrade refusals and permitted HTTPS redirects; keep the native systemd fixture on the exact envelope.

Change-source: pulse-maintainer
2026-10-25 15:47:43 +00:00
pulse-triage[bot] 70a0c54e84 Replace manual update helpers without truncating running readers
The published v6.5.0 to v6.6.0 lifecycle run 40197749411 reported an unmatched quote after the installer rewrote /bin/update in place. Stage, validate and atomically replace the helper so an executing Bash reader keeps its original inode. Preserve the optional non-fatal setup guarantee on every preparation or replacement failure.

Change-source: pulse-maintainer
2026-10-25 13:42:11 +00:00
rcourtman e138bdf7d6 Point the MSP guide at v6.6.0 and self-serve buying
Every /msp evaluation link opens docs/MSP.md, which still installed the
v6.4.1 bundle and said paid licences come through an assisted upgrade
path. Plan in the provider portal has sold every MSP plan since v6.5.0,
so a provider following the site could never reach it.

The guide now installs the signed v6.6.0 bundle, explains buying,
renewing and lapsing from Plan as shipped (paid period plus 14 days,
then 7 days of grace), and adds an upgrade section. Walking it on a lab
VM found three more gaps, now covered: day-2 commands need sudo because
setup writes a root-only .env; client runtimes move only with
--rollout-tenants; and a v6.4.x control plane keeps stopping clients,
which blocks the upgrade gate until it is stopped and the current
runtimes are started. No plan exists above 40 clients, so the guide no
longer offers a custom licence for that.
2026-10-25 12:59:11 +00:00
pulse-triage[bot] 296b128254 Interpret byte-throughput benchmark changes in the right direction
SetBytes benchmarks report B/s beside time and allocation costs. Treat lower byte throughput as adverse, retain lower-is-better cost metrics, and include each finding's unit so scaled values are not ambiguous. Keep the significance, sample and magnitude gates unchanged.

Contract-Neutral: CI benchmark verdict parsing and registered regression controls only; no product runtime or subsystem contract change.
Change-source: pulse-maintainer
2026-10-25 11:25:52 +00:00
pulse-triage[bot] 77350524c4 Keep Recovery overview proof separate from transfer safety
Restore the existing dialog/flow verification policy unchanged and give the Recovery overview its own direct-test requirement. Pin rejection of cross-surface substitutes, cumulative proof for mixed edits and truthful forward/reverse lookup routes without changing frontend bytes or imported history.

Change-source: pulse-maintainer
2026-10-25 10:39:21 +00:00
pulse-triage[bot] 85abbc3f55 Retain Recovery disclosure candidate for bounded proof-policy correction
Change-source: pulse-maintainer
2026-10-25 10:37:16 +00:00
pulse-triage[bot] 3f6560cd2e Keep isolated issue-triage changes on their dedicated CI path (#3252)
The proposed-source triage suite already exercises the locked parser and
silent-mutation consumers. Pure helper edits still queued unrelated
application suites for more than twenty minutes. Recognise only the six
exact triage inputs from a complete tree diff; mixed, missing and
control-path changes retain full application checks. Keep workflow
output outside the fixture source tree so real-diff controls do not
stage it.

Contract-Neutral: CI admission for isolated issue-event inputs only;
locked triage tests, secret scanning, governance and mixed-source
runtime checks remain enforced, with no product contract or permission
change.

---
Fleet candidate `20261025T085429Z-delivery-trust` from the
`delivery-trust` lane. Reviewed tip
`e404c2fe07096fcf9b733f307a5a834719a966c5` on `main`.

[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
2026-10-25 10:23:36 +00:00
pulse-triage[bot] b10c8dc553 Align subsystem lookup with dedicated transfer verification
Complete the same Recovery policy move in lookup coverage, including all three transfer surfaces and their exact proof list. The broader governance run exposed this stale framing expectation after the first repair; no runtime, registry or enforcement changes are required.

Change-source: pulse-maintainer
2026-10-25 10:13:17 +00:00
pulse-triage[bot] bc27f34b70 Align Recovery verification-policy regression coverage
Keep the seven remaining settings shells under framing proof, and assert transfer-specific membership for Recovery, its dialogs and its flow. Confirm dedicated proofs match and generic settings architecture cannot satisfy transfer safety. This repairs PR 3249's reproducible governance-test failure without changing the guard or weakening the registry.

Change-source: pulse-maintainer
2026-10-25 10:02:45 +00:00
rcourtman 5ad599fc98 Keep the system hostname when migrating to the safe profile
Safe-profile migration pinned the output of hostname -f as the agent's
reported name, so every migrated host switched to its FQDN while
root-profile hosts kept the short system hostname the agent reads. Pin
the system hostname instead. An explicit --hostname still wins, and the
server's authority check already accepts short and FQDN forms of the
bound name. Hosts migrated earlier keep their stored name.

Contract-Neutral: Safe-profile migration now pins the system hostname the agent already reports; no agent-lifecycle or deployment-installability clause names the hostname -f choice, and the new install_sh_test.go case proves the behaviour.
2026-10-25 09:43:39 +00:00
pulse-triage[bot] e404c2fe07 Keep isolated issue-triage changes on their dedicated CI path
The proposed-source triage suite already exercises the locked parser and silent-mutation consumers. Pure helper edits still queued unrelated application suites for more than twenty minutes. Recognise only the six exact triage inputs from a complete tree diff; mixed, missing and control-path changes retain full application checks. Keep workflow output outside the fixture source tree so real-diff controls do not stage it.

Contract-Neutral: CI admission for isolated issue-event inputs only; locked triage tests, secret scanning, governance and mixed-source runtime checks remain enforced, with no product contract or permission change.
Change-source: pulse-maintainer
2026-10-25 09:04:08 +00:00
pulse-triage[bot] c6666e9b94 Release v6.6.0 (#3247)
Release preparation for `v6.6.0`. After this merges, the release
workflow runs at this exact head
`76da9cfbbaec64ebd5fe76395bdd53eaaca6867a`.
2026-10-25 09:02:28 +00:00
pulse-triage[bot] 76da9cfbba Prepare v6.6.0
Promote v6.6.0-rc.6 to stable after its 24-hour soak. Only release metadata changes.

Contract-Neutral: Release-only v6.6.0 version, release notes and distribution metadata; no public install or runtime contract changes.
Change-source: pulse-maintainer
2026-10-25 08:39:03 +00:00
pulse-triage[bot] b6618c19a3 Preserve each configuration-backup safety control's deadline
The containing installer suite exhausted a single 30-second Python-class budget after eleven controls and killed the last. Use the existing serial discovery runner with all twelve required methods, retaining each control's 30-second bound and the existing inner shell bounds rather than treating cumulative class time as a safety deadline.

Change-source: pulse-maintainer
2026-10-25 06:49:45 +00:00
pulse-triage[bot] 5d748986b3 Keep native recovery proof aligned with bounded manual downloads
Admit only the manual helper's exact new curl envelope in the existing closed transport fixture. Require a signed emitted-helper round trip and reject altered deadlines, retries and TLS flags through the registered installer suite; do not widen the adapter or execute a native journey.

Change-source: pulse-maintainer
2026-10-25 06:38:18 +00:00
pulse-triage[bot] b239891b75 Bound signed manual-update bootstrap downloads
Keep both bootstrap requests within curl's connection and whole-request deadlines, without ambient retry settings. Arm cleanup before allocation so a second mktemp failure cannot strand the first input. Exercise the emitted helper's signed success, partial download failures, allocation failures and signature rejection without native or production execution.

Change-source: pulse-maintainer
2026-10-25 06:33:50 +00:00
rcourtman 03132e8782 Reduce workload chart overhead and repair browser test setup (#3233)
Cold seven-day mock workload charts synthesized 914 values per series
before discarding most of them. Selecting the existing timestamp grid
before synthesis preserves the retained readings, newest point and
complete history window while bounding expensive work. The controlled
native request fell from 8.9 seconds to 1.3 seconds.

The strict chart query gate also exceeded its 90 ms p95 limit. Profiling
showed repeated SQLite row decoding, so raw fleet value reads now carry
the series and timestamp in one integer per observation. This
statement-local transport preserves exact values, negative-epoch
timestamps, tier reconciliation, resource scope and ordering, with
separate columns when a window could overflow. Full metrics-store tests
and targeted monitoring/API regressions pass, including boundary and
prepared-query cache controls. The 90 ms limit remains unchanged.

Organization browser fixtures arrange activated API fixtures before
their first workspace load. Explicit activation and deletion bounds
cover the existing server deadlines. Cleanup owns partial preparation,
attempts every tracked organization and retains failures. Native backend
teardown retains its final log. CI executes all 63 authentication,
organization and backend lifecycle controls before browser fanout.

Browser OS acquisition uses the hosted runner's existing signed Ubuntu
source definition. An unrelated Microsoft feed returning 403 can no
longer stop browser setup. Missing, unreadable or empty Ubuntu
definitions and incomplete Ubuntu index updates still fail. Existing
mirror, TLS, signature and cached archive hash checks remain in force.
Real apt acquisition controls, 17 package cache tests, 11 ownership
tests and normal commit/push checks pass.

The mock target lookup benchmark keeps fixture lifecycle logs out of
Go's result stream. A combined stdout/stderr control reproduces the lost
original observations and parses all ten corrected observations with
identical 4,731 lookups per operation. The benchmark work and comparison
thresholds remain unchanged.

Current-build browser verification covers
`/proxmox/workloads?type=vm&platform=proxmox-pve` at 1440×1000 and
390×844: seven-day trends, row drawer expansion, history range
selection, oldest/latest keyboard inspection and drawer dismissal.
Twelve organization-route cases cover organization settings, access,
sharing and billing across Chromium, mobile Chrome and mobile Safari
with retries disabled.

The [full stable/probation browser
run](https://github.com/rcourtman/Pulse/actions/runs/40160832317)
passed: 530 passed, 392 skipped, zero failures and no retry/flaky
markers in all eight shard logs. Agent registration and organization
provisioning also passed. This evidence covers product code at 64c0a3f9.
The later correction changes only a Go benchmark fixture and its
performance contract.

The [final-head stable E2E
run](https://github.com/rcourtman/Pulse/actions/runs/40163545118) also
passed all eight shards, agent registration and organization
provisioning: 186 passed, 183 skipped, zero failures.

All nine required source checks passed. The [final-head build and test
run](https://github.com/rcourtman/Pulse/actions/runs/40163545117)
passed, including benchmark comparison and strict chart qualification.
The chart result on valid hosted capacity was p50 38.31 ms, p95 51.01 ms
and p99 52.28 ms against the unchanged 90 ms p95 limit. The retained
artifact binds the measured binary to the tested synthetic merge commit.
The preceding runtime qualification also passed at p95 86.55 ms on its
runner. The benchmark comparison found no regression above the existing
10% and p<0.05 threshold. The corrected lookup fixture supplied all ten
observations without parser warnings.

After main advanced with scoped authentication and tenant runtime
changes, a native compatibility proof composed this exact head with
c809d3c93b. API, configuration API and
monitoring regressions passed. All twelve organization browser cases
passed again with retries disabled. A fresh embedded runtime passed the
desktop and phone seven-day chart matrix with both endpoints accessible.
The reviewed combined tree is 2e9a154b1c.
2026-10-25 05:27:11 +00:00
rcourtman 64c0a3f9df Scope browser OS acquisition to the runner's signed Ubuntu sources
An unrelated Microsoft repository returned 403 during fresh-index admission and stopped a browser shard before any test could run. Load the hosted runner's existing Ubuntu Deb822 definition for browser packages, preserving its mirrors and signature policy. Fail when that definition is missing, unreadable or empty and keep strict index and archive hash checks.

Exercise the real apt parser, exclusion of unrelated feeds, missing definitions and incomplete index failures in private acquisition directories. Register the package helper and policy with their exact verification routes, and update the fixture helper's governance assertion to its scoped proof contract.
2026-10-25 04:00:03 +00:00
pulse-triage[bot] 7adfe647fe Keep local safety checks effective on large staged changes
Admit the complete index and patch reads, and drain pattern matches before interpreting their result under pipefail. Preserve sensitive-file and fallback-secret blocks and required docs, governance and lint admission; distinguish an empty filtered patch from a failed read. Exercise the actual hook with bounded synthetic large inputs and retained failure exits.

Contract-Neutral: Local hook input handling only; existing secret patterns, required checks and production contracts are unchanged.
Change-source: pulse-maintainer
2026-10-25 03:33:27 +00:00
pulse-triage[bot] e1e2860d35 Fix accessible controls, resource provenance and deep drawer scrolling (#3222)
Scrolling through a long platform drawer could unmount its owning row
and close the detail being read. REST resource projection also dropped
source provenance, hiding vCenter context and host placement from
owning-snapshot consumers. Diagnostic commands lacked keyboard
scrolling, and dark-theme text and several Patrol control names failed
accessibility checks.

Measure summary rows and inline details together in the shared bounded
window, preserve canonical resource sources, make diagnostic command
blocks focusable, and repair shared contrast and visible control naming.
Browser fixtures await mounted authentication and keep synthetic
provider inventory authoritative. Journey assertions follow current
read-only capabilities, technical disclosures and composed resource
queries. Long settings audits traverse the actual scroll extent; curated
estate checks use native inventory disclosures and search; disk proofs
follow canonical serial-bound shared history; the published
completed-restore-point calendar checks remain intact, including day
selection and filter reset. Update API proofs no longer mount an
unrelated dashboard before each request.

Fresh password login now waits for mounted bootstrap too. The
delayed-bootstrap regression owns and revokes its own token, so it runs
with cookie-only and primary-token fixtures without replacing the
fixture credential. Update API cases share an admitted cookie fixture.
Growth assertions use the current fixed-window header, LXC refresh
assertions use the fixture's canonical identity, and the gated-panel
observer follows actual gate readiness while still detecting visible
unlocked controls. The Docker browser stack explicitly opts into a
bounded development update budget for its shared bridge IP. Production
and login limits remain unchanged.

The remaining recovered failures exposed three test synchronization
defects. Alerts now leaves the whole editor before judging a staged
change and exercises its sibling-focus contract. Protected panel
assertions wait for mounted bootstrap before their existing readiness
timeout. The delayed-token regression uses its own page, avoiding
interception of reads from a departing setup document. CI retains
failed-attempt HTML diagnostics after a successful retry and small JUnit
results for each completed tier, including stable receipts before
probation starts.

Validation includes negative controls for the original drawer,
provenance and password-bootstrap defects, 335 focused frontend tests,
23 authentication-fixture tests, type-checking and a production build.
The cookie-only follow-up matrix passed 39 cases across Chromium, mobile
Chrome and mobile Safari with 18 existing skips. Twelve additional
onboarding cases passed with no retries, and the token-bootstrap matrix
passed 12 cases with cookies alone and 12 with a primary token. Native
Chromium and WebKit checks exercise the gated-panel detector's positive
and negative controls. The earlier remaining-failures matrix passed 31
cases with 10 existing skips, and both disk-history cases passed on
desktop.

Current-build browser verification covers onboarding, accessibility,
VMware context and exclusion boundaries, demo commercial isolation,
persisted Alerts settings, Patrol, availability and background refresh.
Pixel and interaction review covers infrastructure, Agent Doctor,
Patrol, Docker, Kubernetes and vSphere at desktop, tablet and phone
widths in both themes where applicable. Existing timeouts, skips,
mounted-row limits and the 90 ms chart budget remain in place.

The final recovered-failure matrix passed 27 cases with 14 existing
mobile skips using cookies alone, followed by 12 passes with a primary
token, all without retries. The forced desktop table control reproduces
the old focus failure and passes after leaving the editor. The preceding
qualified tree completed all required source checks and the full
stable/probation matrix. Its executed strict chart proof measured p95
61.1 ms against 90 ms with valid capacity. The updated head is being
qualified again before landing.

Governed work: L12 journey verification and the shared L10 windowing
proof. This source change does not publish a release.
2026-10-25 02:30:21 +00:00