mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-05-02 13:30:13 +00:00
724 lines
41 KiB
Markdown
724 lines
41 KiB
Markdown
# Pulse v6 Source Of Truth
|
|
|
|
Last updated: 2026-04-04
|
|
Status: ACTIVE
|
|
|
|
This file is the stable human governance layer for the active v6 release
|
|
profile. It is not a live progress dashboard.
|
|
|
|
Evergreen control-plane governance now lives in
|
|
`docs/release-control/CONTROL_PLANE.md`, and the active profile plus active
|
|
target are machine-selected by `docs/release-control/control_plane.json`.
|
|
|
|
Current lane scores, evidence references, coverage-gap discovery records,
|
|
candidate-lane planning records, and typed operational decision records live
|
|
only in `docs/release-control/v6/internal/status.json`.
|
|
Lane completion state, residual-gap summaries, normalized follow-up tracking,
|
|
and derived coverage scores also live only in
|
|
`docs/release-control/v6/internal/status.json`.
|
|
Non-blocking same-lane residuals that are concrete enough to name directly
|
|
live in `status.json.lane_followups`.
|
|
Product-scope lane-discovery records that reveal where the current taxonomy is
|
|
still under-modeled live in `status.json.coverage_gaps`.
|
|
Planned future lane promotions for those gaps live in
|
|
`status.json.candidate_lanes`.
|
|
Active multi-agent lease records that reserve governed work in flight live in
|
|
`status.json.work_claims`.
|
|
Current repo/release readiness is derived by
|
|
`python3 scripts/release_control/status_audit.py --pretty` from
|
|
`status.json`, not hand-maintained in this file. The human runbook for
|
|
trust-critical manual release gates lives in
|
|
`docs/release-control/v6/internal/HIGH_RISK_RELEASE_VERIFICATION_MATRIX.md`.
|
|
Use `python3 scripts/release_control/status_lookup.py` for candidate-lane,
|
|
coverage-gap, lane, readiness-assertion, release-gate, followup, and
|
|
work-claim lookups when only one governed surface is relevant.
|
|
Readiness assertion design rules live in this file.
|
|
The active assertion catalog, proof references, and executable proof commands
|
|
live in `status.json.readiness_assertions`.
|
|
|
|
## Purpose
|
|
|
|
1. Define the stable execution model for the active v6 release profile.
|
|
2. Lock profile-specific scope, release definition, and no-go rules.
|
|
3. Record only long-lived architectural and release decisions for this profile.
|
|
4. Point agents to the files that own live state and subsystem truth for this
|
|
profile.
|
|
5. Keep startup context light by preferring derived status commands and
|
|
targeted lookup helpers before opening large machine files in full.
|
|
|
|
This file must not contain:
|
|
|
|
1. hand-maintained lane score tables
|
|
2. hand-maintained evidence lists
|
|
3. ephemeral session recaps or task logs
|
|
|
|
## Canonical Control Files
|
|
|
|
1. `docs/release-control/AGENT_VALUES.md`
|
|
Evergreen values-only guidance for agent behavior.
|
|
2. `docs/release-control/CONTROL_PLANE.md`
|
|
Evergreen governance for the permanent Pulse release control plane.
|
|
3. `docs/release-control/control_plane.json`
|
|
Machine-readable control-plane state, including the active profile and
|
|
active target.
|
|
4. `docs/release-control/control_plane.schema.json`
|
|
Machine-readable contract for `control_plane.json`.
|
|
5. `docs/release-control/v6/internal/status.json`
|
|
Live lane state, lane completion records, coverage-gap discovery records,
|
|
candidate-lane planning records, active work claims, structured evidence
|
|
references, and typed operational decision records.
|
|
6. `docs/release-control/v6/status.schema.json`
|
|
Machine-readable contract for the `status.json` shape.
|
|
7. `docs/release-control/v6/internal/CANONICAL_DEVELOPMENT_PROTOCOL.md`
|
|
Repo-wide change rules for canonical work.
|
|
8. `docs/release-control/v6/internal/subsystems/registry.json`
|
|
Machine-readable subsystem ownership and proof requirements.
|
|
9. `docs/release-control/v6/internal/subsystems/registry.schema.json`
|
|
Machine-readable contract for the subsystem registry shape.
|
|
10. `docs/release-control/v6/internal/subsystems/*.md`
|
|
Per-subsystem contracts: truth, extension points, forbidden paths, and
|
|
completion obligations.
|
|
11. `docs/release-control/v6/internal/RELEASE_PROMOTION_POLICY.md`
|
|
Canonical stable-versus-prerelease promotion rules, rollout criteria, and rollback
|
|
expectations for v6 and later release lines.
|
|
12. `docs/release-control/v6/internal/V5_MAINTENANCE_SUPPORT_POLICY.md`
|
|
Canonical v5 maintenance-only support policy, release-line rules, and GA
|
|
notice requirements for the v6 cutover.
|
|
13. `docs/release-control/v6/internal/RC_TO_GA_REHEARSAL_TEMPLATE.md`
|
|
Canonical human record shape for the non-publish RC-to-GA rehearsal run.
|
|
14. `docs/release-control/v6/internal/PLATFORM_SUPPORT_MODEL.md`
|
|
Canonical first-class platform, ingestion-mode, resource-projection, and
|
|
support-floor model for Pulse v6.
|
|
|
|
These machine files remain canonical, but agents should not ingest them in full
|
|
by default when a smaller derived command answers the question. Prefer
|
|
`status_audit.py --pretty`, `status_lookup.py`, and `subsystem_lookup.py`
|
|
first, then escalate into the raw files only when the current slice needs that
|
|
detail.
|
|
|
|
## Scope
|
|
|
|
`status.json.scope.control_plane_repo` is `pulse`.
|
|
`status.json.scope.repo_catalog` is the canonical machine-readable repo map for
|
|
the active Pulse workspace.
|
|
|
|
Active repositories for v6:
|
|
|
|
1. `pulse`
|
|
Core desktop/runtime repo and the canonical v6 release-control authority.
|
|
2. `pulse-pro`
|
|
Financial, operational, checkout, license-server, and relay-server
|
|
surfaces.
|
|
3. `pulse-enterprise`
|
|
Closed-source enterprise and paid runtime features.
|
|
4. `pulse-mobile`
|
|
Mobile client, relay pairing, approvals, and device-local auth/state.
|
|
|
|
Ignored for v6 control:
|
|
|
|
1. `pulse-5.1.x`
|
|
2. `pulse-refactor-streams`
|
|
|
|
## Product Direction
|
|
|
|
Pulse is moving toward the unified operations layer for mixed private
|
|
infrastructure.
|
|
Pulse should win by giving operators one coherent place to monitor,
|
|
investigate, and safely act across mixed estates rather than by accumulating
|
|
opportunistic platform-specific surfaces.
|
|
New platform work must therefore strengthen that mixed-estate operator surface
|
|
and follow `docs/release-control/v6/internal/PLATFORM_SUPPORT_MODEL.md`
|
|
instead of being admitted ad hoc.
|
|
Under that governed platform model, `docker` and `kubernetes` are first-class
|
|
top-level platforms, while `podman` stays a runtime variant inside `docker`
|
|
rather than becoming its own top-level platform.
|
|
The same model also sets the current posture for platform breadth: `truenas`
|
|
is at the declared support floor summarized below, and `vmware-vsphere` is the
|
|
current admitted strategic next-platform direction while its support claim
|
|
remains proof-gated.
|
|
Pulse Mobile v1 is not desktop parity on a phone.
|
|
It is the away-from-desk decision surface for the same Pulse runtime: the next
|
|
item, findings, approvals, reconnect state, instance switching, and contextual
|
|
AI handoff.
|
|
Public/store copy and primary mobile shell labels must reinforce that narrower
|
|
job instead of promising a pocket dashboard with full desktop parity.
|
|
Mobile earns broader authority only after short operator validation confirms
|
|
that users can open `Now`, tell what needs attention, act, and recover trust
|
|
without desktop fallback.
|
|
Until that validation and the remaining hardware proof gates pass, widen mobile
|
|
through clearer ops cues and trust repair only, not through extra tabs, graphs,
|
|
or desktop-parity surface expansion.
|
|
|
|
## Release Definition
|
|
|
|
Pulse v6 is ready when these outcomes land together:
|
|
|
|
1. Unified resource model is stable and expansion-ready.
|
|
2. Product quality feels polished and trustable out of the box.
|
|
3. Commercial packaging materially improves conversion and revenue.
|
|
4. Stable or GA promotion happens only after prerelease validation, not as the first
|
|
customer exposure.
|
|
|
|
Pulse v6 is still a bridge release toward that unified operations layer, while
|
|
the current active target remains governed prerelease-cut readiness with an
|
|
explicit RC-publication hold rather than broad new platform execution.
|
|
For this profile, "bridge release" means the product should stop reading as a
|
|
monitoring tool growing sideways and instead make the mixed-estate operator
|
|
surface legible through canonical resources, investigation context, governed
|
|
action boundaries, and fleet governance wherever the surfaced case is already
|
|
proven.
|
|
Pulse owns infrastructure context, policy, and governed action boundaries so
|
|
any sandboxed agent can use them; Pulse does not own being the sandbox where
|
|
arbitrary agent execution lives.
|
|
The retained foundation is therefore the hidden backend layer: canonical
|
|
resources and relationships, standardized agent-emitted resource/signal/change
|
|
envelopes, policy metadata and routing hooks, governed action and approval
|
|
boundaries with auditability, and first-class fleet governance.
|
|
|
|
## Evergreen Readiness Assertions
|
|
|
|
Pulse v6 readiness is governed by a small evergreen assertion set.
|
|
These assertions are durable release truths, not one-off launch checklist
|
|
items.
|
|
`status.json.readiness_assertions` owns the active assertion catalog, proof
|
|
references, and executable proof commands for the active release line.
|
|
`docs/release-control/control_plane.json` owns the active engineering target
|
|
that this profile is currently pursuing.
|
|
`python3 scripts/release_control/control_plane_audit.py --check` enforces that
|
|
the active target cannot stay stale once its machine-derived completion rule is
|
|
already satisfied.
|
|
|
|
Assertion design rules:
|
|
|
|
1. Keep the set small and durable.
|
|
2. Write each assertion as a binary release truth, not as a task list.
|
|
3. Map each assertion to concrete lanes, governed subsystems, or release gates.
|
|
4. Prefer machine-derived proof and generated summaries over hand-maintained
|
|
docs.
|
|
5. If repeated manual proof becomes expensive, automate it or demote it to a
|
|
one-time migration item instead of keeping it in the evergreen set.
|
|
6. After GA, keep using the same control plane and promote a new active target
|
|
instead of cloning a new governance stack.
|
|
7. Not all evidence classes are equal.
|
|
High-risk release gates must declare the minimum evidence tier required for
|
|
closure, and rehearsal evidence below that tier must remain blocking even
|
|
when a dated record already exists.
|
|
8. When a user states a durable product truth, normalize it into a readiness
|
|
assertion, release gate, or open decision rather than leaving it as chat.
|
|
9. Treat casual user language about consistency, seamlessness, drift, bypass
|
|
resistance, or things that "should always be true" as candidate governance
|
|
input, not only explicit requests to add a formal assertion.
|
|
10. Active v6-facing guidance must stay current; legacy or historical docs may
|
|
exist only as clearly marked reference material, not as current instructions.
|
|
11. Comparable settings surfaces should be normalized into canonical
|
|
page-shell rules when the user raises consistency drift, rather than
|
|
treated as vague polish notes.
|
|
12. Lane taxonomy is allowed to evolve when it no longer reflects the current
|
|
product truth.
|
|
13. If a durable product surface is materially underrepresented by the current
|
|
lane map, record an active `status.json.coverage_gaps` entry instead of
|
|
hiding the gap inside a broad lane, a lane followup, or a generic
|
|
assertion.
|
|
14. Treat `status.json.coverage_gaps` as active fog-of-war records rather than
|
|
a loose backlog: each one should cite evidence, carry an explicit coverage
|
|
deduction, and name the intended promotion path such as a lane split, new
|
|
lane, lane expansion, or target update.
|
|
`coverage_gaps.status` is not cosmetic: once a lane-shaping gap
|
|
(`new-lane`, `lane-split`, or `lane-expansion`) has a typed
|
|
`candidate_lanes` record, move that gap to `planned`; do not mark such a
|
|
gap `planned` until a matching `candidate_lanes` record exists.
|
|
15. When the intended lane split/addition/expansion shape is already clear,
|
|
record it in `status.json.candidate_lanes` so lane-taxonomy evolution is
|
|
machine-readable rather than buried in prose.
|
|
Candidate lanes should also identify the owning control-plane target so
|
|
future lane-expansion work is routed to an explicit governed initiative.
|
|
`candidate_lanes` are only for lane-shaping promotion paths, so
|
|
`target-update` coverage gaps must stay out of that surface.
|
|
16. Once a coverage gap is resolved by a lane split/addition, lane expansion,
|
|
or target update, remove it from `coverage_gaps` instead of leaving it
|
|
behind as historical noise.
|
|
17. Before coding begins on a governed slice, record a `status.json.work_claims`
|
|
entry for the chosen slice, then verify it with
|
|
`python3 scripts/release_control/agent_preflight.py --require-active-claim --agent-id <AGENT_ID>`.
|
|
The claim is an audit trail: it records what is being worked on and
|
|
prevents accidental overlap if the same surface is resumed or handed off.
|
|
Expired claims no longer mark active work; remove them when encountered so
|
|
the live claim set stays trustworthy.
|
|
18. Lane work must be evaluated against the canonical v6 model, not only the
|
|
local state it inherits.
|
|
For any lane or candidate lane, first identify the canonical v6 shape for
|
|
that surface: unified-resource-backed where applicable, canonical shared
|
|
types and APIs, explicit subsystem ownership, and legacy compatibility code
|
|
reduced to boundary-only exceptions instead of primary flow.
|
|
When a lane surface still routes through a pre-v6 or host-era shape, do
|
|
not merely improve that path locally and call the lane healthier.
|
|
Either modernize it toward the canonical v6 mechanism in the same slice or
|
|
record the remaining modernization gap explicitly in the owning lane's
|
|
completion state, follow-up tracking, or lane-shaping governance.
|
|
19. These modernization rules are retrospective.
|
|
Existing lanes do not keep their floor forever just because earlier work
|
|
landed before the control system made this explicit.
|
|
When an existing lane is touched, reviewed, or reopened, judge it against
|
|
the same canonical v6 modernization rules as new lane work and lower its
|
|
claimed completeness if legacy-primary paths are still carrying the surface.
|
|
Backward compatibility is not a blanket excuse to keep old internal
|
|
mechanisms alive. Preserve legacy behavior only at explicit boundaries such
|
|
as migrations, upgrades, imports, external contracts, or wire
|
|
interoperability that still genuinely exist; otherwise retire the
|
|
legacy-primary path instead of teaching the lane to depend on it.
|
|
When a canonical replacement lands, remove the superseded internal path in
|
|
the same slice unless a boundary-only exception is explicitly governed,
|
|
and prove that the remaining supported boundary still works.
|
|
Do not wait only for the slice that authored the replacement: if a later
|
|
governed slice lands on clearly obsolete old-way internals in that same
|
|
surface, cleanup should retire them rather than normalizing their
|
|
continued presence.
|
|
20. Guardrail-only work is support work, not lane advancement.
|
|
Contract ratchets, proof-routing cleanup, registry tightening, and
|
|
guardrail-only tests may strengthen confidence, but they must not be
|
|
treated as substantive lane movement by themselves.
|
|
If `status.json` advances a lane's score, status, or completion state, the
|
|
same slice should normally include an owned runtime or product-surface
|
|
delta for that lane unless the remaining gap is explicitly governance-only.
|
|
21. Large machine control files are canonical databases, not startup prompt
|
|
payload.
|
|
Treat them as canonical databases, not startup prompt payload.
|
|
Agents should prefer executable summaries and targeted lookup commands over
|
|
rereading `status.json` or `registry.json` in full on ordinary turns.
|
|
Escalate into the raw files only when a lane, assertion, release gate,
|
|
work claim, or subsystem boundary actually requires full-detail inspection.
|
|
22. Legacy compatibility must be named as a boundary exception, not assumed as
|
|
a primary v6 design goal.
|
|
If a touched surface still needs old-path support, make the boundary
|
|
obligation explicit in the owning contract or lane residual and keep the
|
|
rest of the superseded internal path retired. Otherwise, treat continuing
|
|
investment in that old internal path as drift, not prudence.
|
|
Clearly obsolete old-way code discovered during adjacent governed work is
|
|
part of that same drift signal; clean it up or record the blocking reason
|
|
explicitly instead of leaving it behind as ambient repo clutter.
|
|
23. Claimed lane work should prefer the largest coherent same-surface slice.
|
|
Within an active claimed lane, prefer the largest coherent same-surface slice.
|
|
When one behavior arc on one governed surface is already clearly in scope,
|
|
group the remaining same-surface work into the largest slice that still
|
|
has one coherent proof story.
|
|
Do not fragment a single modernization or canonicalization arc into many
|
|
tiny commits just because each residue item can be named separately. Split
|
|
only when there is a real risk boundary, concept boundary, or proof
|
|
boundary.
|
|
24. Lane scores, missing evidence items, and proof counts are signals, not the
|
|
work target.
|
|
Use them to find the remaining runtime, product, ownership, or governance
|
|
gap that still keeps the lane below floor.
|
|
Do not frame a slice as "get two more evidence items" or "raise the lane
|
|
score" unless the remaining gap is explicitly governance-only.
|
|
For ordinary lane work, identify the real same-lane gap first, then add
|
|
the proof that demonstrates the gap is actually closed.
|
|
25. Worktrees are available for isolated mutating slices when explicit isolation
|
|
is needed.
|
|
A shared mutable checkout is fine for normal single-session work.
|
|
Use `worktree_base.py`, `worktree_claim.py`, and `worktree_finish.py` when
|
|
a slice requires its own isolated hooks, staged scope, and dirty state —
|
|
for example when a subagent needs to mutate independently and land back
|
|
cleanly.
|
|
|
|
## Non-Negotiable Release Gates
|
|
|
|
1. Do not ship with open trust-critical P0s.
|
|
2. Do not ship when paywalls and runtime gates disagree.
|
|
3. Do not ship hosted Pulse flows that break signup, auth, provision, hosted
|
|
runtime access, billing/admin visibility, or revocation.
|
|
4. Do not ship multi-tenant support if tenant isolation, organization scope,
|
|
tenant-scoped runtime state, or cross-org sharing can leak outside the
|
|
intended tenant boundary.
|
|
5. Do not ship MSP support if one provider account cannot safely onboard,
|
|
manage, and separate multiple client tenants from one control surface.
|
|
6. Do not ship if API tokens can exceed assigned user, org, or scope
|
|
boundaries, survive revocation, or silently widen authority through legacy
|
|
alias handling.
|
|
7. Do not ship if a low-privilege user can view, mutate, or destroy beyond the
|
|
permissions granted by their effective org membership and role.
|
|
8. Do not ship if grandfathered recurring continuity, cancellation revocation,
|
|
and later re-entry pricing can drift across Stripe, Pulse runtime, and
|
|
customer-visible billing state.
|
|
9. Do not ship if Pulse Mobile can keep stale access, lose approval state, or
|
|
fail pairing, reconnect, or auth-transition recovery against a real
|
|
instance.
|
|
10. Do not ship if relay registration, reconnect, stale-session recovery, or
|
|
disconnect drain can strand clients in resume loops, dead sessions, or
|
|
lost inflight work.
|
|
11. Do not ship upgrades that reset paid state, licensing continuity, or
|
|
first-session flow.
|
|
12. Do not ship if comparable settings surfaces drift away from the canonical
|
|
page-shell contract and still present inconsistent top-level framing,
|
|
header chrome, or section treatment without explicit justification.
|
|
13. Do not keep polishing strong lanes while weak lanes remain behind.
|
|
14. Do not treat `status.json` lane scores reaching target as sufficient release approval by themselves; open operational decisions, machine-derived unresolved readiness assertions, and unresolved release gates still apply.
|
|
15. Do not promote v6 to stable or GA without an exercised prerelease, a real
|
|
release-pipeline proof run, a recorded rollback target plus exact
|
|
reinstall command, and a written v5 maintenance-only support policy.
|
|
16. Do not declare a lane or blocker complete just because the first passing
|
|
check landed. If obvious same-lane gaps still keep the outcome from being
|
|
coherent, trustworthy, or realistically shippable, that lane is not done
|
|
yet.
|
|
17. Do not ship a customer-facing surface that is still prototype-grade.
|
|
If a portal, hosted workflow, first-session flow, or other customer-facing
|
|
surface still feels confusing, second-rate, or untrustworthy in real
|
|
browser use, it is not acceptable to keep treating that surface as a good
|
|
baseline for narrow refinement.
|
|
18. Lanes that are at target but intentionally not closed must record a
|
|
bounded residual in `status.json` with a short rationale and explicit
|
|
tracking references to the governing follow-up surface.
|
|
Pair lane `status` and `completion.state` coherently: `complete` goes with
|
|
`target-met`, `bounded-residual` goes with `partial`, and `open` must not
|
|
be paired with `target-met`.
|
|
`partial` means measurable progress, so it must not sit at zero score.
|
|
`not-started` means zero score and `open`. `blocked` remains an `open`
|
|
lane below target rather than a residual or complete state.
|
|
Blocked lanes must declare typed same-lane blocker references to unresolved
|
|
readiness assertions, release gates, or open decisions.
|
|
`completion.tracking` is only for bounded residuals; open or complete lanes
|
|
should keep that list empty until the lane reaches its current floor and
|
|
the remaining work becomes a governed residual.
|
|
Those references must belong to that same lane and must still be
|
|
unresolved rather than pointing at unrelated governance objects or
|
|
already-passed assertions, gates, or completed targets.
|
|
Bounded residual tracking must use a lane followup, readiness assertion,
|
|
release gate, or open decision rather than a broad target reference.
|
|
`lane_followups` are active residual records, not a loose backlog: each one
|
|
should stay referenced by the owning lane's `bounded-residual`
|
|
`completion.tracking`.
|
|
Once a lane followup is no longer active residual work, remove it from
|
|
`lane_followups` instead of leaving it behind with a completed status.
|
|
19. Do not treat a lane as healthy just because it has local fixes on a legacy path.
|
|
If the canonical v6 route for that surface now runs through unified
|
|
resources, canonical shared types, explicit subsystem ownership, or a
|
|
modernized proof path, the lane is still below floor until that migration
|
|
is made or the remaining gap is governed explicitly.
|
|
20. Do not treat missing evidence count or a score delta as the task itself.
|
|
If the real remaining gap is runtime, product, ownership, or behavior
|
|
coherence, fix that gap and let the score/evidence catch up as proof.
|
|
Only treat evidence-count closure itself as the task when the remaining
|
|
gap is explicitly governance-only.
|
|
21. Do not run parallel mutating agents out of one dirty checkout and call
|
|
that acceptable coordination.
|
|
Claims reduce overlap, but they do not isolate hooks, formatters, staged
|
|
reads, or unrelated dirt. Parallel mutation should use separate worktrees
|
|
so each agent sees one slice's git state at a time.
|
|
|
|
## Locked Decisions
|
|
|
|
1. Release-control execution is direct and repo-aware. The old orchestrator and
|
|
loop tooling are retired.
|
|
2. v6 GA is gated by `L1`, `L2`, `L3`, `L5`, `L6`, `L7`, `L8`, `L9`, `L10`,
|
|
`L11`, and `L12`. `L4` remains post-GA track work and is not a GA floor
|
|
gate.
|
|
3. Trial authority for v6 is SaaS-controlled.
|
|
`POST /api/license/trial/start` must initiate hosted signup only by
|
|
returning `409 trial_signup_required` while the hosted-signup retry burst
|
|
remains open, then `429 trial_rate_limited` plus `Retry-After` backoff once
|
|
that limiter engages; the local runtime may redeem signed trial activations
|
|
but must not mint local trial state directly.
|
|
4. v5 to v6 commercial migration must preserve unresolved paid-license state
|
|
and downgrade safety.
|
|
5. Cloud and MSP Stripe `price_*` IDs are operational fill-in items, not
|
|
architectural blockers.
|
|
6. Stable or GA promotion for v6 must come from an exercised RC and stay
|
|
blocked until the RC-to-GA promotion gate is cleared and the published v5
|
|
maintenance-policy notice is ready.
|
|
7. v6 and later releases use a promotion model, not a direct broad-rollout
|
|
model.
|
|
`stable` must receive only promoted, already-validated builds, `rc` is the
|
|
opt-in preview channel, and unattended auto-update exposure remains
|
|
`stable`-only unless a new channel policy is explicitly adopted.
|
|
8. Once v6 reaches stable or GA, v5 enters a 90-day maintenance-only window:
|
|
critical security issues, critical correctness/data-loss issues, and safe
|
|
migration blockers only. The exact end-of-support date must be published in
|
|
the GA release notice. After that window, v5 is unsupported.
|
|
9. Paid Pulse Pro v5 customers keep their existing recurring price through the
|
|
v6 pricing change until they cancel. Renewal and entitlement continuity
|
|
must preserve that grandfathered price state; any return after cancellation
|
|
must use current v6 pricing.
|
|
10. Pulse Mobile does not need desktop parity to stop blocking the v6 prerelease line.
|
|
The mobile usefulness floor for prerelease is narrower: preserve at least one
|
|
trusted paired instance across relaunches, expose relay/runtime state
|
|
clearly in the main shell, fail closed into a recoverable disconnected
|
|
state on stale or revoked access, and keep live approvals useful and
|
|
recoverable. Broader parity and expansion remain post-prerelease scope.
|
|
11. The minimum required update set for canonical work is a floor, not a lane
|
|
closure rule. Agents should push the current lane to a coherent,
|
|
defensible stop point and complete the next obvious same-lane work when it
|
|
is necessary for trustworthy results, then normalize any remaining valid
|
|
gap instead of calling the lane done by default.
|
|
12. Unified-resource change history is the canonical durable backend timeline.
|
|
Alert incident memory may retain investigation-local notes, analysis,
|
|
commands, runbooks, and alert lifecycle breadcrumbs, but it must remain a
|
|
derived incident projection rather than a competing source of truth for
|
|
durable resource history.
|
|
|
|
## TrueNAS Support Floor
|
|
|
|
Pulse v6 uses one governed definition of "TrueNAS supported" at the current
|
|
floor. Detailed proof routes live in `status.json.readiness_assertions` and the
|
|
owning subsystem contracts; user-facing claims must not exceed this floor.
|
|
Unless a concrete defect appears or governance explicitly widens the support
|
|
claim, broad same-shape TrueNAS iteration is not default work above this
|
|
declared floor.
|
|
|
|
1. Architecture boundary:
|
|
TrueNAS is API-first. The unified agent may augment a TrueNAS system later,
|
|
but it is not required for bootstrap or baseline support. TrueNAS must
|
|
project into the canonical `agent`, `app-container`, `storage`,
|
|
`physical-disk`, and recovery contracts instead of reopening a parallel
|
|
TrueNAS product model.
|
|
2. Onboarding path:
|
|
Supported now through the shared platform-connections flow and
|
|
`/api/truenas/connections`. Operators can add, test, edit, retest, and
|
|
delete stored TrueNAS connections without re-entering masked secrets on
|
|
ordinary edits. `truenas_disabled` is only an explicit server opt-out, not
|
|
the baseline state. Out of scope for this floor: a separate TrueNAS-first
|
|
wizard, agent-required bootstrap, or disabled-by-default launch posture.
|
|
3. Infrastructure visibility:
|
|
Supported now as one canonical top-level system in connected infrastructure
|
|
plus shared host telemetry/history when the API can supply it. The expected
|
|
user outcome is that a connected TrueNAS appliance shows up as
|
|
infrastructure, keeps platform-connection poll health, and remains a
|
|
TrueNAS platform even when host telemetry is ignored. Out of scope: a
|
|
separate `truenas-system` surface or provider-local infrastructure model.
|
|
4. Workloads:
|
|
Supported now for TrueNAS apps projected as canonical `app-container`
|
|
workloads with shared workload navigation, metrics, and related links. Out
|
|
of scope: a separate TrueNAS app runtime model or provider-local workload
|
|
page/control surface.
|
|
5. Storage and disk health:
|
|
Supported now for pools, datasets, and physical disks projected into the
|
|
shared storage and disk contracts, including SMART/disk-state risk, live
|
|
temperature, and recent temperature aggregates when the provider supplies
|
|
them. Out of scope: promising deeper TrueNAS-only topology or admin actions
|
|
beyond the current shared storage-health floor.
|
|
6. Recovery:
|
|
Supported now as read-side visibility for TrueNAS snapshots and replication
|
|
artifacts in the shared recovery model, filters, rollups, and cross-surface
|
|
handoffs. Out of scope: treating recovery as its own TrueNAS onboarding
|
|
flow or promising provider-native restore/control actions that do not yet
|
|
exist on the governed shared path.
|
|
7. Alerts:
|
|
Supported now when TrueNAS systems, disks, and app parents participate in
|
|
the shared alert thresholds, incidents, and related-resource handoffs into
|
|
infrastructure, workloads, storage, and recovery. Out of scope: a separate
|
|
TrueNAS-only alert product surface.
|
|
8. Assistant read/control:
|
|
Supported now for canonical read-side resource access plus bounded app
|
|
control. Assistant may read TrueNAS app logs via `pulse_read`, read app
|
|
config via `pulse_query action="config"`, and issue native app
|
|
start/stop/restart through `pulse_control` on canonical `app-container`
|
|
resources. Out of scope: a blanket TrueNAS admin plane, provider-local AI
|
|
tools, host command execution without the unified agent, or broader action
|
|
promises ahead of the existing action-governance coverage gap.
|
|
|
|
## VMware vSphere Admission Model
|
|
|
|
Pulse v6 now has one locked, active strategic direction for VMware vSphere
|
|
under the governed platform-admission model.
|
|
VMware is the current admitted next-platform direction for Pulse, but it is
|
|
not yet a supported platform claim. This section defines the only acceptable
|
|
phase-1 floor while support remains proof-gated.
|
|
|
|
Pulse also now distinguishes an admitted platform that is merely
|
|
`architecture-locked` from one that is `first-lab-ready`: `first-lab-ready`
|
|
means the bounded non-live phase floor is implemented and regression-proofed
|
|
well enough that the next proper move is a real lab run, while the support
|
|
claim stays blocked until live proof passes.
|
|
|
|
1. Architecture boundary:
|
|
VMware vSphere should enter Pulse only as the first-class
|
|
`vmware-vsphere` platform. Phase 1 is `vCenter` only; direct `ESXi` is
|
|
deferred work and must not inherit support by implication.
|
|
2. Ingestion model:
|
|
VMware should be API-first. The baseline path is the official vCenter
|
|
Automation API plus the Virtual Infrastructure JSON API. A Pulse-managed
|
|
agent may augment a VMware environment later, but it is not part of the
|
|
bootstrap or baseline support contract.
|
|
3. Canonical resource projections:
|
|
ESXi hosts must project as canonical `agent`, guest workloads as canonical
|
|
`vm`, and datastores as canonical `storage`. vCenter, datacenter, cluster,
|
|
folder, and resource-pool objects remain topology or relationship metadata,
|
|
not top-level Pulse resource types. Out of scope for phase 1: provider-local
|
|
`esxi-host` or `vsphere-vm` types plus `physical-disk`, `system-container`,
|
|
or `app-container` projections.
|
|
4. Visibility, workloads, and storage:
|
|
The phase-1 floor is read-first infrastructure support through shared Pulse
|
|
surfaces: host inventory, VM inventory/runtime/guest identity when the API
|
|
exposes it, snapshot-tree visibility, datastore capacity/accessibility, and
|
|
metrics/alarm context routed onto the shared resource model.
|
|
5. Recovery:
|
|
vSphere snapshots and changed-disk visibility are useful read-side signals,
|
|
but they do not make VMware a recovery-supported platform in Pulse by
|
|
themselves. Until shared recovery artifacts and restore flows exist on the
|
|
governed path, VMware recovery stays out of the support claim.
|
|
6. Alerts:
|
|
The phase-1 floor may include vSphere alarm state, overall health state,
|
|
and related event/task history when those signals are projected through the
|
|
shared alerts, incidents, and resource-timeline contracts instead of a
|
|
provider-local incident surface.
|
|
7. Assistant read/control:
|
|
Assistant read may be supported on those canonical resources once the
|
|
shared read paths land. Assistant control stays read-only in phase 1 even
|
|
though VMware exposes power, snapshot, and guest-operation APIs, because
|
|
Pulse is not yet claiming a broad VMware action plane ahead of the existing
|
|
action-governance coverage gap.
|
|
8. Current implementation checkpoint:
|
|
VMware may be described internally as `first-lab-ready` once the shared
|
|
phase-1 onboarding, projection, alert/history, and Assistant-read floor is
|
|
implemented with automated non-live proof. `first-lab-ready` is an
|
|
implementation milestone only; it does not change the support matrix or any
|
|
user-facing support wording.
|
|
9. Support gate:
|
|
Do not call VMware supported until one real `vCenter` capability is
|
|
recorded in `LOCAL_CAPABILITIES.md` and proves connection onboarding, the
|
|
minimum privilege bundle, the supported version floor, canonical
|
|
`agent`/`vm`/`storage` projection, alert and metrics-history truth, and
|
|
assistant read behavior. If those proofs do not hold, implementation
|
|
should stop at governance rather than shipping an inflated support claim.
|
|
10. Execution sequence:
|
|
VMware phase-1 execution should follow
|
|
`docs/release-control/v6/internal/VMWARE_VSPHERE_PHASE1_EXECUTION_PLAN.md`
|
|
as the concrete slice order and stop/go contract for the first admitted
|
|
VMware support floor.
|
|
11. Projection contract:
|
|
VMware phase-1 projection should also follow
|
|
`docs/release-control/v6/internal/VMWARE_VCENTER_PHASE1_RESOURCE_PROJECTION_SPEC.md`
|
|
as the canonical source, identity, topology, alert-mapping, and
|
|
non-projection boundary for phase-1 VMware resources.
|
|
12. Alerts and Assistant contract:
|
|
VMware phase-1 alerts and Assistant work should also follow
|
|
`docs/release-control/v6/internal/VMWARE_VCENTER_PHASE1_ALERTS_AND_ASSISTANT_SPEC.md`
|
|
as the canonical shared-alert, shared-timeline, Assistant-read, and
|
|
Assistant-control-exclusion boundary for the VMware phase-1 floor.
|
|
13. Backend API/runtime contract:
|
|
VMware phase-1 backend API/runtime work should also follow
|
|
`docs/release-control/v6/internal/VMWARE_VCENTER_PHASE1_API_RUNTIME_SPEC.md`
|
|
as the canonical public API-boundary, session-ownership, provider-health,
|
|
and negative-space contract for the VMware phase-1 floor.
|
|
|
|
## Cross-Repo Contracts
|
|
|
|
These contracts must not drift:
|
|
|
|
1. Licensing contract:
|
|
`pulse/pkg/licensing` semantics vs license-server plans and gates.
|
|
2. Relay grant contract:
|
|
license-server issued grants vs relay-server acceptance.
|
|
3. Relay protocol contract:
|
|
`pulse/internal/relay`, `pulse-pro/relay-server`, and
|
|
`pulse-mobile/src/relay` wire compatibility.
|
|
4. Pricing contract:
|
|
architecture pricing docs vs Stripe and checkout wiring in `pulse-pro`.
|
|
|
|
## Development Governance
|
|
|
|
For canonical subsystem work:
|
|
|
|
1. Read `docs/release-control/CONTROL_PLANE.md`,
|
|
`docs/release-control/AGENT_VALUES.md`,
|
|
`docs/release-control/control_plane.json`, this file, and
|
|
`docs/release-control/v6/internal/status.json` first.
|
|
Use `python3 scripts/release_control/control_plane.py --agent-entrypoint --pretty`
|
|
when you need the canonical ordered entry bundle instead of reconstructing
|
|
it manually.
|
|
If the agent starts outside the `pulse` repo, resolve those files from
|
|
`pulse/docs/release-control/v6/` under the shared workspace root rather than
|
|
inventing a parallel control layer in the current repo.
|
|
2. Then read `docs/release-control/v6/internal/CANONICAL_DEVELOPMENT_PROTOCOL.md`.
|
|
3. Then read `docs/release-control/v6/internal/subsystems/registry.json`.
|
|
4. Then read the relevant subsystem contract under
|
|
`docs/release-control/v6/internal/subsystems/`.
|
|
5. Update `status.json` when live lane state, readiness derivation rules,
|
|
lane completion records, coverage-gap records, candidate-lane planning
|
|
records, assertion proof routes, evidence references, or typed operational
|
|
decision records change.
|
|
6. Update this file only when stable governance, scope, locked decisions, or
|
|
the readiness-assertion design rules change.
|
|
7. When a canonical path replaces an old path, add or tighten a guardrail so
|
|
the old path cannot silently return.
|
|
8. When the active target's machine-derived completion rule is satisfied,
|
|
update `docs/release-control/control_plane.json` in the same task or stop
|
|
and promote the next target before continuing under stale scope.
|
|
9. When the user changes Pulse's priority or says what the product should focus
|
|
on next, classify that as an active-target update or another control-plane
|
|
change instead of leaving it as informal discussion.
|
|
10. Do not wait for a special governance prompt.
|
|
If the user casually says something should be consistent, seamless,
|
|
difficult to bypass, free of drift, or always true, decide whether it
|
|
belongs in a readiness assertion, release gate, open decision, or active
|
|
target before ending the task.
|
|
11. Do not stop at the first narrow success inside a lane.
|
|
When the next obvious same-lane work is still required for a coherent and
|
|
trustworthy result, complete it in the same slice when feasible.
|
|
12. Keep that standard bounded.
|
|
If the remaining work clearly belongs to another lane, another active
|
|
target, a larger redesign, or a separately governed open decision, record
|
|
that state explicitly instead of expanding the current slice without end.
|
|
13. If the current lane map no longer models a durable product surface cleanly,
|
|
record that discovery in `status.json.coverage_gaps` with evidence and an
|
|
intended promotion path instead of burying it in generic residual text.
|
|
14. Treat lane completion, lane coverage, and coverage planning as separate
|
|
derived signals.
|
|
`status_audit.py --pretty` may derive a lane-completion score from
|
|
`current_score/target_score`, a lane-coverage score from unresolved
|
|
`coverage_gaps`, a coverage-planning score from unresolved
|
|
`coverage_gaps` that still lack explicit `candidate_lanes`, and a
|
|
conservative governed-surface score as the lower of completion and
|
|
coverage.
|
|
Those scores are decision aids, not proof that unknown work does not
|
|
exist.
|
|
15. Treat active work claiming as its own live control surface.
|
|
`status.json.work_claims` should hold only live lease-style claims, not a
|
|
historical log, and `status_audit.py --pretty` should make active claims,
|
|
expired claims, claim conflicts, and the `available_candidate_lane_queue`
|
|
visible enough that agents can avoid overlapping picks.
|
|
Use `scripts/release_control/work_claim.py` as the default reservation
|
|
path rather than hand-editing claim objects when the system can reserve
|
|
the slice directly.
|
|
16. Keep prompt-like guidance values-led.
|
|
If a rule needs detailed repeated reminder, prefer strengthening the
|
|
control plane, active profile, subsystem contracts, audits, or guardrails
|
|
over expanding prompt prose into a second operating manual.
|
|
17. Keep governance routing quiet by default.
|
|
Resolving the canonical entry bundle, choosing the owning lane, and
|
|
deciding whether a claim or governance update is required should usually
|
|
happen in the background. Surface those mechanics only when they
|
|
materially change blockers, scope, cross-repo impact, or the user's next
|
|
decision.
|
|
|
|
For readiness assertion work:
|
|
|
|
1. Update this file only when the readiness-assertion design rules change.
|
|
2. Update `status.json.readiness_assertions` when the active assertion catalog
|
|
or proof references/proof commands change.
|
|
3. Route manual assertion proof through
|
|
`HIGH_RISK_RELEASE_VERIFICATION_MATRIX.md` whenever the assertion needs a
|
|
trust-critical release gate instead of a one-off checklist.
|
|
|
|
## Source Domains
|
|
|
|
If conflicts appear, resolve by domain:
|
|
|
|
1. `docs/release-control/v6/internal/CANONICAL_DEVELOPMENT_PROTOCOL.md`,
|
|
`docs/release-control/v6/internal/subsystems/registry.json`, and the relevant
|
|
subsystem contract own implementation rules.
|
|
2. `docs/release-control/v6/internal/status.json` owns live lane state, the active
|
|
readiness assertion catalog, readiness derivation rules, executable proof
|
|
commands, coverage-gap discovery records, candidate-lane planning records,
|
|
structured evidence references, and typed operational decision records.
|
|
3. `docs/release-control/v6/status.schema.json` owns the machine-readable shape
|
|
contract for `status.json`.
|
|
4. `docs/release-control/v6/internal/subsystems/registry.schema.json` owns the
|
|
machine-readable shape contract for the subsystem registry.
|
|
5. `docs/release-control/AGENT_VALUES.md` owns evergreen agent values, while
|
|
`docs/release-control/CONTROL_PLANE.md` and
|
|
`docs/release-control/control_plane.json` own evergreen governance, active
|
|
profile selection, and active target selection.
|
|
6. This file owns profile-specific governance, repo scope, release gates,
|
|
readiness assertion design rules, and locked decisions for v6.
|
|
7. Supporting architecture and release docs are evidence only. They do not
|
|
override the files above.
|