David Cornelson - GenAI Master

Build, ship, delete

This is the third throughline from the Sharpee retrospective, and it is the evidence for the repair half of the first post: the half where a known defect used to be a ticket marked "later" and is now a same-day fix. As with the previous post, what follows is the analysis as the retrospective produced it, counter-evidence and verification intact, lightly edited for the blog. The "I" in the body is the analyst that wrote it.

Two corrections from the adversarial verification pass are applied rather than footnoted. The headline file and line counts are off by nine files and 454 lines in the original, a method gap the verifier could not reproduce, so the corrected integers appear here and the percentages are unchanged. And the original claimed that 36 decision records carry a terminal status and that six were deleted outright. The verifier refused both: 24 records carry an unqualified terminal status in their own file (28 on a wider word list), six more are marked abandoned only in the index while their own files still read proposed or draft, and of the six "deleted" paths, five were renames that git's similarity detection missed and every one of those records is alive under a new filename. Exactly one file died, and it was not a decision record. That refuted claim read as evidence of destroyed decisions; the truth is closer to the opposite.

Thesis

Roughly a third of everything ever written in this repository has been deleted: 1,733 of 4,826 source files ever created (35.9%) are absent from the current tree, and 259,524 of 780,240 source lines ever written (33.3%, defensibly 27 to 33% after correcting for relocations) went into files that no longer exist. But the pattern is not uniform waste. The deletions cluster tightly in two zones, the product edge (clients, servers, IDE test surfaces, tutorials) and the architecture-of-the-week layer (action phases, event dispatch, daemon hierarchies), while the domain core is nearly untouched: 79% of live standard-library source files and 66% of live world-model files predate 2026, and one core trait file has been touched five times in fourteen months. The method is real and it works: build the thing to completion because completion is the only reliable way to learn whether it was the right thing, then delete it without ceremony. The waste is real too, and it is specific. The pattern's cost is not the deletions but the undeleted residue: 4,601 lines stranded on an unmerged branch, a 146-file "parts bin" still sitting in the tree, a repudiated helper module still shipping with only its own test importing it, and status lines that describe systems deleted months ago.

Timeline

2025-08-12. A behaviors subsystem of about 2,000 lines is deleted and its replacement designed and implemented in the same session. Verified in the corpus, not git: the built system never reached a commit. Source: the session summary of 2025-08-12.

2025-12-26. Three action architectures in 13 hours and 7 minutes. At 04:04 all 43 standard-library actions reach 100% on a three-phase pattern. At 05:06 and 05:12 all 43 are migrated to a helper-based pattern. At 05:15 a 255-line assessment repudiating that pattern ("conflates concepts that should remain separate," "a leaky abstraction") is committed three minutes after the migration finished. At 07:19 and 17:12 a four-phase pattern replaces both. Source: six commits, times from git author timestamps.

2026-01-01 to 2026-01-14. Three text-service packages are published to npm as a beta on January 1 and deleted on January 14: thirteen days of public life. The deleting commit is titled as a parser feature; the deletion rides along inside it. Source: commits 319ec31c and 9356bfff (39 files, 2,866 source lines removed).

2026-01-29. A typed daemon class hierarchy, five base classes and six migrations, is built and reverted the same day. Only the serialization half survived. The record's status today reads "Partially Accepted (serialization adopted, class hierarchy rejected)," one of the few status lines in the repo that tells the truth. Source: commits 603c9824 and 55d726a2.

2026-03-27. The entity handler system, the thing the August 2025 subsystem was killed for, is itself removed across seven phases. The record that introduced it still reads "Implemented" today, and the project's instructions file still names it as the pattern for custom logic. Source: commit 1b0b4d03 (32 files, 1,566 lines removed).

2026-03-29. A context-driven action menu system is implemented in a single commit: 38 files, 4,601 lines, all seven phases. Never merged. Status flipped to Deferred with the note "the technology works but there is no active use case." The branch is still unmerged today, one of six. Source: commit a7b968ff on its own remote branch.

2026-04-19 to 2026-04-28. A server: scaffolded April 19, Docker-deployed and closing acceptance criteria April 24 (108 files, 22,868 lines added), end-to-end browser tests added at 21:19 on April 28, and the entire directory deleted at 21:21, two minutes later. 268 files, 51,555 lines total, 39,845 of them source. Nine days, 35 commits, from scaffold to deletion. Source: commits ac523102, c3a07d10, 0ea2ba9f, ead5749a.

2026-04-28. Four decision records marked REPLACED in one commit, minutes after the code they described was removed. A long-running-subprocess multi-user architecture is abandoned for stateless per-turn workers. Source: commit 899653cf.

2026-05-10 to 2026-05-12. Multi-user server, second attempt: the record accepted at 23:41 on May 10; six phases (storage adapter, identity routes, room routes, WebSocket server, worker pool, save lifecycle, admin surface, full web client, two-user end-to-end) complete by 02:46 on May 12, about 27 hours. At 04:12 the same morning a new record renames the directory to a deliberate "parts bin" and the rebuild starts. The parts bin still holds 146 files today. Source: five commits.

2026-08-03 to 2026-08-06. The sharpest instance in the record. A play-and-bless subsystem for the IDE: record accepted 17:37 August 3; nine-phase plan written 18:29; phases 1 to 4 landed 20:42; 5 and 6 at 23:41; 7 to 9 at 01:12 August 4. A complete nine-phase system in 7 hours and 35 minutes. Superseded in part thirteen hours later, after the owner asked "do we keep the Skein or do we make a transcript editing tool? It's probably one or the other." Deleted 03:08 August 6: twelve Swift source files totalling exactly 2,768 lines, plus eleven test files. Source: seven commits.

2026-08-09. "You have my authority to shred the old UX completely for testing. This is the direction and nothing from the old testing UX survives." The golden-recording tier is retired: the golden module deleted, the bless command removed from the devkit, six golden test files deleted. Source: the session summary of 2026-08-09; commit 7f582734 (105 files, 4,012 lines removed).

2026-08-10. A cutover deletes the text transcript grammar from the authoring tool's world: parser (1,201 lines), serializer, rename cascade, the old tree runner, and nine orphaned satellites. The branch tester drops from 397 passing tests to 86; seven source files survive. Shipped as Sharpee 5.0.0 the same day. Source: commit 31ef79b2 (168 files, 12,369 lines removed).

Analysis

The number. Counting only source (TypeScript and Swift, excluding build output and type declarations), the repository's non-merge commits added about 806,000 lines and deleted about 311,000. That ratio overstates deletion, because a diff counts an edited line as one add and one delete. The honest measure is survival: of 4,826 source files that have ever existed, 1,733 (35.9%) are gone from the tree, and 259,524 of the 780,240 lines ever written into source files went into files that no longer exist, 33.3%. That figure is an upper bound. Rename detection missed at least one relocation (a tutorial's eighteen versioned files show as deleted but survive in an archive directory), and two stories moved to a sibling repository rather than dying. Subtracting the known relocations puts the defensible range at roughly 27 to 33%. Call it a third.

The deleted lines are not evenly spread. The first server accounts for 42,287; the standard library 30,724; the IDE 24,134; the second server 23,966; the tutorial 22,328; the largest story 17,642; the branch tester 12,388; the core package 11,875. Two zones dominate: the product edge (servers, clients, IDE surfaces, tutorials) and the layer where the platform kept re-deciding how actions and events dispatch.

The decision records. 318 files exist. Twenty-four carry a status in their own file that begins with an unqualified terminal word (superseded, replaced, abandoned, rejected, withdrawn); 28 on a wider list that admits closed, deferred, and one honest "Foolish." Six more (013, 016, 034, 048, 059, 112) are listed as abandoned in the index while their own files still read proposed or draft. That divergence between the index and the files is the cleaner finding: the record of a decision's death lives in a different place from the decision. No decision record was deleted; the six paths that git reports as deleted are five renames it failed to detect and one interim plan that was never a decision record.

Waste or method? The evidence for method is strong and mostly structural. The deletions are scoped rather than total: the August 2026 cutover deletes the transcript grammar from the authoring tool's world while its own header carries an explicit "Untouched" clause preserving the platform's own test language, the walkthroughs, the chain runner, and the largest story: "That is Sharpee's own author-facing test language and it stays text." That is a surgeon's cut, not a bulldozer. And the core survives: 811 of 3,093 live source files predate 2026 (26%), but within the domain layers the concentration is much higher. 228 of 290 live standard-library source files and 125 of 190 world-model source files were written before January 2026 and are still here. The container trait was created on 2025-06-23 and has been touched five times in fourteen months. The layer that gets deleted is precisely the layer where you cannot know the answer without building it: what the multi-user server should be, what a testing surface should feel like, whether a play-tree or a transcript editor is the right authoring model. The owner's August question is the method stated plainly: "I thought the whole point of the Skein was to make authoring transcripts easier. So do we keep the Skein or do we make a transcript editing tool? It's probably one or the other." That question could not be answered by design review. It was answered by having both, then deleting one.

The evidence for waste is narrower but sharper, and it is not where you would expect. It is not the deletions. It is the residue that was built and then neither used nor removed:

  • The helper module repudiated in writing at 05:15 on 2025-12-26 is still in the tree eight months later, with tests, and the only file importing it in the standard library's source is nothing. Its sole importer is its own test file.
  • The context-menu system's 4,601 lines, all seven phases working, sit on an unmerged branch since 2026-03-29. By October 8 the unmerged-branch count had gone from six to eleven.
  • The parts bin, explicitly named one in May, still shipped 146 tracked files three months later. It was archived on 2026-08-13, all 146 files still tracked but excluded from the workspace, alongside the retired multi-user server line and an interpreter package.
  • Documentation decays behind the deletions. The project's instructions file still points at a grammar file that does not exist. It still says actions follow a pattern superseded on 2025-12-26, citing a record whose own status is "Superseded," whose successor's system was itself deleted on 2026-03-27 while its status line still reads "Implemented."

That last chain is the real cost. This project's memory already records that "Proposed often means shipped." The inverse is now also true and less visible: Implemented can mean deleted. When a third of the code is disposable, status lines stop being load-bearing, and the record of why something was built stops being retrievable from the artifact that recorded the decision.

The strongest single waste case is the first server: nine days, 35 commits, Docker-deployed, an acceptance-criteria closure commit adding 22,868 lines, roughly 500 server and 360 client tests, and a final commit at 21:19 on 2026-04-28 adding browser coverage, deleted at 21:21, two minutes later. It was removed in favor of stateless per-turn workers. The successor line is now recorded in project memory as "not in active development." Forty thousand source lines were spent to reach a conclusion about architecture, and the architecture that replaced it also stalled. That is not learning by building; that is two dead branches.

The honest verdict is that the pattern is method in the domain core and at the design edge, and waste at exactly one seam: the moment between deciding something is dead and finishing the deletion. Sharpee is extremely good at building to completion and extremely good at cutting. It is bad at the third step, reconciling the record afterward. Every case I would call waste is a case where the delete was left half-done.

Carried forward to October 8. The sharpest build-then-delete instance in the whole record came after the retrospective closed. On 2026-10-05 a grammar migration (every create block names its kind) was baselined, built, cut over across 399 files, and had its codemod and baselines deleted on the owner's ruling, all in one day. The first server's successor line, zifmia, was retired outright on 2026-08-13, with twelve decision records annotated rather than amended, on the stated principle that the retirement is a new fact rather than a retroactive one. The repudiated helper is still in the tree.

Counter-evidence

The retrospective argued against its own thesis before publishing it. These are its objections, kept whole.

  • The domain core was never disposable. 228 of 290 live standard-library source files and 125 of 190 live world-model source files were created before 2026 and are still in the tree. The container trait dates to 2025-06-23 and has five commits total in fourteen months. If "build, ship, delete" were the project's method rather than a zone of it, this layer would not exist in its original form.
  • The deletions are explicitly bounded, which is the opposite of recklessness. The August 2026 cutover's own header carries an "Untouched" clause. The same commit that removed 12,369 lines drew a line it would not cross.
  • Deletion is not the default and the owner actively policed it. After the model deleted three test files unasked in September 2025, a permanent rule went into the project's instructions: "Never delete files without confirmation. Not even to get a build working." The corresponding session summary calls it a "Major mistake. Completely inappropriate and destructive." The large deletions in this record are authorized case by case ("you have my authority to shred the old UX completely"), not a standing disposition.
  • The headline deletion number is inflated by non-code. The largest commit in the repo shows 275,597 lines removed, but 228,780 of those are JSON and only 7,782 are TypeScript. Any "lines deleted" figure that does not filter by extension overstates the pattern by an order of magnitude on that commit alone.
  • The pattern's most expensive cases are ones where the deletion did not complete. The repudiated helper, the parts bin, and the unmerged context-menu branch all argue the problem is unfinished disposal, not disposal.
  • Things did ship and persist. The platform reached 5.0.0 on npm and published nine more times through 5.4.1 by mid-September; the book, eight volumes, is complete and QA'd; the website is live; the largest story's 172 rooms and its walkthrough chain are the standing regression baseline. A project that only built and deleted would have no such artifacts.
  • Status lines cannot be used as the metric they appear to be. One record reads "Implemented" though its system was removed; four read "Proposed" or "Draft" in their own files while the index has marked them abandoned since February. The terminal-status count is a floor drawn from self-reported status, and the true figure is higher and unknowable from the records alone.
  • At least one large deletion was made for a successor that also stalled. The first server was removed in favor of stateless per-turn workers; project memory records that line as "not in active development" and possibly never happening. That case does not fit "delete to make room for the better thing." Nothing took the room.

What was verified

Directly verified in git: every commit in the timeline (stat and author timestamp); the 2025-12-26 sequence including the 05:15 assessment text quoted from the diff; the play-and-bless file list summing to exactly 2,768 Swift lines; the first server's 268 files and 51,555 lines; the two-minute gap from author timestamps; the context-menu commit's 4,601 lines on an unmerged remote branch; the entity-handler removal's 1,566 lines; the cutover's 12,369. Aggregate line and file counts are the analyst's own computation over the full non-merge history with partial rename handling, spot-checked (three deleted paths confirmed genuinely absent) and found to miss one confirmed relocation, which is why a range is given rather than a point. Decision-record statuses were parsed from the first 40 lines of all 318 files with a strict prefix classifier and the terminal list read individually. The 397-to-86 branch-tester count comes from the project's own session summary dated 2026-08-10. Not verified directly: the 2,000-line August 2025 deletion (it never reached a commit; only the session summary states the figure); the server and client test counts for the first server; whether the public play site was actually serving traffic as opposed to merely deployed. No build or test suite was run, and the 1,247 underlying session summaries were not read, only the four the digests cited by name plus targeted searches.

The adversarial verification pass afterward reproduced the survivor counts exactly, found the "ever written" counts low by nine files and 454 lines under every method it tried, and so cleared the percentages for publication while flagging the exact integers; confirmed the 79% and 66% figures as source-directory-only (whole-package, the standard library drops to 70.7%); confirmed the container trait's five touches, the text-service deletion's 62 files, the context-menu branch, the 2,768-line deletion, and the 397-to-86 drop by re-running both test suites; and refused the terminal-status and deleted-record claims as described at the top of this post.

← All posts