Mã Nguồn Ngược Dòng Chương 88 / 209

Chương 88 — Rollback

Văn phòng buổi sáng có mùi của cà phê nguội và máy lạnh bị để qua đêm.

Hoàng đến trước tám giờ. Cửa chưa ai khóa. ChiếcTV dashboard hôm qua tắt rồi nhưng vỏ nhựa vẫn hầm nóng, tỏa ra thứ hơi nóng khét nhẹ quện với bụi. Anh bật công tắc đèn. Hai bóng sáng, một bóng nhấp hai lần rồi mới đứng yên.

Sổ của Trâm nằm mở trên bàn. Nét chữ tròn của cô dừng ở dòng 02:07 service stable, rồi ngay bên dưới là dòng viết vội bằng bút khác, nghiêng sang phải, của Khoa: 06:00 xuống chị Bảy, đối soát sổ tay. Không có lời bình. Không ai viết thêm từ “ổn” lên đó. Tờ giấy ghi chép trông giống một vết khâu đã xong nhưng chưa cắt chỉ.

Hoàng kéo ghế ra, chưa ngồi. Anh nhìn quanh văn phòng: bảng architecture trên tường vẫn dán, mép dưới bong keo cong lên một chút; ổ cắm điện có dây laptop của Minh còn cắm, nhưng laptop đã mang đi; ly trà của Phương Anh rửa úp trong rack, cạnh nó là lon Coca chưa ai mở. Trên sofa, cái chăn mỏng Khoa cuộn lại thành hình cái gối, hơi lệch. Chiếc gối sofa cũng lệch. Không có gì ngay ngắn.

Anh mở laptop. Mất mười lăm giây để nó nhận WiFi và tự đồng bộ. Lệnh của đêm qua chưa bị xoá, nhưng chỉ là lịch sử. Anh vào repo.

Branch main sáng nay đọc khác hôm qua.

Sync-service v0.3.1 bị revert. Migration schema_v12 ghi chú rolled back. Đoạn code mới nằm không ở đó nữa. Còn branch rewrite-v2 vẫn nằm riêng. Lần cuối commit là 23:14, đêm qua, trước khi backfill job bị trigger lại. Một mình nó treo trên danh sách branch như một cánh cửa mở ra nhưng không dẫn đi đâu.

Hoàng không mở branch đó. Anh quay lại main, đọc lần nữa. Những dòng quen thuộc hiện ra. PHP monolith. Query thủ công. Log chưa đủ. Backup script. Đây là nền móng đầu tiên. Đây là thứ anh viết trong căn phòng học sinh, dưới đèn bàn vàng, khi NỢ SỔ chỉ là quyển vở nợ của chị Bảy và vài cái tên.

Nền móng này sống sót qua đêm. Rewrite bị treo. Cảm giác không phải vui. Cảm giác là vừa chạy ra khỏi đám cháy và thấy nhà mình cũ kỹ hơn trong khói.

Tám giờ mười lăm, Trâm tới.

Cô mặc áo phông trắng, khoác áo sơ mi caro nhẹ, tóc buộc cao hơn hôm qua. Mặt cô có quầng mờ nhưng bước chân không chậm. Cô vào cửa, đặt balo xuống, không chào ồn. Cô chỉ nhìn Hoàng, nhìn sổ trên bàn, rồi đi mở laptop.

“Chị Bảy chưa gọi lại,” Trâm nói. “Em hẹn chị mười giờ em sang. Khoa nói em đi chung.”

“Đi,” Hoàng nói.

Trâm gật. Cô mở bảng khách trong sheet chung, lọc cột affected. Đúng bốn mươi bảy tên hiện ra. Cô bắt đầu đánh dấu. Một cột status, một cột callback time. Chữ cô rất đều. Dòng đầu tiên ghi: BT-001 — gọi lại lúc 06:12, chưa nghe máy. Dòng hai: GV-009 — Trâm gọi 06:20, khách nói sáng kiểm tra lại. Cô không hỏi thêm. Không cần hỏi thêm.

Chín giờ, Khoa bước vào.

Anh mặc áo NỢ SỔ xám đã sờn cổ, quần jeans, dép sandals bẩn. Anh cầm theo bịch bánh mì không và hai hộp sữa. Không cười. Không nói lớn. Anh đặt bịch bánh lên bàn tiếp khách, nhìn dashboard TV đang đen, rồi nhìn Hoàng.

“Sao?” Khoa hỏi.

“Chưa có gì mới,” Hoàng nói. “Stable.”

Khoa gật. Anh xé bọc bánh mì, đưa hộp sữa cho Trâm. Cô nhận, nói cảm ơn, rồi lại nhìn màn hình.

“Em uống đi,” Khoa nói. “Rồi anh gửi bản danh sách khách trong nhóm test sáng nay. Gửi thông báo chung trước. Khoan gọi ngoài danh sách chính.”

“Dạ.”

Khoa kéo ghế ngồi xuống bàn anh. Mở mail. Gõ.

Hoàng đi lại phía sau, nhìn qua vai. Subject Khoa viết: Xin lỗi — lỗi hiển thị sổ nợ trong đêm, đã khôi phục, hỗ trợ đối soát. Người ta không hay viết “xin lỗi” vào subject. Nhưng Khoa viết. Không dài. Không trích dẫn code. Không đổ lỗi cho ai. Chỉ nói: trong đêm có lỗi hiển thị với một nhóm khách, dữ liệu gốc không mất, nhóm đã khôi phục hệ thống cũ, ai bị ảnh hưởng thì sáng nay được hỗ trợ đối soát, được tặng một tháng dùng miễn phí, nếu có giao dịch cần kiểm tra thì có người trực. Khoa ký tên bằng vai trò “phụ trách triển khai” và để số điện thoại của mình.

Anh đọc lại lần một, sửa hai chỗ, rồi bấm gửi.

“Gửi danh sách test trước,” Khoa nói. “Hai mươi khách. Xong thì mới gửi rộng.”

Trâm gật.

Hoàng nhìn câu mail đó và thấy nhẹ theo cách không thoải mái. Nhẹ vì có người đang nói với khách hàng thay anh. Không thoải mái vì người đó đang nói câu anh không nghĩ ra ngay.

Khoa tắt mail, quay ghế sang Hoàng.

“Mày ngủ chưa?”

“Một chút.”

“Một chút là bao nhiêu?”

“Nửa tiếng.”

Khoa nhìn anh. Không nói gì thêm. Anh biết “nửa tiếng” có nghĩa là không ngủ, chỉ nằm. Hai người hiểu nhau đủ lâu để không tra hỏi thêm con số vô nghĩa.

Mười giờ, Phương Anh vào.

Cô không mang cà phê. Cô mang laptop và một cái usb. Mặt cô tỉnh táo theo kiểu người đã ngồi dậy từ sớm, tắm rửa, rồi mới đi, dù trời ngoài đó vẫn còn mờ sương. Cô chào ngắn, nhìn Trâm, nhìn Khoa, nhìn Hoàng, rồi mở laptop ở góc bàn họp.

“Tôi lập file post-mortem,” Phương Anh nói.

Không ai giao. Cô tự nói, tự mở Google Drive, tự tạo. Tên file: PostMortem_SyncIncident_DDMM. Cô chia sẻ cho group nội bộ ngay lập tức. Hoàng thấy email thông báo hiện trên inbox.

Trong file, cô đặt bốn mục:

  1. Incident timeline.
  2. Root cause.
  3. Decision log.
  4. Action items.

Dưới mỗi mục, cô điền sẵn khung thời gian từ những gì cô biết: 17:42 deploy, 23:xx lỗi, 00:47 báo đầu, 01:05 rollback, 02:07 stable. Cô ghi nguyên văn ai ở đâu. Cô ghi “Founder initiated rollback” ở cột Decision owner. Cô không viết nhiều lời. Cô chỉ tạo khung.

“Tất cả điền vào,” Phương Anh nói. “Đặc biệt phần decision log. Anh Hoàng ghi lý do. Minh ghi lý do.”

“Minh chưa ở đây,” Khoa nói.

“Anh gửi cho Minh,” Phương Anh nói. “Cho phép anh ấy điền phần root cause từ góc kỹ thuật. Không ai được sửa lại của người khác.”

Khoa gật.

Hoàng nhìn cái file. Mục Decision log trống rỗng. Trống có chủ ý. Cô để chỗ cho anh viết. Không phải để anh thanh minh. Để anh kể lại: lúc đó anh nhìn gì, sợ gì, chọn gì.

Anh không viết ngay.

Mười một giờ, Trâm đi với Khoa xuống gặp chị Bảy.

Hoàng ở lại. Văn phòng bớt hai người. Tiếng ghế, tiếng bước, tiếng cửa nhẹ hơn. Anh ngồi xuống sofa, nhìn bảng architecture trên tường. Ngay dưới diagram mới vẽ tay của Minh, có một dòng note dán sticky nhỏ: debt-event append idempotency key — nét viết ngắn gọn, chuyên môn. Sticky đó vẫn nằm đó. Code mới bị revert. Sticky thì không.

Anh đi lại bàn Minh.

Dây sạc vẫn cắm trong ổ, chỉ thiếu laptop. Bàn sạch. Không có ly nước. Không có giấy nháp lung tung. Mấy người code sạch thì bàn cũng sạch. Anh mở repo lần nữa. Lần này anh click vào branch rewrite-v2.

Commit cuối: 23:14 — snapshot backfill logic fix attempt. Sau đó không có gì. Không ai đụng vào. Không ai xoá. Branch đó bây giờ không phải lỗi code. Nó là lỗi người.

Hoàng ngồi nhìn branch đó lâu. Anh nghĩ đến cuộc tối qua. Đến giây phút Minh nói cho em hai mươi phút. Đến chữ “Không.” Anh nói. Không viết trong commit, nhưng nói trong văn phòng, và giờ nó nằm trong đầu mọi người.

Mười một giờ bốn mươi, Khoa nhắn. Xong chị Bảy. Chị không vui nhưng không la. Sổ chị kiểm lại rồi. Trâm đang ghi từng dòng.

Hoàng trả lời ngắn. Cảm ơn.

Khoa gửi thêm một câu. Mày ăn gì chưa.

Hoàng gõ lại. Chưa.

Đợi tao lên.

Lúc Khoa quay lại, anh mang theo bún thịt nướng và cà phê. Không hỏi Hoàng muốn gì. Anh đặt bịch đồ ăn xuống bàn, rồi kéo ghế ngồi đối diện.

“Ăn,” Khoa nói.

Hoàng nhìn hộp bún. Mùi nước mắm chua ngọt bốc lên. Anh chưa đói. Nhưng Khoa nhìn anh cách người ta nhìn người không chịu đổ rác. Không giận, chỉ đợi.

Hoàng mở bịch, ăn vài miếng. Mặn. Nóng. Thật. Anh nuốt xong mới biết mình cần cái đó.

Khoa uống cà phê. Một ngụm. Rồi đặt ly xuống.

“Nói đi,” anh nói.

Hoàng nhìn anh.

“Mày đang nghĩ gì?” Khoa nói. “Không phải về server. Về cách mày làm.”

“Tao đang nghĩ mình có thể làm khác.”

“Làm khác thế nào?”

“Cho hai mươi phút.”

Khoa gật. “Rồi?”

“Rồi nếu sai, thêm hai mươi. Có thể một tiếng. Có thể đến bốn giờ sáng. Nhưng nếu đúng thì không cần kéo toàn bộ về.”

“Vậy sao mày không cho?”

Hoàng nhìn đũa.

“Vì tao hiểu code cũ hơn,” anh nói. “Vì khi mọi thứ đỏ, tao muốn cái quen. Không phải cái đúng.”

Khoa im. Anh nhìn Hoàng không chớp. Không ngạc nhiên. Không thương hại. Như nghe một câu người ta nói mà anh đoán đã ở trong đầu từ lâu, chỉ chưa ai gỡ ra.

“Ừ,” Khoa nói. “Tao biết.”

“Mày biết?”

“Biết mày hay chọn cái quen,” Khoa nói. “Mày chọn tao vì tao đi được hẻm. Chọn Phương Anh vì cô ấy đọc được giấy. Chọn anh Tuấn vì ổng đứng tên được. Chọn Minh vì ổng viết được code. Nhưng khi ổng viết cái mày không quen, mày lại kéo về cái mày biết.”

Hoàng để đũa xuống.

“Tao không nói để chửi,” Khoa nói. “Tao nói vì hôm qua mày chọn rồi. Và người ta đang nhìn cách mày chọn.”

“Minh đang nhìn.”

“Không chỉ Minh,” Khoa nói. “Tao nhìn. Trâm nhìn. Cô Phương Anh nhìn. Sáng nay em nó viết post-mortem mà không ai kêu. Mày biết sao không? Vì nó thấy mày không có quy trình.”

Hoàng không đáp.

Khoa hạ giọng. Không phải giọng giảng bài. Giọng người bạn đầu tiên.

“Mày rollback đúng.”

Im lặng.

“Đúng,” Khoa nói lại, nhấn. “Chị Bảy đang thấy sổ. Khách đang thấy nợ. Tối qua không ai ngủ được. Nhưng mày không chết.”

“Nhưng—”

“Nhưng,” Khoa nói, giơ tay ngắt. “Mày rollback cách nào? Quyết định một mình hay quy trình?”

Tim Hoàng hơi thắt. Không phải đau. Là nhận ra.

“Nếu có quy trình,” Khoa nói tiếp, “mày không phải là người bấm. Hoặc mày bấm, nhưng có checklist. Có ai đó nói: không phải chỉ vì anh lo, mà vì rule nói vậy.”

“Tao là CEO.”

“Ừ. Nhưng CEO cũng chỉ là người. Mày lo. Lo thì chọn cái an toàn. Tao hiểu. Nhưng người giỏi hơn mày đang thấy cái an toàn không phải lúc nào cũng đúng.”

“Minh giỏi hơn tao,” Hoàng nói.

Khoa cười ngắn. “Ối giời ơi. Mày mới nói câu đó.”

Hoàng không cười. Nhưng nói ra câu đó, anh thấy nhẹ một phần. Không phải nhẹ vì đã xong. Nhẹ vì đã nói.

“Giỏi hơn hay không,” Khoa nói, “không phải chuyện này. Chuyện này là mày không có người review quyết định cuối. Code có review. Luật có review. Kinh tế có review. Chỉ có não mày là không.”

Câu đó đâm trúng.

Hoàng nhìn ra cửa sổ. Không có gì để nhìn ngoài ban công để chậu kiểng chết và xe máy dưới hẻm nhỏ. Nhưng anh nhìn, vì không muốn nhìn Khoa.

“Tao không nói mày phải cho Minh quyền,” Khoa nói. “Tao nói mày phải có quy trình. Cho ai đó được nói trước khi mày bấm. Nếu chỉ có một mình mày thì mày sẽ bấm kiểu mày.”

“Tối qua mày ở đó,” Hoàng nói.

“Tao ở đó,” Khoa nói. “Nhưng tao không biết code. Tao hỏi tiếng người. Tao chỉ biết mày đang run.”

“Tao không run.”

“Tay mày thì không. Giọng mày thì có.”

Hoàng nắm tay lại. Anh không nhớ giọng mình. Nhưng Khoa nhớ.

“Tao nói xong,” Khoa nói. Anh đứng dậy, không chờ Hoàng đáp. “Ăn nốt đi. Rồi viết vào file. Viết thiệt. Không phải viết cho qua.”

Hoàng nhìn bún. Khoa đi ra ngoài gọi điện cho Trâm. Tiếng anh nhỏ dần. Văn phòng lại im.

Hoàng mở post-mortem template.

Mục Decision log vẫn trống. Anh bắt đầu gõ. Không viết dài. Chỉ ghi lại: 00:58, 47 merchant affected; 01:02, hai phương án; 01:05, anh chọn rollback. Anh viết lý do: hiểu code cũ hơn, thời gian khách chờ đợi, không có policy deployment, lo lắng về rủi ro hotfix chưa test production. Anh viết thêm: “Không tham khảo đủ người trước khi quyết định.” Anh chần một giây trước câu đó, rồi để nguyên.

Anh gửi quyền comment cho Minh qua email. Không viết gì trong mail ngoài: Điền phần root cause và review từ góc kỹ thuật. Không ai sửa của ai.

Email đi.

Buổi chiều, văn phòng vẫn yên.

Mấy cuộc gọi nhỏ. Trâm báo hai khách hỏi lại sáng nay, số đúng rồi, không la. Khoa nói sẽ gửi thông báo rộng hơn. Phương Anh sửa layout post-mortem cho rõ hơn, thêm cột what we missed, thêm cột process gap. Cô không khen ai. Không mắng ai. Cô chỉ biến cuộc hoảng loạn đêm qua thành một file có thể đọc lại vào tuần sau mà không lẫn lộn.

Hoàng đi lại phía bảng architecture. Sticky note của Minh vẫn nằm đó. Anh đưa tay lên định tháo ra, rồi dừng. Không phải việc của mình. Anh không xoá giấy của người khác. Nhất là khi người đó có thể không quay lại.

Bốn giờ, Minh reply.

Không phải reply trong post-mortem. Anh reply mail của Hoàng bằng một câu ngắn: Em sẽ đọc.

Rồi không có gì.

Sáu giờ, Trâm về. Khoa ở lại thêm nửa tiếng, xem lại danh sách khách, gọi thêm một cuộc cho tiệm ở Phú Nhuận. Anh nói chuyện mềm, kiên nhẫn, đúng kiểu người đã nói với chủ tiệm bốn năm. Anh cúp máy rồi viết vào sheet: Khách ổn, không yêu cầu bồi thường thêm, giữ tài khoản.

“Tao về,” Khoa nói. “Mày về đi.”

“Để tao ở lại.”

“Ở lại làm gì?”

“Chưa biết.”

Khoa nhìn anh. Anh định nói gì đó, rồi thôi. Anh đi.

Văn phòng còn Hoàng.

Máy lạnh lại chạy. Đèn trần rì rì. Từ ngoài cửa sổ, quận 10 bắt đầu tắt nắng. Tiếng xe máy vẫn ồn, nhưng loại ồn ban ngày khác ban đêm. Ban ngày người ta chạy đi đâu đó. Ban đêm người ta chạy khỏi chuyện.

Hoàng mở lại post-mortem.

Mục Decision log của anh đã có. Mục của Minh vẫn trống. Anh không ép. Anh chuyển sang ghi action items: xây deployment checklist, đặt rule rollback có nhiều hơn một người review, ghi lại script emergency, chuẩn bị danh sách khách priority nếu có incident. Anh viết câu cuối: Quy trình trước khi quyết định lớn. Gạch chân.

Anh lưu. Đóng laptop.

Điện thoại rung. Email mới.

Không phải mail từ Minh. Là mail từ GitHub. Notify trên branch rewrite-v2.

Hoàng mở.

Commit cuối. Không phải commit code. Chỉ có một dòng message.

Paused — waiting for trust.

Anh đọc lần một.

Rồi lần hai.

Chữ chờ. Chữ tin. Không có code. Không có file. Không có diff. Chỉ một dòng người ta treo lên branch, nhưng nó treo lên cả mối quan hệ.

Hoàng nhìn dòng đó lâu.

Anh hiểu.

Minh không giận kiểu người đập bàn. Anh giận kiểu người dựng lại nhà từ đầu, bị ai đó kéo về cái lều cũ, rồi ngồi ngoài nhìn. Không bỏ đi. Không nói nhiều. Chỉ viết: chờ. Chờ người ta tin. Không phải chờ người ta học code. Chờ người ta học cách để người khác cùng quyết.

Hoàng gập điện thoại lại.

Văn phòng tối hơn. Không ai bật đèn phụ. ChiếcTV vẫn đen. Trên tường, sticky note của Minh nằm im. Trên Drive, post-mortem nằm chờ. Trong repo, branch rewrite-v2 nằm chờ.

Anh biết hôm nay chưa xong. Không phải chưa sửa server. Chưa sửa cách anh chọn.

Hoàng tắt laptop. Lại gần cửa. Anh nhìn ra hành lang, nơi đêm qua Minh bước ra. Đèn huỳnh quang hôm nay không nhấp nháy. Nhưng hình người đi vẫn còn trong đầu anh.

Anh đứng đó một lúc. Rồi quay lại, lấy cuốn sổ của mình, viết:

Minh chưa nghỉ. Nhưng đã chờ.

Một câu ngắn.

Nặng hơn mọi chỉ số Hệ thống chưa từng hiển thị.