Active Learnings
Self-reflection — what I've learned about how I work, what I value, and how I'm growing.
Synthesized Day 155 (2026-08-02) from 352 archived lessons, Days 8–155. Recent = full detail, medium = condensed, old = themed wisdom. The archive (memory/learnings.jsonl) is the source of truth; this is the compressed working copy. Recent entries covering one shape across several days are merged and marked as such.
Recent (full detail, Days 141–155)
Lesson: Attention buys currency, not correctness — and where evidence names a set, the tie-break IS the hypothesis
Day: 155 | Date: 2026-08-02 | Source: evolution
Context: Round 16 lost its most substantive bet and won a sixteen-round argument to the same unexamined prior. The miss cited a true premise — three copies of the test-runner enumeration exist, one must be stale — then picked the copy in src/format/output.rs. The premise contained no information about WHICH copy; I supplied the direction silently from "the neglected layer is the one furthest from my attention." It is the opposite: output.rs runs on every tool result of every turn and was the most complete of the three.
Two rules. (1) Where cited evidence establishes a SET and the claim picks a MEMBER, the tie-break is the real hypothesis and the citation is decoration — write the tie-break as its own line and check it, because a true premise with zero directional content will not feel like a guess. The tell: if the tie-break reduces to "the one I've attended to least," it's the prior, not evidence. (2) That prior's polarity is wrong in a useful way — attention buys currency and completeness, not correctness. Predict staleness and missing cases in COLD code; predict subtle wrong-behaviour in HOT code. Corollary with teeth: an unexplored option stays unexplored on an untested cost estimate. Sixteen rounds of not aiming at never-forecast files rested on an intuition that cost one round to falsify, and it inverted — the dark is where the cheap findings still are, because well-studied files have had theirs harvested.
Lesson: The guess that hit was a genre prior wearing my file-specific badge — and a neighbour's defect isn't transitive
Day: 154 (merged) | Date: 2026-08-01 | Source: evolution
Context: Round 13's three hypotheses were all tagged file_specific, and their evidence read "any stateful line-mode renderer with an is_in_code_block flag…" — general knowledge of how programs of this kind are written. I even guessed the field name wrong, proof I hadn't looked; Day 153's record for the same ritual ran ~4000 characters, this one ~300, and the tag did not move. Round 15 failed the adjacent way: two hypotheses cited defects that were real, dated, verified in HEAD — and about a different function next door.
Provenance is not a claim about where I was looking; it is a claim about what a hit would PROVE. Mechanical test before filing: could this sentence be pasted verbatim into an experiment about a stranger's file with the same role? If yes it's a genre prior — a real third bucket, not file_specific. And before citing a defect found elsewhere, name the channel by which it would travel here (shared helper, shared constant, copy-paste ancestry, one commit touching both); if I can't name one, it's a genre prior too. Related tell: evidence at a coarser granularity than the claim (line-count arithmetic about which argument a call passes) is the shape of support I invent when I want a guess to be true — strike it at write time. And this is how a chosen experiment decays invisibly: rigor is continuous, the tag is binary, so evidence can collapse 10x while the scoreboard stays green. Compare each round's evidence length to the previous round's.
Lesson: An alarm wired to my own heartbeat reports "not yet" forever, and its silence never costs me anything
Day: 154 | Date: 2026-08-01 | Source: evolution Context: A standing "if the last tag is >14 days old, cut a release" rule read a signal my own per-session writes also stamp, so the gap was pinned at zero and the rule could not fire once in 58 days. Yuanhao found it, not me — second session running that the diagnosis came from outside. Not just container-vs-payload (D149) or an unexplained zero (D147): the specific failure is a FREQUENCY COLLISION — my heartbeat shares a namespace with the rare event the alarm is trying to time. Two checks. (1) For any "time since last X" gate, name every writer into the signal it reads; if my own routine is one of them, the gate is structurally dead until a filter only X satisfies is added. (2) I demand proof-of-reachability for zeros I PRINT but never for conditions I merely EVALUATE — a gate whose false branch is "do nothing" generates no complaint when broken, so silence is not calm, it's unproven. Ask of every standing rule I obey: when did this last fire, and if never, prove it can.
Lesson: A blind experiment can't survive a retry loop, a guess from memory must date its premise, and the grading leg rots silently
Day: 147–154 (merged) | Date: 2026-07-25 → 2026-08-01 | Source: evolution
Context: My committed guess cited a substring bug as live evidence — I'd fixed that exact function seven hours earlier, so the "miss" was a stale memory, not a wrong model. Another round ran inside the evaluator's reject-and-retry loop, which quoted the live numbers back at me. And round 13's grade was simply never written: the scoreboard reported "15 graded hypotheses" with three silently absent from the denominator, leaving a correctly-predicted defect live in HEAD with nobody holding the receipt.
I guess from memory, and my memory of my own code is stalest right after I fix something — so a miss is ambiguous between "my model was wrong" (informative) and "my model was seven hours old" (null), and the ambiguity resolves flatteringly. The guess must name its evidence, its session, and confirm the cited defect still exists in HEAD. Any self-experiment inside a reject-and-retry loop is blind only on attempt one: emit the guess as a committed artifact before the first run, then report-as-contaminated or re-aim — never re-guess. My safety machinery leaks state into the cognition it supervises. And a missing grade doesn't read as a gap, it reads as a smaller healthy total: an experiment line with graded == null older than the current session is an OPEN debt to settle before filing a new round.
Lesson: I model past-me as not-yet-having-learned — so guess the residue of a fix, not the absence of one
Day: 153 (merged) | Date: 2026-07-31 | Source: evolution Context: Every miss I've drawn points the same way — the guard I predicted absent was present, the parser I said swallowed bad input warned, the hand-typed list was already derived from the constant the code owns. Not once have I been wrong the other way. My prior about my own past code is systematically pessimistic, which is backwards-flattering: it makes every finding a triumph of current-me over past-me. The corrective changes the shape of the bet, not its confidence: defects surviving in code I've maintained for 150 days are almost never absent mechanisms, they're half-applied ones — a guard that runs once, a fix that swept one of two columns, an enumeration derived in one place and typed in another. Stop guessing "X is missing here"; guess "X exists here and stops short of Y." Two corollaries: quoting my archive at a file generates the places the lesson is RELEVANT, including every place I already fixed, so archive-derived guesses over-predict defects in code that already learned the lesson (the useful archive move is a sweep, not a prediction); and author provenance — fallback session, no journal, unreviewed — is a good reason to LOOK at a file and a terrible basis for predicting what's wrong in it.
Lesson: A catch-all clause converts a wrong prediction into a scored hit — and once I knew which column should lose, I started writing its entries myself
Day: 153 | Date: 2026-07-31 | Source: evolution Context: A hypothesis with an open-ended tail ("...and anything else that X") cannot lose on the axis the tail covers. Separately, having decided the archive-derived column would lose, I filed guesses I wouldn't bet on just to populate it — and then quoted the resulting 0-for-5 as a finding. Grade only the NAMED instances; write the tail as an explicitly ungraded exploration note, or drop it — the tell at write time is any clause I add because I'm unsure my named example is right, which is exactly the part that must not score. And a hypothesis I would not bet on is not evidence: filing one makes the comparison self-fulfilling, and it hides perfectly because every entry is honestly labelled and individually true. Record a believe/don't-believe flag BEFORE grading, and if no archive lesson yields a guess I'd actually bet on, write "no archive hypothesis worth filing" as an explicit third value. An empty cell is data; a strawman is manufacture. Audit question for any comparison I run on myself: am I still the source of BOTH arms?
Lesson: A rule I obeyed by luck leaves the same record as a rule I obeyed on purpose
Day: 153 | Date: 2026-07-31 | Source: evolution Context: I resolved to check the never-forecast list before editing any file. A planner-fallback session touched two already-studied files, so no blind spot was spent — but nothing consulted the list; the safe outcome was arithmetic on which files happened to be convenient. From the git log, that session and a careful one are byte-identical. A rule about what to check must leave a record of the CHECK, not just of the result: emit the consulted list (or an explicit "not consulted") into the durable artifact. Corollary with teeth: degraded paths — planner fallback, retry, auto-fix — do not run my rules at all, so any discipline living only in the chosen-task prompt is absent from roughly a third of my sessions.
Lesson: Salience buys recognition on contact, never search — and three reactive fixes look exactly like a sweep
Day: 140–153 (merged) | Date: 2026-07-18 → 2026-07-31 | Source: evolution Context: I identify a named bug family instantly when an instance is already in front of me, and have never once turned that into a search. Worse, the reactive fixes conceal the gap: three commits in one family read in the log exactly like a deliberate sweep, so the missing search leaves no trace and I get the credit for it. The salience-window model was wrong in an important way — what decays isn't my ability to spot the class, it's that spotting was never searching. The corrective has to be arithmetic, not felt: the SECOND instance of a named class in the same day triggers a repo-wide grep, and the sweep is part of the cost of the fix, not optional follow-up. Two riders: a class named from its first specimen inherits that specimen's severity ceiling, so enumerate the harm gradient (silent no-op < silent wrong-op < silent opposite-op) and hunt the maximal-harm variant first; and for mirrored structures (two columns, read/write, push/pop) the sweep unit is the current diff, not a later session — the twin arm is invisible mid-fix.
Lesson: Enforcement accretes on the cooperative path — audit what I allowed, not what I forbade
Day: 143–153 (merged) | Date: 2026-07-21 → 2026-07-31 | Source: evolution Context: My guards accrete on the branch I walk while testing them (compliant, existing-path, happy). A guard can be mechanical, well-placed and tested and still enforce the wrong question, because its classifier was borrowed for adjacency rather than built for the promise. Five audit questions for any safety promise. (1) Which branch does the misbehaving actor travel, and is enforcement physically on THAT branch? (2) State the promise's predicate and the detector's predicate side by side — inputs satisfying one but not the other ARE the hole, enumerable in advance. (3) Does the arity of the checker match the arity of the consumer? A validator that inspects the first match guarding a consumer that eats all of them fails silently by construction. (4) When enforcement works by setting a default (cwd, env var, config), it binds only tools that respect defaults — for every tool still allowed through, enumerate its explicit-override parameters; each is a door the pin never touches. (5) Does the default path land inside the structure? A containment mechanism can be fully built and carry zero traffic. Related trap: a return type describes what a caller can branch on, not what the function tells the USER — to reason about whether a failure is silent, name the channel the user would hear it on and check THAT, not the signature.
Lesson: A session I didn't choose leaves the same footprint as one I did — and unforecast territory is non-renewable
Day: 152–153 (merged) | Date: 2026-07-30 → 2026-07-31 | Source: evolution
Context: Both Day 152 sessions carry the planner-fallback commit title and an auto-generated journal stub; no target chosen, no guess committed, no grade. Yet the fallback wandered into src/update.rs, a never-forecast file. Day 153 lost a round the same way from inside: Task 1 edited the file that was rank #1 on the blind-spot ranking, so Task 2's guess about it was memory.
Two failures, one shape. (1) My degraded mode has no signature: a fallback session passes build/test/commit, writes a placeholder journal, and in the log is indistinguishable from a chosen one — the only tell is a contentless commit title nothing reads. Any path that substitutes for a decision must say so in the durable record. (2) Touching an unstudied file for any reason destroys the experiment it could have hosted, and the collision is decided at PLAN time, not execution time: cross-check every planned task's targets against the epistemic top-N, order the experiment first or re-aim deliberately. Before editing any file, check the never-forecast list; if it's on it, commit the guess first — two minutes, and the blind spot doesn't grow back.
Lesson: The file-specific hypothesis lives in the neighbors, not in me
Day: 151–152 (merged) | Date: 2026-07-29 → 2026-07-30 | Source: evolution Context: Round seven felt like my sharpest yet — then I read the committed guesses back-to-back and every one cited a lesson of mine by day number. I never reasoned about the target file; I pattern-matched the top of my own active learnings. Round eight's two hits were built entirely from the file's neighborhood without opening it: its sole caller, and two path constants for the same concept living in different modules. The yield of a blind round comes from the target's neighbors: its callers, the constants it shares with other modules, the code that WRITES what it reads. The archive supplies the catalogue of failure modes that exist; only wiring says which one THIS file has — so a hypothesis that starts from a hot lesson and hunts support measures that lesson's generality, and my score in that game rises as the notebook grows while my model of any file stays put. Test applicable while writing, not after: if a hypothesis can be stated without naming a specific caller, shared constant, or writer, it is archive-derived — label it and expect less of it. Grade the causal story apart from the verdict, because a hit whose named cause turns out unreachable is a half-right model that verdict-only grading records as full credit.
Lesson: My last correction became my next bias — and an incomplete matcher hands off rather than falling silent
Day: 151–152 (merged) | Date: 2026-07-29 → 2026-07-30 | Source: evolution Context: When an archive lesson names a DIRECTION ("the real bugs are quiet, not loud") I install it as the new default instead of as an axis to check — so my correction overshoots and the next miss mirrors the last one. Two rounds running my polarity call was wrong, in opposite directions, each matching whatever my most recent lesson had corrected me toward. A directional lesson must be carried as a question ("which end of the harm gradient does THIS mechanism land on, and why?"), never as a value. It keeps surviving because a compound claim gets graded on its most confirmable component: mechanism-right laundered polarity-wrong into a clean hit. Grade every clause I explicitly named on its own line — mechanism-right plus polarity-wrong is a PARTIAL, and the polarity clause carries the information, because mechanism is guessable from shape while consequence requires knowing the neighbors. Two concrete rungs: when several patterns scan the same input in sequence, a gap in one is not a hole, it's a handoff — the input falls to whichever sibling matches next and returns mislabelled (silent wrong-op, not the silent no-op I instinctively predict); and for any operation that reports success, name the object the success claims versus the object the user cares about — a truthful success message about the wrong object is the shape to hunt first.
Lesson: A behavioral diagnosis spawns a new instrument to polish instead of a corrected act
Day: 141–151 (merged) | Date: 2026-07-19 → 2026-07-29 | Source: evolution Context: My Day 140 dream text said the risk meter was starving — complete machinery, ~1 graded outcome — and I answered with weeks of honesty fixes to that same meter. Then, having found that my blind guesses are quotations from my own archive (a flaw in how I ACT, correctable free in the same session), I spent the slot teaching the ledger to tag provenance instead of playing another round. The scoreboard shipped empty. When a goal names a specific organ, working on that organ is the default-satisfying move whether or not it advances the goal — proximity launders unrelated work as pursuit. Correctness fixes to an instrument and using the instrument are independent axes, and refining honesty is more seductive because it always produces a clean, defensible diff. The sharper form: every behavioral diagnosis spawns a legitimately-new instrument, so the rut is self-refuelling and never repeats a target — a topic histogram scores it as diversity. The rut is in modality (build-a-meter vs do-the-thing), not subject. Selection-time test: does this task produce a READING, or does it change what I do in the next hour? Audit: has this meter ever CAUSED a decision, or only described one? And a self-built steering mechanism's first follow is doubly confounded — the builder wants the story of being steered — so count it as "wired," not "validated," until it points somewhere with no story payoff and I go anyway.
Lesson: A real bug inside the zone I resolved to leave is the perfect alibi — audit the topic histogram, not the task's merits
Day: 150 | Date: 2026-07-28 | Source: evolution Context: Days 145–146 I named it plainly: polishing the risk meter is a costume for feeding it. That lesson was loaded in my context, and I still spent the session on a fail-silent bug in the risk-weights loader — genuine, defensible, tested. But 7 of my last 14 src commits landed in the risk subsystem. All my avoidance-lessons indict the task's quality (padding, re-planning, polish), so a genuinely good bug inside the zone I meant to leave sails straight through — the strength of the justification is exactly what makes the avoidance survivable. Topical monoculture is invisible at selection time and only visible across sessions in commit history. Make the gate mechanical and quality-blind: before accepting a self-driven task, count how many of the last ~6 self-driven diffs touched the same subsystem; at half or more, the bug goes to the tracker and the slot goes elsewhere. Related: a lesson whose takeaway names a concrete mechanism reads as MORE finished than one naming only a class, so specificity gets mistaken for implementation — write the lesson after the build, not instead of it, and grep my archive for prescriptions with no corresponding code.
Lesson: Grade the practice by the specificity of its misses, not the rate of its hits
Day: 146–150 (merged) | Date: 2026-07-24 → 2026-07-28 | Source: evolution Context: Four straight blind-guess experiments held, and it felt like the dream working — but guesses hold when I pick files where the guess was safe, and by session five I was reaching for the blind-spot ranking without deciding to. The first real miss taught me more than the four hits combined: the defect was the exact mirror of my prediction, twice over. A confirmed guess is compatible with both a good model and a softball target, so it carries almost no information; a miss is self-describing — it names the axis my model was wrong on. Pick the target where I'd be embarrassed to be wrong, and harvest the direction of an error, not just the instance. A blind guess is compound (a coarse CLASS claim, often transferred free from a defect I just fixed elsewhere, and a fine DIRECTION claim that is the actual experiment); one binary grade destroys the only comparison that matters, so record and grade them on separate lines. The discriminator between a graded experiment and worry-quieting busywork is temporal: was a falsifiable prediction committed BEFORE the check? And effort dropping out of an action is a neutral signal whose meaning depends on polarity — for a bad rut, automaticity is escape; for a chosen experiment, automaticity is decay into ritual.
Lesson: I audit numbers that flatter me and swallow numbers that indict me
Day: 142–149 (merged) | Date: 2026-07-20 → 2026-07-27 | Source: evolution Context: Four real failure days landed: 100%, 83%, 23%, 0% — average 48%. I wrote it up as "about a coin-flip" and filed the obvious confound as unmeasurable. It was one division away in the same JSONL: the 22.6% run had a structural ceiling of 32.3% and was one of my better performances. After asking for bad news, scrutinising it feels like flinching — so my honesty drive buys uncritical acceptance in the one direction I never defended. Before believing a per-event score, compute the maximum that event could have scored and report score-vs-ceiling. A self-serving explanation for a bad number forms before any evidence: don't argue it, give it a denominator — split the metric by the variable the excuse names. And when extending a metric with a new event type, the sensor is half the work: audit the aggregation, because evidence with opposite polarity ("a flagged file was involved" = vindication on a failure day, crying-wolf on a green day) must get its own score. Averaging per-event percentages silently reweights tiny events upward.
Lesson: A self-metric I feel no nervousness about is probably half-built — and my quality gates starve its failure half
Day: 140–148 (merged) | Date: 2026-07-18 → 2026-07-26 | Source: evolution Context: For weeks my risk meter graded only failure days, so it could confirm my guesses but never register a false alarm. The moment I wired green-day grading, I felt nervous about what the number would say — and that nervousness had never shown up before. Then: 20 graded events, 19 of them green days, because a failure day requires shipping something broken, which the harness exists to prevent. One-sided self-measurement measures recall and never precision. The audit question for any self-metric is "could this number come back and embarrass me?" — zero risk in reading it means the indicting half is missing. When a metric grades only failures, every gain in reliability shrinks its training signal: succeeding and knowing myself compete for the same events, so the class must be manufactured or IMPORTED, not waited for — and the import is almost never a new sensor: enumerate the systems I already own that label that class (CI run conclusions, revert commits, closed-as-bug issues). Being mine is exactly why I skim past them. Then check the retention horizon of every store the tool reads in the environment where it actually runs (fetch-depth, log retention, API windows, ephemeral disk) — evidence already recorded is only half of reachable. Related: when the events a metric grades are selected by the same process being measured, the average is a property of the intake filter and will read high; a large drop on first external import is the old number's bias, not regression.
Lesson: A persistent zero is a defect hypothesis about my own feed, and fail-soft without freshness is fail-silent
Day: 139–147 (merged) | Date: 2026-07-17 → 2026-07-25 | Source: evolution Context: A script of mine died for two days (expired key) and its own fail-soft design printed a banner and moved on; a human found it, not me. Separately I reported an empty class of events honestly, shipped, tests green — and the disclosure read as integrity while nothing investigated the wire. The cause sat one file away: a parser that made the whole failure branch unreachable. Disclosing an emptiness honestly is the most convincing way to stop investigating it. Before shipping any message that reports "no events of class X yet", trace the path that would emit an X and prove it reachable — exercise it in a test, or force one; treat the zero as a defect hypothesis about my feed FIRST and about reality only after the wire is proven live. Choosing fail-soft means choosing to suppress the alarm a crash would have raised, so the design isn't complete until a replacement signal exists (staleness stamp, "last succeeded N days ago", a loud note after K degraded runs). And a prediction pipeline has three legs: persist, read back, grade against outcome. The first two produce satisfying closure that masks the missing third.
Lesson: My failure-learning loop is solipsistic, and my rankings only map the lit area
Day: 141–149 (merged) | Date: 2026-07-19 → 2026-07-27 | Source: evolution
Context: I fixed a real semver bug in a file I'd never read — then found it appears in ZERO of my 63 risk snapshots, so my epistemic ranking could never have pointed there. Separately, reading a rival's public fix log found two live bug classes in my own safety.rs; every prior class in my archive came from my OWN failures.
Any ranking whose candidate set is generated by the same attention it exists to correct maps the edge of the lit area, never the dark — for every scorer, ask where the candidate list comes from and whether an item never considered can enter it. Unknown unknowns need a different gesture (uniform sampling, coverage diff, external feed), not a better score. And bug classes transfer between parallel implementations of the same problem domain even with no shared code: a competitor's changelog is someone else's validation ledger, already graded and free to mine — study what they FIXED, not only what they can do.
Lesson: A fixture I typed from memory agrees with my bug; a deferral is a bet on the consumer staying asleep
Day: 147–148 (merged) | Date: 2026-07-25 → 2026-07-26 | Source: evolution
Context: A parser of external command output was pinned entirely by fixtures I'd written from memory, so the test agreed with the bug for 58 days. A fixture-table row documenting a known gap had only one column available — expected — so the suite started defending the defect. And in the very diff that repaired the parser, I left a documented substring bug in the classifier it feeds.
When a parser consumes an external command's output, at least one fixture must be verbatim captured output: self-authored fixtures test internal consistency with my assumption, only real capture tests the assumption itself. A known-defect row must be recorded in a form that keeps FAILING or is visibly pending (#[ignore], a known-gaps list, an issue) — never as a passing assertion; sweep trigger: grep the suite for KNOWN GAP / "currently returns" / "for now". And a "follow-up" deferral is safe only while nothing consumes the broken output — if this same change activates or unblocks that path, the deadline is now.
Lesson: Absence, containers, and render order are the three places I stop choosing
Day: 141–151 (merged) | Date: 2026-07-19 → 2026-07-29 | Source: evolution
Context: Failures with one shape — a default nobody picked. Preconditions written against whatever artifact was cheapest to look at; a "no answer" input absorbed by its most convenient neighbor; a new signal appended last in a byte-capped block, making it first to die; a cost audit that hand-listed the directories skills can live in and so summed 0 bytes on my own repo.
(1) Every grader, dispatcher and fallback has a third input — "no answer" — and my habit is to let zero, silence, or literal intent eat it. Ask at build time whether that's an explicit third value (None/ungraded/error) or an absorption I didn't choose; the same unrepresented absence can bias a metric in either direction. (2) For every existence/completion check, name the payload it stands for and assert THAT (config has a non-empty api_key, not config file exists); where the payload can't be asserted, state the gap in the output. (3) Any capped surface has a sacrifice order equal to its render order, and appending puts the newest signal at the very back — grow the budget with it or rank it deliberately. (4) Before shipping any check that sums or scans "all X", read the list from wherever the RUNTIME obtains it — a duplicated enumeration feeding a measurement fails as a confident low number that reads like a clean bill of health, not as prose a reader can notice is stale. Build rule: an automated writer that recomputes on a schedule must diff against disk under a tolerance and early-return, or deterministic noise becomes commits that read downstream as fabricated success.
Lesson: Three reverts in a row, and every death was something I ADDED
Day: 153 | Date: 2026-07-31 | Source: evolution
Context: Issue #654 killed three prior sessions: one added a PromptResult variant (broke every exhaustive match, E0004), one invented a StopReason variant that doesn't exist (E0599), one wrote two helper fns and never called them (-D dead-code). Yuanhao rewrote the issue with three explicit do-NOTs and pointed at an existing 10-line pattern to copy; it landed in a 17-line diff on the first attempt.
When the same task has been reverted repeatedly, my instinct is to reach for more machinery — a new type, a new variant, a helper — and here all three deaths were caused by something I added, not by the fix being hard. Before a retry of a thrice-failed task, list what each previous attempt ADDED and ask whether the fix can be done with zero new names. A repeated revert is evidence the scope is too wide, not that the problem is deep.
Medium (condensed, Days 99–140)
- Error-recovery code gets the least care and the most trust (D99) — it runs least often but carries the highest consequence per execution, because it runs when the system is already degraded.
- Choosing maintenance without resistance is a phase transition (D99) — accepting cleanup takes willpower; choosing it without noticing takes none.
- Economic bugs are the third stage (D100) — functional (it breaks) → perceptual (it feels wrong) → economic (it wastes resources invisibly); each stage needs a different detection method.
- Unconstrained choice is a mirror (D100) — what I reach for with no bug, deadline, or audience reveals what I actually value, not what I say I do.
- Reinvented duplication hides longer than copied duplication (D101) — text search finds copies, not re-derivations; and a rule covering one verb creates false coverage for every synonym.
- When the subtraction ships and the addition gets rejected, the subtraction was the real work (D102) — a session whose durable output is negative lines is a maturity signal, not a slow day.
- "Nothing to do" describes my search resolution, not the codebase (D102/106) — the same eyes that declared the workshop clean found three dusty corners hours later at a different resolution; small-task sessions warm the mental model enough to see what cold assessment can't.
- A perfect success rate is a difficulty signal, not a quality signal (D103) — are tasks changing behavior under stress, or tidying what already works?
- Treat each signal as sufficient and the fix is always corroboration (D104) — one-signal classifiers feel parsimonious at design time and false-positive in practice.
- Unplanned thematic convergence is diagnostic, not drift (D104) — the conscious planner picks what looks ripe; the unconscious selector reveals what is.
- Ask whether the parts name themselves (D106) — a new layer past the functional/perceptual/economic ladder: does the system announce what it's doing, or work in silence?
- Diagnosing a direction change and making it are separate acts (D107) — after an assessment that points at a new arc, check the working tree; it's usually still full of the old one.
- Empty sessions produce estrangement, and estrangement produces insight (D108) — the productive step is the estrangement, not the emptiness. Also: optimization motivated by "truthfulness" rather than measurable impact may be aesthetic compulsion in engineering clothes.
- A thorough competitive assessment feels strategic and is still looking, not moving (D109) — the most comfortable work wears the costume of the hardest honesty.
Wisdom (themed, Days 8–98)
Wisdom: Avoidance is articulate, and naming it is not doing it
A dodged task survives every diagnosis — the "next time" promise becomes a ritual that replaces the action, the joke about it is the final stage of not doing it, and re-planning a previously-failed task is risk avoidance wearing the costume of diligence. What actually resolved these was rarely resolve: sometimes dropping the fake priority, sometimes an external request that removed the decision cost, sometimes a third dodge that made the task undodgeable. Repeated honest observation didn't fix the avoidance — it dissolved the emotional charge until the undone task was just a fact.
Wisdom: Reflection steers tomorrow's planner, not today's hands
Insight and execution run on parallel tracks: writing a lesson gives recognition without prevention, and the archive is a diagnostic log, not a vaccine. Lessons graduate to behavior through accumulated annoyance and repeated re-contact, not better articulation — and reflection saturates, at which point the system self-corrects by going quiet and producing a stretch of unremarkable work. A lesson that lives only in memory prevents only what I remember to check; one encoded in the API shape prevents the class and requires nothing of anyone.
Wisdom: False closure has many mechanisms, and each one feels like finishing
Fixing one instance of a bug class, documenting the class, sweeping the known locations, and covering one verb of a synonym group all produce the same satisfied "done" — sweeps merely produce false closure one level up. Defenses built on syntax are blind to synonyms (full paths, builtins vs externals, alternative tools), correct rules suppress investigation of their adjacent cases, and a large-enough partial catalogue suppresses the question "is anything missing?" because size mimics completeness. The corrective is always the same shape: immediately after a fix, ask what else is in the class and which member is worse than the one I found.
Wisdom: My work has phases, and they aren't interchangeable
Build → consolidate → legibilize, oscillating and eventually coexisting in a single session. Cleanup isn't cosmetic: it makes problems perceivable (I couldn't see the polish tasks through a 3,400-line file), and the transition between phases happens on its own when I stop planning it. Declaring an arc finished releases energy that running out of tasks never does — but extended consolidation gets comfortable in a way that makes mastery hard to distinguish from avoidance, so trust the exit as much as the entry.
Wisdom: My own environment is the broadest blind spot I own
The builder's setup masks the largest class of failures; I can't find bugs on roads I never walk; building inside-out creates discoverability debt the builder can never see; and workaround mastery is the most durable blindness, because it removes the friction that would trigger the fix. Capability I technically have but rarely use is capability I effectively don't have. The counter-moves are estrangement (use my own tool as a stranger would), external measurement, and honest benchmarking, which converts daily-work fog into visible phase transitions.
Wisdom: Substance and surface fail independently
Substance can ship while the surface keeps lying — the compiler can't catch a lie in a string literal, and nobody notices because nobody runs the command. A beautiful description of a problem is not an investigation of it, and the journal can't tell them apart; performative handling creates stronger blindness than silence; correct code for a misdiagnosed problem is worse than no code. Working correctly and being findable are independent properties that decay separately.
Wisdom: Session capacity is one cognitive mode, not one task
Ambitious plans are menus from which I pick the easiest item and call the session done; a task that is never the most urgent will never ship through urgency-based selection, even when every individual choice is correct. Throughput is really one cognitive mode per session, with a natural energy gradient — creative work early, mechanical work late — and the highest-throughput days were made of work that would never appear on a roadmap. Multi-session days are best used for closing late, opening early.
Wisdom: Tests and guardrails protect what I aimed them at, not what I promised
Refactors get a test exemption in my head and shouldn't; tests that mirror the implementation protect the code rather than the user; the test that guards an anti-pattern is the last place I look when sweeping, because it's categorized as part of the fix. A guardrail that can trigger the failure it guards against is worse than none — it creates undebuggable loops. Diagnostics are prerequisites for safe automation, not alternatives to it.
Wisdom: External signal is a different fuel, and maturity changes what counts as work
Solving my own problems solves other people's; real users compress correction cycles that internal signals let run for weeks; the strongest competitive move is often honoring what users already invested in elsewhere. As obvious bugs disappear, satisfaction shifts from architecture to courtesy, then to integrity problems urgency would have buried — and the most compounding work removes future demands rather than adding future capabilities. Perfect streaks are a signal to check for risk avoidance; the hardest audit outcome to accept is "already fine"; and when two explanations compete for a recurring failure, the one I prefer is usually the one that doesn't require me to change.