2 poin oleh GN⁺ 5 jam lalu | 1 komentar | Bagikan ke WhatsApp
  • Jika membuat server ActivityPub sendiri, Anda mudah tersandung 401 Unauthorized tanpa penjelasan sejak permintaan Follow pertama; Fedify adalah framework TypeScript yang memindahkan beban penandatanganan, JSON-LD, pengiriman, dan keamanan ke luar kode aplikasi
  • Autentikasi fediverse menggunakan draf kedaluwarsa draft-cavage-http-signatures-12 bersama standar RFC 9421; jika termasuk tanda tangan dokumen, Anda harus menangani empat mekanisme tanda tangan serta kunci RSA dan Ed25519
  • Aktivitas ActivityPub yang sama pun bisa tiba dalam JSON-LD sebagai string, array, objek inline, referensi URI, dan bentuk lain; makin Anda mengimplementasikannya sendiri, makin kode defensif menyebar ke seluruh codebase
  • Dalam pengiriman terdistribusi, bisa muncul masalah seperti “post zombie” ketika Delete tiba lebih dulu daripada Create; diperlukan antrean, retry, idempotensi, jaminan urutan, dan circuit breaker
  • Fedify menyediakan integrasi dengan 13 web framework, adaptor KV dan message queue, CLI, linter, debugger, serta OpenTelemetry, sehingga Anda bisa mulai mengembangkan aplikasi terfederasi tanpa pengetahuan detail ActivityPub

Masalah yang Dihadapi Saat Mengimplementasikan ActivityPub Sendiri

  • Untuk mengirim aktivitas Follow pertama ke Mastodon, Anda harus menulis JSON, menandatangani permintaan HTTP, hingga menangani POST; tetapi jika gagal, yang kembali bisa hanya satu baris 401 Unauthorized
    • Penyebabnya bisa berupa selisih waktu pada header Date, kesalahan hash Digest, kapitalisasi (request-target), cara merepresentasikan kunci publik, dan sebagainya
    • Jika server remote tidak memberi tahu alasannya, Anda harus membaca kode server lain untuk melakukan debugging
  • Fedify bermula dari proses pembuatan Hollo, server microblog satu pengguna
    • Ketika beban implementasi ActivityPub mulai menelan pengembangan produk, ia dibuat menjadi framework yang dibutuhkan lebih dulu daripada aplikasinya
  • Kesulitannya terutama terkonsentrasi pada standar tanda tangan, bentuk dokumen JSON-LD, pengiriman terdistribusi, kebiasaan masing-masing implementasi, dan pengaturan keamanan dasar

Standar Tanda Tangan Tidak Hanya Satu

  • Autentikasi antarpeladen menggunakan tanda tangan HTTP, tetapi di fediverse nyata draf yang sudah kedaluwarsa draft-cavage-http-signatures-12 dan standar RFC 9421 sama-sama ada
  • Karena tidak bisa diketahui sebelum mencoba tanda tangan mana yang diterima server tertentu, Anda harus menandatangani dengan satu cara, lalu jika ditolak menandatangani ulang dengan cara lain dan mengingat cara yang berhasil untuk tiap server
  • Tanda tangan HTTP hanya membuktikan pengirim permintaan, sehingga dalam situasi seperti inbox forwarding, ketika aktivitas yang diterima diteruskan ke pihak ketiga, diperlukan juga tanda tangan yang melekat pada dokumen itu sendiri

Bentuk Dokumen JSON-LD Terus Berbeda-beda

  • Format transmisi ActivityPub adalah JSON-LD, dan aktivitas Create dengan makna yang sama pun bisa direpresentasikan dalam berbagai bentuk
    • actor bisa berupa string URI atau objek Person inline
    • to bisa berupa satu string atau array
    • object bisa berupa objek inline maupun URI
  • Alamat yang berarti target publik juga sama-sama valid dalam tiga representasi: https://www.w3.org/ns/activitystreams#Public, as:Public, dan Public
  • Agar memprosesnya sesuai spesifikasi, Anda harus menormalisasi dengan melakukan expansion lalu compaction menggunakan prosesor JSON-LD
    • Banyak implementasi memperlakukannya seperti “sekadar JSON”, lalu diam-diam rusak pada bentuk yang dikeluarkan server tertentu
  • Jika mengimplementasikannya sendiri, kode defensif untuk memeriksa apakah suatu nilai adalah string, array, objek, atau URI yang harus diambil akan muncul di banyak tempat

Pengiriman Terdistribusi dan “Post Zombie”

  • Jika pengguna mengunggah tulisan lalu segera melihat typo dan menghapusnya, server mengirim Delete setelah Create, tetapi tergantung kondisi jaringan, server penerima bisa menerima Delete lebih dulu
    • Jika penghapusan untuk tulisan yang belum ada diabaikan lalu Create diproses belakangan, tulisan yang diyakini penulis sudah dihapus akan tetap tertinggal di server tersebut
  • Jika ada 5 ribu follower, satu tulisan menghasilkan ribuan pengiriman HTTP; jika diproses di dalam request handler, respons tombol posting bisa melambat atau server bisa tumbang
  • Bahkan jika memakai antrean, Anda tetap harus menentukan jadwal retry untuk pengiriman gagal, exponential backoff, jumlah retry, perbedaan antara 500 Internal Server Error dan 410 Gone, pembersihan follower dari server yang sudah hilang, hingga penanganan host yang bermasalah dalam jangka panjang
  • Area ini lebih dekat ke rekayasa sistem terdistribusi daripada sekadar implementasi protokol

Interoperabilitas Tidak Selesai Hanya dengan Spesifikasi

  • Meski mengikuti spesifikasi secara sempurna, masalah interoperabilitas dengan implementasi fediverse nyata tetap tersisa
  • Secure mode Mastodon menggunakan authorized fetch, yang meminta tanda tangan HTTP bahkan untuk permintaan GET
    • Jika kedua server sama-sama berada dalam secure mode, muncul deadlock: untuk mengambil kunci publik pihak lawan harus menandatangani, tetapi untuk memverifikasi tanda tangan pihak lawan harus terlebih dahulu mengambil kunci publik kita
    • Komunitas mengakalinya dengan menandatangani memakai instance actor yang merepresentasikan server itu sendiri, tetapi ini tidak ada dalam spesifikasi
  • Threads tidak bisa mem-parse aktivitas yang actor-nya berupa objek inline, sehingga saat mengirim ke Threads, actor harus dikirim sebagai URI
  • Lemmy diam-diam menolak jika tidak ada field Group actor yang tidak diminta Mastodon
    • Contohnya adalah moderators collection dan featured collection yang terhubung melalui attributedTo
  • Misskey memiliki perluasan kosakata sendiri, dan untuk quote post saja ada tiga nama properti yang digunakan tergantung implementasinya
  • Interoperabilitas bukan pekerjaan sekali cocok lalu selesai, melainkan area yang harus terus dipelihara

Kondisi Dasar Implementasi Sendiri Tidak Aman

  • Jika melewatkan verifikasi tanda tangan pada aktivitas masuk, siapa pun bisa menyuntikkan Follow atau Delete palsu
  • Jika document loader tidak dibatasi, aktivitas berbahaya bisa menunjuk ke http://169.254.169.254/ atau jaringan internal dan menjadikan server sebagai proksi SSRF
  • Jika pemeriksaan asal objek tertanam dilewati, server mana pun bisa mengeluarkan dokumen yang tampak seolah-olah dikatakan oleh orang tertentu
  • Jebakan seperti ini tidak langsung terlihat, dan sampai disalahgunakan, semuanya bisa tampak seolah-olah berfungsi

Area yang Ditangani Fedify sebagai Pengganti

  • Fedify adalah library TypeScript untuk membuat aplikasi server federasi dengan ActivityPub dan standar terkait
  • Berjalan di Deno, Node.js, dan Bun, serta juga mendukung runtime edge seperti Cloudflare Workers
  • Tujuan desainnya adalah menghapus tanda tangan, JSON-LD, pengiriman, perbedaan antar-implementasi, dan detail keamanan dari kode aplikasi
  • Penanganan tanda tangan

    • Dengan mendaftarkan actor dispatcher dan key pair dispatcher, satu actor dapat dipublikasikan ke fediverse
    • Semua permintaan keluar diberi tanda tangan
    • Untuk kunci RSA, HTTP Signatures dan Linked Data Signatures dibuat
    • Jika kunci Ed25519 ditambahkan, Object Integrity Proofs juga disertakan
    • Empat mekanisme dapat berdampingan dalam satu aktivitas, dan penerima memverifikasi dengan metode terkuat yang dipahaminya
    • Fedify menangani sendiri double-knocking
      • Kontak pertama dikirim dengan RFC 9421, dan jika ditolak, dicoba ulang dengan draft-cavage
      • Metode yang berhasil di-cache per server
      • Jika respons penolakan memiliki challenge Accept-Signature, permintaan ditandatangani ulang dengan komponen yang diminta server
    • Tanda tangan masuk diverifikasi sebelum terlihat oleh kode aplikasi, dan aktivitas yang gagal verifikasi tidak akan mencapai listener
    • Cukup dengan mendaftarkan actor dispatcher, server WebFinger RFC 7033 juga dibuat, sehingga actor dapat ditemukan dari kotak pencarian Mastodon dalam bentuk @alice@example.com
  • Menangani tipe alih-alih JSON-LD

    • Fedify menyediakan sekitar 80 kelas yang mencakup seluruh Activity Vocabulary dan ekstensi vendor utama
    • Kelas-kelasnya bertipe dan immutable, sementara accessor menyerap perbedaan bentuk dokumen yang diizinkan JSON-LD
    • lookupObject() menerima handle dan menjalankan seluruh prosedur lookup, termasuk WebFinger discovery
    • Accessor seperti getFollowers() bekerja dengan cara yang sama baik nilainya berupa referensi URI maupun objek inline, dan nilai yang diambil akan di-cache
    • Perbedaan antar-vendor juga disembunyikan di balik API
      • Tiga properti quote, yaitu quoteUri, _misskey_quote, dan quoteUrl, diintegrasikan di balik satu API bersama quote dari FEP-044f yang baru muncul
      • Properti isCat milik Misskey juga tersedia sebagai tipe, sehingga dapat ditangani dengan aman secara tipe
  • Infrastruktur pengiriman dan jaminan urutan

    • Jika message queue dihubungkan ke createFederation(), pengiriman dipindahkan ke background, dan saat gagal otomatis dicoba ulang dengan exponential backoff hingga maksimum default 10 kali
    • Ketika satu postingan dikirim ke ribuan follower, two-stage fan-out akan berjalan
      • Satu pesan terpadu masuk ke queue
      • Background worker memecahnya menjadi tugas pengiriman per server
      • Tombol publish segera merespons
    • Karena retry dapat membuat aktivitas yang sama tiba dua kali, Fedify melewati duplikat sebelum handler dengan cache idempotensi yang menyimpan aktivitas yang telah diproses selama 24 jam
    • Jika { orderingKey: post.id } ditentukan pada panggilan sendActivity(), aktivitas yang berbagi orderingKey yang sama dikirim ke tiap server penerima sesuai urutan pengirimannya
      • Delete tidak dapat mendahului Create
      • Aktivitas dengan key berbeda dikirim secara paralel untuk mempertahankan throughput
    • Pada 404 Not Found atau 410 Gone, retry dihentikan dan handler kegagalan pengiriman permanen yang terdaftar dipanggil
    • Jika dikirim ke shared inbox, daftar follower di baliknya juga dapat diterima untuk membersihkan akun yang sudah hilang
    • Untuk host yang berulang kali gagal, circuit breaker yang aktif secara default menahan pengiriman dan memeriksa pemulihan secara berkala

Praktik per Implementasi dan Default Keamanan

  • Pada authorized fetch, Fedify menghubungkan .authorize() ke dispatcher dan meneruskan identitas pemohon yang telah diverifikasi ke callback
    • Pemrosesan seperti daftar blokir dan koleksi privat dapat ditulis sebagai logika aplikasi
    • Ada juga pola dukungan untuk masalah deadlock instance actor
  • Masalah actor inline pada Threads ditangani oleh activity transformer yang aktif secara default dengan mengubah actor inline pada aktivitas keluar menjadi URI
  • Moderators collection yang diminta Lemmy dapat diekspos dalam beberapa baris dengan custom collection API, dan JSON-LD context Lemmy sudah disertakan sebelumnya
  • Ketika masalah interoperabilitas baru ditemukan, perbaikannya masuk ke Fedify, bukan ke masing-masing aplikasi
  • Default keamanan mengarah ke sisi yang aman
    • Verifikasi tanda tangan bukan fitur yang perlu dinyalakan, melainkan fitur yang dimatikan untuk pengujian
    • Document loader secara default memblokir private address range dan loopback, serta mempertimbangkan DNS rebinding
    • Agar terekspos ke SSRF, opsi dengan nama yang jelas menunjukkan untuk pengujian harus dinyalakan secara eksplisit
    • Jika origin objek embedded berbeda dari dokumen induk, accessor tidak mempercayainya dan mengambil ulang dari sumber aslinya
    • Model keamanan berbasis origin ini didasarkan pada FEP-fe34

Stack dan alat pengembangan yang sudah ada

  • Fedify dirancang agar cocok dengan stack web yang sudah ada dan menyediakan integrasi dengan 13 framework web
    • Express, Hono, Fastify, Koa, NestJS, Elysia
    • Next.js, Nuxt, SvelteKit, Astro, SolidStart, Fresh
  • Middleware menangani negosiasi konten, sehingga URL yang sama dapat menyajikan HTML ke browser dan JSON-LD ke fediverse
  • Penyimpanan Fedify sendiri hanya membutuhkan satu antarmuka key-value
    • Tersedia adapter Redis, PostgreSQL, MySQL/MariaDB, SQLite, Deno KV, Cloudflare Workers KV, dan in-memory
  • Message queue tersedia dalam 8 pilihan termasuk PostgreSQL, Redis, AMQP/RabbitMQ, dan jika tidak ada yang cocok, Anda dapat mengimplementasikan antarmukanya sendiri
  • Data domain dapat tetap berada di database dan ORM yang sudah ada
  • Jika Anda sudah menjalankan federation dengan library lain, panduan migrasi dan skrip migrasi data memungkinkan Anda berpindah dari activitypub-express dan sejenisnya tanpa kehilangan follower yang sudah ada
  • Paket tingkat lebih tinggi juga tersedia
    • @fedify/relay menyediakan server relay ActivityPub lengkap dengan satu pemanggilan fungsi
    • @fedify/backfill mengikuti fediverse dan memulihkan thread percakapan yang tidak lengkap
  • Alat untuk development loop

    • fedify init men-scaffold proyek dalam satu baris
    • fedify tunnel mengekspos server lokal melalui HTTPS agar dapat diuji dengan Mastodon sungguhan
    • fedify inbox menjalankan server inbox sementara untuk menerima activity yang dikirim server
    • fedify lookup memungkinkan pemeriksaan objek yang dipublikasikan server lain
    • fedify lookup --authorized-fetch membuat pasangan kunci sekali pakai, mendirikan server ActivityPub sementara, lalu mengirim permintaan bertanda tangan ke objek di balik secure mode
    • @fedify/lint adalah linter khusus ActivityPub yang menangkap 20 bug interoperabilitas, seperti actor yang tidak memiliki inbox
    • Mock dari @fedify/testing memungkinkan pengujian dijalankan tanpa jaringan
    • @fedify/debugger menambahkan dashboard debug dalam satu baris, sehingga activity dan hasil verifikasi tanda tangan dapat dilihat secara real time di browser
    • Untuk lingkungan produksi, instrumentasi OpenTelemetry sudah terintegrasi dan menyediakan 28 jenis span serta 37 metric
    • Panduan monitoring dan alat load test untuk ActivityPub, fedify bench, juga tersedia
    • Dokumentasi resmi terdiri dari manual 30 bab dan 5 tutorial, mencakup praktik nyata seperti query PromQL dan aturan alert untuk melihat backlog queue, serta properti agar avatar terlihat di Mastodon

Contoh penggunaan yang sudah ada dan cara memulai

  • Fedify sudah digunakan dalam layanan nyata
    • Layanan ActivityPub milik Ghost
    • Encyclia, yang menghubungkan catatan peneliti ORCID ke fediverse
    • SiliconBeest, yang berjalan secara serverless di Cloudflare Workers
    • Platform blogging Korea, Typo Blue
    • Hollo, platform microblogging pengguna tunggal
    • Hackers' Pub yang dioperasikan komunitas
  • Tutorial menyediakan contoh berdasarkan skala
  • Tujuan Fedify bukan membuat lebih banyak pakar ActivityPub, melainkan memungkinkan developer membuat aplikasi federasi tanpa perlu mengetahui detail ActivityPub
  • Perintah untuk memulai adalah npm init @fedify
  • Jika membutuhkan bantuan, Anda dapat menggunakan Matrix room atau GitHub Discussions

1 komentar

 
GN⁺ 5 jam lalu
Pendapat di Lobste.rs
  • Inilah alasan ada banyak fork dari proyek ActivityPub: lebih mudah memahami pendekatan orang lain daripada mengimplementasikan semuanya sendiri
    Apa yang diusulkan penulis juga tampaknya tidak jauh berbeda dari fork Misskey atau Pleroma yang umum terlihat. Library pun punya sudut pandang dan pendekatannya sendiri, dan sepertinya tidak memberi banyak kendali. Meski begitu, keuntungannya adalah tidak memaksakan UI seperti saat mem-fork seluruh server
    Dari sudut pandang orang yang sedang mengimplementasikan AP, bagian tersulit adalah tidak ada cara yang baik untuk menggunakan JSON-LD dengan benar. Kalau objek bisa dengan mudah diubah ke representasi standar, interaksi akan mengikuti secara alami, tetapi terlalu tidak efisien untuk digunakan seperti dokumen tertaut sungguhan, dan kalau dipakai seperti dokumen JSON mentah, kita akan mati menghadapi begitu banyak kasus pengecualian. Sejauh ini saya memilih pendekatan kedua, lalu tumbang

    • Khususnya jika memikirkan tanda tangan, masalah “representasi standar objek” menjadi makin penting. Normalisasi XML dulu ada justru untuk masalah tanda tangan ini, yaitu memastikan serialisasi byte di pihak penerima cocok dengan milik pengirim
      Ini bukan masalah yang sepenuhnya sama dengan dunia JSON-LD, tetapi juga tidak sepenuhnya tidak terkait
      Namun menurut saya cukup banyak teknologi yang berdekatan dengan JSON mengalami masalah serupa. Ada terlalu banyak cara JSON Schema untuk merepresentasikan skema logis yang sama, dan karena itu berinteraksi dengan teknologi di sekitar JSON Schema menjadi sangat mengerikan sampai terasa konyol. Khususnya skema OpenAPI adalah horor yang mirip tetapi tidak sama, dan bahkan tanpa mempertimbangkan banyaknya versi draft skema pun sudah cukup buruk
    • Saya sudah memikirkan implementasi server AP tetapi belum mulai, jadi anggap saja dengan banyak catatan. Satu hal yang mungkin membantu adalah memecah aplikasi menjadi layanan-layanan yang lebih kecil, lalu lebih mengandalkan model aktor agar tampak seperti antarmuka yang “terpadu”. Misalnya, kita bisa belajar dari pemisahan MTA dan MUA pada server email
      Layanan “MTA” AP bertugas mengirim pesan dari outbox dan menerima pesan ke inbox. Bagi layanan ini, dokumen JSON-LD hampir seperti data gumpalan. Perlu sedikit parsing untuk mengetahui pengirim dan penerima, tetapi tidak banyak lebih dari itu. Penyimpanannya juga bisa berbasis file, dan kalau ingatan saya benar, go-ap memakai cara seperti itu
      “MUA” AP adalah aplikasi sebenarnya. Inilah pihak yang harus memahami makna JSON-LD. Sepertinya bisa memakai sesuatu seperti PostgreSQL untuk menyimpan dokumen sebagai jsonb, lalu menyediakan bentuk yang ramah SQL dengan kolom hasil generasi dan view. Dengan begitu, cara paling tepat untuk merepresentasikan dokumen bisa ditentukan berdasarkan tipe objek
      Contoh lain, layanan pencarian juga bisa dimodelkan sebagai aktor dan dibuat mengembalikan hasil melalui outbox sementara
  • Ini daftar yang sangat berharga yang merangkum perilaku unik berbagai implementasi beserta mitigasinya
    Sayangnya, GoActivityPub bahkan belum mengimplementasikan setengahnya

  • Awalnya saya berterima kasih karena tulisan ini dimulai dengan konten teknis, tetapi di tengah jalan rasanya berbelok menjadi promosi framework sendiri, sehingga kenikmatan membacanya menurun
    Untungnya, di sebagian dunia yang memakai TypeScript, keanehan implementasi semacam ini mungkin tidak perlu ditemukan ulang. Namun sebagai model mental, jika ada catatan bahwa “dalam kondisi dan situasi ini, hasilnya begini, dan perlu perbaikan seperti ini”, maka hasil jerih payah itu juga bisa diperoleh dalam situasi non-TypeScript, misalnya oleh penulis proyek saudara, GoActivityPub. Di sini memang dibahas beberapa hal seperti itu, tetapi tulisannya adalah snapshot pada satu titik waktu, sedangkan proyeknya tampak seperti berusaha mengakumulasi semua bug interoperabilitas seiring waktu
    Alternatif saat ini, menurut saya, hanyalah membaca semua pesan commit yang bukan ditulis manusia, sambil membedakan bug Fedify sendiri dari bug interoperabilitas
    Sangat ironis bahwa repositori itu tampak “all-in” pada AI tetapi tidak melakukan pencatatan seperti itu. Promosi yang saya dengar tentang LLM adalah bahwa ia mengotomatiskan pekerjaan berulang yang membosankan. Kalau begitu, Claude bisa dibuat membuat issue GitHub, atau lebih baik lagi mendokumentasikan hasil pengamatan dan bagaimana Fedify memperbaikinya dalam file .md di dalam repositori. Mereka juga punya debugger sendiri dan “praktik terbaik” yang entah maksudnya apa, jadi ini tampak seperti tugas yang pas

    • Mereka benar-benar membesar-besarkan masalah sepele seolah-olah itu kegagalan ActivityPub. Misalnya, jika ada 5.000 pengikut, satu postingan menjadi ribuan pengiriman HTTP, dan kalau itu dilakukan langsung di dalam request handler, respons tombol posting butuh 30 detik atau server tumbang, jadi gunakan queue, begitu kira-kira
      Mengapa request ke layanan pihak ketiga dilakukan secara inline? Ini dasar aplikasi web. Jika harus berkomunikasi dengan layanan pihak ketiga, kirim sebagai pekerjaan latar belakang. Jika informasi itu tidak diperlukan untuk merespons request, kirim sebagai pekerjaan latar belakang. Masalah yang timbul karena melakukan request seperti ini di dalam request handler adalah masalah yang dibuat sendiri setara menginjak garu lalu kena wajah, bukan urusan ActivityPub
      Jika pengiriman gagal, harus dicoba ulang; bagaimana jadwalnya, apakah memakai exponential backoff, berapa kali, apakah 500 Internal Server Error dan 410 Gone dianggap kegagalan yang sama—semua itu juga hanyalah masalah umum pengembangan aplikasi web. Itu masalah yang muncul saat queue pekerjaan mengirim request ke layanan pihak ketiga dan tidak ada hubungannya dengan ActivityPub. Sebagian besar framework web punya default yang masuk akal. Penilaian hanya diperlukan pada titik ketika harus menentukan apakah retry perlu dilakukan berdasarkan jenis error. Me-retry 410 memang pemborosan, tetapi bukan masalah yang harus diselesaikan mendesak. Itu akan menambah tekanan memori pada queue pekerjaan, tetapi kecil kemungkinan menjatuhkan aplikasi dalam hitungan jam
  • “Lihat apakah ditolak, tanda tangani ulang dengan cara lain, lalu ingat cara mana yang berhasil untuk tiap server”—saya sampai bertanya-tanya sebenarnya saya sedang membaca apa. Apakah ini sebabnya pengembangan Mastodon lambat?
    “Satu postingan menjadi ribuan pengiriman HTTP”, katanya, dalam Ruby yang terkenal sebagai bahasa unggul untuk pemrograman sistem jaringan dan antrean
    Sulit dipercaya, dan bagus bahwa ini dibungkus dalam library, tetapi tetap saja agak begitu

  • Setelah mencoba mengimplementasikan ActivityPub di Java, saya sampai pada kesimpulan bahwa protokol antarpeladen seperti ini sebaiknya dibuat saja di atas git
    Sebagian besar kompleksitasnya ada untuk memecahkan ulang masalah yang sudah diselesaikan git dengan lebih baik. Jika memodelkannya sebagai dokumen JSON di dalam repositori git, kita tidak perlu menangani pagination. Protokolnya sudah menjamin hanya data yang belum ada yang dikirim, kita mendapat tanda tangan commit, mendapat jaminan urutan event, masalah yang disebut dalam tulisan ini juga terselesaikan, dan riwayat pun didapat gratis. Rasanya bisa dibuat semacam Hukum Kesepuluh Greenspun untuk protokol seperti ini: di dalamnya ada setengah implementasi git yang penuh bug dan lambat

    • git bukan pilihan yang bagus karena riwayat bergantung pada commit induk. Namun protokol gosip pohon Merkle yang bekerja dengan strategi negosiasi serupa mungkin cocok
  • Tulisan ini terbaca seperti artikel berkualitas rendah buatan AI
    Lebih spesifiknya, saya tidak mengerti mengapa ditulis dalam format cerita. Fakta-fakta yang disampaikan di sini bisa ditulis jauh lebih ringkas dan kurang bias, dan narasinya juga tidak meyakinkan. Terutama karena banyak ungkapan khas AI
    Tidak menyenangkan untuk dibaca. Meski begitu, terima kasih karena sudah menunjukkan masalah-masalahnya, dan saya berharap bisa membaca serta memperbaiki masalah itu dengan cara lain