KubernetesNameText renders a generated name as a truncating head and a
kept tail, and both are flex items. Flex items are blockified, so a
browser copy put a line break between them: copying a pod name gave
"cron-nightly-backfill\n-28918234", and pasting that into kubectl logs
broke. The same happened for the Pods table Node column and controller
names.
A copy whose selection sits inside one name now writes the name without
the break. Wider selections, such as a whole row, still copy as the
browser builds them.
## Outcome
This batch makes guest identity persistence safer, keeps broadcast
resource rows and their History targets in one captured generation, and
makes completed-backup evidence accessible by keyboard and touch.
Existing help now explains container CPU scales and passive comparisons.
Native macOS guidance checks receive real GNU timeout without replacing
unrelated system utilities.
The work follows retained identity-write/shutdown failures, fleet CPU
and History consistency evidence, inaccessible backup disclosures and
confusion about container CPU readings. It improves those existing paths
without claiming field recovery or complete performance relief.
## Included reviewed candidates
The complete proposed range is
`800329cbd83c48fdb7402a18633189f2c8a2d6ff..9b057cb141221526a96fac05bdbdf8ed6e8625fc`:
- Guest metadata ordering/coalescing and safe retained shutdown:
`244d322dce` and `5e51069048`, integrated at `d7a305922a`.
- Native guidance prerequisites: `13f6d10798` and `443faa53b6`,
integrated at `f7fca0e164`.
- Accessible existing Workloads backup details: `02e6a90374`, integrated
at `8661c1fc65`.
- Paired complete resource/History capture and faithful full-content
controls: `54de7bdca7`, `32f09dc13d`, `8b12e0ee1b`, `d206b03990` and
`9cc8523881`, integrated at `2787b4eabd`.
- Container CPU documentation: `0c283d2dd5`, integrated at `15e8c5ccf6`.
- Router-owned limiter joins and sealed late worker admission:
`5b560521e2`.
Reviewed identities and authors are unchanged. Current upstream Docker
link editing and platform layout repairs are incorporated by an additive
full-SHA merge; earlier upstream governance and Kubernetes layout
history are retained. The later upstream Docker image badge sizing
repair at `800329cbd83c48fdb7402a18633189f2c8a2d6ff` is also retained
after one successful bounded refresh and additive merge.
## Behaviour and safeguards
Identity polls merge only monitor-owned fields, preserve operator
links/tags/notes and OCI classification, and do not spin-retry
filesystem failures. Incomplete tenant shutdown retains ownership and
prevents directory removal. Router shutdown joins its own limiters
without resetting budgets or stopping another Router.
Broadcast resources and target mappings are detached together. Health
comparison controls use one evaluation instant while production still
samples real UTC at the existing boundary. Full-content, overlay/clear,
identity and observation-time controls remain.
Backup disclosures preserve hover and add keyboard/touch access to the
same read-only evidence. CPU guidance distinguishes host-capacity
normalisation, VM CPU counts, version-qualified rounding, missing
readings and actual alert delivery; it asks for ordinary observations,
not forced workload or threshold changes.
## Validation and remaining limits
- Provenance, retained ancestry, clean additive merge and whitespace
checks pass.
- Every unpublished non-merge commit passes the canonical
completion/history guard. Final-range browser receipt coverage, public
registry audit and contract audit pass.
- Accepted candidate evidence includes focused writer/API races, startup
observations, vet and actual builds; 363 connected backup frontend tests
with four desktop/touch browser cases; CPU help's 132 connected frontend
tests, lint/types/build/budgets, focused Go checks and four Docs browser
cases. Browser receipts cover unchanged final backup bytes and are not
rerun merely because the batch contains several candidates.
- Gate frontend proof at `9daeed13`: 246 tests in four connected files,
type-check, all lint checks, actual embed build and bundle budgets pass;
complete output hash matches and guest stop completes.
- Exact refreshed head `9b057cb1` passes 49 Docker native-table and
platform-layout guardrail tests (`source-l8diazgn`); complete output and
guest stop are verified. This covers the later width-only upstream
change without repeating the earlier full frontend checks.
- Gate backend attempt `source-pz6qwk2t` fails in guest readiness after
capacity waiting, client exit 2, with no command verdict and confirmed
guest stop. It is not a test pass and is not replayed. All backend Go
source, manifests and native workflow bytes are unchanged from reviewed
`5b560521` and its focused races/vet/real-build evidence; that evidence
remains usable without inventing an aggregate pass.
- The retained broad API ten-minute timeout, earlier drain/startup
failures, adverse allocation/frame costs and failed stable RSS retest
are not erased by these focused results. Required exact-head CI remains
authoritative for landing.
- This is not native guest thaw/recovery, PBS badge agreement, CPU/RSS
relief, notification delivery or release inclusion. Independent thaw,
fresh writes on every covered filesystem, liveness and only-prior-active
restoration remain necessary before resuming uncertain monitoring.
Related to #2199
Related to #1723
Related to #2439
Related to #2447
[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
## Problem
Two platform tables cut a status badge at the cell edge at tablet
widths.
- **Docker containers, Updates column.** Columns are sized per layout
mode with weights that renormalize over whichever optional columns show
(State, Restarts, Host, Engine). Between a 34rem container and the md
breakpoint, where the phone wrap rule stops, Updates got 54–76px. So
"Update" (74px) and "Current" (69px) were cut from 573 to 800px, and
ungrouped up to 1100px.
- **Kubernetes Nodes, Status column.** The tablet band split equally
(51px of room at 573px), and md gave Status 8% (53px at 768px). So
"Degraded" (64px) was cut.
## Change
**Docker containers** (`dockerContainerTableModel.ts`): Updates takes
room only from the CPU bar, which never shows a sublabel, and the
collapsed actions menu. Every other column keeps its exact width in
every layout mode and optional-column set, so the memory bar keeps its
used/total sublabel.
- The 74px states (Update, Current, Pinned, Failed) fit at each layout's
narrowest table width in every column set.
- The 100px states (Check failed, Updating..., Completed) fit in most
layouts, but can still clip at a layout's narrow end when several
optional columns show.
- Wide rows also gain the 108px their expanded lifecycle controls need.
- A new model test checks every layout and column set.
**Kubernetes Nodes** (`KubernetesNodesTable.tsx`):
- The tablet band now sizes each column for its header, and Status for
Degraded, at a 34rem table.
- md moves 2.5 points from CPU (whose bar has no sublabel) to Status.
The visible total stays the same, so Node, Cluster, Roles, Memory and
Capacity keep their widths at every md width.
- Degraded, NotReady and Unknown fit from 573px. Unschedulable (89px)
fits from about 900px; main cut it at every width.
The guardrail test pins the new widths. Contract notes are in
`unified-resources.md` and `frontend-primitives.md`.
## Verification
Mock-mode private stack on main 800329cbd8, before against after, at
18–20 widths from 390 to 1600px:
| Table | Badge clipped (main) | Badge clipped (after) | Total clipped |
Columns worse | Sublabels lost |
|---|---|---|---|---|---|
| Docker containers, grouped | 573–900px | none | 89 → 53 | none | none
|
| Docker containers, ungrouped | 573–1100px | none | 195 → 132 | none |
none |
| Kubernetes Nodes | 573–800px | none | 85 → 78 | none | none |
- **Interactions:** sorting by Updates and by Status, and row expand and
collapse, work at 600, 768 and 1280px with no console errors.
- **Tests:** `src/features`, `src/hooks`, `src/components/shared` and
`src/components/Workloads` pass (489 files). The new and updated checks
fail against main's source.
**Known residuals:**
- "Review action" (112px, shown only while an update awaits review) can
still clip at tablet widths when the table is crowded.
- The Docker "RESTARTS" header was already clipped in the 480–768px
range on main and is unchanged.
The browser receipt is
`frontend-modern/browser-verification/6683727b493b9b45.json`.
The Docker container Updates column and the Kubernetes Nodes Status
column hold badges that cannot truncate, and both were cut at the
cell edge at tablet widths.
Docker containers size columns by layout mode with weights that
renormalize over whichever optional columns show (State, Restarts,
Host, Engine). Updates got 54-76px between a 34rem container and the
md breakpoint, where the phone wrap rule no longer applies, so Update
(74px) and Current (69px) were cut from 573 to 800px. The column now
takes its room only from the CPU bar, which never shows a sublabel,
and the collapsed actions menu, so every other column keeps its width
in every layout and column set and the memory bar keeps its used/total
sublabel. The 74px states fit in every layout and column set at the
layout's narrowest table. The 100px states (Check failed, Updating...,
Completed) fit in most layouts but can still clip at a layout's
narrow end when several optional columns show. Wide rows also gain the room their expanded
lifecycle controls need. A model test checks every layout and column
set.
Kubernetes Nodes Status shared the tablet band equally (51px of room
at 573px) and had 8 percent at md (53px at 768px), so Degraded (64px)
was cut. The band now sizes each column for its header and Degraded
at a 34rem table, and md moves 2.5 points from CPU to Status, keeping
the visible total, so Node, Cluster, Roles, Memory and Capacity keep
their widths everywhere. Degraded, NotReady and Unknown fit from
544px; Unschedulable (89px) fits from about 900px.
Incorporate the scoped-read upstream identity through the completed bounded refresh; preserve all reviewed commit identities and existing source evidence.
Change-source: pulse-maintainer
## Problem
On `/docker/images` the Update check badge was cut off at tablet widths.
Its longest labels ("Update available", "Managed by Pulse") need about
122px including cell padding.
- In the tablet band (a 34rem container below a 768px viewport) every
non-name column took an equal 17.5% share. That left Update check 100px
at 600px and 110px at 700px.
- The 16% md width left it 111px at 768px.
The badge was cut at the cell edge with a stray ellipsis dot, and the
"UPDATE CHECK" header clipped at 600px.
## Change
`DockerImagesTable.tsx` changes only column widths. The badge label is
unchanged.
| Column | Band (`bandWidth`) | md before → after |
|---|---|---|
| Image | 30 | 30 → 30 |
| Host | 17.5 | 18 → 17 |
| Used by | 17.5 | 24 → 23 |
| Size | 12 | 12 → 11 |
| Update check | 23 | 16 → 19 |
Host and Used by keep the band share they already had. Size gives up the
room in the band, because its widest values ("1023 MB", "9.99 GB",
49.6px) still fit its narrowest cell (53px). The md change takes one
point each from Host, Used by and Size.
`platformOverviewLayout.guardrails.test.ts` pins the new md and band
widths. Contract notes are in `unified-resources.md` (Docker images) and
`frontend-primitives.md` (sizing a badge column for its narrowest table
in each range).
## Verification
I ran a mock-mode private stack on main 8e68bab55a, which already
includes #2514's Used by span change.
- **Clip sweep:** 15 widths from 390 to 1440px, checking `scrollWidth >
clientWidth + 1` on every cell and its overflow-hidden descendants.
- The update badge clipped at 600, 640, 700 and 768px on main, and
nowhere after this change.
- Image, Host, Used by and Size have the same clip counts at every
width. Total clipped elements went from 65 to 61.
- **Label probe:** all six update labels cloned into the narrowest
Update check cell. On main, "Managed by Pulse" overflows from 600 to
800px and "Update available" at 600, 640, 700 and 768px. After this
change, every label fits at every width.
- **Headers:** no header clips at any width, including with a sort
indicator.
- **Interactions:** row expand and collapse works at 390, 600, 768 and
1440px. No console errors.
- **Tests:** `src/features/platformPage` and `src/features/docker` pass
(37 files, 653 tests). The updated guardrail test fails against the old
source.
The browser receipt is
`frontend-modern/browser-verification/7db5e194a586019d.json`.
The Images table's Update check badge needs about 122px with its cell
padding for its longest labels ("Update available", "Managed by
Pulse"). Between the phone projection and the md breakpoint every
non-name column took an equal 17.5 percent share, which left the
column 100px at a 600px viewport, and the 16 percent md width left it
111px at 768px. The badge was cut at the cell edge with a stray
ellipsis dot, and the "UPDATE CHECK" header clipped at 600px.
The table now declares tablet-band widths through the sortable
header's bandWidth (Update check 23, Size 12; Host and Used by keep
their 17.5) and moves 3 points of md width to Update check, one each
from Host, Used by and Size. The longest size values ("1023 MB",
"9.99 GB") still fit both narrower Size columns.
A clip sweep on a mock stack from 390 to 1440px (15 widths) found the
update badge clipped at 600, 640, 700 and 768px before and nowhere
after. A probe of all six labels against the narrowest Update check
cell found none clipping at any width, and no other column clipped
more often than before. The base already carries the Used by
block-truncate span from #2514, so Used by was measured as it now
renders.
Follow-up to rcourtman/Pulse#2477.
**Docker containers get the bulk editor**
The strongest demand for saved links (#1556, #624) came from Docker
users, but the editor only reached Proxmox and vSphere guests. The
Docker containers table header now has the same **Edit links** panel,
worded for containers.
- Rows are keyed through `toDiscoveryConfig`, the container drawer's own
metadata target, so bulk and drawer saves read and write the same
`app-container:<host>:name:<name>` record. This includes Docker running
inside Proxmox LXCs.
- The editor now takes a source. Workload tables pass live guests, so
the row model still loads only with the panel. Other tables pass
ready-made rows.
- The Docker table lazy-loads the trigger. Without that, Rollup merged
it into the chunk the Docker and workloads pages share, renamed that
chunk, and broke the `DrawerDiskListCard` bundle budget.
**Read-only tokens no longer see edits that would fail**
Metadata writes require `monitoring:write` for API-token sessions (the
backend's `EnsureScope`). Browser sessions always pass, because metadata
routes have no role check. A kiosk-style `monitoring:read` token saw
edit controls that every save refused with 403. The session store now
mirrors the gate from the security status `tokenScopes`
(`sessionCanWriteMonitoringMetadata()`):
- the bulk editor's **Edit links** button is hidden for such sessions;
- the shared web-interface field shows the saved URL with open and copy,
plus a one-line explanation, but no input, Save, Remove, or "Use this"
suggestion.
**Fewer refetches**
Saves now dispatch their metadata-changed events together after the
writes. `useUnifiedResources` coalesces onto one in-flight refetch, so a
bulk save costs two resource refetches whether it changes 2 links or 4.
Before this, it cost one per link.
**Verification**
- Private mock stack, Docker page and Proxmox page, at 1280 and 375px.
- Real token sessions with the admin bypass off: a `monitoring:read`
token sees no edit affordances, and a `monitoring:read+write` token
saves a container link.
- Receipt: `frontend-modern/browser-verification/e8946b639f30703c.json`.
- Production build: `WorkloadsSurface` 69.08 kB, `Docker` 28.56 kB,
`DrawerDiskListCard` unchanged; no violations.
- Full frontend lint, plus 841 test files (15,618 tests) across
features, hooks, components and stores.
Follow-up to #2509, which fixed the Kubernetes tables. The Docker,
Proxmox and vSphere tables still put summary values in a capped
`inline-block` span (`max-w-48 truncate`, `max-w-[18rem] truncate`, or
`truncate inline-block max-w-32`). These tables are `table-fixed` and
their `td` already truncates, so the cap ignored the column width:
- **Spill with no ellipsis.** Where the cap was wider than the cell, a
long value ran past the cell edge and was cut mid-glyph. At 700 wide: a
swarm service image by 225px, secret labels by 184px, image "Used by" by
168px, Mail Gateway domains by 71px. At 1440: volume mountpoints by
51px.
- **Off the row line.** An `inline-block` with hidden overflow aligns
its bottom edge to the baseline, so every one of these values sat
2–2.5px above the rest of the row.
A `block truncate` span fills the cell, ends in an ellipsis inside it,
and sits on the row line.
**Changed cells (19 spans in 11 files)**
- Docker: Configs (Created, Labels), Secrets (Created, Labels), Tasks
(Current), Volumes (Created, Mountpoint), Images (Used by), Networks
(Subnets), Services (Stack, Image, Update)
- Proxmox: backup coverage Node, restore-evidence Location and Details,
recoverable Location and Details, Mail Gateway drawer Top domains
- vSphere: Hosts vCenter
The Docker service **Update** cell still wraps on phones. From md it now
truncates inside its column instead of at a fixed 10rem cap.
The guardrail from #2509 (`keeps platform summary cells truncating
inside their own column`) now covers every table source that carried the
pattern. `ProxmoxCoverageTable.test.tsx` checks that a long node name
renders as the cell's only child, in a `block truncate` span, inside a
`table-fixed` table. Both tests fail against main's sources.
**Verification** (private mock stack, Playwright)
- **Live DOM, before switching anything.** At 700 and 1440, every one of
the 1,000 measured spans is the only child of its cell. Every table
computes `table-layout: fixed`, including the Mail Gateway drawer's Top
domains table.
- **After.** No span runs past its cell, all 134 truncated values end in
an ellipsis inside their own column, and row text sits on one line (0px
offset).
- **Clip sweep.** All eight affected routes (/docker/images,
/docker/networks, /docker/storage, /docker/swarm, /proxmox/backups/date,
/proxmox/backups/coverage, /proxmox/mail, /vmware/overview), 8 widths
from 390 to 1440. Clipped cells go from 931 to 928 out of 19,209
measured, and no column is worse at any width. The count barely moves
because a spilled value was already clipped by its cell. What changes is
a hard cut becoming an ellipsis.
- **Mock gap.** The mock Mail Gateway reports no domain stats, so the
drawer table was mounted by adding eight domains to the real
`/api/pmg/instances` response through a route intercept.
- **Tests.** Docker, Proxmox, vSphere, platformPage and app-level
suites: 79 files, 1,549 tests pass.
- **Receipt.** The browser receipt is included.
The bulk web-link editor only reached Proxmox and vSphere guests, but the
strongest demand for saved links (#1556, #624) came from Docker users. The
Docker containers table now offers the same Edit links panel, keyed through
the container drawer's own metadata target so bulk and drawer saves share
one record. The trigger is lazy-loaded so it does not merge into the chunk
the Docker and workloads pages already share.
Metadata writes require monitoring:write for API-token sessions, so a
kiosk-style read-only token saw edit controls that every save refused. The
session store now mirrors that gate from the security status token scopes:
the bulk editor is hidden and the shared web-interface field shows the saved
URL without input, Save, Remove, or suggestion adoption. Browser sessions
are unaffected because the backend does not check roles on metadata writes.
Saves now dispatch their metadata-changed events together after the writes,
so a bulk save costs two resource refetches instead of one per link.
Follow-up to #2509, which fixed the Kubernetes tables. Docker, Proxmox
and vSphere summary cells still wrapped long values in a capped
inline-block span (max-w-48 truncate, max-w-[18rem] truncate, or
truncate inline-block). The cap ignored the column width of these
fixed-layout tables, so a long value ran past a narrower cell with no
ellipsis (a swarm service image by 225px at 700 wide, volume mountpoints
by 51px at 1440), and the inline-block sat about 2px above the row's
text line.
A block truncate span fills the cell, ends in an ellipsis inside it and
sits on the row line. The Docker service Update cell keeps its phone
wrap and truncates inside its column from md instead of at a 10rem cap.
The guardrail from #2509 now covers every platform table source that
carried the pattern, and the coverage table test pins the Node cell.
## Problem
The registry audit requires `require_explicit_path_policy_coverage:
true` on every subsystem. Under that setting,
`build_verification_requirements` never uses a rule's default
verification policy: a runtime file that no path policy matches becomes
a `missing-path-policy-coverage` gap. As a result, nothing ever consults
the rule-level `verification.test_prefixes` and
`verification.exact_files` lists. Their only readers were the audit's
format and path-existence checks, plus one test that pinned monitoring's
list as data.
Even so, 13 of the 16 rules carried them: 93 files and one prefix.
Authors kept adding proofs there as if they counted. relay-runtime alone
listed 20, and performance-and-scalability listed 30. This is the same
misleading-config problem as `allow_same_subsystem_tests`, which #2505
retired, one level up.
## What happens to the 94 entries
- 92 of the 93 files are already proof on a path policy: 77 on their own
subsystem's policies and 15 on another subsystem's.
- api-contracts' default prefix `frontend-modern/src/api/__tests__/` is
already on three of its own policies.
- The one orphan is `internal/api/router_bench_test.go`. It benchmarks
the api-contracts router, not any performance-and-scalability runtime
file, so no policy should take it. It stays an owned file of
performance-and-scalability.
Nothing was folded into a policy, because folding would loosen the
guard.
## Change
- `registry.json`: empties the 13 rules' default `test_prefixes` and
`exact_files`. The keys stay, since the schema requires them.
- `registry_audit.py`: requires both lists to be empty, and points
authors at the path policy whose runtime files the proof covers. This
replaces the per-entry format and path checks, which only ever validated
lists nothing reads.
- `CANONICAL_DEVELOPMENT_PROTOCOL.md`: states the empty-default rule. It
also drops the promise that same-subsystem tests count "when the
registry explicitly allows them", which the audit no longer permits.
- Audit test fixtures now model valid registries, with empty defaults
throughout. A new test covers the rejection.
**No verdict changes.** I compared `build_verification_requirements`
under the old and new registry. It returns identical requirements for
all 2,746 owned runtime paths, and for an uncovered path in every
subsystem.
## Verification
- `go test ./internal/repoctl`: passes.
- The Python suites (registry_audit, canonical_completion_guard,
status_audit, subsystem_lookup, staged_commit_shape_guard,
dev_runtime_governance, contract_audit, control_plane_audit): 427 tests
pass.
- New `test_audit_registry_payload_rejects_default_verification_proofs`
fails against the previous audit.
- `registry_audit.py --check` on the live registry: no errors.
- Open PR #2508 adds a path policy and owned files only, with no default
proofs, so it is unaffected.
Every subsystem must declare require_explicit_path_policy_coverage, so
build_verification_requirements never falls back to a rule's default
verification policy; an unmatched runtime file becomes a path-policy gap
instead. The default test_prefixes and exact_files were therefore never
consulted, yet 13 of 16 rules carried them (93 files and one prefix),
and authors kept adding proofs there as if they counted.
92 of the 93 files were already proof on some path policy, and
api-contracts' default prefix is on three of its own policies. The one
orphan, internal/api/router_bench_test.go, benchmarks the api-contracts
router rather than any performance-and-scalability runtime, so no policy
should take it; it stays an owned file only.
The registry drops the lists, registry_audit requires them empty and
points authors at the path policy instead, and the canonical protocol
says so. The protocol also stops promising same-subsystem tests "when
the registry explicitly allows them", which the audit no longer permits.
No verdict changes: build_verification_requirements returns identical
requirements for all 2746 owned runtime paths, and for an uncovered
path, under the old and new registry.
Capture all endpoint limiters under their Router owner and seal late worker
admission. Concurrent shutdown joins each cleanup worker without resetting
request budgets or stopping another Router. Integration fixtures use the real
shutdown lifecycle before monitor teardown.
Contract-Neutral: Router worker ownership and concurrent shutdown only; HTTP payloads, limits and windows, auth, tenant selection, revocation and persistence contracts are unchanged.
Change-source: pulse-maintainer
Accept exact PI commit 0c283d2dd5 with retained focused source and Docs browser proof. Preserve conditional runtime-host examples and passive comparison safeguards; this is documentation maintenance, not native collection or alert-delivery acceptance.
Change-source: pulse-maintainer
Follow-up to #2506. The Kubernetes Configuration and Deployments tables
still clipped names and values between phone and desktop widths.
- **Tablet band widths.** Between the phone projection and the md column
widths (a 34rem container below a 768px viewport) these tables split
their width evenly, which cut names to a few letters. Headers can now
declare a band percent through `bandWidth` /
`platformTableBandWidthStyle`, and both tables give names the most room.
- **Scope shows the namespace.** With one cluster in view, every scope
cell repeated the cluster name ("Production EU/ser…"). The cell now
shows the namespace (`Cluster` for cluster-scoped objects) and keeps the
full scope on the title and for screen readers. Several clusters keep
the combined label.
- **Deployments.** Desired appears only on wide tables, because Ready
already reads `2/2`. Ready keeps its denominator until Desired is shown.
On a phone, Age takes Ready's spare width so `18h ago` fits.
- **Summary cells.** Values sat in a capped `inline-block` span that
ignored the column width. Long values spilled past narrow cells with no
ellipsis and sat about 4px above the row. A `block truncate` span fills
the cell, ends in an ellipsis inside it, and lines up with the rest of
the row.
Verification:
- Clip sweep of every Kubernetes tab at 600–1440px, compared with main:
clipped cells drop from 566 to 356, and no column is worse at any width.
- Deployment, Resource and Namespace clips on Workloads and
Configuration drop from 25 to 0, and Scope clips from 136 to 7.
- Row text alignment is 0px spread on every tab.
- The browser receipt is included.
The five predeclared diagnostic cases retain a real 1m versus 2m health-age counterexample between separate wall-clock evaluations. Give the independent content oracle and production projection the same private health clock without removing any JSON field; pin minute-boundary age advancement and original LastSeen. Production samples real UTC at the unchanged post-read evaluation point.
Contract-Neutral: Internal health-clock test seam preserves the real UTC evaluation point, public resource/history fields, source precedence, agent identity/lifecycle, tenant/revocation and safety contracts; no wire or permission delta.
Change-source: pulse-maintainer
Document host-capacity normalisation, version-qualified rounding and the difference between collected readings and delivered alerts. Keep comparisons on ordinary workload observations rather than forced load, threshold changes or diagnostic reruns.
Contract-Neutral: Existing container CPU semantics and safety guidance only; no runtime, API, threshold, permission or lifecycle contract changes.
Change-source: pulse-maintainer
Preserve the exact Web candidate and its own-parent browser receipt. Retained connected source checks and desktop/touch evidence cover the existing read-only disclosures without changing collection or backup operations.
Change-source: pulse-maintainer
Between the phone projection and the md column widths (a 34rem container
below a 768px viewport) the Configuration and Deployments tables split
their width evenly, so names were cut to a few letters beside short
counts. Headers can now declare a percent width for that band through
bandWidth / platformTableBandWidthStyle, and both tables size names
first.
With one cluster in view every scope cell repeated the cluster name and
crowded out the namespace that tells rows apart, so scope cells show the
namespace alone and keep the full cluster/namespace scope on the title
and for assistive technology. Several clusters keep the combined label.
Deployments Desired returns only with wide tables, since Ready already
reads ready over desired, and Ready keeps its denominator until Desired
is visible. On a phone Age takes Ready's spare width so "18h ago" fits.
Summary cells used a capped inline-block span that ignored the column
width: long values spilled past narrow cells with no ellipsis and sat
above the row's text line. A block span fills the cell, ellipsizes there
and aligns with its neighbours.
The new complete-content oracle exposed a typed-view discrepancy. Keep that failed result and report the first differing JSON field, rather than accept an undifferentiated mismatch or normalise away evidence. Only the synthetic fixture failure message changes; equality assertions and production source are unchanged.
Change-source: pulse-maintainer
Use native read-only disclosure buttons for both backup entry points, with the shared Dialog preserving named completion evidence, focus and guest row action ownership. Keep existing freshness and uncertainty semantics, collection and backup operations unchanged. Include connected regression tests, the subsystem contract and inspected desktop/phone browser verification.
Change-source: pulse-maintainer
The full current-state regression now requires a critical alert to reach the same freshly projected row. Continuity controls compare a healthy VM, critical transition and clear instead of using an already-offline host as a vacuous health control.
Change-source: pulse-maintainer
The independent full-state oracle retains the parent unified view watermark. The paired benchmark preprocesses active health alerts once per pass, like the exact parent, rather than adding per-row work to the baseline. Production projection and source fields are unchanged.
Change-source: pulse-maintainer
Resolve canonical source mappings once per complete projection while preserving detached resource content and target selection after host coalescing. Bind resources and targets to the same locked generation, including absence and continuity overlays, and avoid another owned outer-slice copy. No timestamp cache or native CPU/RSS claim. Retain cold, clean and dirty full-content controls and paired complete-projection measurements.
Contract-Neutral: Internal bulk-read and copy-ownership repair preserves existing public resource/history fields, source precedence, agent identity/lifecycle, tenant/revocation and safety contracts; no wire or permission delta.
Change-source: pulse-maintainer
Kubernetes names clipped badly between about 600 and 900px wide. At
700px node names read "Pr…" and deployment names two letters.
**Why:** between a 544px table container and a 768px viewport, platform
tables show their phone-hidden columns again, but `md:w-[…]` widths are
viewport media queries and don't apply yet. So every visible column took
an equal share. A seven-column Kubernetes table left its name 83px, with
the chevron and status dot inside it. From 768px the Kubernetes name
widths (14–19%) still cut common node, service and event names.
**Fix:**
- The shared table shell keeps the phone 30% name anchor in that band.
Tables sized by a weighted colgroup are unaffected.
- Kubernetes name columns get room for typical names at 768px. The Nodes
columns are rebalanced so Capacity fits at 1100px and wider.
- Generated names (pods, a pod's node, controllers) truncate their head
and keep the trailing segment that tells siblings apart:
`checkout-a…-c7z2p`, `prod…-02`. The tail never outgrows its cell.
Deployment names keep plain end truncation.
**Measured** with a clip sweep over every Kubernetes tab at 600–1440px:
- Identity-column clips fall from 284 to 186. Most of the remainder are
pod heads truncated by design.
- The Nodes table has no name clipping at any width.
- In the band, TrueNAS Storage and a vSphere resource table go from 14
name clips to 0, with no new clips on other platforms.
## Problem
`check_staged_contracts` (and `canonical_commit_shape_errors`) passed
the impacted entry from `infer_impacted_subsystems` as the `rule`
argument of `staged_verification_files_for_requirement`. The
`allow_same_subsystem_tests` branch matches through
`subsystem_matches_path(rule, path)`, which reads `owned_prefixes` and
`owned_files`, and the entry carried neither. So since the v6 import
(778a2577b6) a same-subsystem test never satisfied a requirement.
Meanwhile `subsystem_lookup.py`, which passes the real registry rule,
and the guard's own BLOCKED text ("same-subsystem test/spec files are
also accepted") both said it would.
## Decision: keep the strictness, don't honour the flag
Honouring the 12 registry flags would have loosened the guard far beyond
what the flags appear to have been meant for:
- All 16 rules set `require_explicit_path_policy_coverage`
(`registry_audit` makes it mandatory). The default policy is never
consulted, so the 5 rule-level flags (alerts, cloud-paid, monitoring,
relay-runtime, unified-resources) are dead either way.
- On the 7 path policies, the flag accepts any test the subsystem owns,
not just tests near the policy's code. Proof files each policy would
newly accept on `main`:
| policy | accepted today | newly accepted |
|---|---|---|
| ai-runtime/canonical-mutation-registry | 4 | 455 (any `internal/ai`,
AI Chat or `internal/agentcapabilities` test) |
| ai-runtime/patrol-qualification | 27 | 433 |
| unified-resources/product-trust-actions-frontend | 16 | 128 (Go tests
in `internal/unifiedresources`) |
| agent-lifecycle/action-runner-runtime | 4 | 119 (mostly
`internal/hostagent`) |
| agent-lifecycle/collector-lifecycle-installer-transport | 7 | 118 |
| agent-lifecycle/agent-privilege-helper-runtime | 8 | 115 |
| security-privacy/audit-log-runtime-store | 10 | 7 (`pkg/audit` tests)
|
Six of the seven already list their own directory in `test_prefixes`, so
the flag only added reach across the subsystem. That reach would also
grow whenever the subsystem gained ownership, without anyone editing the
policy.
## Change
- `registry.json`: sets the 12 flags to `false`. This is what the guards
have actually enforced.
- `registry_audit.py`: rejects `true` at both the rule level and the
path-policy level, and tells the author to list proofs in
`test_prefixes` or `exact_files`.
- `canonical_completion_guard.py`: the impacted entry now carries the
rule's `owned_prefixes` and `owned_files`. The completion guard, the
commit-shape guard, `subsystem_lookup.py` and the BLOCKED message now
read the flag the same way.
**Enforcement does not loosen.** No live requirement accepts a proof it
rejected before. The visible change is in `subsystem_lookup.py`: it
stops reporting matches the guard refused. For example, a new
`internal/hostagent/*_test.go` used to claim three agent-lifecycle
policies and now claims none.
`security-privacy/audit-log-runtime-store` is the one policy where the
flag was the only directory-level proof route. It keeps its 12 exact
files. If `pkg/audit` tests should count, the explicit form is
`"test_prefixes": ["pkg/audit/"]`.
## Verification
- `python3 -m unittest canonical_completion_guard_test
registry_audit_test staged_commit_shape_guard_test subsystem_lookup_test
status_audit_test dev_runtime_governance_test`: 400 tests pass.
- New
`test_check_staged_contracts_reads_same_subsystem_tests_from_ownership`
runs `check_staged_contracts` end to end with a synthetic flagged
policy. Against the unfixed guard it fails (`1 != 0`).
- New
`test_audit_registry_payload_rejects_same_subsystem_tests_wildcard`
covers both rejection sites.
- `registry_audit.py --check` on the live registry: no errors.
Between a 544px table container and a 768px viewport, platform tables
show their phone-hidden columns again, but md:w widths are viewport media
queries and do not apply yet, so every visible column took an equal share.
A seven-column Kubernetes table left its name 83px, with the chevron and
status dot inside it, so node names read "Pr..." and deployment names two
letters. From 768px the Kubernetes name widths (14 to 19 percent) still
cut common node, service and event names.
The shared table shell now keeps the phone 30 percent name anchor in that
band. Tables sized by a weighted colgroup are unaffected. Kubernetes name
columns get room for typical names at 768px, with the Nodes columns
rebalanced so Capacity fits at 1100px and wider. Generated names (pods,
the node a pod runs on, controllers) truncate their head and keep the
trailing segment that tells siblings apart, and that tail never outgrows
its cell.
staged_verification_files_for_requirement() matches
allow_same_subsystem_tests against a subsystem's
owned_prefixes/owned_files, but both commit guards passed it the
impacted entry, which carried neither. Since the v6 import (778a2577b6)
a same-subsystem test never satisfied a requirement, while
subsystem_lookup.py (which passes the registry rule) and the guard's own
BLOCKED message ("same-subsystem test/spec files are also accepted")
said it would.
Honouring the 12 flags would have loosened the guard well past their
apparent intent. Every rule requires explicit path-policy coverage, so
the five rule-level flags are never consulted, and on the seven path
policies the flag reaches every test the subsystem owns: a
mutation-registry change would accept any internal/ai or AI Chat test
(~455) instead of its 4 listed proofs, and a frontend Actions change any
Go test under internal/unifiedresources. Six of the seven already list
their own directory in test_prefixes.
So the strictness stays and the tools now agree on it: the registry sets
the 12 flags to false (what has always been enforced), registry_audit
rejects true and points at test_prefixes/exact_files, and the impacted
entry carries the rule's ownership so the completion and commit-shape
guards read the flag the same way subsystem_lookup does.
No requirement accepts a proof it rejected before. subsystem_lookup
stops reporting matches the guard refused: a new internal/hostagent test
no longer claims three agent-lifecycle policies.
TestSSEBroadcaster_AddClientWritesCurrentStatusBeforeReturning failed
under -race in CI on unrelated frontend PRs (2479, 2485). The test
broadcast a stage and connected straight away. When the broadcast loop
picked that message up after the client had registered, it queued the
stage for the new client too, so the client's writer goroutine wrote
the httptest recorder while the test read it without a lock.
AddClient itself is correct: it writes the preamble and current status
before returning, and a stage racing the connect can reach the client
twice, which the update modal already ignores. The test now lets the
broadcast reach an earlier client before connecting, so nothing else
writes the recorder and the status in the body can only come from the
synchronous snapshot write.
Reproduced by injecting the CI schedule through -overlay (broadcast
loop held until the client registers, caller paused as AddClient
returns): the old test failed 199/200 runs with DATA RACE, the new one
0/200. A mutant that moves the snapshot write onto the writer goroutine
still fails the new test 100/100.
Follow-up to #2502. CI now compares contract text against the commit
being checked, but the guard still decided which contracts that commit
owed using the subsystem registry and contract index from `HEAD`. In CI,
HEAD is the branch tip (or `main` after a merge), so a later commit
could still change an earlier commit's verdict:
- **False block.** A later commit adds a `Shared Boundaries` reference
to a file. An earlier commit that changed that file was complete when
written, but is now told it is missing the referencing contract.
- **False pass.** A later commit drops ownership of a file from the
registry. An earlier commit that changed that file without its contract
now passes.
The pre-commit hook reads both from the commit's own index, so CI and
the hook could still disagree.
**Change**
- `repo_file_io.read_repo_text` / `load_repo_json` and
`subsystem_contracts.tracked_contract_paths` / `tracked_contract_files`
/ `load_contract_index` accept a `revision`, alongside the existing
working-tree and index reads.
- A revision read uses only that commit's tree. It fails closed and
never falls back to the disk.
- In diff-base mode, the guard reads the registry and contract index
from the evaluated commit. So does the Prettier-only inference that
`--commit` enables.
- Pre-commit mode still reads the index, unchanged.
**Tests**
- `EvaluatedCommitGovernanceSourceTest` runs the real guard against a
temporary repo with its own registry and contracts, and covers both
cases above. Both fail against current `main`.
- New revision-read tests for `repo_file_io` and `subsystem_contracts`.
**Replay.** I replayed CI's per-commit loop (history registry,
Contract-Neutral trailers, `--diff-base <c>^ --commit <c>`) over the
last 120 non-merge commits on `main`, with the current and the new
guard. Verdicts are identical, and every historical registry loaded. The
PR #2494 commits still pass with HEAD at that PR's tip.
The maintainer preflight and coordinator already pass `--commit`
(rcourtman/pulse-dev-infra#704), so they pick this up without changes.
The comment in AddClient said a broadcast racing a connect is either in
the snapshot or queued behind it. It can be both, so the client then
receives that status twice, possibly with an older in-flight stage in
between. Trusting the "either" is what led the connect-snapshot test to
assume nothing writes the recorder after AddClient returns, which made
it flaky under -race. Say what actually happens and why it is harmless:
stage progress only rises and the update modal ignores backwards stages.
Contract-Neutral: Comment-only correction in internal/updates/sse.go; no runtime or contract change.
The completion guard's CI mode now compares contract text against the
evaluated commit (#2502), but it still decided which contracts a commit
owed from HEAD's registry and contract index. CI walks a branch with HEAD
at the tip (or at main after a merge), so a later commit could change an
earlier commit's verdict. If a later commit added a Shared Boundaries
reference to a file, an earlier commit that was complete when written got
blocked. If a later commit dropped ownership of a file, an earlier commit
that changed it without its contract passed. The pre-commit hook read
both from the commit's own index, so CI and the hook could still
disagree.
repo_file_io and subsystem_contracts can now read from a revision as well
as the working tree or index. A revision read uses only that commit's
tree and fails closed rather than falling back to the disk. In diff-base
mode the guard reads the registry and contract index from the evaluated
commit, as does the Prettier-only inference that --commit enables.
Replaying CI's per-commit loop over the last 120 commits on main gives
the same verdicts as before.
TestSSEBroadcaster_AddClientWritesCurrentStatusBeforeReturning failed
under -race in CI on unrelated frontend PRs (2479, 2485). The test
broadcast a stage and connected straight away. When the broadcast loop
picked that message up after the client had registered, it queued the
stage for the new client too, so the client's writer goroutine wrote
the httptest recorder while the test read it without a lock.
AddClient itself is correct: it writes the preamble and current status
before returning, and a stage racing the connect can reach the client
twice, which the update modal already ignores. The test now lets the
broadcast reach an earlier client before connecting, so nothing else
writes the recorder and the status in the body can only come from the
synchronous snapshot write.
Reproduced by injecting the CI schedule through -overlay (broadcast
loop held until the client registers, caller paused as AddClient
returns): the old test failed 199/200 runs with DATA RACE, the new one
0/200. A mutant that moves the snapshot write onto the writer goroutine
still fails the new test 100/100.
The canonical completion guard gave a different verdict in CI than in
the pre-commit hook for the same commit.
**Cause.** CI (`canonical-governance.yml`) and `scripts/dev-prepush.sh`
walk a branch's commits with HEAD at the tip, and run the guard per
commit with `--diff-base <commit>^`. In that mode the guard compared the
parent's contract text against `HEAD`, not against the commit it was
checking. So each commit was judged by the state of the whole branch.
The pre-commit hook compares HEAD with the staged index, which is the
commit's own change, so the hook and CI disagreed.
This had nothing to do with section headings. The paragraph sits under
`## Current State`, and both paths use the same substantive-section
rule. Only the texts they compared differed.
**Evidence.** In #2494, a99f3804a7 rewrote a Current State paragraph in
`performance-and-scalability.md`, and dfd6b4bd19 reverted it word for
word. Parent-vs-HEAD saw no change, so CI blocked a99f3804a7, which the
hook had correctly passed. With HEAD at dfd6b4bd19:
| guard | a99f3804a7 | dfd6b4bd19 |
| --- | --- | --- |
| before | blocked | passes |
| after | passes | passes |
The same comparison also let a bare runtime commit through when a later
commit on the branch carried its contract update.
**Change.**
- When `--commit` is given, the guard resolves the diff base against
that commit and reads the new contract text from it. CI already passes
`--commit`.
- `dev-prepush.sh` now passes `--commit` as well.
- Without `--commit` the guard still compares against HEAD, which is
right only when the commit being checked is the one checked out.
**Tests.** New tests in `canonical_completion_guard_test.py` build a
real temporary repo and cover both directions: a later revert no longer
blocks the commit that wrote the paragraph, and a later contract update
no longer passes an earlier bare commit. The dev-prepush test now checks
that each commit is passed as `--commit`. Against the old guard, the
false-pass test and the dev-prepush test fail.
The maintainer candidate preflight and coordinator in pulse-dev-infra
call the guard the same way. They get the same flag in a companion
pulse-dev-infra PR.
Expose only the installed GNU gtimeout as timeout through a new runner-owned directory. Keep native BSD utilities on their original PATH so installing the missing dependency cannot silently change the other platform checks. The connected workflow test verifies the symlink identity and that the directory contains no other utilities.
Contract-Neutral: Narrow the native CI dependency PATH and its proof; no shipped installer or runtime contract changes.
Change-source: pulse-maintainer
Both macOS native jobs fail the copied temperature recipes before reading any sensor. Install coreutils into the workflow PATH and verify GNU timeout for every Unix runner. Exercise the actual workflow snippets with real GNU timeout and fail-closed install, missing-tool and unsupported-tool controls; leave the recipes and their TERM/KILL/privacy controls unchanged.
Contract-Neutral: Native CI prerequisite and its fixture coverage only; no installer, runtime, API, permission or diagnostic contract changes.
Change-source: pulse-maintainer
Keep admission sealed and reuse a still-running close observer. A later explicit shutdown attempt may persist retained state after a completed write failure; successful close remains idempotent. This avoids a permanent offboarding dead end after an ordinary filesystem repair without an automatic spin retry or overlapping writes.
Contract-Neutral: Internal JSON writer recovery behaviour only; public routes, fields, permissions, identity format, private file mode and atomic persistence are unchanged.
Change-source: pulse-maintainer
CI and dev-prepush walk a branch's commits with HEAD at the branch tip and
run the completion guard per commit with --diff-base <commit>^. The guard
then compared the parent's contract text against HEAD rather than against
the commit it was evaluating, so every commit was judged by the whole
branch. The pre-commit hook compares HEAD with the staged index, which is
the commit's own parent-to-commit change, so the two disagreed.
PR 2494 hit this: its second commit reverted a Current State paragraph in
performance-and-scalability.md that its first commit wrote. Parent-vs-HEAD
saw no change, and CI blocked a commit the hook had correctly passed. The
same comparison lets a bare runtime commit through when a later commit in
the branch carries the contract update.
When --commit is given, the guard now resolves the diff base and reads the
new contract text from that commit. CI already passes --commit, and
dev-prepush now does too. Without --commit the guard still compares with
HEAD, which is right when the evaluated commit is checked out.
Admit detached metadata in order, merge identity fields without restoring stale
operator edits, and persist complete snapshots with one owned writer. Seal late
writes and return shutdown failures before organisation data or offboarding is
removed. Preserve existing drain budgets, file format, tenant boundaries and
atomic persistence. Add controlled burst, ordering, write-error, blocked-close
and real deletion controls.
Contract-Neutral: Behavioural repair of existing JSON persistence and organisation deletion; no route, field, permission, identity format, schema or provider authority change. Shutdown failure uses the existing HTTP error envelope. Internal ownership methods and explanatory contract text change, not the public contract shape.
Change-source: pulse-maintainer
## Outcome
- Small positive container CPU readings display as fractions rather than
zero, while raw readings, sorting and alert thresholds retain their
existing host-capacity scale.
- Both guest History entry paths distinguish retained/unavailable memory
and paused filesystem readings from current measurements. Original
observation source/time and stored samples survive refresh; unavailable
is not measured zero.
- Agent lookup avoids cloning unrelated Kubernetes metadata, and
registry bulk reads/grouping avoid repeated derived-metadata work while
preserving full inventory, identity, freshness and copy ownership.
- Failed alert sends reconcile delivery health only after releasing
their delivery gate and attempting the audit write. Operator transitions
remain immediate; retry budgets/policy are unchanged.
- PBS/API/History/temperature/VM and NAS instructions keep credentials
and diagnostic results private, bound requests, preserve logs and
unexpected files, and stop on unsafe preparation. NAS guidance now
matches the existing QNAP data-volume default, with private per-attempt
staging rather than destructive cleanup advice.
The demand is misleading container labels (Related to #2447),
false-current guest readings (Related to #2439), unnecessary per-report
work in the #2199 estate evidence, and unsafe existing diagnostic
recipes. Native metric accuracy, CPU/RSS relief, alert delivery, guest
recovery and every-symptom report resolution are not claimed.
Related to #2199
## Reviewed candidates and complete range
Complete proposed range:
`b2b5be27e94839c2561a8df5680cfe45810fd84f..5127e10164f5d743baa901813187d8b54594de1e`.
Starting reviewed tip `b21969de1a2bb17c849a0241384827bd6f4e6fef` is
preserved in final ancestry.
This advances the completed, failed proposal head
`e3652756fceb69d5389ebb932dceb39ced2e5e19`; it does not interrupt a
still-checking batch. Its existing PBS/API/fractional CPU/agent-lookup
candidates remain in ancestry. The added reviewed work includes:
- Passive VM `3a0a7f630205082c9610bb0cb8e5e5c139070b0a`; passive
temperature `4cb1c8a232576778ee6754bb1e5655d125c854db`; token-aware
Proxmox permissions `3c249ecacf4ab747ab822ad972527f7799bc00a0` and
composed webhook proof `899414d8ca2fbc86b2245675bf51bc30d14bfac9`.
- Mutation-bound materialisation
`51ef7edddab15f987fc930e31dbcf897777728f4..bec1d6455f870a877fc66df41a0c5e0ad02525db`;
pass-local owner grouping
`ff4626450343a0e4cb73b2516f52cf76ed4e0891..ab15c4db8a9f84a59d5d2f74ae50da1793f031e3`.
- Private-guide fixtures and phase/runner corrections
`5082c60d27d4946814ac05af512155eb3447238c`,
`8ad902ed1faecbee19da4908be8c23fe451f64f3`,
`eb9cf740bf1da0f4c4d092ffe976b353054b4b2a`,
`4bcca1a100f652db5024da614fa702f6a515e2f4`,
`87790b90428206e2c228748c9df46d3a26ac166d`,
`c0f0474423869e5ccc3d59db2d3013669ac37215` and
`c4207580689166eb04233a050706416da4a8c362`.
- Clone-boundary allocation controls
`476805821693146a79b3fcceca36613bfbe691b3` and alert callback ordering
`d500b4f211526bda3509adef6a7c4fb3e0337506`.
- Canonical History `ca255a0e3f81a8d1588f3e783b7084fc863b37c8`, composed
Docker evidence `d358adf7d0becc1deeca0bcb1a135fea024b4702`, NAS guide
`34a568ef656bf59a73f67cffaa23cdcf7910febf`, integrated at
`b21969de1a2bb17c849a0241384827bd6f4e6fef`.
All reviewed identities and additive upstream merges are retained.
Batch-start upstream `93652f453a3a30299b8159c52cd92ae1840d5cbc` was
already an ancestor. During proof admission current main advanced to
`b2b5be27e94839c2561a8df5680cfe45810fd84f` (TrueNAS storage
explanations, PR2497). Bounded refresh
`a0323a355e22fb6f0c707b6462e9cd49ad262f346d435812483e8437b1d563dd`
completed with exit 0 and unchanged source; additive full-SHA merge
`5127e10164f5d743baa901813187d8b54594de1e` then incorporated it without
conflict or rewriting accepted work. Independent drawer, security, Audit
Webhooks and storage presentation are preserved. No product selection
was performed.
## Validation and retained limitations
PR2486 run 37255054627 fails old whole-registry allocation measurement
(983→1,000), PBS bootstrap literals and copied API/PBS recipe
assertions. Governance run 37255054792 actually fails the same
bootstrap-doc assertion; its API-contract BLOCKED text is a logged,
successfully suppressed Contract-Neutral requirement, not the workflow
failure. These deterministic failures do not warrant unchanged-head
retries. The newer source corrects those checks without relaxing their
safety limits. The allocation test now measures the clone boundary with
unchanged three samples/+10 and a full-publication positive control; it
does not establish the old whole-admission envelope.
Retained reviewed evidence includes agent lookup `source-bg4zd66_`,
materialisation `source-u0i3z9yq`, grouping
`source-176ctacf`/`source-wv738zr1`, callback `source-xx7omeec` and
complete Core races/vet/build `source-liltmi2o`. Materialisation cold
List-only regressions (+4.05% time/+4.49% bytes/+13.33% allocations),
grouping time increases (+0.82% demo/+1.48% empty), earlier writer/drain
failures and unknown historical results remain; these synthetic controls
prove no estate CPU/RSS improvement.
History parent `source-t7yab3c2` reproduces false-current; final
`source-etqcidkl` passes 22,695 frontend tests,
types/lint/embed/budgets, with complete recorded raw-output hash match
and own guest stop. Twelve History/Docker browser cases have 44
owner-inspected captures; earlier selector/console failures and three
skipped tests remain. Final range browser guard confirms unchanged
covered bytes, so those sufficient visual checks were not replayed. NAS
`source-9rx_y8hp` passes 25 copied-command/mirror tests and public-doc
checks with parent failure controls; wrong-directory attempt remains
failed.
Combined-batch `source-w_c7gm41` passes full models, unified-resources,
notifications and installer suites at starting tip `b21969de`; its
overall exit is 1 because two repoctl cross-repository existence checks
lack private sibling checkouts in this single-module VM. The subsequent
chained checks did not run. That result remains failed, with complete
1,685-byte hash-matched output and completed stop; no private-evidence
acceptance is inferred. Backend code/tests/manifests and copied-guide
inputs are byte-identical across the upstream merge, so those passing
suites were not repeated. Starting-tip frontend `source-7sfiykc1` passes
type-check, 353 tests across nineteen connected suites, and embed build.
Exact final head `5127e101` is checked by:
- `source-o6i0fysr`: offline npm graph installation, types, 289 tests
across eight TrueNAS storage/History/Docker/docs/shared-primitives
suites and production embed build.
- `source-vdatp7x7`: repoctl using the repository's existing public-only
Actions profile, focused agent lookup controls, scoped vet, all 80
selected copied-guide Python tests, 241 public Markdown files and 62
shipped mirrors. This profile deliberately leaves private sibling
existence to the separate private governance job; it is not private
evidence or actual hosted execution.
Both final receipts have exit 0, independently hash-matched complete raw
output (60,374 / 1,633 bytes) and completed guest stops. Frontend
long-line observer flags are retained without truncation or overflow.
Earlier missing-context failure is not relabelled green.
Publication provenance, whitespace, every in-range non-merge completion
guard and final-range browser guard pass. No release, installed
safety/metric accuracy, native thaw/every-covered-filesystem
writes/liveness, or permission for uncertain monitoring resumption is
established. Required exact-head CI and protected landing remain
separate, with native/reporter follow-through still owned.
[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)