From c9b02653e5dd6bb9e74b5d42ce6ad804c3f8e158 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Thu, 16 Apr 2026 10:45:29 +0200 Subject: [PATCH] =?UTF-8?q?refactor:=20rename=20register=20symbol=20from?= =?UTF-8?q?=20=CF=89=20(omega)=20to=20=CF=86=20(phi)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Align with latest Gray Paper revision which changed the PVM register notation. Updates all user-facing labels, trace display, divergence details, host call descriptions, and supporting comments/tests. Co-Authored-By: Claude Opus 4.6 (1M context) --- apps/web/e2e/integration-smoke.spec.ts | 2 +- apps/web/e2e/sprint-03-instructions.spec.ts | 14 +-- apps/web/e2e/sprint-04-registers.spec.ts | 4 +- .../web/e2e/sprint-28-asm-raw-popover.spec.ts | 26 ++-- .../src/components/debugger/RegisterRow.tsx | 2 +- .../debugger/RegistersPanel.test.tsx | 10 +- .../web/src/components/drawer/HostCallTab.tsx | 6 +- .../drawer/hostcalls/GasHostCall.tsx | 4 +- .../drawer/hostcalls/LogHostCall.tsx | 2 +- .../drawer/hostcalls/StorageHostCall.tsx | 4 +- .../drawer/hostcalls/host-call-registers.ts | 2 +- .../components/drawer/trace-display.test.ts | 6 +- .../src/components/drawer/trace-display.ts | 4 +- apps/web/src/hooks/useDebuggerActions.ts | 2 +- apps/web/src/hooks/useDisassembly.test.tsx | 12 +- apps/web/src/hooks/useDisassembly.ts | 4 +- .../web/src/hooks/useDivergenceCheck.test.tsx | 12 +- apps/web/src/hooks/useDivergenceCheck.ts | 2 +- apps/web/src/lib/fetch-codec.ts | 12 +- apps/web/src/lib/fetch-utils.ts | 8 +- apps/web/src/lib/storage-utils.test.ts | 4 +- apps/web/src/lib/storage-utils.ts | 4 +- packages/orchestrator/src/orchestrator.ts | 2 +- .../sprint-49-register-symbol-omega-to-phi.md | 112 ++++++++++++++++++ 24 files changed, 186 insertions(+), 74 deletions(-) create mode 100644 spec/ui/sprint-49-register-symbol-omega-to-phi.md diff --git a/apps/web/e2e/integration-smoke.spec.ts b/apps/web/e2e/integration-smoke.spec.ts index 99a722c..63bced6 100644 --- a/apps/web/e2e/integration-smoke.spec.ts +++ b/apps/web/e2e/integration-smoke.spec.ts @@ -190,7 +190,7 @@ test.describe("Sprint 36 — Integration Smoke Test", () => { timeout: 5000, }); - // r9 should be 102 (0x66) — proving editing ω7 changed the downstream result + // r9 should be 102 (0x66) — proving editing φ7 changed the downstream result const regHex9 = page.getByTestId("register-hex-9"); await expect(regHex9).toHaveText(/0x0{14}66/i, { timeout: 5000 }); }); diff --git a/apps/web/e2e/sprint-03-instructions.spec.ts b/apps/web/e2e/sprint-03-instructions.spec.ts index 2537ed4..3ccaa65 100644 --- a/apps/web/e2e/sprint-03-instructions.spec.ts +++ b/apps/web/e2e/sprint-03-instructions.spec.ts @@ -49,7 +49,7 @@ test.describe("Sprint 03 — Flat Instruction List", () => { await expect(mnemonicElement).toHaveText(/.+/); }); - test("register arguments use omega notation (ω)", async ({ page }) => { + test("register arguments use phi notation (φ)", async ({ page }) => { // Load the add-jam example (SPI, in wat category — collapsed by default) await page.goto("/#/load"); await page.getByTestId("category-toggle-wat").click(); @@ -69,21 +69,21 @@ test.describe("Sprint 03 — Flat Instruction List", () => { const panel = page.getByTestId("instructions-panel"); await expect(panel).toBeVisible(); - // At least one instruction should contain omega notation + // At least one instruction should contain phi notation const argsElements = panel.getByTestId("instruction-args"); const count = await argsElements.count(); expect(count).toBeGreaterThan(0); - // Find at least one args element with omega notation - let foundOmega = false; + // Find at least one args element with phi notation + let foundPhi = false; for (let i = 0; i < count; i++) { const text = await argsElements.nth(i).textContent(); - if (text?.includes("ω")) { - foundOmega = true; + if (text?.includes("φ")) { + foundPhi = true; break; } } - expect(foundOmega).toBe(true); + expect(foundPhi).toBe(true); }); test("current PC row is visually highlighted", async ({ page }) => { diff --git a/apps/web/e2e/sprint-04-registers.spec.ts b/apps/web/e2e/sprint-04-registers.spec.ts index f030f2b..4daec74 100644 --- a/apps/web/e2e/sprint-04-registers.spec.ts +++ b/apps/web/e2e/sprint-04-registers.spec.ts @@ -41,7 +41,7 @@ test.describe("Sprint 04 — Registers + Status Display", () => { await expect(gasValue).toHaveText(/^[\d,]+$/); }); - test("all 13 register rows render with omega labels", async ({ page }) => { + test("all 13 register rows render with phi labels", async ({ page }) => { await loadProgram(page); const panel = page.getByTestId("registers-panel"); @@ -52,7 +52,7 @@ test.describe("Sprint 04 — Registers + Status Display", () => { await expect(row).toBeVisible(); const label = page.getByTestId(`register-label-${i}`); - await expect(label).toHaveText(`ω${i}:`); + await expect(label).toHaveText(`φ${i}:`); } }); diff --git a/apps/web/e2e/sprint-28-asm-raw-popover.spec.ts b/apps/web/e2e/sprint-28-asm-raw-popover.spec.ts index d1f8c26..18acac6 100644 --- a/apps/web/e2e/sprint-28-asm-raw-popover.spec.ts +++ b/apps/web/e2e/sprint-28-asm-raw-popover.spec.ts @@ -30,7 +30,7 @@ async function loadProgram( } test.describe("Sprint 28 — ASM/Raw Toggle + Binary Popover", () => { - test("ASM mode shows omega notation", async ({ page }) => { + test("ASM mode shows phi notation", async ({ page }) => { await loadProgram(page, "add-jam"); const panel = page.getByTestId("instructions-panel"); @@ -40,21 +40,21 @@ test.describe("Sprint 28 — ASM/Raw Toggle + Binary Popover", () => { const asmBtn = page.getByTestId("display-mode-asm"); await expect(asmBtn).toBeVisible(); - // Instruction args should contain omega notation + // Instruction args should contain phi notation const argsElements = panel.locator("[data-testid='instruction-args']"); const count = await argsElements.count(); expect(count).toBeGreaterThan(0); - // At least one arg should contain omega (ω) character - let hasOmega = false; + // At least one arg should contain phi (φ) character + let hasPhi = false; for (let i = 0; i < count; i++) { const text = await argsElements.nth(i).textContent(); - if (text?.includes("ω")) { - hasOmega = true; + if (text?.includes("φ")) { + hasPhi = true; break; } } - expect(hasOmega).toBe(true); + expect(hasPhi).toBe(true); }); test("toggling to Raw mode changes displayed text", async ({ page }) => { @@ -87,7 +87,7 @@ test.describe("Sprint 28 — ASM/Raw Toggle + Binary Popover", () => { expect(firstRaw).toMatch(/^[0-9A-F]{2}( [0-9A-F]{2})*$/); }); - test("toggling back to ASM restores omega notation", async ({ page }) => { + test("toggling back to ASM restores phi notation", async ({ page }) => { await loadProgram(page, "add-jam"); const panel = page.getByTestId("instructions-panel"); @@ -106,18 +106,18 @@ test.describe("Sprint 28 — ASM/Raw Toggle + Binary Popover", () => { const mnemonics = panel.locator("[data-testid='instruction-mnemonic']"); expect(await mnemonics.count()).toBeGreaterThan(0); - // Omega notation should be present in args + // Phi notation should be present in args const argsElements = panel.locator("[data-testid='instruction-args']"); const count = await argsElements.count(); - let hasOmega = false; + let hasPhi = false; for (let i = 0; i < count; i++) { const text = await argsElements.nth(i).textContent(); - if (text?.includes("ω")) { - hasOmega = true; + if (text?.includes("φ")) { + hasPhi = true; break; } } - expect(hasOmega).toBe(true); + expect(hasPhi).toBe(true); }); test("clicking an instruction opens the binary popover", async ({ page }) => { diff --git a/apps/web/src/components/debugger/RegisterRow.tsx b/apps/web/src/components/debugger/RegisterRow.tsx index 2927a68..5fe1146 100644 --- a/apps/web/src/components/debugger/RegisterRow.tsx +++ b/apps/web/src/components/debugger/RegisterRow.tsx @@ -111,7 +111,7 @@ export function RegisterRow({ data-testid={`register-label-${index}`} className="text-muted-foreground w-8 shrink-0 select-none" > - ω{index}: + φ{index}: {editing ? ( { />, ); - // omega3 changed -> should have delta + // phi3 changed -> should have delta expect(screen.getByTestId("register-delta-3")).toBeDefined(); - // omega0 did not change -> no delta + // phi0 did not change -> no delta expect(screen.queryByTestId("register-delta-0")).toBeNull(); // PC changed -> delta expect(screen.getByTestId("pc-delta")).toBeDefined(); @@ -133,7 +133,7 @@ describe("RegistersPanel — Change Highlighting", () => { />, ); - // Step 1->2: omega5 changes + // Step 1->2: phi5 changes rerender( { />, ); - // omega7 differs -> divergence indicator + // phi7 differs -> divergence indicator expect(screen.getByTestId("register-divergence-7")).toBeDefined(); - // omega0 matches -> no indicator + // phi0 matches -> no indicator expect(screen.queryByTestId("register-divergence-0")).toBeNull(); }); }); diff --git a/apps/web/src/components/drawer/HostCallTab.tsx b/apps/web/src/components/drawer/HostCallTab.tsx index afc0625..effdcfe 100644 --- a/apps/web/src/components/drawer/HostCallTab.tsx +++ b/apps/web/src/components/drawer/HostCallTab.tsx @@ -75,7 +75,7 @@ function Sidebar({ data-testid="output-preview" className="text-xs font-mono border-t border-border pt-1" > - ω₇ ← + φ₇ ← {outputValue.toString()} {outputValue !== NONE && ( @@ -305,7 +305,7 @@ export function HostCallTab({ setNoneChecked(checked); setUserModified(true); if (checked) { - // NONE: ω₇ = 2^64-1, no memory writes, clean up previously applied mem writes + // NONE: φ₇ = 2^64-1, no memory writes, clean up previously applied mem writes for (const addr of appliedMemAddrsRef.current) { pendingChanges.removeMemoryWrite(addr); } @@ -394,7 +394,7 @@ export function HostCallTab({ )} {noneChecked && (

- NONE mode: returning ω₇ = 2⁶⁴−1 with no memory writes. + NONE mode: returning φ₇ = 2⁶⁴−1 with no memory writes.

)}

{ stableOnEffects({ registerWrites: new Map([[7, currentGas]]), @@ -25,7 +25,7 @@ export function GasHostCall({ info, onEffectsReady }: GasHostCallProps) { return (

- Returns current gas counter in ω₇. + Returns current gas counter in φ₇.

Current gas: diff --git a/apps/web/src/components/drawer/hostcalls/LogHostCall.tsx b/apps/web/src/components/drawer/hostcalls/LogHostCall.tsx index 9e147aa..8cebe59 100644 --- a/apps/web/src/components/drawer/hostcalls/LogHostCall.tsx +++ b/apps/web/src/components/drawer/hostcalls/LogHostCall.tsx @@ -29,7 +29,7 @@ function toHexString(data: Uint8Array): string { /** * Log host call view (index 100). * - * Log registers: ω7=level, ω8=target_ptr, ω9=target_len, ω10=msg_ptr, ω11=msg_len + * Log registers: φ7=level, φ8=target_ptr, φ9=target_len, φ10=msg_ptr, φ11=msg_len * * Decodes message text from trace memory reads (resumeProposal.memoryWrites) * when available, otherwise reads memory from the orchestrator using the diff --git a/apps/web/src/components/drawer/hostcalls/StorageHostCall.tsx b/apps/web/src/components/drawer/hostcalls/StorageHostCall.tsx index 7b08c50..cdb13b6 100644 --- a/apps/web/src/components/drawer/hostcalls/StorageHostCall.tsx +++ b/apps/web/src/components/drawer/hostcalls/StorageHostCall.tsx @@ -244,7 +244,7 @@ export function StorageHostCall({ const isRead = info.hostCallIndex === 3; const regs = info.currentState.registers; - // For read: ω7=serviceId, ω8=keyPtr, ω9=keyLen, ω10=dest, ω11=offset, ω12=maxLen + // For read: φ7=serviceId, φ8=keyPtr, φ9=keyLen, φ10=dest, φ11=offset, φ12=maxLen const serviceId = regs[7] ?? 0n; const keyPtr = Number(regs[8] ?? 0n); const keyLen = Number(regs[9] ?? 0n); @@ -271,7 +271,7 @@ export function StorageHostCall({ // Only seed if key doesn't already exist (don't overwrite user edits) if (!storageTable.store.get(fullKey)) { // The trace's memory write at destAddr is the sliced value; we need to reconstruct the full value. - // The ω₇ return value from the proposal is the full value length. + // The φ₇ return value from the proposal is the full value length. const _fullLen = Number(proposal.registerWrites.get(7) ?? 0n); // For simplicity, seed the sliced portion — this is what the trace knows about. const mw = proposal.memoryWrites.find((w) => w.address === destAddr); diff --git a/apps/web/src/components/drawer/hostcalls/host-call-registers.ts b/apps/web/src/components/drawer/hostcalls/host-call-registers.ts index 44e712d..14681fc 100644 --- a/apps/web/src/components/drawer/hostcalls/host-call-registers.ts +++ b/apps/web/src/components/drawer/hostcalls/host-call-registers.ts @@ -10,7 +10,7 @@ export interface RegisterMeta { format: RegisterFormat; } -/** Metadata for the output register (typically ω₇). */ +/** Metadata for the output register (typically φ₇). */ export interface OutputRegisterMeta { index: number; label: string; diff --git a/apps/web/src/components/drawer/trace-display.test.ts b/apps/web/src/components/drawer/trace-display.test.ts index df4e12d..1b0588e 100644 --- a/apps/web/src/components/drawer/trace-display.test.ts +++ b/apps/web/src/components/drawer/trace-display.test.ts @@ -82,7 +82,7 @@ describe("formatEntryLines", () => { it("formats header line with ecalli index and gas", () => { const entry = makeEntry({ index: 2, gas: 999n }); const lines = formatEntryLines(entry); - expect(lines[0]).toBe("ecalli 2, ω7 = 999"); + expect(lines[0]).toBe("ecalli 2, φ7 = 999"); }); it("formats memory reads", () => { @@ -106,7 +106,7 @@ describe("formatEntryLines", () => { registerWrites: new Map([[7, 42n]]), }); const lines = formatEntryLines(entry); - expect(lines).toContainEqual(" ω7 ← 42"); + expect(lines).toContainEqual(" φ7 ← 42"); }); it("formats gas update when gasAfter is present", () => { @@ -134,7 +134,7 @@ describe("formatEntryLines", () => { const entry = makeEntry({ index: 0, gas: 100n }); const lines = formatEntryLines(entry); expect(lines).toHaveLength(1); - expect(lines[0]).toBe("ecalli 0, ω7 = 100"); + expect(lines[0]).toBe("ecalli 0, φ7 = 100"); }); }); diff --git a/apps/web/src/components/drawer/trace-display.ts b/apps/web/src/components/drawer/trace-display.ts index a4db453..daa2ad8 100644 --- a/apps/web/src/components/drawer/trace-display.ts +++ b/apps/web/src/components/drawer/trace-display.ts @@ -50,7 +50,7 @@ export function formatEntryLines(entry: TraceEntry): string[] { const name = getHostCallName(entry.index); const lines: string[] = []; - lines.push(`ecalli ${entry.index}, ω7 = ${entry.gas}`); + lines.push(`ecalli ${entry.index}, φ7 = ${entry.gas}`); // Memory reads for (const mr of entry.memoryReads) { @@ -66,7 +66,7 @@ export function formatEntryLines(entry: TraceEntry): string[] { // Register writes for (const [reg, val] of entry.registerWrites) { - lines.push(` ω${reg} ← ${val}`); + lines.push(` φ${reg} ← ${val}`); } // Gas update diff --git a/apps/web/src/hooks/useDebuggerActions.ts b/apps/web/src/hooks/useDebuggerActions.ts index ddefd01..19ec2f6 100644 --- a/apps/web/src/hooks/useDebuggerActions.ts +++ b/apps/web/src/hooks/useDebuggerActions.ts @@ -149,7 +149,7 @@ export function persistWriteToStorage( const keyHex = deriveKeyHex(hc); if (!keyHex) return; - // For write, value is at ω9/ω10 + // For write, value is at φ9/φ10 const valPtr = Number(hc.currentState.registers[9] ?? 0n); const valLen = Number(hc.currentState.registers[10] ?? 0n); diff --git a/apps/web/src/hooks/useDisassembly.test.tsx b/apps/web/src/hooks/useDisassembly.test.tsx index c69c9d4..46e6550 100644 --- a/apps/web/src/hooks/useDisassembly.test.tsx +++ b/apps/web/src/hooks/useDisassembly.test.tsx @@ -28,7 +28,7 @@ describe("useDisassembly", () => { expect(result.current).toEqual([]); }); - it("args use omega notation, rawArgs use numeric indices", () => { + it("args use phi notation, rawArgs use numeric indices", () => { const bytes = new Uint8Array( readFileSync(resolve(fixturesDir, "generic/add.pvm")), ); @@ -39,14 +39,14 @@ describe("useDisassembly", () => { expect(instructions.length).toBeGreaterThan(0); // Find instructions that have register arguments - const withRegArgs = instructions.filter((i) => i.args.includes("ω")); + const withRegArgs = instructions.filter((i) => i.args.includes("φ")); expect(withRegArgs.length).toBeGreaterThan(0); for (const instr of withRegArgs) { - // ASM args should contain omega - expect(instr.args).toMatch(/ω\d+/); - // Raw args should NOT contain omega, should contain plain numbers - expect(instr.rawArgs).not.toContain("ω"); + // ASM args should contain phi + expect(instr.args).toMatch(/φ\d+/); + // Raw args should NOT contain phi, should contain plain numbers + expect(instr.rawArgs).not.toContain("φ"); // Raw args should be non-empty (they have register operands) expect(instr.rawArgs.length).toBeGreaterThan(0); } diff --git a/apps/web/src/hooks/useDisassembly.ts b/apps/web/src/hooks/useDisassembly.ts index 747a5d8..884f008 100644 --- a/apps/web/src/hooks/useDisassembly.ts +++ b/apps/web/src/hooks/useDisassembly.ts @@ -16,14 +16,14 @@ export interface DecodedInstruction { mnemonic: string; rawBytes: Uint8Array; args: string; - /** Numeric-only argument string (register indices as numbers, no omega notation). */ + /** Numeric-only argument string (register indices as numbers, no phi notation). */ rawArgs: string; /** Index of the basic block this instruction belongs to (0-based). */ blockIndex: number; } function regName(index: number): string { - return `ω${index}`; + return `φ${index}`; } function formatImm(decoder: { getI32(): number }): string { diff --git a/apps/web/src/hooks/useDivergenceCheck.test.tsx b/apps/web/src/hooks/useDivergenceCheck.test.tsx index 9d88880..212d05a 100644 --- a/apps/web/src/hooks/useDivergenceCheck.test.tsx +++ b/apps/web/src/hooks/useDivergenceCheck.test.tsx @@ -112,8 +112,8 @@ describe("useDivergenceCheck", () => { useDivergenceCheck(snapshots, "typeberry", 0), ); expect(result.current.summary).toBe("2 registers"); - expect(result.current.details).toContain("ω3:"); - expect(result.current.details).toContain("ω7:"); + expect(result.current.details).toContain("φ3:"); + expect(result.current.details).toContain("φ7:"); }); it("shows 1 register for single register divergence", () => { @@ -186,7 +186,7 @@ describe("useDivergenceCheck", () => { ); // PC diverges (typeberry vs polkavm), Gas diverges (typeberry vs ananas), - // register ω3 diverges (typeberry vs both) + // register φ3 diverges (typeberry vs both) expect(result.current.summary).toBe("PC, Gas, 1 register"); // Details should have entries for each diverging PVM @@ -196,9 +196,9 @@ describe("useDivergenceCheck", () => { // Gas diverges only with ananas, PC only with polkavm expect(details).toContain("Gas:"); expect(details).toContain("PC:"); - // ω3 diverges with both - const omega3Lines = details.split("\n").filter((l) => l.startsWith("ω3:")); - expect(omega3Lines.length).toBe(2); + // φ3 diverges with both + const phi3Lines = details.split("\n").filter((l) => l.startsWith("φ3:")); + expect(phi3Lines.length).toBe(2); }); it("reports divergence from perspective of selected PVM", () => { diff --git a/apps/web/src/hooks/useDivergenceCheck.ts b/apps/web/src/hooks/useDivergenceCheck.ts index ffb8389..3fcc993 100644 --- a/apps/web/src/hooks/useDivergenceCheck.ts +++ b/apps/web/src/hooks/useDivergenceCheck.ts @@ -81,7 +81,7 @@ export function useDivergenceCheck( if (selected.registers[i] !== other.registers[i]) { divergentRegIndices.add(i); detailLines.push( - `\u03C9${i}: ${selectedPvmId}=0x${BigInt.asUintN(64, selected.registers[i]).toString(16)}, ${pvmId}=0x${BigInt.asUintN(64, other.registers[i]).toString(16)}`, + `\u03C6${i}: ${selectedPvmId}=0x${BigInt.asUintN(64, selected.registers[i]).toString(16)}, ${pvmId}=0x${BigInt.asUintN(64, other.registers[i]).toString(16)}`, ); } } diff --git a/apps/web/src/lib/fetch-codec.ts b/apps/web/src/lib/fetch-codec.ts index ab3e037..6740303 100644 --- a/apps/web/src/lib/fetch-codec.ts +++ b/apps/web/src/lib/fetch-codec.ts @@ -82,20 +82,20 @@ export const FETCH_KIND_INFO: Record = { [FetchKind.OtherWorkItemExtrinsics]: { name: "OtherWorkItemExtrinsics", description: - "Extrinsic blob from another work item (x̄[ω₁₁]_{ω₁₂}, refine only)", + "Extrinsic blob from another work item (x̄[φ₁₁]_{φ₁₂}, refine only)", }, [FetchKind.MyExtrinsics]: { name: "MyExtrinsics", - description: "Current work item's extrinsic at index ω₁₁ (refine only)", + description: "Current work item's extrinsic at index φ₁₁ (refine only)", }, [FetchKind.OtherWorkItemImports]: { name: "OtherWorkItemImports", description: - "Import segment from another work item (ī[ω₁₁]_{ω₁₂}, refine only)", + "Import segment from another work item (ī[φ₁₁]_{φ₁₂}, refine only)", }, [FetchKind.MyImports]: { name: "MyImports", - description: "Current work item's import at index ω₁₁ (refine only)", + description: "Current work item's import at index φ₁₁ (refine only)", }, [FetchKind.WorkPackage]: { name: "WorkPackage", @@ -123,12 +123,12 @@ export const FETCH_KIND_INFO: Record = { [FetchKind.OneWorkItem]: { name: "OneWorkItem", description: - "One work item summary (62 bytes fixed, S(p.workitems[ω₁₁]), refine + is-auth)", + "One work item summary (62 bytes fixed, S(p.workitems[φ₁₁]), refine + is-auth)", }, [FetchKind.WorkItemPayload]: { name: "WorkItemPayload", description: - "Work item payload blob (p.workitems[ω₁₁].payload, refine + is-auth)", + "Work item payload blob (p.workitems[φ₁₁].payload, refine + is-auth)", }, [FetchKind.AllTransfersAndOperands]: { name: "AllTransfersAndOperands", diff --git a/apps/web/src/lib/fetch-utils.ts b/apps/web/src/lib/fetch-utils.ts index dbd82c9..709e3f4 100644 --- a/apps/web/src/lib/fetch-utils.ts +++ b/apps/web/src/lib/fetch-utils.ts @@ -43,14 +43,14 @@ export function safeFromHex(hex: string): Uint8Array { /** * Compute the full fetch host call effects from the response blob. * - * Implements: slice by offset/maxLen, set ω₇ = totalLength (or NONE), + * Implements: slice by offset/maxLen, set φ₇ = totalLength (or NONE), * produce memory write at destAddr. * * @param fullBlob - The full response blob for this fetch kind * @param isNone - If true, the response is ⊥ (NONE) - * @param destAddr - Destination memory address (ω₇ register value) - * @param offset - Offset into the full blob (ω₈) - * @param maxLen - Maximum bytes to write (ω₉) + * @param destAddr - Destination memory address (φ₇ register value) + * @param offset - Offset into the full blob (φ₈) + * @param maxLen - Maximum bytes to write (φ₉) */ export function computeFetchEffects( fullBlob: Uint8Array, diff --git a/apps/web/src/lib/storage-utils.test.ts b/apps/web/src/lib/storage-utils.test.ts index d4b0847..c2f1832 100644 --- a/apps/web/src/lib/storage-utils.test.ts +++ b/apps/web/src/lib/storage-utils.test.ts @@ -38,7 +38,7 @@ describe("deriveKeyHex", () => { expect(deriveKeyHex(info)).toBeNull(); }); - it("derives key for read host call (index 3) from ω8/ω9", () => { + it("derives key for read host call (index 3) from φ8/φ9", () => { const regs = Array(13).fill(0n) as bigint[]; regs[8] = 0x1000n; // key ptr regs[9] = 4n; // key len @@ -61,7 +61,7 @@ describe("deriveKeyHex", () => { expect(deriveKeyHex(info)).toBe("0xdeadbeef"); }); - it("derives key for write host call (index 4) from ω7/ω8", () => { + it("derives key for write host call (index 4) from φ7/φ8", () => { const regs = Array(13).fill(0n) as bigint[]; regs[7] = 0x2000n; // key ptr regs[8] = 2n; // key len diff --git a/apps/web/src/lib/storage-utils.ts b/apps/web/src/lib/storage-utils.ts index d57c484..c62f9ba 100644 --- a/apps/web/src/lib/storage-utils.ts +++ b/apps/web/src/lib/storage-utils.ts @@ -4,8 +4,8 @@ import { toHex } from "@pvmdbg/types"; /** * Derive the storage key hex string from a storage host call's state. * - * For read (index 3): key pointer at ω8, length at ω9. - * For write (index 4): key pointer at ω7, length at ω8. + * For read (index 3): key pointer at φ8, length at φ9. + * For write (index 4): key pointer at φ7, length at φ8. * * The key bytes are found by matching a trace memory write at the key pointer address. * Returns null if no key can be derived (no proposal or no matching memory write). diff --git a/packages/orchestrator/src/orchestrator.ts b/packages/orchestrator/src/orchestrator.ts index af28cdc..ebb4470 100644 --- a/packages/orchestrator/src/orchestrator.ts +++ b/packages/orchestrator/src/orchestrator.ts @@ -428,7 +428,7 @@ export class Orchestrator extends TypedEventEmitter { /** * Capture memory reads for log host calls (index 100) from the live PVM. - * Log registers: ω8=target_ptr, ω9=target_len, ω10=msg_ptr, ω11=msg_len. + * Log registers: φ8=target_ptr, φ9=target_len, φ10=msg_ptr, φ11=msg_len. */ private async captureLogMemoryReads( session: Session, diff --git a/spec/ui/sprint-49-register-symbol-omega-to-phi.md b/spec/ui/sprint-49-register-symbol-omega-to-phi.md new file mode 100644 index 0000000..20f0f20 --- /dev/null +++ b/spec/ui/sprint-49-register-symbol-omega-to-phi.md @@ -0,0 +1,112 @@ +# Sprint 49 — Register Symbol Rename: ω → φ + +Status: Implemented + +## Goal + +Rename the PVM register symbol from ω (omega, U+03C9) to φ (phi, U+03C6) throughout the codebase, aligning with the latest Gray Paper revision which changed the register notation. + +## Background + +The Gray Paper recently changed the symbol used for PVM registers from ω (omega) to φ (phi). All user-facing labels, code comments, and test assertions need to be updated to match the new convention. + +## Prior Sprint Dependencies + +- Sprint 03: flat instruction list (introduced ω notation in disassembled args) +- Sprint 04: registers and status (introduced ω labels in register panel) +- Sprint 21: ecalli trace tab (introduced ω in trace display) +- Sprint 25: divergence detection (introduced ω in divergence detail strings) +- Sprint 28: ASM/Raw toggle (tests assert ω in ASM mode) +- Sprint 42: host call UX redesign (introduced ω₇ in output preview, NONE description, and handler comments) +- Sprint 43: fetch handler and JAM codec (introduced ω subscript notation in fetch kind descriptions) + +## What Changed + +### 1. Register Name Function (`useDisassembly.ts`) + +`regName()` returns `φ${index}` instead of `ω${index}`. This is the single source of truth for register notation in disassembled instruction arguments (ASM mode). The JSDoc on `rawArgs` updated from "no omega notation" to "no phi notation". + +### 2. Register Panel Labels (`RegisterRow.tsx`) + +Each register row label changed from `ω{index}:` to `φ{index}:`. + +### 3. Trace Display (`trace-display.ts`) + +- Host call header: `ecalli ${index}, φ7 = ${gas}` (was ω7) +- Register writes: `φ${reg} ← ${val}` (was ω) + +### 4. Host Call Tab (`HostCallTab.tsx`) + +- Output preview label: `φ₇ ←` (was ω₇) +- NONE mode description: `φ₇ = 2⁶⁴−1` (was ω₇) +- NONE toggle comment: `φ₇ = 2^64-1` (was ω₇) + +### 5. Divergence Check (`useDivergenceCheck.ts`) + +Unicode escape in detail line changed from `\u03C9` (ω) to `\u03C6` (φ) for register divergence labels like `φ3: typeberry=0xa, polkavm=0x14`. + +### 6. Host Call Handlers + +- **GasHostCall.tsx**: Comment and UI text updated to reference φ₇. +- **LogHostCall.tsx**: JSDoc register list updated (φ7=level, φ8=target_ptr, etc.). +- **StorageHostCall.tsx**: Comment register list updated (φ7=serviceId, φ8=keyPtr, etc.) and φ₇ return value comment. +- **host-call-registers.ts**: JSDoc updated to reference φ₇. + +### 7. Supporting Libraries + +- **fetch-codec.ts**: Six fetch kind descriptions updated (φ₁₁, φ₁₂ subscript notation). +- **fetch-utils.ts**: JSDoc for `computeFetchEffects` updated (φ₇, φ₈, φ₉). +- **storage-utils.ts**: JSDoc for `deriveKeyHex` updated (φ8/φ9 for read, φ7/φ8 for write). +- **useDebuggerActions.ts**: Comment updated (φ9/φ10 for write value). + +### 8. Orchestrator (`orchestrator.ts`) + +Log host call register comment updated (φ8=target_ptr, φ9=target_len, etc.). + +## Files Changed + +| File | Changes | +|------|---------| +| `apps/web/src/hooks/useDisassembly.ts` | `regName()` returns `φ`, JSDoc updated | +| `apps/web/src/components/debugger/RegisterRow.tsx` | Label `φ{index}:` | +| `apps/web/src/components/drawer/trace-display.ts` | Header and register write lines use φ | +| `apps/web/src/components/drawer/HostCallTab.tsx` | Output preview, NONE description and comment use φ₇ | +| `apps/web/src/hooks/useDivergenceCheck.ts` | Unicode escape `\u03C6` | +| `apps/web/src/components/drawer/hostcalls/GasHostCall.tsx` | Comment and UI text use φ₇ | +| `apps/web/src/components/drawer/hostcalls/LogHostCall.tsx` | JSDoc register list uses φ | +| `apps/web/src/components/drawer/hostcalls/StorageHostCall.tsx` | Comments use φ | +| `apps/web/src/components/drawer/hostcalls/host-call-registers.ts` | JSDoc uses φ₇ | +| `apps/web/src/lib/fetch-codec.ts` | Fetch kind descriptions use φ subscripts | +| `apps/web/src/lib/fetch-utils.ts` | JSDoc uses φ₇/φ₈/φ₉ | +| `apps/web/src/lib/storage-utils.ts` | JSDoc uses φ8/φ9 and φ7/φ8 | +| `apps/web/src/hooks/useDebuggerActions.ts` | Comment uses φ9/φ10 | +| `packages/orchestrator/src/orchestrator.ts` | Comment uses φ8–φ11 | +| `apps/web/src/hooks/useDisassembly.test.tsx` | Assertions match φ notation | +| `apps/web/src/components/drawer/trace-display.test.ts` | Expected strings use φ | +| `apps/web/src/components/debugger/RegistersPanel.test.tsx` | Comments use φ | +| `apps/web/src/hooks/useDivergenceCheck.test.tsx` | Assertions and variables use φ | +| `apps/web/src/lib/storage-utils.test.ts` | Test names use φ | +| `apps/web/e2e/sprint-03-instructions.spec.ts` | E2E assertions match φ | +| `apps/web/e2e/sprint-04-registers.spec.ts` | E2E label assertions match φ | +| `apps/web/e2e/sprint-28-asm-raw-popover.spec.ts` | E2E ASM mode assertions match φ | +| `apps/web/e2e/integration-smoke.spec.ts` | Comment uses φ7 | + +## Acceptance Criteria + +- All user-facing register labels display φ (phi) instead of ω (omega). +- Disassembled instruction arguments in ASM mode use `φN` notation. +- Trace display uses `φ7` in host call headers and `φN` in register writes. +- Divergence detail strings use `φN:` prefix. +- Host call output preview shows `φ₇ ←`. +- No remaining references to ω in `.ts` or `.tsx` source or test files. +- All 683 unit tests pass. +- The spec/ directory documentation files are not updated (they are historical records of prior sprints). + +## Verification + +```bash +npm run build +npm test +# Confirm no ω remains in source/test files: +grep -r 'ω' --include='*.ts' --include='*.tsx' apps/ packages/ +```