Releases: Phinetwork/phi.network
v30.0.0
ΦNet Sovereign Gate — v30.0.0 Release Notes
Codename: Full Determinism / Genesis-Locked μpulse Anchor
Scope: App shell refactor + deterministic time hardening + PWA warmup/perf
🔥 Headline Changes (What’s Actually New)
✅ 1) Genesis seed is now canonical across devices (wall-clock independent)
This release removes “0-based” or “device-time-based” boot behavior and replaces it with a Genesis-anchored μpulse coordinate that is:
-
Derived from the canonical Genesis bridge (
GENESIS_TS + pulses * PULSE_MS) -
Stored as μpulses since Genesis under a single stable key:
phi_kai_anchor_pmicro_v1
-
Re-sealed on lifecycle boundaries (boot, visibility return, focus) so the app never “drifts into fake time”
-
Persisted on a fixed cadence (every 15s + pagehide/visibilitychange)
Result: the pulse coordinate is deterministic and consistent across machines even if their wall clocks are wrong, because the app’s “now” is enforced as Kai μpulse state, not Chronos sampling.
🧠 Deterministic Engine Hardening (μpulse-first)
✅ 2) μpulse is now the canonical internal clock format
New canonical internal invariant:
-
Everything runs off
pμ(BigInt μpulses since Genesis) -
UI timestamps (epoch-ms, ISO, etc.) are derived, never sourced:
epochMs = GENESIS_TS + (pμ / 1e6) * PULSE_MS
✅ 3) Added normalization layer so “kairosEpochNow” can’t poison determinism
A major failure mode in hybrid systems is when a “now” provider changes units (μpulses vs ms vs seconds) and silently corrupts downstream math.
v30 introduces a strict normalization gate:
- If the raw value looks like a plausible μpulse range → accept as μpulses.
- If it looks like an epoch-ish number → convert to μpulses via the Genesis bridge.
- If it’s unsafe to convert → refuse to pretend, pass through without corrupting state.
This is what makes the system resilient across builds, environments, and future refactors.
✅ 4) Banker's rounding (ties-to-even) for all Number→BigInt bridges
Any time you must cross the float boundary (ms → pulses → μpulses), v30 enforces:
- ties-to-even rounding
- no float accumulation
- no “random rounding bias over time”
This eliminates long-run systematic skew from conversion jitter.
⏱ Live Kai Clock: Boundary-Exact, Low Re-render
✅ 5) Live ticker now schedules on true pulse boundaries
Instead of “update every N ms”, the ticker computes:
into = pμ % 1_000_000remainMicro = 1_000_000 - intodelayMs = (remainMicro / 1e6) * PULSE_MS
So updates happen exactly at the next φ pulse boundary, not “close enough.”
✅ 6) Memoized LiveKaiButton + render-diff guard
The live clock no longer causes the app to churn. Updates are filtered:
- if
pulseStr,beatStepLabel, anddmyLabelhaven’t changed → no state update - Live UI is isolated + memoized to keep deterministic ticking without repaint storms
🧮 KKS v1.0 Display Math (Beat/Step/DMY) Stabilized
✅ 7) Deterministic Beat/Step/Day math is clamped and integer-stable
computeBeatStepDMY() now enforces:
- strict bounds for beat (0–35) and step (0–43)
- robust day index selection (uses
dayIndex/dayIndex0/dayIndexSinceGenesisif present) - safe fallback
floor((pulse + eps)/PULSES_PER_DAY)to avoid boundary wobble
Net: no negative wrap bugs, no out-of-range UI, no boundary flicker.
🧱 App Shell Refactor (Performance + Modularity)
✅ 8) Centralized shell constants + behavior isolated into focused helpers
v30 turns App.tsx from a monolith into a deterministic shell with clean modules:
- central route lists (
SHELL_ROUTES_TO_WARM,SIGIL_STREAM_ROUTES) - deterministic title routing (
pageTitleFromPath) - panel lock rules (
lockPanelForPath) - viewport sizing + layout gates
- stable navigation metadata (
NAV_ITEMSreused, no regeneration churn)
⚡ Lazy Loading + “No Splash” Enforcement
✅ 9) Instant first paint preserved with empty Suspense fallbacks
Heavy modules remain lazy-loaded without a splash screen regression:
KaiVohModal,SigilModal,HomePriceChartCard,SigilExplorer,EternalKlock- fallbacks are empty (
null) or invisible height placeholders (chart)
✅ 10) Splash killer runs twice (module eval + layout)
To guarantee “zero splash” even under weird PWA restore behavior:
- kill splash immediately at module eval
- kill again via isomorphic layout effect on route changes
🛰 Service Worker Warm-Up (Offline-First, Battery-Sane)
✅ 11) SW cache warmup is now controlled, gated, and targeted
New behavior:
-
sends
WARM_URLSmessage to active/waiting/installing worker -
warms both offline artifacts + shell routes
-
auto-disables warmup on:
saveDatamodeslow-2g / 2g
Also re-warms on focus (debounced), improving “return to app” speed without hammering low-end connections.
📱 Mobile / iOS Hardening
✅ 12) VisualViewport publisher is RAF-throttled and shared
- one global store
- subscribable listeners
- RAF-throttled updates
- prevents resize storms from re-rendering the whole app
✅ 13) iOS scroll lock is fixed-position safe
Locks body scroll without breaking restore position:
- stores scrollY + inline styles
- applies fixed positioning + restores cleanly on unlock
✅ 14) Portal host safety checks
Modals/popovers avoid attaching into a transform/backdrop-filter hostile host when unsafe, preventing iOS fixed-position glitches.
♿ Accessibility + UX
- Skip link added (
#app-content) - ARIA labels for major regions (topbar/panel/nav)
- SR-only announcements when portals open (KaiVoh / Explorer / Klock)
- Mobile nav autoscroll to active item
- DNS IP copy includes Clipboard API + textarea fallback with feedback animation
✅ Fixes / Cleanups Included in v30.0.0
- Replaced old “zero-based fallback seeding” with Genesis-aligned μpulse anchoring.
- Guarded deterministic “now” plumbing after seeding to prevent null/undefined propagation (resolves the class of TS/runtime issues seen in shared μpulse ticker wiring).
- Normalized timer typing (
number) to avoid NodeJS.Timeout bleed in browser code. - Deterministic scheduling now pauses while hidden and re-seals on return (prevents background jitter illusions and saves battery).
⚠️ Behavioral Notes (Important)
Storage impact
-
This release introduces/standardizes:
phi_kai_anchor_pmicro_v1
-
Clearing site data resets the persisted anchor (expected). The system will reseal deterministically on next boot.
“Wall clock irrelevant” clarification (what this release guarantees)
- If a device’s wall clock is wrong, the app no longer “believes” it for Kai time once seeded.
- All displayed “now” and all scheduling is derived from μpulse since Genesis, not Date.now/perf clocks.
🔍 Verification Checklist (Prove it’s deterministic)
-
Set Device A clock wrong (hours/day off). Keep Device B correct.
-
Load v30 on both (same build).
-
Confirm:
- pulse display follows Kai logic (no timezone weirdness)
- beat:step boundaries tick cleanly at pulse boundaries
-
Toggle:
- background → foreground
- focus changes
- refresh
-
Confirm:
- anchor persists (
phi_kai_anchor_pmicro_v1present) - “NOW” resumes sealed (no reset-to-0 behavior, no drift jumps)
- anchor persists (
Summary
v30.0.0 is the determinism milestone.
The app shell now boots and runs on a Genesis-anchored μpulse coordinate, persists it as a single canonical checkpoint, schedules UI updates on exact φ pulse boundaries, and keeps the entire PWA experience fast, splashless, and offline-ready—without letting host wall clocks inject distortion.
What's Changed
- v29.9.5 by @Phinetwork in #73
- v29.9.6 by @Phinetwork in #74
- v29.9.7 by @Phinetwork in #75
- v29.9.8 by @Phinetwork in #76
- v30.0.0 by @Phinetwork in #77
Full Changelog: v29.9.0...v30.0.0
VCLOSED
OFFICIAL NOTICE — REPOSITORY RELOCATED
This repository is no longer the canonical source of truth for PHI.NETWORK.
✅ New official repository: https://github.com/phinetwork/phi_network
Effective Immediately
All development, releases, issues, and pull requests must be directed to the new repository.
Status of This Repository
This repository is retained for historical reference only and will receive no further updates.
What's Changed
- v30.0.1 by @Phinetwork in #78
- v30.0.3 by @Phinetwork in #79
- v30.0.4 by @Phinetwork in #80
Full Changelog: v30.0.0...VCLOSED
v29.9.0
v29.9.0 — The Chronos Exit (Official Spec-Locked Release)
v29.9.0 is the first complete Kai-Klok release where Chronos is no longer a runtime dependency anywhere. The entire system now implements Kai-Klok exactly as the Kairos State Machine: one-time coordinate selection (seed) → deterministic integer μpulse evolution (no ongoing wall-clock sampling).
What changed (the headline upgrades)
1) Chronos removed from everything
- No
Date.now(), nonew Date(), no wall-clock parsing, no Unix-time “drift chasing.” - Any timestamp-like UI needs (labels, ISO strings, “ms”) are derived only from Genesis + μpulses × pulse period (a deterministic bridge), not from live clock reads.
2) “NOW” is now a state, not a measurement
- “Now” is not sampled continuously.
- “Now” is computed from the current Kai state (μpulse counter) and advanced by tick events.
3) Spec-true architecture: boundary condition vs driving stream
Kai-Klok now matches the spec distinction:
- Initialization: consumes exactly one reference input to select the initial coordinate (
k0 = f(R, G, P)). - Evolution: advances by deterministic counting (
kₙ₊₁ = kₙ + uₙ) with no dependence on an absolute-time stream.
4) Single-source-of-truth timing
- All Kai pulse / beat / step / boundary logic is routed through the canonical timing engine (no duplicate math, no “almost the same” clocks in components).
What this guarantees (audit-grade invariants)
Determinism
Given the same seed + the same tick stream behavior, the system produces the same Kai state progression every time—offline, online, across reloads.
Non-time-tracking (in the strong computational sense)
After initialization, the system’s transitions do not require an ongoing absolute-time measurement channel—exactly matching the spec’s definition of “not time-tracking.”
Offline sovereignty
The system continues coherently without network time, NTP, servers, or platform time authority. The user’s device can be disconnected and the state machine remains internally consistent.
Verifiability
This release is provable by inspection:
- you can audit for any prohibited time reads,
- you can verify that only the initialization path can accept a reference datum,
- and you can confirm steady-state evolution is pure μpulse counting.
Why this is a big deal (for developers)
It ends “time ambiguity” as a bug class
Chronos introduces hidden instability: timezone quirks, clock drift, OS corrections, daylight rules, parsing inconsistencies, “works on my machine” timestamp failures. v29.9.0 removes the entire failure surface by making time stateful + deterministic.
It makes the system portable across platforms and hostile environments
Because you’re not tracking wall-clock time, you’re not vulnerable to:
- device clock tampering,
- NTP jumps,
- time API inconsistencies,
- background throttling side effects turning into “time truth.”
It upgrades Kai-Klok from an implementation to a spec-locked machine
This is now an architecture you can reason about like any other formally defined system:
- state,
- inputs,
- invariants,
- transitions,
- proofs and audits.
Why this is a big deal (for everyone)
Human time no longer has to be “rented” from institutions
Most modern systems quietly depend on external clock authority (telecom, OS vendors, NTP infrastructure, server timestamps). v29.9.0 proves a different model exists: coherent progression without continuous measurement dependence.
It’s a new foundation for trust
If “time” is a measurement stream, whoever controls the measurement can shape the record.
If “time” is a deterministic state machine, the record becomes inspectable, replayable, and resilient.
It enables sovereign continuity
When connectivity fails, platforms disappear, or services censor: a Chronos-dependent product degrades.
A Kairos state machine continues.
Upgrade notes (what to expect)
Potential breaking expectations
- Any code that assumed “current time = Date()” must now use the Kai-derived epoch bridge (Genesis + μpulses).
- Any integration that relied on system clock changes to “fix” drift will no longer behave that way (by design).
Practical verification checklist
- Search the codebase for
Date.now,new Date,performance.timeOrigintime math, or wall-clock parsing. - Confirm the only allowed reference input happens on initialization (seed).
- Confirm runtime updates come from tick/boundary scheduling + integer μpulse progression.
The one-sentence release claim (official)
v29.9.0 makes Kai-Klok formally true in code: a Kairos state machine that uses a single initialization reference only to choose the starting coordinate, then evolves by deterministic μpulse counting without continuous wall-clock sampling.
What's Changed
- v29.9.0 by @Phinetwork in #72
Full Changelog: v29.8.6...v29.9.0
v29.8.6
v29.8.5
v29.8.4
v29.8.3
v29.8.2
Release Notes — v29.8.2
- Typography calibration: reduced
--font-baseby 5% to tighten overall scale and improve cross-device consistency (regular iPhone vs Max). - UI polish only: token-level change; no changes to PWA/offline behavior, routing, or data sync logic.
What's Changed
- v29.7.5 by @Phinetwork in #61
- v29.7.6 by @Phinetwork in #62
- v29.7.8 by @Phinetwork in #63
- v29.7.9 by @Phinetwork in #64
- v29.8.0 by @Phinetwork in #65
- v29.8.1 by @Phinetwork in #66
- v29.8.2 by @Phinetwork in #67
Full Changelog: v29.7.3...v29.8.2
v29.7.3
Release Notes — v29.7.2 (Sovereign Gate / ΦNet PWA + Sigil Explorer Breath-Sync Hardening)
🔥 Highlights
- Breath-cadenced global sync (LAH-MAH-TOR): SigilExplorer now runs on a true inhale/exhale lifecycle with φ-pulse cadence (~5.236s) and Kai-time deterministic ordering (pulse/beat/step), not Chronos sorting.
- Sharing + routing made “real-world safe”: Legacy stream routes and short token routes normalize cleanly so links actually survive copy/paste + mobile share surfaces.
- PWA stability & speed upgrades: Service worker behavior, precache guarantees, and “first paint” performance have been tightened so the app feels instant and stays reliable offline.
✅ What’s New
1) SigilExplorer v3.10.7 — LAH-MAH-TOR Breath Sync (Mobile Scroll Stability Hardening)
-
On OPEN behavior is sealed:
- Inhale: push everything local → API
- Exhale: pull anything new ← API
-
Every φ-pulse (~5.236s):
- inhale (flush) + seal-check + exhale (pull-if-changed)
-
No double adds:
- URL-level registry is a Map
- UI dedupes by content identity
-
Remote echo-loop prevention:
- Remote imports do not re-inhale automatically (prevents feedback loops)
-
Deterministic ordering is Kai-only:
- Ordered by Kai pulse/beat/stepIndex
- No Chronos ordering used anywhere in the canonical flow
-
Stream view normalization baked in:
- Any
/stream/p/<token>(or/p~<token>) is displayed/opened as/stream#p=<token> - Copy/Open always uses the working normalized format
- Any
2) Router normalization — legacy hash → canonical stream open
-
Added/strengthened rewriting so older link forms don’t fragment the UX:
#/stream/p/<token>?add=...→ canonical#-based open flow- Short token route support aligned with your SMS-safe strategy (
/p~<token>)
-
Net result: links remain stable across browsers, mobile share sheets, and copy/paste contexts.
3) App shell performance hardening (instant first paint + heavy UI deferred)
From your App.tsx work today:
-
Instant first paint strategy:
- Heavy modules are code-split
- Suspense fallback stays null/blank spacer (no “fake loading splash”)
-
Homepage splash killer behavior preserved:
- Boot overlays don’t block
/
- Boot overlays don’t block
-
Warm timer fix:
warmTimer not defined→ resolved using a ref-based timer
-
SW warming is disciplined:
- runs idle-only
- re-warms on focus
- abort-safe
- respects Save-Data / 2G style constraints
4) Lazy route prefetching — real UX speed (without jank)
-
Prefetch targets were defined for the routes you’re actually using:
SigilFeedPageSigilPagePShortVerifyPageVerifierStamper
-
Result: navigation feels “already loaded” without forcing upfront bundle weight.
5) PWA build pipeline tightening — version + asset correctness
Based on the Vite/plugin work you showed today:
- Build version stamping uses package version + commit SHA (when present), producing a stable
VITE_APP_VERSIONstyle identity for deploys. - Static PWA assets explicitly tracked (ex:
offline.html,manifest.json,favicon.ico) to avoid “it works on desktop but not on mobile PWA” cache divergence. - Overall goal achieved: assets and SW stay in sync across releases, preventing “ghost lag” from stale worker/caches.
🛠 Fixes
-
Service Worker correctness preserved as a hard invariant:
/sw.jsand (if present)/service-worker.jsmust return JavaScript (not HTML via SPA fallback).
-
Mobile stability improvements:
- Reduced-motion compatibility + splash phase logic (show → fade → hidden) avoids iOS reflow/jank patterns.
-
Share-path survivability:
- The
/p~<token>direction aligns with your goal of not breaking in SMS/iMessage contexts and keeps sharing viable even when long payload URLs glitch.
- The
⚡ Performance & UX Impact
- Perceived speed: faster first meaningful paint + smoother route transitions via prefetch.
- Deterministic rendering: one canonical view per payload, even if multiple URL variants exist.
- Offline/PWA snappiness: reduced cache mismatch risk by making build output + worker identity consistent.
🔁 Upgrade / Compatibility Notes
-
Old links are still supported, but canonical output is normalized:
- Canonical open/display:
/stream#p=<token> - SMS-safe short form supported:
/p~<token>
- Canonical open/display:
-
If any external posts still point to
/stream/p/<token>, they will still resolve, but UI will “snap” to the canonical format for consistency.
✅ Verification Checklist (v29.7.2)
Run this exactly after deploy:
- Service worker endpoints
- Open:
/sw.js - Open:
/service-worker.js(if you expose it)
Confirm response is JS, not HTML.
- Fresh install
- Incognito → load app → confirm SW installs + claims clients.
- Offline truth
- Load once → toggle offline → navigate to core routes → confirm cached views load.
- Route normalization
-
Test these inputs:
/stream/p/<token>/p~<token>#/stream/p/<token>?add=...
-
Confirm they resolve and end up opening as:
/stream#p=<token>
- Breath cadence behavior
-
Open SigilExplorer and watch:
- immediate inhale → exhale
- repeating φ-pulse cycle (~5.236s)
- no duplication in UI when URL variants exist
What's Changed
- v29.6.2 by @Phinetwork in #54
- v29.6.3 by @Phinetwork in #55
- 29.6.4 by @kojibai in #56
- v29.6.7 by @Phinetwork in #57
- v29.6.8 by @Phinetwork in #58
- v29.7.2 by @Phinetwork in #59
- v29.7.3 by @Phinetwork in #60
New Contributors
Full Changelog: v29.6...v29.7.3
v29.6
Release Notes — v29.6
PWA Offline Fix (Service Worker Routing Hardening)
Summary
This release restores true offline-first PWA behavior by preventing service worker scripts from being swallowed by the SPA catch-all route. sw.js (and service-worker.js, if you ship both) are now served as real JavaScript files end-to-end, allowing the browser to install, register, cache, and claim clients reliably.
What changed
✅ Service worker scripts are served directly (no SPA rewrite)
-
Ensured requests to:
/sw.js/service-worker.js(if present)
-
are handled as static JS assets and never rewritten to your app’s
index.htmlvia SPA fallback rules.
✅ Correct MIME + payload delivered
- These endpoints now return JavaScript, not HTML.
- This fixes the classic failure mode where the browser tries to execute
index.htmlas the worker script, causing install/register to silently fail or loop.
Why it matters
Offline-first is back
With service worker routing fixed, the PWA regains its core guarantees:
- Reliable service worker registration
- Asset + route caching behaves deterministically
- Clients are claimed properly (navigation + control works immediately)
- Offline navigation works (cached shell/pages render without network)
- Background sync / update flows resume (where supported)
In short: the PWA works like a PWA again — installable, resilient, and offline-capable.
How to verify
1) Confirm service worker script responses are JS
After redeploy:
-
Open DevTools → Network
-
Visit:
/sw.js/service-worker.js(if applicable)
-
Confirm:
- Status:
200 - Content-Type:
application/javascript(or equivalent JS type) - Response body: actual worker JS (not HTML)
- Status:
If you see
<!doctype html>anywhere in the response, the SPA fallback is still intercepting it.
2) Validate install + claim in a clean session
-
Open a fresh Incognito window
-
Load the site once
-
DevTools → Application → Service Workers
-
Confirm:
- Service worker is installed
- Service worker is activated
- Clients are claimed (page shows “controlled by service worker”)
3) Confirm offline navigation works
-
With the app loaded and the worker installed, toggle:
- DevTools → Network → ✅ Offline
-
Navigate between routes (or hard reload if your caching strategy supports it)
-
Confirm:
- App shell loads
- Cached pages/assets render without network
- No “online-only” blank screens
Notes
- This fix is intentionally boring and absolute: service worker scripts must never be routed through SPA HTML fallbacks.
- If you ship both
sw.jsandservice-worker.js, keep them both protected from rewrites to avoid environment-specific failures.
✅ v29.6 restores offline-first behavior by making the worker script endpoints untouchable by SPA rewrites.
What's Changed
- v29.5.8 by @Phinetwork in #51
- v29.5.9 by @Phinetwork in #52
- 29.6 by @Phinetwork in #53
Full Changelog: v29.5.5...v29.6