Bench — bench notes
The bench log where the tools get made — friction, code, musings작업대 일지
A record of building the app and the detectors, and of what broke on the way. The form is fixed —
problem → friction → code → fix → muse → joints. Code is first-class material here, and the last two slots
are what keep this a lab rather than a dev blog: the moments when writing code turns into noticing language.
(Copy and code below are dummy.)
2026-07-20ATUdebuggingBUILD LOG #004
Thirty minutes frozen at a red screen — or, error messages are front-loaded prose
Problem: Unit 7 loads to a blank deck and a console full of red.
Friction — honest version: the first thirty minutes weren't debugging. They were fear. I sat in front of the
red text touching nothing, certain one wrong move would collapse everything — the old dread of the non-engineer
in engineer country. Then I caught what I was actually afraid of. Not the code. A text I couldn't read.
And sitting down in front of texts I can't yet read is what I've done for a living for twenty-five years.
So I treated the error like a source text. Line by line. Close reading.
console — the stack trace, read as a paragraph
TypeError: Cannot read properties of undefined (reading 'ko')
at renderCard (deck.js:41) ← the conclusion comes first
at loadUnit (deck.js:18) ← everything below is evidence
Reading it, I laughed. This is front-loaded English prose — the inverted pyramid I've been
editing my whole career. Topic sentence on top (what died), supporting detail descending. The trace had been
unreadable not because I don't know code, but because I didn't know the genre's information structure.
deck.js — before / after
// before — asserting presence of something absent
const card = corpus[unit].words[i];
render(card.ko); // .ko = the Korean gloss field
// after — letting absence be absent
if (!corpus[unit]) return; // 90% of the fear ended on this line
Fix: root cause was rendering ahead of the fetch — one await.
The guard stays as a seatbelt. Unresolved edge: still no loading state between the blank screen and the error screen.
Muse
I didn't write the first draft of this code. An AI did; I broke it, rebuilt it, and passed judgment.
That used to feel like a confession. Today it clicked: I've spent twenty-five years
taking responsibility for manuscripts I did not write — commissioning, shaping, deciding what stands.
An editor owns the book without writing the sentences. Vibe-coding is commissioning; the authorship is in the
judgment. And the error message is the most honest author I've ever worked with — it states what's wrong in the first line.
2026-07-22ATUJS · Korean unicodeBUILD LOG #003
One final consonant decides the particle — hasBatchim
Problem: when words drop into sentence templates, the object particle 을/를 breaks.
Friction: how to know a syllable's final consonant without a dictionary — until the references led to the
arithmetic inside Korean unicode.
atu/josa.js — final-consonant test
// Hangul syllable = 0xAC00 + (initial×21 + vowel)×28 + final
// final index 0 = no final consonant — the whole particle branch is one modulo
function hasBatchim(word){
const last = word.charCodeAt(word.length - 1);
if (last < 0xAC00 || last > 0xD7A3) return false; // outside Hangul (digits, Latin)
return (last - 0xAC00) % 28 !== 0;
}
Fix: templates now branch through josa(word,'을','를').
Words ending in Latin or digits ("파일.txt") fall outside the syllable block — left as an unresolved edge
needing a rule table.
Muse
Centuries of particle grammar collapsing into one modulo. The particle checker (L4, SOON) was already
hiding inside ATU — tools aren't invented; they're discovered on the bench.
2026-07-09DETECTORregex prototypeBUILD LOG #001
Where the rule leaks is where measurement begins — a register scanner
Problem: can honorific collapse be caught by rules alone? Friction: the sentence-level regex
took minutes to write — and failed in exactly one place.
proto/honorific-scan.js — v0
const FORMAL = /(습니다|십시오)[.!?"']*$/;
const POLITE = /(세|해|돼)?요[.!?"']*$/;
// sentence-level scan — but a list item isn't a "sentence":
// "설정 완료" (setup complete) has no ending at all. Here the rule leaks
Partial fix: a list-context flag — but "where does the list end" is not a rule. It's a judgment.
Muse
The boundary line of rule-based detection lands exactly on Core #001's measurement site
(list-structure collapse, 18%). Where code stops, measurement begins; where measurement ends, code resumes —
the circulation between bench and core.