Test-only wave, contract-neutral. New *_branchcov0719pm_test.go files cover
previously-uncovered pure value-in/value-out helpers, each verified to move
its target functions from 0% to full coverage:
- internal/agentcontext: formatKubernetesServicePorts (empty/single/cap/overflow
arms) and addMetricFact (nil-metric, percent/value/ratio arms) now 100%.
- pkg/reporting: reportLogoTypeFromPath 0->100, reportLogoTypeFromData 28.6->100,
scaledLogoSize 70->90 (extension and aspect branches).
- internal/cloudcp/email: RenderMagicLinkEmail 0->80 (render success path; the
compile-time template-error arm is unreachable and left uncovered).
- internal/recovery: recoveryDetailString (nil map, missing key, non-string,
string arms) and recoveryPointObservedAt 40->100.
- internal/ai/tools: ErrStrictResolution/ErrRoutingMismatch ToToolResponse 100.
- internal/ai/providers: every NormalizeCollections receiver 0->100.
No source or existing test modified.
Cover pure functions the recent canonical Operational Trust and protection
posture work landed with no unit test:
- recovery/model posture: enum Valid, struct Clone/Validate/Payload and the
normalize/cloneTime/validOutcome/sortedUniqueStrings/compareProviderStates
helpers (20 funcs, all 0%->100%)
- operationaltrust contracts: EvidencePayloadRef/Acknowledgement/Suppression/
LifecycleTransition Validate plus LifecycleTransition/NotificationLink Clone
- cloudcp/proxytrust: ClientIP, ExtractRemoteIP, rightMostUntrustedForwardedIP
and IsTrustedProxyIP forwarded-header and CIDR parsing
- mockmodel: NormalizeBlendWeight, SeriesForTimestamps, seriesForProfile,
diskIOValue and flatValue deterministic seeded math
- updatesignature: DecodePrivateKey and HasTrustedPublicKeys
- recovery keys: ProxmoxPBSGuestLooseContinuityKey branch guards
- vmware SourceID and truenas availableAppLogContainers formatting
Test-only, contract-neutral. New *_branchcov0719_test.go files only; no source
or existing test touched.
New *_branchcov0718_test.go files extend the Go coverage wave to three more
areas of previously-uncovered pure logic. Covered areas include the domain-type
NormalizeCollections normalizers in models.go, the cloud control-plane pure
helpers for hosted-entitlement org-id normalization, magic-link URL redaction
and default MSP backup paths, and the actionlifecycle dispatch-attempt context
round-trip plus the typed-error Error and Unwrap methods.
Test-only, with no runtime or subsystem-contract change. Impure targets that
need a live Docker manager or tenant registry were skipped per the purity gate
and noted in the wave reports. Verified in a clean worktree at HEAD with go vet
and package tests green, gofmt clean, and every covered target moved from 0
percent toward full coverage.
The MSP portal support row deep-linked docs/MSP.md at blob/main, which
the repo-docs link-drift guard rightly rejects: a released portal build
must not reference branch-tip docs that can move out from under it.
The row keeps the docs/MSP.md path as text and links the repository
root instead, matching every other runtime surface. Portal dist rebuilt
alongside.
The portal shipped with a GitHub-Primer palette, light-only, while every
"Open client" hands the operator into the slate/blue Pulse product UI
(which most monitoring users run dark). The portal now uses the product's
Tailwind slate/blue semantic tokens so both halves of the MSP workflow
read as one product:
- Light theme mirrors the product exactly: slate-100 page, white surfaces,
slate borders/inks, blue-600 solid buttons.
- Full dark theme (slate-900/800 surfaces, blue-400 links, product-style
translucent status chip backgrounds with readable 300-series text),
applied via prefers-color-scheme by default with a persisted header
toggle (data-theme override in localStorage, nonce'd no-flash bootstrap
in the page template).
- Hardcoded badge/status border literals, the toast, the danger-button
hover, and border-only panels that relied on the old white page are all
tokenized so every state renders in both themes.
- Dropped two dead Roboto @font-face blocks and their data-URI payloads
(nothing referenced the family): portal_app.css shrinks 135KB -> 43KB.
Verified live in both themes: workspace roster, setup queue, client
onboarding panel chips, Access invite panel, signed-out instruction card,
and the error toast; theme choice survives reload and sign-out. Portal
vitest suite 103/103 incl. new theme tests; frontend/dist sync test green.
Exercised the full provider portal as a pilot MSP would and fixed what
made it feel broken:
- The signed-out portal promised "a sign-in link is on the way" even when
the control plane has no email provider (the bundle default), and team
invitations silently sent nothing. The portal bootstrap now carries
email_sign_in_available and provider_hosted_mode; the sign-in page shows
the host command that actually prints a link, and the invite panel says
invitation emails are not sent and how to hand over a link instead.
- New "provider-msp portal-link --email" CLI mints a one-time portal link
for an account member or pending invitee, so teammates can sign in at
all on email-less installs (bootstrap only covers the owner).
- Portal sessions were fixed at 12h; CP_SESSION_TTL now configures them
and provider-hosted MSP mode defaults to 7 days.
- Creating a client past the license cap showed a generic "Failed to
create workspace." toast: the limit error is now a JSON payload with
current/limit, the API client no longer drops non-JSON error bodies
(double body read), and the toast explains the license limit.
- Copy polish: provider-mode sign-in intro (no refunds/privacy register),
least-privilege default invite role, queue tile label matches "Client
onboarding", softer Support tab with a docs/MSP.md pointer, setup.sh
summary now prints the bootstrap next step and day-2 sign-in commands,
.env.example and docs/MSP.md document portal sign-in and sessions.
Contracts updated (cloud-paid, api-contracts, deployment-installability,
security-privacy) with verification pins in tenant_handlers_test,
config_test, magiclink_test, and provider_msp_deploy_test.
Verified live against a dockerless control plane: portal-link for an
invitee redeems, promotes the invitation, and sets a 7-day session;
the at-cap toast shows the license copy; portal vitest suite and
cloudcp/auth/account/installtests Go suites pass.
Completes the approved trial flow end to end. The License panel's plan
comparison gains a 'Start 14-day free Pro trial' action (shown only when
unlicensed, trial-eligible, and never-trialed) that rides the existing
purchase-start handoff with trial=1; the handler already forwards
non-reserved params. Pulse Account portal reads the trial arrival flag,
relabels the pro monthly checkout button, shows the card-required note,
and sends trial:true to the checkout session endpoint (server support
deployed in pulse-pro 4c3a28c). Organic portal and public pricing
arrivals see no trial anywhere, per the no-upsell doctrine; retired
local trial-acquisition routes remain 404. Portal dist rebuilt.
1. Regenerate pulse-mcp README from canonical manifest (doc drift)
2. Add 31 missing Pulse Intelligence telemetry fields to both PRIVACY.md
copies to match current Ping struct JSON tags
3. Rebuild portal frontend bundle to update build_manifest.json hash
4. Update action execution contract test to match current code structure
(handler wrapped with withExternalAgentCapabilityActivity, error codes
referenced via agentcapabilities constants instead of literal strings)
Full Go test suite now passes clean: 126 packages, 0 failures.
Manifest-backed MCP tools, prompts, and resources with surface affordance contracts; agent capability manifest and governance projection; API contract tests and capability route projection; operations-loop and intelligence-funnel telemetry; release-control subsystem documentation, registry, and tooling; licensing and configuration.
The variable signs hosted entitlement leases; the trial-activation name is
left over from the retired trial era and reads as trial machinery to an
operator generating their licensing root key. The provider MSP bundle has
no installed base yet, so the canonical rename is free today and frozen
the moment the first design partner installs.
- Control plane reads CP_ENTITLEMENT_SIGNING_PRIVATE_KEY first and falls
back to CP_TRIAL_ACTIVATION_PRIVATE_KEY, so existing Pulse-hosted cloud
deployments (deploy/cloud, hibernated snapshot) keep working unchanged.
- deploy/provider-msp (.env.example, compose, setup.sh), MSP.md, and the
install-test pins use the canonical name; error messages name it too.
- deploy/cloud intentionally keeps the legacy name: that stack historically
signed hosted trial activations, and its snapshot predates the rename.
Provider-hosted MSP client workspaces previously sat at Community tier
forever: the runtime refreshed leases against the built-in Pulse Cloud URL
(hibernated, 522) instead of the provider control plane, and release-build
images verify leases only against the embedded Pulse key, which an
operator-generated CP_TRIAL_ACTIVATION_PRIVATE_KEY can never satisfy.
- Inject PULSE_PRO_TRIAL_SIGNUP_URL=CP_BASE_URL into client containers so
lease refresh targets the provider control plane.
- Chain trust through the Pulse-signed provider MSP license: the license
binds the provider's lease signing public key
(entitlement_signing_public_key claim); the control plane embeds the
license in every lease (provider_license claim); release-build runtimes
verify embedded Pulse root -> provider license -> lease signature.
- Cap chain-verified leases at ProviderChainedLeaseCapabilities: MSP tier
plus white_label (branded per-client reports), minus Pulse-service-backed
relay/mobile_app/push_notifications, which otherwise loop doomed
registrations against Pulse's relay.
- Fail fast at control-plane startup when the license does not bind the
configured signing key, instead of provisioning silently unlicensed
client workspaces.
Verified live on a Colima harness: release-tagged tenant image with test
embedded root, Traefik TLS, full provider-msp proof, tenant reports
valid=true plan_version=msp_growth with white_label and zero relay
failures.
Hosted tenant containers received PULSE_TENANT_ID but not
PULSE_TENANT_NAME, so alert webhook payloads from provider-hosted client
runtimes fell back to the raw tenant ID instead of a human-readable
workspace label. Resolve the display name from the tenant registry at
container-create time via a ManagerConfig resolver and stamp it
alongside the tenant ID. Display-name changes after creation apply on
the next runtime rollout, which recreates the container with freshly
resolved env.
Tighten v5-to-v6 upgrade safety, release installability, provider MSP mode handling, AI cost accounting, metrics flushing, and frontend guardrails for the v6.0.0 GA candidate.
Dead-code sweep. Functions flagged unreachable by golang.org/x/tools/cmd/deadcode
and confirmed unused across pulse, pulse-enterprise, pulse-pro and pulse-mobile by
adversarial cross-repo verification. Cross-module reachability was checked
explicitly (only pkg/ exported symbols are importable by other modules; internal/
packages and _test.go files are not). go build, go vet and test-compile all pass.
Add a Stripe-free provider-hosted MSP mode with local MSP plan workspace limits and portal behavior that hides hosted billing surfaces when no billing record exists.
Make the public MSP signup path create immediate subscription checkout sessions instead of inheriting the individual Cloud trial helper. Preserve the existing individual Cloud trial path, mark checkout billing mode in metadata, and seed MSP checkout-created Stripe account mappings as active.
Adds public self-serve signup for the hosted MSP offering alongside the
existing individual Cloud signup page. New handlers serve /cloud/msp/signup,
/cloud/msp/signup/complete, and /api/public/msp/signup, gated behind the same
PublicCloudSignupEnabled flag. Per-tier Stripe prices
(CP_MSP_STARTER_PRICE_ID, CP_MSP_GROWTH_PRICE_ID, CP_MSP_SCALE_PRICE_ID) are
validated against the canonical msp_starter/growth/scale plan versions; the
page renders an explicit "not open yet" notice when no MSP price is
configured. Checkout sessions carry account_kind=msp metadata so the
provisioner seeds an isolated operator workspace. The cloud and MSP JSON
signup endpoints now share one checkout skeleton parameterized per path.