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

Chương 91 — Quy trình

Trâm rải ba bảng checklist lên bàn họp trước khi máy lạnh kịp mát.

Giấy in còn nóng. Mực chưa ráo. Cô dùng thước kẻ gạt cho phẳng, xong rồi dán một miếng giấy nhớ vàng ngay góc trên bên trái mỗi bản: review, staging, deploy. Cô viết chữ tròn, không hoa, không uốn lượn. Chữ của người sợ người khác không biết mình cần làm gì.

Hoàng nhìn ba miếng giấy nhớ, rồi nhìn đôi giày trắng mới của Trâm.

“Em lau rồi,” Trâm nói, không chờ bị hỏi. “Quán bánh mì gần công ty bị tràn nước mắm sáng nay. Em bước trúng. Nhưng dép lọt kẹt, em thay giày.”

“Đi dép cho lành.”

“Em không mang dép đi họp.”

Phương Anh bước vào ngay câu đó. Cô đặt balo xám xuống ghế cuối, kéo laptop ra, mở file, mắt chưa rời checklist. Mũi giày đen của cô dừng trước bản dán chữ deploy. Cô chỉ vào ô cuối.

“Rollback plan.”

“Minh chưa ghi,” Hoàng đáp.

“Đúng. Nhưng ai ghi?” Cô hỏi.

“Người viết feature.”

“Anh ấy.” Phương Anh hạ giọng một bậc, nhưng vẫn đủ rõ. “Tốt. Tôi muốn thấy đường lùi trước khi thấy đường lên.”

Hoàng gật. Anh không cãi, không nhắc chuyện cũ. Câu “người ra quyết định rollback không mặc định là CEO” vẫn nằm trong văn bản ký từ tuần trước. Nó nằm đó không phải để ai đó giơ ra mỗi khi căng, mà để nhắc ai cũng có thể bị cuốn quá xa nếu chỉ nhìn phía trước.

Chín giờ hai phút, Minh đến.

Anh không vội. Không hoãn. Không có vẻ người đang giữ trách nhiệm lớn. Mắt hơi sưng, tóc chưa chải, áo thun xám, balo đen đeo lệch một vai. Anh dừng ở cửa nhìn một lượt. Bảng checklist. Ba ly giấy. Bàn trống của mình cách hai tuần trước còn nằm im nay đã có laptop mở sẵn.

“Chào,” anh nói.

“Chào,” Phương Anh đáp lại, cũng ngắn.

Khoa từ dưới lầu đi lên, tay cầm cà phê sữa đá, miệng đang chửi yêu ai đó qua điện thoại. Anh nghe tiếng Phương Anh nói rollback plan là cúp máy ngay, không xin lỗi, không chào.

“Đừng ai deploy trước khi tao test,” anh nói, giọng như người từng một lần bị khách chửi oan.

Trâm nhét cho anh ổ bánh mì pate.

“Anh Khoa ăn đi rồi nói. Chị Bảy tạp hoá không cần anh đói.”

“Chị Bảy sắp được test,” Khoa đáp, rồi cắn một miếng lớn.

Hoàng nhìn năm người trong phòng. Có một người viết code. Có một người giữ quy trình. Có một người nói tiếng người bán hàng. Có một cô gái biết khi nào chủ tiệm giận thật và giận cho vui. Và có anh — người từng nghĩ chỉ cần mình đủ giỏi thì mọi thứ sẽ chạy.

Minh mở laptop.

Màn hình sáng lên đúng chỗ branch rewrite-v2 đang mở từ đêm. Anh không chào ai thêm. Anh kéo deployment-review.md lên, lướt nhanh ở những đoạn quen, chậm lại ở mục rollback. Anh kéo ghế ngồi cạnh Phương Anh, đặt laptop giữa hai người.

“Em chưa ghi,” anh nói.

“Biết.” Phương Anh gập tay trước ngực. “Tôi muốn anh ghi. Anh viết feature, anh hiểu đường lùi.”

Minh nhìn cô một giây, rồi nhìn màn hình.

“Được.”

Anh gõ ngay.

Nội dung không dài. Chỉ rõ: nếu deploy mới gây mất dữ liệu đồng bộ trên staging, dừng ngay. Nếu staging ổn nhưng production chập chờn, giữ rollback plan trong bốn giờ. Nếu rollback, gọi Trâm trước, Khoa sau. Minh viết bằng câu ngắn, không hoa, không biện minh. Viết xong anh kéo cho Phương Anh đọc.

“Giữ,” cô nói.

“Tôi biết.”

Hoàng không chen vào.

Anh nhìn hai người đó trao đổi. Không phải giám sát. Không phải chờ sai. Chỉ nhìn một quy trình mới đang tự học cách đứng bằng chân nó.

Hai tuần trước, một branch ghi Paused — waiting for trust. Một tuần trước, một branch ghi Resumed — trust learning. Hôm nay, một checklist bắt đầu có hình. Có rollback. Có staging test. Có decision log. Có người chịu trách nhiệm giải thích.

Không ai ăn mừng. Không ai gọi đó là chiến thắng. Nhưng trong phòng, máy lạnh bắt đầu mát hơn, và mùi cà phê sữa đá của Khoa bớt nồng đi một chút.

Phương Anh chỉ vào checklist cuối.

“Có three customers?”

“Có.” Khoa đáp, tay vẫn cầm ổ bánh mì. “Chị Bảy tạp hoá. Chú Thanh bán sắt. Quán cà phê Thanh Thuỷ.”

“Mỗi người một kiểu?”

“Chị Bảy hỏi kỹ. Chú Thanh không hỏi nhưng để ý. Quán cà phê Thuỷ thì không nói nhiều, chỉ kêu ‘để từ từ coi’.”

“Tốt. Trâm gom phản hồi sau deploy hai tiếng.”

Trâm gật ngay.

“Em hỏi gì?”

“Hỏi tính năng mới sống hay chết khi chạm vào tay người thật.”

“Mất thời gian.”

“Đúng. Nhưng nếu không làm, mình không biết mình đang mừng cái gì.”

Hoàng nhìn cô. Câu đó không phải của một người chỉ chăm sóc khách. Câu đó là của người muốn biết thứ mình đang giữ có thật hay không.

Minh kéo ghế lại gần hơn. Anh mở terminal, kiểm tra branch. Mọi thứ sạch. Hai tuần không ai đụng. Anh thở ra, nhẹ, không ồn.

“Deploy feature gì?” Trâm hỏi.

“Xuất báo cáo doanh thu,” Minh nói. “Từ nay chủ tiệm mở app, chọn khoảng ngày, bấm nút, ra file.”

“Chị Bảy sẽ biết bấm?”

Minh mở staging, zoom vào nút.

“‘Xem doanh thu.’ Hai chữ. Không phải ‘Export revenue report’. Không có icon. Không có bước thừa.”

Trâm nhìn vào đó.

“Chị Bảy hay hỏi lại em.”

“Thì nay chị ấy hỏi. Em trả lời.”

“Nếu chị ấy không hiểu?”

“Em tới ngồi cạnh.”

Khoa cười.

“Nghe dễ. Nhưng mà đúng.”

“Đúng.” Minh đáp. “Sản phẩm không sống trên staging.”

Phương Anh đặt tay lên bàn.

“Bắt đầu.”


Mười giờ mười lăm, pipeline năm bước chạy lần đầu.

Bước một: Minh code feature trên branch, commit rõ ràng. Không giấu. Không vội. Mỗi commit một ý. Commit cuối ghi feat: revenue export v1 — ready for review. Hoàng thấy dòng đó. Anh không nói. Nhưng nhìn chữ ready for review anh hiểu người viết không còn muốn mình vừa viết vừa tự duyệt.

Bước hai: Hoàng review.

Anh mở pull request, kéo diff lên, bắt đầu đọc. Ban đầu mọi thứ quen. Route mới. Controller mới. Service gọi database. Anh đọc được logic. Anh hiểu flow. Nhưng khi lướt sâu hơn, anh thấy một lớp trung gian nằm giữa service và ORM. Lớp đó dùng decorator. Decorator dùng một hook anh chưa thấy.

Hoàng dừng.

Anh đọc lại. Một lần. Hai lần. Đoạn code ngắn. Nhưng cú pháp lạ. Cách truyền dependency lạ. Anh kéo lên trên, thấy import từ một thư viện anh không nhớ Minh đã cài.

“Thư viện gì đây?” anh hỏi.

Minh không ngẩng.

“Typedi.”

“Khi nào?”

“Tuần trước.”

“Sao không nói?”

“Em nói ở commit.” Anh chỉ vào message của hai commit trước. chore: add typedi for DI. Rồi: refactor: inject revenue service via container.

Hoàng nhìn hai dòng commit đó.

Anh biết dependency injection. Anh hiểu ý nghĩa. Nhưng anh không nhớ mình đã đọc hai dòng đó. Có thể anh đọc. Có thể anh bỏ qua. Có thể anh vẫn đang quen review code như người từng viết từng dòng trong sản phẩm này từ ngày đầu.

Anh mở Google.

Tiếng gõ phím nhỏ trong phòng. Không ai để ý. Trâm đang ghi lại câu hỏi cho Khoa. Khoa đang gọi chị Bảy báo trước. Phương Anh đang soạn impact brief. Nhưng Hoàng ngồi đó, gõ từ khoá, đọc docs, kéo ví dụ, rồi quay lại diff.

Anh review được logic.

Anh hiểu flow.

Nhưng anh không hiểu từng dòng.

Lần đầu tiên trong đời review code NỢ SỔ, anh tra cứu để hiểu sản phẩm mình.

Minh quay lại, thấy Hoàng đang mở docs.

“Anh hỏi em được.”

“Để tôi tự đọc.”

“Được.”

Không có ai cười. Không có ai khinh. Chỉ có một khoảnh khắc nhỏ: người viết code không giấu gì, và người review không giấu mình đang phải học lại.

Hoàng đọc thêm mười phút. Anh approve, nhưng để comment: Em thêm note giải thích decorator ở đây cho người đọc sau. Minh gật. Anh không nói được hay oke. Anh chỉ mở file, viết thêm hai dòng chú thích, commit.

docs: explain DI container usage for revenue service.

Bước ba: Phương Anh kiểm tra impact.

Cô không đọc code. Cô đọc câu hỏi: thay đổi này ảnh hưởng gì đến vận hành, đến tiền, đến khách, đến hợp đồng. Cô mở impact brief Minh gửi, thấy anh đã viết rõ: tính năng mới không chạm dữ liệu nợ cũ. Không thay đổi schema. Không đụng lịch sử giao dịch. Chỉ thêm một view mới. Nếu sai, chỉ view sai. Nếu đúng, doanh thu nhìn thấy rõ hơn.

“Được,” cô nói. “Nhưng nếu view sai số, ai chịu?”

“Em,” Minh đáp. “Em ghi trong decision log.”

“Giữ.”

Bước bốn: Khoa test với ba khách.

Anh không chạy script. Không kiểm tra endpoint. Anh gọi điện.

Chị Bảy nghe máy ngay.

“Con ơi app mới hả?”

“Dạ mới.”

“Có khó không?”

“Chị mở lên, thấy chữ ‘Xem doanh thu’, bấm vô.”

“Bấm vô rồi sao?”

“Thấy số.”

“Số nào?”

“Số bán.”

Chị Bảy cười.

“Trời ơi dễ quá.”

“Dạ. Nhưng chị thử coi có đúng không.”

“Để tao coi.”

Mười phút sau, chị Bảy gọi lại.

“Sai.”

Khoa im.

“Sao sai?”

“Tao chọn ngày sai.”

“Thì chị chọn lại.”

“Ủa được hả?”

“Được.”

“Thì được.”

Khoa cúp máy, nhìn Trâm.

“Chị Bảy chọn ngày sai. Sản phẩm không lỗi. Người dùng lỗi. Nhưng nếu người dùng lỗi, mình phải cho họ sửa.”

Trâm gật, ghi lại.

“Em thêm vào script trả lời.”

“Đúng.”

Chú Thanh bán sắt thì không gọi lại. Anh chỉ nhắn một dòng: Được. Không dấu chấm. Không cảm xúc. Nhưng Khoa nhìn dòng đó rồi gật. Chú Thanh là người kiệm lời. Nếu chú nói Được, tức là được.

Quán cà phê Thanh Thuỷ thì khác. Cô chủ quán trẻ hỏi:

“Sao không in luôn?”

“Gì?” Khoa hỏi.

“Báo cáo. In ra.”

“Để làm gì?”

“Để chồng em coi.”

Khoa cười.

“Để tao nói tụi nó.”

Anh nhắn Trâm ngay: Khách muốn in. Trâm ghi. Không hỏi thêm.

Bước năm: Trâm gom phản hồi.

Cô không đợi hai tiếng. Cô gom ngay sau khi Khoa gọi xong. Không phải vì vội, vì vì cô muốn biết ngay khi mọi thứ còn nóng. Cô mở file, ghi lại từng câu. Không tóm tắt. Không khái quát. Chỉ ghi nguyên văn.

Chị Bảy: “Trời ơi dễ quá.” Chú Thanh: “Được.” Quán Thanh Thuỷ: “Sao không in luôn?”

Cô nhìn ba dòng đó, rồi thêm một dòng cuối:

Phản hồi đầu tiên cho thấy khách hiểu nhanh, nhưng muốn thêm bước đi xa hơn.

Hoàng đọc file đó.

Anh không nói. Nhưng nhìn ba dòng phản hồi, anh hiểu một điều nhỏ mà trước đây anh hay quên: sản phẩm không sống ở pull request. Nó sống ở miệng người ta nói về nó.


Mười một giờ ba mươi, deploy staging.

Mọi thứ xanh.

Không có lỗi. Không có warning. Dashboard staging hiện view mới. Nhẹ. Ít dữ liệu. Nhưng chạy được.

Minh nhìn vào đó, không mừng. Anh mở log, kiểm tra thời gian query. Tốt. Anh kiểm tra cache. Tốt. Anh kiểm tra rollback plan. Đã có.

“Deploy production?” anh hỏi.

Không hỏi riêng Hoàng. Hỏi cả phòng.

Phương Anh gật. Khoa giơ ngón cái. Trâm gật nhanh. Hoàng nói:

“Đi.”

Minh bấm.

Không có âm thanh. Không có hiệu ứng. Chỉ có một dòng log chạy lên terminal. Deploying revenue export v1… Rồi: Done.

Xong.

Không incident. Không gián đoạn. Không có ai phải gọi cho khách xin lỗi. Không có ai phải chạy rollback lúc ba giờ sáng.

Lần đầu tiên trong đời NỢ SỔ, một feature đi qua đầy đủ năm bước và sống.

Mười hai giờ, Khoa gọi lại chị Bảy.

“Chị bấm chưa?”

“Bấm rồi.”

“Thấy gì?”

“Thấy tiền.”

“Thấy tiền nào?”

“Tiền bán.”

“Đúng không?”

“Để tao coi.” Im lặng vài giây. “Đúng.”

“Oke.”

“Ê.”

“Gì?”

“Sao bây giờ mới có?”

Khoa cười.

“Tụi con học chậm.”

“Ừ. Nhưng được.”

Chị Bảy cúp máy. Khoa nhìn Trâm.

“Ghi đi.”

“Em ghi rồi.”

Trâm lật sổ. Cô chỉ vào dòng ghi nhanh: Chị Bảy: “Sao bây giờ mới có?” — tính năng đúng nhu cầu.

Khoa đọc, gật.

“Hay.”

“Em biết.”

“Biết gì?”

“Biết khách nói ‘sao bây giờ mới có’ tức là họ cần từ lâu.”

Hoàng nghe câu đó.

Anh nhìn cô gái năm cuối kinh tế, bán thời gian, đang ghi chép như người đã hiểu khách không phải để làm vui, mà để giữ sản phẩm sống.

Buổi chiều, Phương Anh tổng hợp impact brief cuối.

Cô ghi:

Feature mới deploy thành công. Không incident. Không downtime. Khách hiểu nhanh. Phản hồi đầu tiên cho thấy đúng nhu cầu. Một đề xuất mới: in báo cáo.

Cô nhìn dòng cuối, cười nhỏ.

“Khách đòi in,” cô nói. “Mình chưa có.”

“Thì làm,” Minh đáp.

“Không vội.” Phương Anh lắc đầu. “Tôi muốn giữ đúng quy trình. Nếu in, phải qua năm bước.”

“Được.”

“Giữ.”

“Giữ.”

Hoàng nhìn hai người đó, rồi nhìn checklist trên bàn.

Năm bước. Có người viết. Có người review. Có người kiểm tra impact. Có người test khách. Có người gom phản hồi.

Anh không phải người duy nhất nữa.

Anh không phải người nắm hết.

Anh không còn là người biết từng dòng code.

Và lần đầu tiên, điều đó không khiến anh sợ.

Nó khiến anh thấy lạ.


Tối, văn phòng chỉ còn hai người.

Minh chưa về. Anh đang commit nốt dòng cuối cho sprint. Hoàng cũng chưa về. Anh đang đọc lại pull request.

Không phải vì nghi. Không phải vì muốn kiểm tra. Chỉ vì anh muốn hiểu.

Anh kéo diff lên, đọc lại decorator. Lần này anh không tra Google. Anh hỏi.

“Em giải thích cho anh đoạn này.”

Minh ngẩng.

“Đoạn nào?”

“Decorator.”

Minh kéo ghế lại.

Anh giảng ngắn. Không dài dòng. Không khoe. Chỉ nói: decorator ở đây để inject service, để mình không phải truyền dependency bằng tay, để test dễ hơn, để code gọn hơn.

Hoàng nghe, gật.

“Anh hiểu.”

“Được.”

“Nhưng anh chưa quen.”

“Thì học.”

“Ừ.”

Hai người ngồi đó một lúc. Không ai nói thêm. Ngoài cửa sổ, xe máy chạy qua. Máy lạnh kêu. Mùi cà phê nguội còn sót lại trong ly giấy.

Hoàng nhìn diff lần cuối, rồi nhìn Minh.

“Cảm ơn.”

Minh không đáp. Anh chỉ gõ thêm hai dòng comment trong code, rồi commit.

docs: clarify DI usage for legacy reviewers.

Hoàng đọc dòng đó, cười.

“Legacy reviewers?”

“Anh.”

“Anh là legacy?”

“Anh là người viết từ đầu.”

“Thì legacy.”

“Thì đúng.”

Hoàng cười lần nữa. Lần này cười thật.

Anh không giận. Không buồn. Chỉ thấy câu đùa đó giống một sự thật. Anh viết từ đầu. Anh giữ từ đầu. Nhưng bây giờ người khác đang viết tiếp. Và viết khác.

Minh đóng laptop.

“Em về.”

“Ừ.”

“Nếu mai có incident, em xử lý.”

“Nếu mai có incident, mình xử lý theo quy trình.”

Minh nhìn anh.

“Được.”

Anh đi ra cửa, rồi dừng.

“Anh.”

“Gì?”

“Quy trình chạy.”

“Ừ.”

“Em biết.”

Hoàng nhìn theo.

Anh không đáp. Nhưng trong đầu, anh lặp lại câu đó.

Quy trình chạy.


Đêm, văn phòng vắng.

Hoàng ngồi một mình trước màn hình.

Anh mở Hệ thống.

Giao diện hiện ra. Không có nhiệm vụ mới. Không có phần thưởng. Chỉ có chỉ số quen thuộc. Độ bền tổ chức Lv.2. Lệ thuộc tổ chức: trung bình. Mảnh thông tin tương lai vẫn khóa.

Và ở góc, một dòng mới.

KIẾN THỨC KỸ THUẬT CỦA FOUNDER — ĐANG LỆCH KHỎI CODEBASE.

Hoàng đọc dòng đó.

Anh không buồn. Không mừng. Chỉ thấy nó giống một câu nói thật.

Anh review code hôm nay bằng Google. Anh nghe giải thích về decorator từ người viết mới. Anh hiểu flow, nhưng không hiểu từng dòng.

Trước đây, anh là người biết hết.

Bây giờ, anh là người học lại.

Và lần đầu tiên, anh thấy điều đó không phải mất mát.

Đó là hậu quả tự nhiên của chia quyền.

Nếu mình chia quyền, mình cũng chia hiểu biết.

Nếu mình muốn người khác giỏi, mình phải chấp nhận người ta giỏi hơn mình ở chỗ mình từng giỏi nhất.

Hoàng nhìn dòng chỉ số thêm vài giây, rồi tắt Hệ thống.

Anh mở sổ tay, viết một câu.

Hôm nay, quy trình chạy. Feature sống. Khách hiểu. Nhưng tôi không còn hiểu hết code sản phẩm mình. Và tôi thấy ổn.

Anh viết xong, đóng sổ, tắt đèn.

Trong phòng, chỉ còn tiếng máy lạnh kêu nhỏ và ánh sáng từ ngõ hắt lên tường trắng.