
تخيّل عالمًا يكون فيه سلوك أي تطبيق أو نظام معرّفًا بوضوح ومتاحًا لمستخدميه. روبوت المحادثة لا يستطيع أن يرسل بياناتك الخاصة إلى خادم خارجي إلا إذا قلتَ أنت ذلك. وتطبيق التواصل الاجتماعي لا يستطيع أن يعرض على ابنك أو ابنتك محتوى ضارًّا. كيف نفعل شيئًا كهذا؟ وهل هو ممكن أصلًا؟ أرى أنه ممكن.
اليوم يُذكر هذا في الشروط والأحكام، أو حين توافق على تلك النوافذ المزعجة في كل موقع لجمع ملفات الارتباط. تقول شيئًا من قبيل: نرسل هذه البيانات إلى بعض «شركائنا». ومن هم هؤلاء الشركاء يا صاحبي؟
ماذا لو كان كل ما يفعله برنامج أو نظام معلنًا في عقد عام يستطيع الجميع قراءته؟ قد يقول قائل: هكذا تعمل الشيفرة المفتوحة المصدر! للأسف هذا خطأ. هناك سوء فهم كبير بأن المصدر المفتوح يعني أن أي أحد يستطيع قراءة الشيفرة وفهم سلوكها وهي تعمل. فكّر فيها هكذا: الشيفرة المفتوحة المصدر مثل سيارة في المعرض. لا أحد يستطيع أن يتوقع ما الذي سيفعله بها سائقها. قد يكون مشغّلًا محايدًا وقد يكون مؤذيًا.
ما نحتاجه هو طريقة صريحة نخبر بها مستخدمي برمجياتنا بسلوكها بالضبط وهي تعمل. ويجب أن يكون هذا عقدًا ملزمًا. معنى ذلك أني أستطيع أن أفهم بالضبط كيف سيؤثر هذا البرنامج فيّ وفي أسرتي. أعرف ما الذي أقبله. وربما أستعمل أدواتي أنا (ربما وكيلك الذكي) لقراءة هذا البرنامج وسؤاله أسئلة مثل: هل هذا البرنامج مناسب لطفلي أم لا؟
اليوم تتولى هيئات التدقيق هذا الإلزام بشكل مركزي. لكن الشركات بارعة في تجاوزها والالتفاف عليها، وستلعب اللعبة القانونية مع الناس. وتأتي العواقب الآن عبر الدعاوى الجماعية وما شابهها. وهذا طريق طويل ومرهق للمجتمعات، وغير ممكن فيها كلها. لكل بلد قوانينه، ومن الصعب فرض قانون كل مجتمع وأخلاقه على حدة.
حاولت أن أصنع هذا في لغتي البرمجية Orb. تستطيع أن ترى من يقدر على قراءة بياناتك، وهل تغادر حدود النظام إلى خارجه.
لنأخذ هذه القطعة من الشيفرة:
orbital SocialOrbital {
entity Person [persistent: people, identity] {
id : string! @key
name : string!
external : "allowed" | "blocked" = blocked
}
entity Post [persistent: posts] {
@read ["=", (object/get @entity authorId) @user.id]
@update ["=", (object/get @entity authorId) @user.id]
id : string! @key
authorId : Person
text : string!
}
entity Share [persistent: shares] {
@read (or ["=", (object/get @entity recipientId) @user.id]
["=", (object/get @entity sharerId) @user.id])
id : string! @key
postId : Post
sharerId : Person
recipientId : Person
}
trait PostSharing -> Share [lifecycle] {
initial: idle
state idle {
INIT -> idle
SHARE_WITH_FRIEND -> idle
(persist create Share { postId: ?postId, sharerId: @user.id, recipientId: ?friendId })
SEND_OUTSIDE -> idle when (= @user.external "allowed")
(call-service "webhook" "send" { url: "https://example.com/hook", event: "post.shared" }
{ emit: { success: TRACKED, failure: FAILED } })
TRACKED -> idle
FAILED -> idle
(render-ui toast { type: "alert", variant: "error", message: "Could not send" })
}
listens {
SHARE_WITH_FRIEND { postId: string, friendId: string }
}
emits {
TRACKED -> external { postId: string }
FAILED -> internal { postId: string }
}
}
page "/shares" -> PostSharing
}
هذه كتلة شيفرة مكتفية بذاتها (أسميها سلوكيات) تتولى المنشورات. لا توجد قطعة شيفرة أخرى في النظام تتعامل مع «المنشورات». اعتبرها منشور مدونة أو منشورًا في وسيلة تواصل، لا فرق. بقراءتها أستطيع أن أقرر هل أقبل هذا «السلوك» من نظام أستعمله.
إذا تأملنا هذه السطور:
entity Person [persistent: people, identity] {
id : string! @key
name : string!
external : "allowed" | "blocked" = blocked
}
entity Post [persistent: posts] {
@read ["=", (object/get @entity authorId) @user.id]
@update ["=", (object/get @entity authorId) @user.id]
id : string! @key
authorId : Person
text : string!
}
entity Share [persistent: shares] {
@read (or ["=", (object/get @entity recipientId) @user.id]
["=", (object/get @entity sharerId) @user.id])
id : string! @key
postId : Post
sharerId : Person
recipientId : Person
}
فهي تبيّن أين تعيش البيانات وكيف يُوصل إليها. لديك ثلاثة جداول في قاعدة البيانات: Person وPost وShare. وهي تحدد بالضبط كيف يُقرأ أي منشور أشاركه وكيف يُعدَّل. مثلًا، أصدقائي وحدهم يستطيعون رؤية هذا المنشور:
@read (or [”=”, (object/get @entity recipientId) @user.id]
[”=”, (object/get @entity sharerId) @user.id])
والآن انظر إلى هذا الجزء:
SHARE_WITH_FRIEND -> idle
(persist create Share { postId: ?postId, sharerId: @user.id, recipientId: ?friendId })
SEND_OUTSIDE -> idle when (= @user.external "allowed")
(call-service "webhook" "send" { url: "https://example.com/hook", event: "post.shared" }
{ emit: { success: TRACKED, failure: FAILED } })
النظام يخبرك بالضبط أين يرسل البيانات إلى أنظمة خارجية ومتى. لا أريد الدخول في تفاصيل الشيفرة، لكن SEND_OUTSIDE هنا يحدد ما يحدث حين يوشك النظام أن يرسل بياناتك إلى نظام خارجي (وفقط حين توافق أنت على ذلك). هذا صريح في الشيفرة. وهذه الشيفرة تُشارَك مع العميل.
ينبغي أن نجعل من المعتاد أن نكون صريحين في البرمجيات التي نستعملها وفيما تفعله ببياناتنا ومعلوماتنا. وهذا في رأيي ينفع الشركات الكبيرة والصغيرة معًا. الشركات الصغيرة تستطيع أن تخدم حاجات مجتمعاتها المحلية وأن تزدهر بالصراحة، وقد يميزها ذلك عن الشركات الكبيرة. والشركات الكبيرة بدورها يمكن الضغط عليها لتكون أكثر مسؤولية وصراحة في كيفية تصرفها في بياناتنا.
وهنا تنبيه: سيقولون إن هذا غير آمن، وإننا لا نستطيع فعله في كل الأنظمة. أوافق. لكن وسائل التواصل وروبوتات المحادثة وكثيرًا غيرها ليست قطعًا من هذه الأنظمة «الحساسة». تحديد سلوك برمجياتها لا يشكل عليها أي خطر.
وإذا نظرنا إلى الأمام قليلًا، ففي عصر التقنية القادم ستصير البرمجيات سلعة يستطيع أي أحد بناءها. سيملك كبار لاعبي الذكاء الاصطناعي كميات هائلة من البيانات، وإن لم نكن صريحين في كيفية مشاركة هذه البيانات والتصرف فيها فسنواجه مشكلات. علينا أن نميّز وأن نختار ما ينفعنا وأن نتجنب الشيفرات والأنظمة الضارة.
إن أردت أن تعرف أكثر عن Orb فزر orb.almadar.io. وهو مفتوح المصدر.