mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-11 22:12:23 +00:00
Align source of truth with RC stabilization
This commit is contained in:
@@ -0,0 +1,522 @@
|
||||
# Pulse v6 Source Of Truth
|
||||
|
||||
Last updated: 2026-03-17
|
||||
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/status.json`.
|
||||
Lane completion state, residual-gap summaries, normalized follow-up tracking,
|
||||
and derived coverage scores also live only in
|
||||
`docs/release-control/v6/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/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/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/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/RELEASE_PROMOTION_POLICY.md`
|
||||
Canonical stable-versus-RC promotion rules, rollout criteria, and rollback
|
||||
expectations for v6 and later release lines.
|
||||
12. `docs/release-control/v6/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/RC_TO_GA_REHEARSAL_TEMPLATE.md`
|
||||
Canonical human record shape for the non-publish RC-to-GA rehearsal run.
|
||||
|
||||
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`
|
||||
|
||||
## 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 RC validation, not as the first
|
||||
customer exposure.
|
||||
|
||||
Pulse v6 has a bridge-release direction, but the current stabilization target
|
||||
stays on the monitoring-and-alerting RC floor rather than the finished private
|
||||
operational broker.
|
||||
For this profile, "bridge release" means the product should stop reading as a
|
||||
monitoring product growing sideways only where the surfaced case is already
|
||||
proven; the broader resource-centric, policy-aware, action-ready control
|
||||
platform remains a future lane.
|
||||
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.
|
||||
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.
|
||||
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. Otherwise,
|
||||
treat continuing investment in that old internal path as drift, not
|
||||
prudence.
|
||||
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 RC, 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. 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.
|
||||
18. 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.
|
||||
19. 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.
|
||||
20. 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; 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 RC line.
|
||||
The mobile usefulness floor for RC 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-RC 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.
|
||||
|
||||
## 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/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/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/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/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.
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
# RC-to-GA Promotion Readiness Blocked Record
|
||||
|
||||
- Date: `2026-03-13`
|
||||
- Gate: `rc-to-ga-promotion-readiness`
|
||||
- Result: `blocked`
|
||||
|
||||
## Blocking Facts
|
||||
|
||||
1. No Pulse v6 RC has shipped yet.
|
||||
2. The repository contains accidental prerelease git tag history (`v6.0.0-rc.1`),
|
||||
but those tags were never published and do not count as shipped RC lineage.
|
||||
3. GitHub still validates `Release Dry Run` workflow dispatch inputs against the
|
||||
default branch `main`, whose current workflow contract does not
|
||||
accept the governed stable rehearsal metadata envelope (`promoted_from_tag`,
|
||||
`rollback_version`, `ga_date`, and `v5_eos_date`).
|
||||
4. The governed release profile in `docs/release-control/control_plane.json`
|
||||
currently declares both `prerelease_branch` and `stable_branch` as
|
||||
`pulse/v6-release`.
|
||||
5. The active control-plane target is still `v6-rc-stabilization`, not
|
||||
`v6-ga-promotion`.
|
||||
6. The active local `pulse/v6-release` branch currently reports `VERSION=6.0.0-rc.1`, so the
|
||||
working line is still prerelease and there is not yet a governed local stable
|
||||
`6.0.0` candidate.
|
||||
7. There is still no governed `RC-to-GA Rehearsal Record` proving a successful
|
||||
non-publish `Release Dry Run` for the eventual stable `6.0.0` candidate.
|
||||
8. `docs/releases/RELEASE_NOTES_v6.md` and
|
||||
`docs/release-control/v6/V5_MAINTENANCE_SUPPORT_POLICY.md` now carry the
|
||||
currently proposed exact dates for the eventual GA notice:
|
||||
- `v6` GA date: `2026-03-24`
|
||||
- `v5` end-of-support date: `2026-06-22`
|
||||
9. There is still no governed `Release Dry Run` artifact or rehearsal record
|
||||
exercising stable inputs for:
|
||||
- `version=6.0.0`
|
||||
- no governed `promoted_from_tag` exists yet because no RC has shipped
|
||||
- the artifact-owned candidate stable tag for that rehearsal
|
||||
- the artifact-owned promotion channel for that rehearsal
|
||||
- the artifact-owned promoted RC tag for that rehearsal
|
||||
- the artifact-owned rollback target for that stable candidate
|
||||
- `ga_date=2026-03-24`
|
||||
- an explicit `rollback_version`
|
||||
- the exact derived rollback command that artifact will publish
|
||||
- `v5_eos_date=2026-06-22`
|
||||
|
||||
## Why The Gate Cannot Be Cleared Yet
|
||||
|
||||
The blocker is no longer missing governance text. The remaining problem is that
|
||||
the control plane still treats v6 as an RC-stabilization line, the working
|
||||
version is still prerelease (`6.0.0-rc.1`), and there is still no exercised
|
||||
`Release Dry Run` record proving the eventual stable `6.0.0`
|
||||
candidate is ready for GA-style promotion. Until that rehearsal exists, stable
|
||||
users would still be the first real cohort for the final promotion path.
|
||||
|
||||
## Required Unblock Steps
|
||||
|
||||
1. Promote the active target from `v6-rc-stabilization` to
|
||||
`v6-ga-promotion` only when that change is actually intended.
|
||||
2. Push the governed `pulse/v6-release` branch state that is intended to become the
|
||||
stable `6.0.0` candidate, including the eventual `VERSION=6.0.0`
|
||||
change and release-control records, to `origin/pulse/v6-release`.
|
||||
3. Land the canonical `.github/workflows/release-dry-run.yml` workflow-dispatch input
|
||||
contract on the default branch `main` so GitHub accepts the
|
||||
governed stable rehearsal metadata envelope when dispatching from `pulse/v6-release`.
|
||||
4. Ship the first real RC through the governed prerelease release path and record
|
||||
its exact published prerelease tag plus rollback target and exact derived
|
||||
rollback command.
|
||||
5. Run `Release Dry Run` from `pulse/v6-release` using that published RC as
|
||||
`promoted_from_tag` with:
|
||||
- `version=6.0.0`
|
||||
- an artifact-owned candidate stable tag matching that rehearsal
|
||||
- an artifact-owned promotion channel matching that rehearsal
|
||||
- an artifact-owned promoted RC tag matching that rehearsal
|
||||
- an artifact-owned rollback target for the stable candidate
|
||||
- the exact planned GA and v5 end-of-support dates for the publish notice
|
||||
- `ga_date=2026-03-24`
|
||||
- an explicit stable `rollback_version`
|
||||
- the exact derived rollback command that artifact will publish
|
||||
- `v5_eos_date=2026-06-22`
|
||||
6. Capture the `rc-to-ga-rehearsal-summary` artifact and run URL.
|
||||
7. Materialize the final rehearsal record from that artifact without
|
||||
hand-repairing any missing candidate tag, promoted RC tag, rollback
|
||||
target, rollback command, or GA/EOS metadata.
|
||||
8. Change the gate from `blocked` only if the rehearsal passes and the rollout
|
||||
inputs remain explicit.
|
||||
Reference in New Issue
Block a user