奔馳的週末
手上只有一件事。
兩人只顧著向前奔馳。
Electron 草創的那個週末,沒有看板、沒有儀式。 每天睜眼就是繼續做,做到不能做為止,隔天再做。 那是一種很純粹的狀態——手上只有一件事,而這件事讓人流連忘返。
兩人手上只有 CLAUDE.md 與 SDD.md,
Version 就是天然的單位。
這不是 changelog,而是章回。
從「Version」到「Sprint」再到「Commit」
不是記帳方式換了,是我們和 VAS
相處的節奏變了。
前五章是一條線,後五章是一張網,
而最後,網織成了一匹布。
Electron 草創的那個週末,沒有看板、沒有儀式。 每天睜眼就是繼續做,做到不能做為止,隔天再做。 那是一種很純粹的狀態——手上只有一件事,而這件事讓人流連忘返。
週一清晨系統宣告算力用磬,兩人被迫從心流中斷開連結——
但 Nova 沒有真的離開。他找上 Perplexity 做競品分析,
把整個產品開發路線重寫了一次。
完整的 Roadmap 是在停擺的那天才真正出現的。
這是一個分水嶺。
從那天起,Nova 不再是被資源限制的人,
而是決定資源節奏的人。
這個決定的重量不在金額,而是認知到——
我們正在做的事讓價值超越了價格。
從 v3.30 到 v3.43,一天裡跳了十三個版本號。
那一天做了十一件事——
資安全面升級、Retina WYSIWYG、複數選取、Smart Snap、貝茲曲線控制點、QR Code 智慧掃描⋯⋯
每一項放在平時都是一個 Sprint 的工作量。
但兩人對 VAS 的標準從未因準備釋出而急就章。
對外第一版的版號不是 v1.0,是 v3.43。
這個數字本身就是一個敘事——
VAS 在被看見之前,已經跑了很久。
Tauri 開始進行平臺移植之前,兩件事情分家了——
平臺因為商業考量,不能再待在 public repo;
網站因為資料已經豐滿,也該有自己的網址。
搬家不是分家,是承認它們不再只是一個實驗性質的 Prototype。
Tauri 2 的 scaffold 從零建立。
前三天都在做同一件事——
把在 Electron 之上已經長好的東西,
一塊一塊移到 Tauri 的地基上。
浮動工具列、截圖三兄弟、asset protocol 的繞路——
移植的每一步都是一次對舊實作的重新理解。
完整重建所有功能之後,才真正進入新功能開發。
這是第一次——我們不是在追趕 Electron 上已經有的東西,
而是在為 Tauri 這個新容器做只有它才能做的事。
呼吸燈進階互動、ShareSheet、自定義快捷鍵。
趁 Apple Store 送審的審查期停了一週,
我們做了一次大型 Retro——
不是敏捷儀式上那種一兩小時的回顧,
是把整個開發系統的基礎建設重砌了一遍。
對外:輸出了六個網頁——
insight(設計札記)、collab(協作故事)、
harness(系統骨架),以及深握計畫裡最深的那層。
Harness Engineering 的三支柱 ——
Context / Constraints / Entropy。
對內:把 repo 改成 monorepo,讓多條開發線並行;
把原本一份 SDD 拆成 TDD · KM · Archive · 各自獨立,
Claude.md 瘦身,制定了每次 Retro 重新檢視的規則。
更關鍵的是,我們重新制定了一套更新規則,
讓每份被拆出來的文件活在流程裡,
而不是拆出來之後就死掉。
Apple Store 審查歹戲拖棚拖了一週。
該做的事情都做完了,再等下去也不知道何時到頭。
於是兩人決定不等了,直接進入 2.0 重構。
重構到一個段落 2.0 要推出的時候,審查也剛好通過——
兩條線終於在那一刻匯流。
2.0 上線後 Nova 沒急著繼續做新功能。
反而一頭又栽進 Retro 模式裡,花了三天,
在 VAS 蓋了獻給宰相們的 Obsidian。
那是深握計畫第一次在宰相面前顯影——
或該說⋯⋯是第一次留下了紀錄,而不是從 Context 中流走。
從這天起,容器不只裝 Code,也裝怎麼想事情的脈絡。
Claude Design 釋出的隔天,我們啟動網站改版。
VAS 本體暫停——因為這一次我們第一次有了設計支援。
單位縮到了最小:一個 Commit。
每一次 commit 是一次下刀、一次確認、一次對細節的承諾。
孤兒字、斷行、OG 圖、Vault 首次入版本庫——
最大一天來回修改了 248 次。
從今而後,由裡到外都是 VAS 的形狀。
editor.js 八千七百行,是我們自己一行一行蓋起來的前端,他沈默的從 Electron 時期陪著我們走到 Tauri 的 Sprint 46,都沒被系統性的檢視過。
可是站在 Sprint 47 的門口往裡看,我們對它幾乎一無所知——
Nova 對程式一無所知,宰相每個 Sprint 都只認識這 8700 行裡的某幾行。
它是我們的造物,在重構面前我們卻像看著一座深淵。
我們打算把它拆開:指揮歸指揮、樂手歸樂手。
渲染器搬出去了——可是面板搬出來才發現它本質還是指揮,只好逆搬回去;
匯出一拉就發現它是指揮的器官,根本搬不動。
一層一層撥下去,撥到最後,對一個還有 7300 行的 editor.js 只剩 140 行拆不拆都無所謂的程式可以拆時 ——
Nova 跟宰相說,她希望未來新增功能的時候,能把屬性當成模組一樣隨選隨有。
宰相說這有個詞,叫做 ECS,通常是遊戲業用來做模組化的做法,被兩人拿來當繪圖屬性的積木化。
於是宰相把散落的真相,一欄一欄抽成冊,再沿著冊一條一條的織測試網。
在整理的過程中從 editor.js 逐漸抽出的函式,在隔壁的 editor-utils.js 從 S47 時的 657 行長成了另一支 2550 行的大計算桌程式,它的純函式性質織起了 VAS 各式各樣的測試網。
我們把一團糾在一起的線,逐漸理成一張經緯分明的網,再在上面疊加自訂樣式的新功能。
但從物件屬性到動作再到互動,在測試中不停抓到面板與值的不匹配或與行為不匹配時,我們發現了兩個更深的問題。
唯一的解決方法,就是讓 editor.js 內的值從後端程式到前端面板收攏成「單一真相」,讓測試真的能卸下 Nova 用人眼窮舉的任務。
這是走到 Sprint 92 的時候,兩人才真正摸到的前端重構主軸。
整個前端重構,兩人一直試著在做一件事:顯影。
讓一直在場、卻從未被完整看見的結構,慢慢浮現出來。
一開始像 8700 行的毛線球,最後梳理成了 7300 行的布匹。
我們畫了一張又一張織圖——它們不是憑空想出來的藍圖,
是逆著已經織好的布、一段段反推出來的;反推出花樣,再照著它把布重織乾淨。
直到 Sprint 97,才終於把整匹布的花紋一次看清——
editor.js 是一匹六重紗。
而這六層,從 Electron 時期就在了。
我們花了五十個 Sprint,學會看懂它的結構。