Skip to content

Add Kernel House educational visualization#25

Merged
jserv merged 1 commit intomainfrom
tiny-office
Mar 27, 2026
Merged

Add Kernel House educational visualization#25
jserv merged 1 commit intomainfrom
tiny-office

Conversation

@jserv
Copy link
Contributor

@jserv jserv commented Mar 27, 2026

Pixel-art cross-section of Linux subsystems driven by syscall telemetry from kbox's seccomp-unotify intercept path.

Scene layout:

  • 8 rooms (User Space, Syscall Gate, VFS, Process, Memory, Network, Block I/O, FD Table) rendered on an offscreen-cached static canvas
  • Warm tinyoffice-inspired palette with floor tile grid
  • Theme-aware (dark/light) for all visual elements

Character system:

  • 16x28px Tux sprite sheets (7 frames x 3 directions) at 2.5x scale
  • Waddle animation: sinusoidal side-to-side sway + vertical bob + body tilt
  • 6 resident penguins with role accessories (hat, folder, stopwatch, etc.)
  • 8-penguin guest pool representing active syscall flows

Telemetry binding:

  • SSE sampled events drive guest penguin lifecycle (attic -> gate -> room)
  • /api/snapshot deltas drive room glow intensity
  • Disposition color coding (green=CONTINUE, blue=LKL, orange=ENOSYS)
  • PID tracking with syscall-pattern activity inference for User Space

Interactive features:

  • Hover tooltip showing PID, command, syscall, dispatch method
  • Clickable rooms with kernel subsystem descriptions from strings.json
  • Narrator mode for educational commentary on interesting transitions
  • Flow arrows showing active gate-to-room dispatch paths
  • FD Table gauge (fd.used/fd.max with color-coded bar)
  • Demo mode with scripted "cat /etc/hostname" narrative
  • Screenshot export via canvas.toDataURL

Robustness:

  • Offline detection (2 consecutive poll failures -> overlay + animation stop)
  • Pause freezes animation without accumulating tick backlog
  • Demo runs independently of pause state, cancellable via Stop Demo
  • Intent queue with room-fair FIFO scheduling and walk concurrency cap
  • demoVersion token invalidates in-flight walk callbacks on cancel

Change-Id: I25f0eaea1d3622b4a838144904c9e543b343e8a2


Summary by cubic

Adds the “Kernel House” visualization: a pixel‑art cross‑section of Linux subsystems driven by seccomp telemetry. It’s interactive, theme‑aware, and includes a demo and screenshot export.

  • New Features

    • New tab bar and “Kernel House” tab with a canvas scene of 8 rooms (User Space, Gate, VFS, Process, Memory, Network, Block I/O, FD Table).
    • Penguin system: resident roles with accessories plus an 8‑penguin guest pool; smooth walk/type/error animations and speech bubbles.
    • Telemetry bridge: SSE events animate guest flows (attic → gate → room); /api/snapshot deltas drive room glow; disposition colors; PID/tooltips and FD gauge.
    • Education tools: clickable room panels from strings.json, narrator mode, flow arrows, demo (“cat /etc/hostname”), and screenshot export.
    • Infrastructure: serve .png/.json in the web server; include PNG/JSON in scripts/gen-web-assets.sh; adds sprite generator and art assets; robust pause/offline handling and a fair intent queue.
  • Migration

    • Rebuild the web server to pick up new content types and assets.
    • Optional: regenerate sprites via scripts/gen-penguin-sprites.py if modifying art.

Written for commit c673958. Summary will update on new commits.

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

10 issues found across 24 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="web/js/penguin.js">

<violation number="1" location="web/js/penguin.js:136">
P2: Reset `flipX` when movement is vertical so horizontal mirroring does not leak into up/down facing sprites.</violation>

<violation number="2" location="web/js/penguin.js:242">
P2: Only render trail dots during walking (or clear them on state change) to avoid stale ghost trails when penguins stop.</violation>
</file>

<file name="web/js/bubble.js">

<violation number="1" location="web/js/bubble.js:106">
P2: Delayed bubble removal captures a loop-scoped `var`, so multiple expirations in one pass can remove the wrong element.</violation>
</file>

<file name="web/js/scene.js">

<violation number="1" location="web/js/scene.js:312">
P2: Room label fallback is broken: missing translations render i18n key paths instead of `room.label`.</violation>

<violation number="2" location="web/js/scene.js:383">
P3: Clamp FD usage percentage before drawing to prevent gauge overflow/underflow on inconsistent telemetry.</violation>
</file>

<file name="web/js/education.js">

<violation number="1" location="web/js/education.js:49">
P2: `||` fallbacks after `KScene.str(...)` never execute, so missing strings show raw key paths instead of the intended defaults.</violation>
</file>

<file name="web/js/intent.js">

<violation number="1" location="web/js/intent.js:284">
P1: The delayed guest release uses a stale timer guard (`visible`) that can release a reused guest from a newer flow.</violation>
</file>

<file name="web/js/house.js">

<violation number="1" location="web/js/house.js:246">
P2: Reset `crowdCount` during offline cleanup to avoid a stale overflow badge after guests are cleared.</violation>

<violation number="2" location="web/js/house.js:624">
P3: Set `g4.room` when it arrives in Scene 4 so tooltip/state reflects the actual room.</violation>
</file>

<file name="web/js/strings.json">

<violation number="1" location="web/js/strings.json:25">
P2: The Process Management description incorrectly says scheduling syscalls are forwarded to LKL; they are handled via host CONTINUE.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.


/* Fade out in-place (guard: skip if guest was already released
* by showOffline or cancelDemo while this timer was pending) */
setTimeout(function() {
Copy link

@cubic-dev-ai cubic-dev-ai bot Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: The delayed guest release uses a stale timer guard (visible) that can release a reused guest from a newer flow.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At web/js/intent.js, line 284:

<comment>The delayed guest release uses a stale timer guard (`visible`) that can release a reused guest from a newer flow.</comment>

<file context>
@@ -0,0 +1,297 @@
+
+    /* Fade out in-place (guard: skip if guest was already released
+     * by showOffline or cancelDemo while this timer was pending) */
+    setTimeout(function() {
+      if (!guest.visible) return;
+      KHouse.resetGuest(guest);
</file context>
Fix with Cubic

if (Math.abs(dx) > Math.abs(dy)) {
p.facing = 2;
p.flipX = dx > 0;
} else if (dy < 0) {
Copy link

@cubic-dev-ai cubic-dev-ai bot Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Reset flipX when movement is vertical so horizontal mirroring does not leak into up/down facing sprites.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At web/js/penguin.js, line 136:

<comment>Reset `flipX` when movement is vertical so horizontal mirroring does not leak into up/down facing sprites.</comment>

<file context>
@@ -0,0 +1,306 @@
+    if (Math.abs(dx) > Math.abs(dy)) {
+      p.facing = 2;
+      p.flipX = dx > 0;
+    } else if (dy < 0) {
+      p.facing = 1;
+    } else {
</file context>
Fix with Cubic

var dy = Math.round(p.y - dh) + bob;

/* Motion trail (3 dots max, only for walking tinted guests) */
if (p.trail.length > 0 && p.tint) {
Copy link

@cubic-dev-ai cubic-dev-ai bot Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Only render trail dots during walking (or clear them on state change) to avoid stale ghost trails when penguins stop.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At web/js/penguin.js, line 242:

<comment>Only render trail dots during walking (or clear them on state change) to avoid stale ghost trails when penguins stop.</comment>

<file context>
@@ -0,0 +1,306 @@
+    var dy = Math.round(p.y - dh) + bob;
+
+    /* Motion trail (3 dots max, only for walking tinted guests) */
+    if (p.trail.length > 0 && p.tint) {
+      ctx.save();
+      ctx.fillStyle = p.tint;
</file context>
Fix with Cubic

sctx.strokeRect(rect.x + 0.5, rect.y + 0.5, rect.w - 1, rect.h - 1);

/* Label with text shadow */
var label = this.str('rooms.' + id + '.name') || room.label;
Copy link

@cubic-dev-ai cubic-dev-ai bot Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Room label fallback is broken: missing translations render i18n key paths instead of room.label.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At web/js/scene.js, line 312:

<comment>Room label fallback is broken: missing translations render i18n key paths instead of `room.label`.</comment>

<file context>
@@ -0,0 +1,468 @@
+      sctx.strokeRect(rect.x + 0.5, rect.y + 0.5, rect.w - 1, rect.h - 1);
+
+      /* Label with text shadow */
+      var label = this.str('rooms.' + id + '.name') || room.label;
+      sctx.textAlign = 'center';
+      sctx.textBaseline = 'top';
</file context>
Fix with Cubic

this.closePanel();
if (!KScene.overlay) return;

var name = KScene.str('rooms.' + roomId + '.name') || roomId;
Copy link

@cubic-dev-ai cubic-dev-ai bot Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: || fallbacks after KScene.str(...) never execute, so missing strings show raw key paths instead of the intended defaults.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At web/js/education.js, line 49:

<comment>`||` fallbacks after `KScene.str(...)` never execute, so missing strings show raw key paths instead of the intended defaults.</comment>

<file context>
@@ -0,0 +1,266 @@
+    this.closePanel();
+    if (!KScene.overlay) return;
+
+    var name = KScene.str('rooms.' + roomId + '.name') || roomId;
+    var desc = KScene.str('rooms.' + roomId + '.desc') || '';
+    var src = KScene.str('rooms.' + roomId + '.source') || '';
</file context>
Fix with Cubic

/* Clear bubbles and intent queue */
KBubble.clear();
KIntent.queue = [];
KIntent.activeWalks = 0;
Copy link

@cubic-dev-ai cubic-dev-ai bot Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Reset crowdCount during offline cleanup to avoid a stale overflow badge after guests are cleared.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At web/js/house.js, line 246:

<comment>Reset `crowdCount` during offline cleanup to avoid a stale overflow badge after guests are cleared.</comment>

<file context>
@@ -0,0 +1,665 @@
+    /* Clear bubbles and intent queue */
+    KBubble.clear();
+    KIntent.queue = [];
+    KIntent.activeWalks = 0;
+    /* Cancel any demo */
+    if (this.demoRunning) {
</file context>
Fix with Cubic

Pixel-art cross-section of Linux subsystems driven by syscall telemetry
from kbox's seccomp-unotify intercept path.

Scene layout:
- 8 rooms (User Space, Syscall Gate, VFS, Process, Memory, Network,
  Block I/O, FD Table) rendered on an offscreen-cached static canvas
- Warm tinyoffice-inspired palette with floor tile grid
- Theme-aware (dark/light) for all visual elements

Character system:
- 16x28px Tux sprite sheets (7 frames x 3 directions) at 2.5x scale
- Waddle animation: sinusoidal side-to-side sway + vertical bob + body tilt
- 6 resident penguins with role accessories (hat, folder, stopwatch, etc.)
- 8-penguin guest pool representing active syscall flows

Telemetry binding:
- SSE sampled events drive guest penguin lifecycle (attic -> gate -> room)
- /api/snapshot deltas drive room glow intensity
- Disposition color coding (green=CONTINUE, blue=LKL, orange=ENOSYS)
- PID tracking with syscall-pattern activity inference for User Space

Interactive features:
- Hover tooltip showing PID, command, syscall, dispatch method
- Clickable rooms with kernel subsystem descriptions from strings.json
- Narrator mode for educational commentary on interesting transitions
- Flow arrows showing active gate-to-room dispatch paths
- FD Table gauge (fd.used/fd.max with color-coded bar)
- Demo mode with scripted "cat /etc/hostname" narrative
- Screenshot export via canvas.toDataURL

Robustness:
- Offline detection (2 consecutive poll failures -> overlay + animation stop)
- Pause freezes animation without accumulating tick backlog
- Demo runs independently of pause state, cancellable via Stop Demo
- Intent queue with room-fair FIFO scheduling and walk concurrency cap
- demoVersion token invalidates in-flight walk callbacks on cancel

Change-Id: I25f0eaea1d3622b4a838144904c9e543b343e8a2
@jserv jserv merged commit 1e9b419 into main Mar 27, 2026
3 checks passed
@jserv jserv deleted the tiny-office branch March 27, 2026 02:32
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