Skip to content

docs: FEAT-588 record the arriving breath as a gate, not a diminished practice - #483

Merged
MP2EZ merged 1 commit into
developmentfrom
feat/FEAT-588-arriving-breath-gate-vocabulary-ruling
Sep 10, 2026
Merged

docs: FEAT-588 record the arriving breath as a gate, not a diminished practice#483
MP2EZ merged 1 commit into
developmentfrom
feat/FEAT-588-arriving-breath-gate-vocabulary-ruling

Conversation

@MP2EZ

@MP2EZ MP2EZ commented Sep 10, 2026

Copy link
Copy Markdown
Owner

Closes FEAT-588

The deliverable is a ruling, not a change

FEAT-588 asked whether the Daily Loop's arriving breath presents itself as a practice when its job is to be a gate. philosopher and ux ruled independently and reached the same verdict: no change. The beat is a gate wearing session chrome, and its differences from the standalone practices are intent.

So what merges is the record. Nothing about the app's behaviour changes.

Why the ruling went that way

Five differences are the load-bearing evidence, all verified in source:

  1. It starts itself. isBreathActive initialises to showBreath, where all three standalone practices gate on PracticeToggleButton's Begin β†’ Pause β†’ Resume. The absence of a Begin button is the gate β€” you do not enter a threshold, you are already in it.
  2. It carries no name while it runs. The title is an instruction ("Take a moment to arrive"); the principle name appears only once you are through.
  3. It ends in the next beat. breathCompleted flips and the same ScrollView re-renders β€” no completion screen, no quote, no Continue. A practice in this app always ends in a bounded artefact.
  4. No session haptics, because the opt-in promises eyes-closed practice and this beat is eyes-open by construction (FEAT-565's recorded ruling).
  5. It is not in STANDALONE_PRACTICES β€” a doorway, not a room.

One premise of the report is inverted

The strongest item on the "borrowed practice vocabulary" list turns out to point the other way. Timer's built-in Pause/Resume is not borrowed β€” it is orphan vocabulary. All three standalone practices pass showControls={false} ("using custom button below"); the only two live sites rendering Timer's own transport are this beat and DailyLoopCompleteScreen's coda. The practices refused this control. The beat is not a stripped-down practice; it is the raw Timer default, and the loop's two breaths share one internally consistent idiom.

Deliberately not changed

All considered, none owed by the ruling: dropping showControls (a real improvement both lenses liked, but it needs an accessibility sign-off on WCAG 2.2.2 β€” auto-starting motion over 5s β€” and it intersects DEBUG-468's ruling that Pause is this beat's stay-with-it affordance); showProgress; and 30000 β†’ 32000 ms for four clean cycles, which is a refinement rather than a defect, would invalidate three shipped rationales written around 3.75 cycles, and would leave the coda's 15000 ms (1.875 cycles) inconsistent unless carried too.

Where the record lives, and why the style matters

The in-code half is a * -prefixed block in DailyLoopStepScreen's module header, plus a // anchor beside breathCompleted. That is deliberate and it is the difference between this PR costing nothing and costing a simulator gate.

practices/dailyloop/ is a Protected Path, so Phase 2.5's inert filter is what decides. It strips //, /**, * and */ β€” but not a JSX {/* … */} block, whose opener is {/* and whose body lines carry no *. FEAT-565's own record-only commit (7bba8f4c, +19/βˆ’0, pure prose) is written that way and left 17 surviving lines, so it paid a full gate run for a comment. Replaying the same filter over this diff gives 0 surviving lines in the .tsx; the docs bullet is outside app/, so it never enters the candidate set at all.

Verified, not assumed β€” the filter was run against both commits.

The crisis pass changed the record

crisis is required for any dailyloop/ diff, comment-only included β€” the inert filter exempts the Maestro half, never the agent half. It returned NEEDS_EDIT and all three corrections are applied:

  • The record said "no session haptics". That is a term of art in this codebase naming only the sessionStart/sessionEnd anchors, but FEAT-565 declined the whole hook, both channels β€” so as written a reader could take scheduled breath cues to be open. Crisis-adjacent, not stylistic: wiring any haptic channel onto this beat would import DEBUG-587's recorded-and-unfixed 1–3 frame blur residual onto a surface that currently has none.
  • The case against 30000 β†’ 32000 ms listed only content and consistency rationales, so a reader who satisfied all of them would reasonably conclude the constant was theirs to move. BREATH_DURATION_MS is load-bearing in a crisis ruling: tenseMode.ts re-hosted quick depth's SUPPORT_LINE onto Sphere Sovereignty precisely because Aware Presence's reflection phase sits behind this 30s gate, and crisis review rejected the alternative as making quick's crisis affordance strictly less available than deep's. The header now says so.
  • The docs bullet took the same correction so the two records cannot drift.

Both would have propagated silently β€” through a record written specifically to be quoted back at future readers. Confirmed independently: Aware Presence carries SUPPORT_LINE in no (depth, mode) combination, and the root FAB is live throughout the breath (DailyLoop is in IMMERSIVE_ROUTES, not SUPPRESSED_ROUTES), so the gate delays no 988 affordance.

philosopher ruled during planning.

Checks

Typecheck, lint baseline, 179 dailyloop tests, test:accessibility 456, test:integration 162 β€” all green. No executable line changed.

πŸ€– Generated with Claude Code

https://claude.ai/code/session_01CkZagJp7dzojvrjY7uYwkh

… practice

The deliverable is a ruling, not a change. `philosopher` and `ux` ruled
independently and reached the same verdict: the Daily Loop's Aware Presence beat
is a gate wearing session chrome, and its differences from the standalone
practices are intent. No behaviour changes.

Five differences carry the ruling, all verified in source: the beat starts itself
(no Begin β€” all three standalone practices gate on PracticeToggleButton, and the
absence of that button IS the gate); it carries no name while it runs; it ends in
the next beat rather than a completion screen; it has no haptics at all, because
the opt-in promises eyes-closed practice and this beat is eyes-open by
construction; and it is absent from STANDALONE_PRACTICES.

One premise of the tester report is inverted, and it is the strongest item on its
list. Timer's built-in Pause/Resume is not borrowed practice vocabulary β€” it is
ORPHAN vocabulary. All three standalone practices pass `showControls={false}`
("using custom button below"); the only two live sites rendering Timer's own
transport are this beat and the closing coda. The practices refused this control.

Declined, all considered: dropping `showControls` (needs an accessibility
sign-off on WCAG 2.2.2 and intersects DEBUG-468's ruling that Pause is this
beat's stay-with-it affordance), `showProgress`, and 30000 -> 32000 ms.

Comment STYLE is what makes this free rather than a ~21-minute simulator gate.
`practices/dailyloop/` is a Protected Path, and Phase 2.5's inert filter strips
`//`, `/**`, `* ` and `*/` but not a JSX `{/* */}` block. FEAT-565's own
record-only commit 7bba8f4 is written that way and left 17 surviving lines, so
it paid a full gate run for a comment. Replaying the same filter over this diff
gives zero surviving lines in the .tsx; the docs bullet is outside app/ and never
enters the candidate set. Verified against both commits, not assumed.

`crisis` reviewed the recorded text (required for any dailyloop diff β€” the inert
filter exempts the Maestro half, never the agent half) and required three
corrections, all applied: the record said "no session haptics", which is a term
of art naming only the anchors and would have left scheduled breath cues reading
as open when FEAT-565 declined the whole hook; and the case against the duration
change listed only content rationales, when BREATH_DURATION_MS is load-bearing in
tenseMode.ts's crisis ruling that re-hosted quick's SUPPORT_LINE onto Sphere
Sovereignty. Both would have propagated silently through a record written to be
quoted back.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CkZagJp7dzojvrjY7uYwkh
@MP2EZ
MP2EZ merged commit e4e2273 into development Sep 10, 2026
11 checks passed
@MP2EZ
MP2EZ deleted the feat/FEAT-588-arriving-breath-gate-vocabulary-ruling branch September 10, 2026 05:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant