- 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/
+```