Saturday, July 4, 2026

technology: bad

it ain't just, "the number of the beast."

it also the terrible user experience. 

Friday, July 3, 2026

litany of complaints

i thought only jerky web page designers did low-contrast foreground text vs. background color. but i have come across books with ink that was not really sufficiently dark. maybe they just cheaped out on printing? "The PEN / O. Henry Prize Stories 2010". 

Thursday, July 2, 2026

Saturday, June 27, 2026

can i get an amen?!

> Yeah, this is the devastating observation that undermines the whole clean taxonomy. It goes even deeper than people usually acknowledge.

Just integers alone: C says int is "at least 16 bits," could be 32 or 64. Java says int is always 32-bit signed twos-complement. JavaScript has no integers — everything is f64, and |0 is a convention not a type. Python integers are arbitrary precision by default. Rust has i8 through i128 plus isize which is platform-dependent. Haskell's Int is "at least 30 bits" per the spec but GHC makes it machine-word-sized, while Integer is arbitrary precision.

And that's just width. Overflow behavior is where it gets genuinely treacherous. C says signed overflow is undefined behavior — the compiler can assume it never happens and optimize based on that assumption, which means your program can do literally anything. Rust panics on debug, wraps on release, unless you explicitly pick wrapping_add or checked_add or saturating_add. Java wraps silently. Python can't overflow because integers grow. JavaScript... you get floating point rounding once you exceed 2^53, silently, and then n + 1 === n evaluates to true.

Division semantics differ too. -7 / 2 is -3 in most languages (truncation toward zero) but -4 in Python (floor division). The modulo operator disagrees across languages in the same way. This isn't academic — it causes real bugs when porting numeric code.

And this is the thing everyone supposedly agrees on

Integers are the canonical example of something "every language has." If we can't even agree on what a + b means, the whole portability spectrum I described is built on sand. What I called "Level 0 — universal" doesn't actually exist. Even fibonacci(n) isn't portable because for large enough n, it overflows differently per target, or doesn't overflow at all.

This extends to basically every "primitive":

Floating point is the closest to standardized thanks to IEEE 754, but languages differ on whether they expose NaN-boxing, how they handle denormals, whether -0.0 == 0.0, and whether the optimizer is allowed to reassociate operations (C with -ffast-math says yes, which breaks IEEE semantics entirely).

Strings are a nightmare. Rust has UTF-8 byte sequences. Java has UTF-16 code units. Python 3 has an abstract unicode sequence with an internal representation that varies. JavaScript uses UTF-16 but exposes individual code units, so "😀".length === 2. Go strings are UTF-8 byte slices but indexing gives you bytes not characters. Even "the length of a string" is not a well-defined concept across languages.

Booleans seem safe until you realize C didn't even have a boolean type until C99, _Bool can be 0 or 1 but any nonzero integer is truthy, while in Python bool is a subclass of int so True + True === 2, and in JavaScript [] == false but if ([]) takes the truthy branch.

Equality itself is incoherent across targets. Reference equality vs structural equality vs some hybrid. JavaScript has == vs ===. Java's == on objects is reference comparison, .equals() is structural but only if the class implements it. Haskell's ==is typeclass-dispatched. Python's is vs ==. Floating point NaN isn't equal to itself in IEEE 754, but some languages have container equality that disagrees with element equality.

What this really tells us

The honest conclusion is that there is no portable semantic foundation, not even at the level of arithmetic. Every "cross-platform" system quietly picks a semantics and then has impedance mismatches with every target. The question isn't whether to have mismatches but which mismatches you're willing to tolerate.

The approaches that actually work in practice tend to pick one of these strategies:

Lowest common denominator. Define integers as arbitrary precision, strings as unicode scalar sequences, floating point as strict IEEE 754. This is semantically clean and maximally portable, but it means emitting arbitrary-precision arithmetic on targets that don't need it — your "portable" fibonacci now runs 100x slower on C than native C because every addition goes through a bignum library when a machine instruction would have sufficed. This is roughly what Erlang/Elixir do and the performance characteristics are accepted as a tradeoff of the platform.

Pick a concrete semantics and document the gaps. This is what Java did (everything is specified precisely — 32-bit signed twos-complement wrapping integers, IEEE 754 doubles, UTF-16 strings) and it works great as long as your only target is the JVM. The moment you try to cross platforms, those precise choices become the source of mismatches.

Make the programmer choose explicitly. Rust's approach of having wrapping_addchecked_addsaturating_addoverflowing_add as separate operations. This acknowledges that "addition" is not one operation but a family of operations with different edge-case behaviors. A cross-platform kernel could adopt this — make the programmer state their intent about overflow, and then each target backend maps to the appropriate implementation. But now you've made the programmer think about something they usually don't want to think about, and you've lost the simplicity that makes a language adoptable.

Give up on semantic portability and only guarantee behavioral equivalence for some well-defined subset of inputs. This is what most practical cross-platform tools actually do. Your code is portable as long as your integers stay under 2^31, your strings are ASCII, you don't depend on hash ordering, and you don't observe overflow. The moment you leave that safe zone, behavior diverges. Nobody says this out loud but it's the pragmatic reality.

The philosophical upshot

I think what your observation really points to is that "portability" was always a spectrum of probability of correct behavior across targets, not a binary property. Even the most "universal" operation — integer addition — has target-dependent semantics at the edges. The useful question isn't "is this portable" but "for what range of inputs and usage patterns will this behave identically across targets, and how likely is my program to stay within that range?"

Which is a much harder thing to analyze or communicate to a developer, and maybe explains why nobody has really built the tooling we were discussing. The honest version of the portability annotation would be something like:

a + b
// ⚠ Portable for |result| < 2^31
// Diverges on overflow:
//   C: undefined behavior
//   Java/Rust-release: wraps to negative
//   Python: continues correctly (arbitrary precision)
//   JS: loses precision above 2^53

And if even a + b needs a footnote that long, the dream of automated portability analysis starts to look less like an engineering problem and more like a fundamental tension in computing that we just manage rather than solve.

testify!

> Booleans seem safe until you realize C didn't even have a boolean type until C99, _Bool can be 0 or 1 but any nonzero integer is truthy, while in Python bool is a subclass of int so True + True === 2, and in JavaScript [] == false but if ([]) takes the truthy branch.

Thursday, June 18, 2026

foced labor

empirically it doesn't matter if the system is so-called capitalist or communist, you are grist for the mill, or not that many steps away from it.

forced labor brands

Sunday, June 7, 2026

nuc7 worse than nuc8, hardy har har

Technical Post-Mortem: Why Linux Fails on the Dual-HDMI Intel NUC7 Commercial Series (Dawson Canyon)

If you are attempting to deploy a Linux distribution (such as Ubuntu, Debian, Mint, or Arch) on an Intel NUC7 Commercial Mini-PC layout featuring dual physical HDMI ports and zero Type-C/Thunderbolt interfaces (e.g., NUC7i7DNBE, NUC7i7DNK, NUC7i5DNKE), paired with an ultra-high resolution or ultrawide monitor ($3440 \times 1440$), you are walking into a hardware dead-end.

This warning document breaks down the underlying motherboard flaws that cause permanent black screens and keyboard locks on this hardware, and defines your only real choices forward.

1. The Invisible Hardware Lie: The LSPCON Protocol Converter

The underlying fault on these specific NUC7 units is a severe architectural mismatch between what the processor outputs and how the chassis interfaces are physically wired:

  • The Hardware Architecture: The integrated Intel graphics engine inside the CPU does not speak or output HDMI signaling lanes natively. It outputs pure, native DisplayPort (DP) signals.

  • The Middleman: To provide two full-sized physical HDMI ports on the back panel, Intel soldered a dedicated protocol converter chip directly onto the motherboard—the MegaChips LSPCON (Level Shifter / Protocol Converter).

  • The Insulation: The Linux operating system cannot see past this chip. The kernel Direct Rendering Manager (DRM) believes it is communicating directly with a native internal DisplayPort interface, completely isolating it from what the monitor is actually doing.

2. The Boot Race Condition and Kernel Deadlock

When booting a standard Linux distribution on this dual-HDMI layout, a catastrophic timing loop triggers between the software graphics driver and the motherboard firmware:

  1. The Fast Driver Load: Linux initializes incredibly fast. The millisecond the Intel i915 kernel graphics driver loads, it executes its mandatory early-boot Kernel Mode Setting (KMS) to map the video layout.

  2. The Premature Signal: The onboard LSPCON converter chip powers up and instantly signals a premature "Ready" status back to the incoming Intel driver.

  3. The Handshake Latency: While the LSPCON chip tells the kernel it is ready, it has not actually finished its own electrical link-training handshake with high-bandwidth external displays (especially massive ultrawide monitors or 4K panels, which take an extra second to negotiate power states).

  4. The Deadlock: Linux blindly trusts the premature success signal and throws the video pipeline data down the path. Because the display handshake hasn't finished, the signal hits a brick wall. The driver misinterprets this silent drop as an established success, permanently locks down the display pipeline, stops trying to initialize the port, and leaves your screen pitch-black.

3. Linux vs. Windows: Why One Breaks and One Works

It is easy to assume a physical hardware defect is present because Microsoft Windows handles the exact same machine and monitor flawlessly. The divergence comes down to entirely different driver management concepts:

  • Windows (Intel DCH Drivers): The native Windows graphics engine is explicitly written to anticipate unstable active protocol bridges and third-party motherboard level-shifters. If a video handshake fails during a boot or sleep wake cycle, the Windows driver aggressively clamps onto the Hot Plug Detect (HPD) line and runs an instantaneous background recovery loop, repeatedly resetting the video link until the hardware catches the signal.

  • Linux (DRM & i915 Driver): The Linux kernel display stack operates on rigid, structural transitions. It runs an early-boot configuration check once. If the hardware bridge fails to respond immediately, the system drops the state engine. It completely ceases active polling, leaving the pipeline jammed in a broken state.

4. The User-Space Trap: Xorg (X11) vs. Wayland

How devastating this black-screen failure is depends entirely on your chosen display server layout:

  • Legacy Xorg (Used by Xubuntu, Mint, Cinnamon, MATE): X11 operates on a rigid, blocking architecture. When a display manager like LightDM initializes early in the boot track, it assumes an exclusive system monopoly over the Linux Input stack and Virtual Terminals (VT). When the i915 driver deadlocks on the uninitialized LSPCON chip, the entire X11 server freezes. This freeze traps your input stack along with it, turning your keyboard completely dead. It is physically impossible to press Ctrl + Alt + F2 to reach a rescue terminal; the machine is completely bricked until a hard power cycle.

  • Modern Wayland (Used by standard Ubuntu, GNOME, Fedora): Wayland decouples hardware inputs via an isolated kernel abstraction layer (libinput). If the LSPCON chip drops its sync under Wayland, your screen will still go black, but your system and keyboard remain fully alive. You can instantly press Ctrl + Alt + F2 to drop into a crisp, responsive text console to rescue the machine, modify files, or gracefully check logs.

5. The False Fixes: Why Standard Advice Fails

If you browse forums looking for fixes for this specific dual-HDMI NUC7 architecture, standard advice will run into a wall:

  • The Thunderbolt Bypass (FAILED): Standard Linux documentation for consumer NUCs or NUC8 units recommends abandoning the HDMI port and using a high-quality USB-C to DisplayPort cable to bypass the LSPCON chip entirely. On a commercial Dawson Canyon NUC7, this port does not physically exist. You have no Type-C or Thunderbolt outputs. You are completely trapped behind the LSPCON.

  • Forcing Xrandr Modelines (FAILED): Trying to manually create and push custom resolutions via user-space (xrandr --newmode) throws unyielding BadValue / RRSetCrtcConfig hardware errors. The driver maps the math to the simulated DisplayPort pipeline, but the physical LSPCON bridge rejects the translations and collapses.

6. The Only Definitive Workarounds for Dawson Canyon Owners

If you own this hardware and need to deploy it, do not waste time rewriting Xorg configuration files or flashing motherboard microcode. You have only three realistic options:

Option A: Force Non-Accelerated Framebuffer Mode

You can completely break the black-screen boot lock by forcing the Linux kernel to rely entirely on the generic EFI framebuffer that your motherboard's BIOS already established safely before Linux started.

Open your bootloader configuration:

Bash
sudo nano /etc/default/grub

Set your parameter line to look exactly like this:

Plaintext
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash i915.modeset=0 nomodeset"

Run sudo update-grub and reboot.

  • The Trade-Off: The computer will boot smoothly into your full, gorgeous $3440 \times 1440$ resolution every time. However, setting nomodeset completely bars the Intel iGPU driver from running. You will have absolutely no hardware acceleration (neither 3D nor 2D). Your CPU must compute every single window movement, web browser scroll, and video canvas redraw in software. The system will be entirely stable, but the visual interface will feel sluggish.

Option B: Downgrade to a Standard 1080p Monitor

The latency of the LSPCON chip is directly tied to display bandwidth. If you connect this specific dual-HDMI NUC7 to a basic $1920 \times 1080$ display, the handshake completes fast enough to beat the Linux boot timer. You can safely remove the nomodeset restrictions and enjoy full hardware 2D and 3D acceleration.

Option C: Relinquish the Machine to a Windows OS

If the machine must drive a massive ultrawide canvas with native hardware acceleration, remove Linux and install Windows 10 or 11. The Windows Intel driver loop was exactly what this compromised dual-HDMI hardware topology was designed to run.