可穿戴国际大阪第三开发部“8·15”特大实验器材失控事故调查报告

2158 年 8 月 15 日,可穿戴国际大阪第三开发部自律微观材料实验室发生特大实验器材失控事故,事故在五天之内,对以南海高野线白鹭站前的第三开发部大楼为中心,约 3 公里半径内的所有建筑造成了断电的影响,由此带来的直接、间接损失是难以估量的;此外,事故还使当天位于第三开发部大楼内部的所有 730 名工作人员及碰巧路过附近的 26 名无辜民众造成了 5 天内失去正常社会功能的后果。

此次事件泄露出的实验性设备及其对民众所进行的行为不仅严重影响了可穿戴国际的形象,也完全违背了其立业的初衷与宗旨,性质极其恶劣。事故发生后,可穿戴国际(新亚)立即与有关部门成立了联合调查组,通过现场勘验、检测、鉴定、取证等步骤,并委托生物、机械、信息等领域的有关专家反复论证,查明了事故发生的深层次原因,并提出了对有关单位的建议和事故的防范与整改措施。

现将有关情况报告如下:

1 事故基本情况

1.1 事故现场情况

自律微观材料实验室位于开发部大楼四层,占据了四层全域,在总层数 24 层的大楼中并不算高。除了楼梯间、卫生间等设施,实验室分成器材保管与维护、计算资源存储、设备测试等多个区域。本次事发的设备测试区位于东区,有共 16 个测试场地,每个场地为长、宽、高各 10m 的立方体空间,占据了三层至五层的同等区域。按照惯例,可穿戴国际的大部分实验均是租用其他场地,只有有技术保密性和安全性的考虑的项目才会选择在开发部内申请场地。

出于对实验事故处理的便捷性与实验材料的安全性的考量,实验空间未与外界进行强隔离。最外侧的两个测试场地左右两侧便是楼梯井和电梯井,这给了本次失控的 1D-599-1 设备进行大规模破坏的可能性。

1.2 事发项目情况

代号为 1D-599 的实验项目全名为“基于持久化自律微观材料的便捷人种牲畜实验套件”,于 2150 年 4 月 17 日由第三开发部向伦理委员会提交,并于同年 7 月 1 日正式开展实验。该项目旨在将最新发表在学术会议上的持久化自律微观材料实用化。

持久化自律微观材料的概念,是在 2149 年 7 月 2 日由伊顿尼亚合众国军方在一篇内部论文中提出的,并意外由可穿戴国际的一名研究员获知。在她提出请求之后,伊顿尼亚合众国政府与可穿戴国际签订了相关协议,允许其在一定限度内使用此研究及其关联、衍生研究中产生的数据。出于保密性的需求,隐去论文题目。该项目被交给了当时刚被调到这个部门不久的现自律微观材料实验室高级研究员木村武志负责,经过三年的开发之后,交由资源管理部门审议,并获准使用 6 号实验空间与位于地下一层的批量材料生产设备进行为期两年的静物实验,以验证 1D-599-1 设备的材料韧性、结构稳定性等功能。

2154 年 10 月 24 日,在多个重大难关被攻破后,木村武志研究员申请将她的私人财产 Kimura-3 作为实验材料。虽然直接在人种牲畜上展开实验符合惯例,但出于耗损度的考量,其他实验使用的均是公司的公有财产,但使用私人财产并未违反任何安全规范与协定;木村研究员的解释,是出于 Kimura-3 曾和她共同参与了一部分 1D-599 项目的研发工作的经历,以及 Kimura-3 自身的意愿,选择使用 Kimura-3 作为实验体。

2158 年 1 月 4 日,在解决了大部分结构韧性问题后,第三开发部内部决定测试已部分安装在商用设备上的紧急拒止操作在 1D-599-1 上的性能,1D-599 项目组无异议,并积极配合。

1.3 实验材料与器械管理情况

登记编号为 1D-599-1 的实验设备是一种由特殊微观材料组成的大型结构,其在工作时形似若干条缠绕在一起但分工明确的触手。为了方便阅读,本报告部分称其为触手设备。此外,Kimura-3 的登记编号为 1D-599-2。

此项目的其它主要器械还包括 1D-599-3 和 1D-599-4。1D-599-3 是一个半球形金属网,用于为形成触手的微观材料提供支撑,以减少其自身为建立、维持所需结构带来的能耗;1D-599-4 是一台常规服务器,同样安置于四层,用于控制触手设备并处理其发回的信息。可以说 1D-599-4 就是 1D-599-1 的大脑。

在闲置状态下,1D-599-1 设备的触手会接受计算机命令,自我分解成液态材料,储存在 6 号实验空间的下方,以节省能耗;无法储存的部分,会储存在材料生产设备附近的特殊容器中。

2 事故经过

2.1 事故发生经过

2158 年 1 月 5 日至 8 月 15 日,项目组共以 Kimura-3 为基础展开紧急拒止实验约 450 次。在第 451 次实验的时候,触手设备在形成紧急拒止所必要的注射接口后,出现了部分结构性断裂。由于材料的每个基本组分都有记录自己的力学信息,以及附近一些组分的相对空间位置的能力,因此读取断裂结构的所有信息,就能还原当时事发的力学模型,这对解决问题是至关重要的,但有一个小问题,就是需要有人把断掉的结构捡出来。自从实验开始到现在,这个任务都是木村研究员执行的。

虽然触手结构有通过细微震动感知空间的能力,以及让任何身份的人种(Homo Sapine)生物失去活动的倾向,但项目组和开发部的相关人员被加入了黑名单,因此即使设备感知到木村研究员,也会视而不见;此外,6 号实验空间的入口和 1D-599-3 设备的入口均被涂上了触手可识别的特殊材料,其在遇到这种材料的时候,将不会越过这些材料进行扩散。综上所述,安全性是可以保证的。

此外,在与第三开发部联合实验之后,项目组将公司内部安保系统的人员识别模块接入了触手的感知,以进行兼容性测试,但事实上,由于需要被拒止的人种生物一直只有 Kimura-3 一个,因此这个操作对实验是可有可无的。

8 月 15 日上午 09:33:47:443,木村研究员解除了门锁,走进了 6 号实验空间。

09:33:55:448,项目组收到了一则来自安保部门的联络,为了隐私考虑,以下的语音转文字均隐去了人员姓名:

S1-11:这里是安保一队。请问是自律微观材料实验室吗?我们发现了异常现象。

M3-4:是的,我是 M3-4。请问有何贵干?

S1-11:这边服务器的流量增大了很多,我们确认后,发现你们在反复对整栋楼的所有人进行身份识别。这是正常现象吗?

M3-4:不应该啊……实验里面没有这一项。M3-7,你看看接口调取记录,这是怎么回事?

S1-13:我刚去服务器看过,今天这么大的流量绝对不正常。她们一般也只是在系统自检的时候进行一次全域识别,没见过反复全域识别啊……

M3-17:我拿到断裂结构了,现在就出来。裕子,再过一个月你就可以回家啦~

M3-4:好闪……

M3-7:是啊……说回正题,我查到的信息是触手的感知系统从 M3-17 开始逐渐向这层楼扩展,然后逐渐上升到了安保系统看到的所有人……有什么地方不对。

M3-17:好神奇。有什么更具体的信息吗?

M3-7:没有。M3-17,你先出来,我们重启一下系统……等等,快跑!你被触手识别成拒止对象了!

M3-17:(愣在原地)不可能啊?我不是在黑名单里吗?

M3-2:不仅是你,所有人都成了对象……但一会 true 一会 false 这是怎么回事……

M3-17:诶?触手怎么从我的腿上……哦天啊!重启系统!快!

M3-2:这就操作!你们去救 M3-17!

M3-4:不行啊,我要被触手侵犯了……不行!

【杂音】

【尖叫声】

S1-13:微观材料实验室,这边的流量越来越大了,到底……

M3-2:我在重启设备,应该马上就好……可恶的触手,这一点都不色!滚开!

【砸东西的声音】

【尖叫声】

【娇喘声】

【警报声】

S1-11:可恶,看来是那边出事了!(按下警报按钮)紧急情况!四层!疏散无关人员!!!

S1-13:我去疏散其他楼层!

根据事后的录像回调,M3-2 试图重启系统,但由于触手的干扰未能如愿。在拒止了四层的所有研究人员之后,触手顺着楼梯井往两个方向攀爬,最终包裹了大楼全域以及部分外侧地面。所幸警报发送及时,附近的平民及时逃离了这里。然而,由于楼梯井被大量触手占据,除了 1、2 层的约一半人员以外,所有人都被卷进了触手结构失控的事件之中。

3 事故原因分析

“为什么实验设备会把所有人都识别成拒止对象?为什么实验设备能扩散到远超材料上限的程度?”这个问题的答案,看似简单,实则是一连串的意外造成的复杂结果。

3.1 实验器材 1D-599-1

3.1.1 组成

本质上讲,1D-599-1 由五种可以互相转化的微观材料组成,它们分别是仿自人体组织的的肌肉、结缔、骨骼、神经材料,以及一种特殊的节能材料。五种材料可以在手动或自动的情况下相互转化。

在收到服务器的指令之后,节能材料开始变成神经材料,并试着往计算机指定的方向生长。所谓的生长,是指从储存的材料种获取资源,并一个个基本单元往外推的操作;由于神经材料有一定持久性,可以在一定程度内维持不断裂。神经材料会像周围的材料辐射一种短距离电磁信号,五种材料都会吸收信号。如果接收到信号本身,代表它处于最外层,这时候它会变成结缔材料,形成类似皮肤的结构;如果一个区域结缔材料太多,部分材料会自发地变成神经材料。

神经材料还负责传输服务器的命令,如果它发现命令没有传达,便会要求附近的一部分结缔材料变为肌肉材料。肌肉材料可以在一定限度内单独支撑结构,但如果过于疲劳则会把自己的一部分切下去变成骨骼材料。骨骼材料在过于轻松的时候,也会削减自身的强度,变回结缔材料。在下达关机或紧急停机命令后,神经材料会发送一种特殊的信号,所有材料在收到这种信号之后,都会试图反向生长,从而流回存储设备中。

通过这四种基本材料的操作,触手可以生长到一种令人难以置信的尺寸。虽然项目组预估其最大只能支撑一个半径约 24m 的球体结构,但此次事故显然大大超出了她们的预期。

3.1.2 操作模式

如前所述,1D-599-1 设备执行命令的行为很像流行文化中的“触手”。这并不是开发人员的恶趣味,而是算法自行学习得到的功能。1D-599-4 会首先尝试将命令编译成一个衡量达成命令程度的函数,此函数越接近 0,说明越接近目的;开发人员希望其在下达(一个集合内的)任何命令的情况下都能尽可能地接近目的,在数次学习之后,1D-599-4 自发地学到了类似“触手”的模式。根据项目组的分析与研究,触手确实是一种很方便的工具,不仅几乎能够对任何静物施加任何种类、任何方向的力,还能够充当众多接口(比如注射器、USB 接口、类似枪械的发射器等)的管线。

在经过数年的调试之后,自律微观材料实验室将当初论文中提出的设想变成了现实,而且即使发生了如此惨烈的事故,呈现的效果也可以说大大超出预期。

服务器会分析触手的基本组分发射并反射的,以及环境中固有的机械、电磁波,来为环境进行初级建模,之后运行特定的功能,比如身份识别。这些信息在事实上成为了触手的感官输入。

3.2 第三开发部的实验环境

第三开发部的历史可以追溯到可穿戴国际立业之初,并以创新性与鲁棒性兼具的技术,为公司打下了最初的基础;1D-599 项目使用的Ɔ##语言也有至少 40% 是她们的功劳。然而,在可穿戴国际的网络上线后,伊顿尼亚合众国的一家名为深思科技有限公司(Deliberation Technology Co. Ltd.,本报告简称深思科技)的公司突然出现,开始以压倒可穿戴国际的创新性,逐步蚕食着其在海外的市场。2148 年,公司高层忍无可忍,要求众多开发人员提出一个针对深思科技的解决方案。由于当时公司的网络已经上线,其生产的贞操带也在员工中有了一定的普及,面对可能发生的未知的惩罚性调教,大多数开发人员只能硬着头皮提出方案,但仍不理想。后来,管理层察觉到了这种压力,便执行了一些排除性的措施,结果也不理想。

2149 年初,第三开发部的负责人同样忍无可忍,她借着一次去伊国出差的机会,潜入了深思科技位于伊顿尼亚大陆西海岸新汉萨州的一间研究中心,发现了深思科技的秘密。对于现在的开发部人员来说,这其实算不得什么惊天的发现,但在那时,公司内部的开发环境很少有像样的 UI——大家都在用命令行操作。最近的一些研究表明,这其实会大大降低研究人员的工作热情和性奋度。但当时的负责人已经发现了这一点,她入侵了对方公司的系统,获得了一个账号,发现她们有一套十分精巧的 UI 和开发环境管理系统。有了这种系统,深思科技的可移植性、开发效率、项目自由度都是碾压级别的。

然而,由于时间不足,她没办法摸清更具体的架构,因此只能将一份环境打包发回公司内部的团队存储空间,并给同事留了言,这也是她最后一次与公司联系。再听到她的消息的时候已经是几个月之后了,深思科技因为窃取商业机密,准备起诉可穿戴国际;当时的可穿戴国际在伊顿尼亚市场立足未稳,因此选择了息事宁人,代价便是负责人变成对方开发部负责人,也是她的大学同学,的私人财产。

由于深思科技不知道她发了一份环境回来,第三开发部的人员一直在秘密进行逆向工程,在 2149 年秋天摸清了深思科技开发环境的构造。

环境采用了一种在现在极为常见甚至落伍,但在当时算得上是创新的引擎-界面分离模式。界面采用了一种类似 Clay Flicker 的语言,通过其中被大幅修改的 getUrl()loadVariables() 两个系统级函数与引擎通信;引擎没有特别的要求,只要能对这两个函数进行响应即可。

说到这里,不得不言及 Clay Flicker 技术以及 ASTA-106 标准规定的 ASTAScript 语言。

距今约 30 年前,色情行业由于“全人类美少女化计划”的实施成功,正处于如日中天的态势,并试图进一步发展。当时,人们已经很深地了解到刺激并不是时间越长越好,而是需要根据一定的模式施加,因此不同色情产品的制造商纷纷推出了自己的模式化刺激标准,但却遇到了不小的问题。不同产品的刺激模式不能互通,人们对不同模式、位点和产品的接受程度也因人而异,于是诸如喜欢一个设备,但不喜欢它的模式,或者喜欢一种模式,但无法将其应用于适合自己的设备的情况,便经常出现。

这时,一家名为 WebScene 的公司站了出来,她们预见到设备需要变得更加动态且高度可自定义,于是开发了一种面向普通人员的,比较易于学习的胶水编程语言,使模式得以从这种语言保存下来,并在不同的设备上转移。她们将这种语言命名为 EvilScript,并在随后的一段时间内在同类产品的角逐中杀出一条道路。2131 年,也就是可穿戴国际刚成立的那一年,搭载 EvilScript 的产品已经占据了几乎全球的市场,WebScene 便想将这种语言标准化,便交给了前身为亚洲性科技协会(Asia Sex Technology Association)的 ASTA International 审议。不久后,ASTA 发布了 106 号标准,规定了标准化的 EvilScript:ASTAScript。

后来,为了搭上 Jaʌa 的顺风车,EvilScript 被更名为了 JaʌaScript,但这又是另一个故事了。

在 EvilScript 出现之后,一家名为枕头媒体(Makura Baitai K. K.)的公司,本着使玩具更好操纵的观点,发布了现在被称为 Shocking Tide Flicker(STF)的文件格式,它的作用主要用于自定义可互动的界面,这样对于不会写代码的人来说,操作玩具的难度也降低了不少。该文件格式引入了内置一种 ASTAScript 实现的 KoiScript 。在 STF 被导入部分色情设备,并由于 KoiScript 语言特性使得 JaʌaScript 的开发者很容易上手,收获了一定程度的好评之后,Clay 公司看中了枕头媒体的潜力,并收购了它,这种技术也被正式命名为 Clay Flicker。

Clay Flicker 和 ASTAScript 共同为色情行业带来了一个春天。有了它们的存在,产品的使用者可以完全自定义界面与刺激模式,这大大地增加了产品的易用性。

虽然由于安全性问题,Flicker 技术于 2155 年被宣布放弃,但 ASTAScript 却一直在活跃。即便如此,事故的第一块拼图在此时已经制作完成:ASTAScript 对多线程的暧昧态度,导致各种语言在这方面表现得并不一致。

在 ASTA-106 标准中,除了万物均对象这一理念之外,还有两个重要的概念:作用域(Scope)和执行上下文(Execution Context)。其中作用域规定的是一个变量可以被访问的区域,而执行上下文则规定了一段代码被执行的时候,代码可以访问的变量,以及代码执行完毕后的操作。在一个作用域中定义的函数会拥有自己的新的作用域,因此作用域是树状的,但执行上下文,根据实现不同,可以是栈状、树状甚至图状的。其主要的两种实现,KoiScript 和 JaʌaScript,均采用栈来决定活动的执行上下文,也就是说,在顶层的执行上下文没有执行完成之前,下层的上下文不会被执行。

如果事情只是这样的,那其实不足以酿成灾难,但 ASTAScript 还有两个关键字:simwaitforsimsimutaneous 的缩写,意为“同时发生的”;waitfor 则直接取英文原意,意为“等待”。标记为 sim 的函数,在不同语言中实现不同。在 JaʌaScript 中,它返回一个 Appointment 对象,该对象记录了函数是否执行完成之类的信息;waitfor 本质上是一个操作符(operator),它能够自动对这种信息进行解包;但即便如此,由于 JaʌaScript 本质上是个单线程的语言,它使用了一个队列实现了这两个关键字,而并没有为相关的函数创建什么线程。考虑以下代码:

function takeLongTime() {
    return new Appointment(res => {
        setTimeout(() => res("long_time_value"), 114514);
    });
}

var i = 0;
sim function a(g) {
    waitfor takeLongTime();
    for (var j = 0; j < 3; ++j)
        print(i++, g);
}

a(1); 
a(2); 
a(3); 
a(4); 
a(5);

对于一个多线程语言,执行相同的代码,过了 114.514 秒后,得到的是五个“a”的乱序输出,但在 JaʌaScript 中,输出结果如下:

0 1
1 1
2 1
3 2
4 2
5 2
6 3
7 3
8 3
9 4
10 4
11 4
12 5
13 5
14 5

这是由于系统仅仅为包含了 takeLongTime() 这个模拟耗时极长的操作的函数的 a() 函数创建了一个执行上下文,并放到了一个队列中,阻止其对主上下文的阻塞;在主上下文执行完毕后,队列一共积攒了五个上下文。此时,系统会分别开始执行这五个上下文的 takeLongTime() 函数,并在执行 setTimeout() 函数的时候接着执行队列中的其它上下文。在五个上下文都等待 114.514 秒后,依次完成五个函数的控制台打印。可以发现,在同一时刻,仍然只有一个执行上下文被激活,这就是单线程的 ASTAScript 实现的特点。

此外,由于 ASTA-106 当时的版本还没有这两个关键字,所以原生的 KoiScript 是不支持的;KoiScript 则在另一些特性上面与 JaʌaScript 相异:它并不是一个纯粹的解释型语言。这要从其名称中的 Koi 一词说起。

最初在枕头媒体开发 Flicker 文件格式的时候,程序媛们设想了一种用于指示界面行为,并在特定时刻执行的指令格式,并取行为二字的罗马音“Koi”为其命名。之后,随着指令集越来越复杂,她们又为 Koi 设计了一种高级语言和一个编译器,这就是 KoiScript。考虑如下代码:

function a(g) {
    for (var i = 0; i < 3; ++i)
        print(i++, g);
}

它可能会被编译成:

DefineFunction2(FunctionName="a", NumParams="1", RegisterCount=2, Flags=0x00000000, Parameters=(2, "g"), CodeSize=(下面所有代码的长度))
PushByte(0)
StoreRegister(1)
Pop()
label1:
PushByte(3)
PushRegister(1)
Less2()
LogicalNot()
If(label2)
PushRegister(2)
PushRegister(1)
Increment()
SetRegister(1)
PushByte(2)
PushString("print")
CallFunction()
Goto(label1)
label2:
Return()

直到目前为止,都十分正常;有人可能还会感叹,KoiScript 比 JaʌaScript 更像 Jaʌa,JaʌaScript 只是在蹭热度。

然而,深思科技公司在从 Clay 购买了 Flicker 的部分使用权后,使用了一种修改版本的 STF 格式,她们的程序媛们在 Koi 其中加入了几种额外的指令,与此次灾难直接相关的是 DT_CallFunctionPopDT_CallMethodPop。这两个指令的共通之处在于最后那个 Pop。原始的 CallFunctionCallMethod 指令在函数返回之后,会将它的返回值推入上一层执行上下文的栈中,如果没有返回值,就推入一个 undefined;但这两个新加入的指令不会这么做。无论函数返回什么,它们都会直接无视返回值,接着往下执行。

不仅如此,她们还完全修改了 getUrl()loadVariables() 这两个函数的作用。本来它们是用来访问网络的,但在生产环境中,不需要访问网络,两者就分别变成了给引擎发指令,和从引擎中取得数据的函数。

发送指令 CommandName,并指定参数 Arg1Val1Arg2Val2,可以这么写:

getUrl("EngineCommand:CallFunction", "%CommandName?Arg1=Val1&Arg2=Val2")

获取变量 VariableName 并在控制台打印可以这么写:

var new_Obj = new Object()
loadVariables("QueryProductionEngine?VariableName", new_Obj)
print(new_Obj.VariableName)

深思科技靠着修改版本的 Flicker 编写的界面,确实大大提升了生产力,但可穿戴国际在获取情报之后,就一直在秘密逆向这个界面,并逐渐投入使用。在 2157 年 11 月,由于深思科技经营不力,可穿戴国际收购了深思科技。当初那位负责人虽然获得了自由,但她已经彻底接受并爱上了她的人种牲畜的身份,所以拒绝恢复人格权。

在收购之后,可穿戴国际就可以光明正大地使用这个生产环境了。但这么多年来,很多事情变化了,包括 Flicker 因为安全性和耗电等问题被 Cyan 放弃,并逐渐退出了主流市场的舞台这件事。但第三开发部的人们对深思科技的这个开发环境表示高度赞许,于是她们大胆地决定重制 Flicker 和 STF 格式——剔除无谓要素,修复问题,增加现代要素。她们将一种新的基于 ASTAScript 最新标准的语言命名为 WearScript。

程序媛们决定替换 Flicker 老旧的 DOM,重新设计一套 DOM,这也导致指令集中多了 19 个指令位,但这还不够——想要实现多线程和新的对象抽象,至少需要 24 个指令位;又由于原来的指令集已经几乎没有空隙,直接寻找 5 个空隙显然是不明智的,她们就打算重新设计,然后重新编译所有的 KoiScript 代码。

然而她们发现这不可行。部分已经被编译成 STF 文件的汇编代码所对应的源代码已经丢失,重新编写工作量又太大,她们便找来这些丢失的代码,并统计一下使用得比较少和根本没用过的指令,看看能不能去掉这些指令来重新设计。结果她们又排除了 5 个无关紧要的指令,其中便包括 DT_CallMethodPopDT_CallFunctionPop

然而,事实上 DT_CallMethodPopDT_CallFunctionPop 并非没有出现过,只不过由于统计程序的 BUG 被意外地排除了。后来,她们重新规划了指令对应的二位十六进制数。在转写的过程中,转写程序发现了这两个指令所对应的十六进制数,只不过由于它并没有被写入与这两个指令相关的映射,按照规则,它会进行字符串比对,并找到合适的指令,这就使它们被翻译成了 CallMethodCallFunction。这便是灾难的第一块拼图的诱因。

事实上,仅仅是如此也没有关系。KoiScript 的编译器做过一些优化,使得对与一个执行上下文而言,它的栈在执行完一条非控制语句之后应该是平衡的,因此新的语句总是假设上一条语句执行完后栈深度为 0。很幸运,在绝大多数情况下,这两条被修改的指令,在重构的虚拟机中没有出问题,但 for-in 语句是个例外。原生 KoiScript 使用 EnumerateEnumerate2 指令来编译 for-in 语句,这两者都会从栈上读取,或者根据自身的参数获取一个 object 类型变量,先将一个 null 入栈,之后将这个变量的所有可枚举字段的名称逐一入栈。

这样的话,在 for-in 语句块内的栈不平衡就是大问题了。有多余的 pop 操作,会使得对象不能被完全遍历;有多余的 push 操作带来的效应更可怕——这个循环将永远无法跳出。很不巧,那些丢失源代码的代码中唯一一个 for-in 语句,正是藏在指定生产设备生产何种微观材料,生产多少数量的代码中,根据事故调查组的还原,应该是这么写的(无法保证命名一致):

// ......
var cache = new Object();
for (var k in missingMaterials) {
    getUrl(`EngineCommand:CallFunction", "%ProduceMicroMats?Type={k}&Amount={missingMaterials[k]}`);
    loadVariables("QueryProductionEngine?LastOperationSucceeded", cache);
    if (!cache.LastOperationSucceeded) {
        reportIssue(k);
        break;
    }
    else {
        reportPassed(k);
    }
}
// ......

getUrl()loadVariables() 函数由于直接被编译成了 GetUrlGetUrl2 指令,不会留下多余的值,但后面两个函数,在原来的编译器中被编译成了 DT_CallFunctionPop 指令,这导致除了一次正确的发送以外,函数一直在向生产设备发送“生产名为 undefined 的材料 undefined 个。”其中,前一个 undefined 被引擎解析成了0,也就是节能材料的枚举值,后一个 undefined 则被解析成了最小需求量。而函数只有在生产设备没有材料可用的时候才会返回,在此次事故中,这给了触手结构充足的材料去覆盖整幢建筑。

但仅仅如此,还只是材料被多生产了很多而已,顶多是浪费资源的问题。这就要引入重构虚拟机的过程中的第二项修改了。

前文提到,当时的 KoiScript 没有 waitforsim 关键字,且 JaʌaScript 的这两个关键字也没有多线程的含义。可是,这次负责重构虚拟机的程序媛们,却决定给多线程加入语法层面的支持,为此还参考 Ɔ##,加入了 vodka 关键字,并加入了 atomiclock 关键字以支持原子操作和互斥锁。

这项操作不仅没有任何问题,反而应该大力赞扬,只是生产环境需要缓慢过渡而已。

3.3 1D-599 项目自身的问题

与安防系统联合调试的 1D-599 项目组有幸成为了第一个用上新的编译器和虚拟机的项目组。她们在仔细检查之前的前端代码的互斥锁问题,将安防系统接入原有的引擎之后,由于认为并不是什么重要的问题,将前端的任务交给了一个实习生。

这个实习生是做 JaʌaScript 开发出身的,虽然在开始工作前被强调了注意多线程的区别,但并没有真正理解两者的区别。于是她脑中想到,并实现了如下代码:

class BackendCoordinator extends CoordinatorBase {
    ......
    stupid _oprReturnCache = new Object();

    stupid sim queryOperationPermission(opr, id) {
        getUrl(`EngineCommand:CallFunction", "%SelectObject?Id={id}`)
        switch (opr) {
            ......
            case OprCodes.OPR_FORCE_REJECT:
                waitfor loadVariables("QueryDatabase?IsRejectionTarget", _oprReturnCache);
			    return _oprReturnCache.IsRejectionTarget;
            ......
        }
    }
    ......
    stupid getAllObservableHomoSapines() {
        ......
    }
    stupid orderTentaclesToAct() {
        var hss = BackendCoordinator.getAllObservableHomoSapines();
        var dhss = {};
        var tasks = [];
        for (var hs in hss) {
            var task = BackendCoordinator.queryOpeationPermission(OprCodes.OPR_FORCE_REJECT, hs.id);
            task.then(exec => {
                    dhss[hs.id] = exec;
                });
        }
        waitfor Appointment.whenAll(tasks);
        for (var hsid in dhss) {
            if (dhss[hsid]) {
                getUrl(`EngineCommand:CallFunction", "%FroceReject?Id={id}&IgnoreSelfRecognition=false`);
            }
        }
    }
    ......
}

上述代码的 BackendCoordinator.orderTentaclesToAct() 方法会以一个 2000 毫秒的间隔被反复调用。

该代码在多线程语言中,显然会遇到线程不安全的问题,但是在单线程语言中是可以按照预期运行的。然而,WearScript 并不是一个线程安全的语言,这段代码除了可能会给引擎传入错误的实体 ID ,即使 ID 正确,还可能会将是否需要拒止的值返回给她人。此外,由于只有在 BackendCoordinator.queryOperationPermission() 返回 true 的时候,这段代码才联系引擎,因此如果之后发现被错误识别了,是没有任何手段在前端阻止对象被拒止的。

然而,由于 WearScript 是大多数第三开发部员工接触到的第一门基于 ASTAScript 的多线程语言,代码审核者也没有意识到这段代码有问题,于是这段代码被投入实验了。这便是事故的第二块拼图。

其实到了这一步,依然是可以挽回的,触手结构有自身的感知,对于黑名单内的人员不会有任何操作,而且这个实习生将 ForceReject 函数的 IgnoreSelfRecognition 参数设为了 false,这表示让其优先自身的鉴别。那么,为什么项目组内的人也会被触手缠绕呢?

这要从触手识别人员的原理说起。为了进行身份识别,其做法是接受自身发射而反射回来的微小机械、电磁波,从而重建环境内的 3D 特征,这么做最多能知道有个人在某个地方,而不能知道那个人是谁;为了高精度地重建一张人脸,需要在距离她的面部 5m 以内存在一定数量的触手结构。

此外,即使在接入安防系统以后,控制触手的服务器仍然会先判断是否有人存在,再根据安防系统的位置-身份 API,判断那个人是谁,这需要触手结构的人种感知。一般情况下,其只能感知到 Kimura-3;偶尔打开门的情况下,其才能感知到实验空间外侧的成员。

前述的优先自身鉴别的机制很好地帮助了触手结构及其控制器避开项目组的成员。然而,在事发当天,有一名不属于自律微观材料实验室的成员碰巧通过东区的实验空间走廊,触手发现了她,在调取有问题的 API 后,错误地将她识别成了需要拒止的人种生物,便尝试前往她的位置。此时一只脚已经迈出实验空间的木村武志研究员,因为在黑名单内的缘故,被算法理解成静物,因此其趁着她愣住的这段时间,以她为桥梁越过了特殊材料的限制,试图拒止那名路过的工作人员,在这期间,项目组的成员均不同程度地被触手覆盖。

与此同时,项目组在开发触手的感知功能的时候,没有考虑距离过近的情况,这导致了一旦一个人的一定面积被覆盖,系统将失去内建的对此人的身份识别。这便是项目组的所有人都被当成紧急拒止对象的原因,也是事故的第三块碎片。

直到这里,其实还有两道防线。第一是紧急安全措施,第二是当地供电部门下达的断电指令。

1D-599 项目的紧急措施,在当时全部失效。项目组的所有人以及 Kimura-3 都有权限强制终止 1D-599-4 服务器的运行,但在全员都已经被限制活动的情况下,无人能够强制终止;自动的紧急措施也是针对不会从实验空间泄露的,一般认知中的“机械”设计的,没有考虑过 1D-599 项目这种大规模泄露的情况,至此,紧急措施已经失效。

至于为什么在断电后触手仍能活动的问题,尚不能给出结论,需要进一步调查。

4 事后处理及整改措施

4.1 事发后的救援尝试

紧急拒止操作的目的,在于快速使目标失去行动能力,由于面向的是强制拆毁设备的不法人士,其设计很简单:

  1. 静脉注射高烈度春药;
  2. 对所有可刺激的性感带进行最高强度的刺激。

对于贞操带类的产品来说,这两点都很好理解,但考虑到触手类设备必须从体外侵入,项目组在编写相关流程的时候,加入了破坏阻挡第二项执行的障碍的操作,因此所有被卷入此次时间的人员全身的衣服都被撕得粉碎;其佩戴的贞操带设备,也被触手通过运送并使用消防设备的手段破坏(调查组注:贞操带的佩戴在当地没有被写入法律,因此这不违反章程)。根据部分毁坏设备的记录,我们发现其自身已经启动紧急拒止程序。

对于不幸卷入此次时间的人的影响,调查组认为亲历者最有体会。第三开发部的所有员工与资产,都在触手的暴走下,以全身所有穴道都被肆意侵犯的状态,被触手强制高潮了五天五夜。白鹭站附近的居民,除了少数主动接触触手结构的特殊性癖者,均在军队的保护下撤离了这片区域,这阻止了触手的进一步蔓延。

8 月 15 日下午,当地市政府经研究决定,切断白鹭站附近的供电系统,同时就近安置居民——本州管区面临大型地震设计的避难措施,竟在此时派上了用场。在断电后,人们惊讶地发现触手仍在活动,公安部门便决定封锁这片区域。考虑到不知卷入事件的人生死为何,无法启用大规模破坏性武器,因此军方只得和可穿戴国际的其他下辖组织联络,研讨解决方案。

在得出方案之前,1D-599 项目超过 120 小时无操作自动停机的机制出发,包裹整幢建筑的触手开始逐渐缩回建筑内部,直到完全变回节能材料。此后,恢复神智的项目组成员立刻启动了强制终止程序,市政府经研判决定恢复当地供电。

4.2 损失统计

4.2.1 对当地居民造成的损失

共 26 名当地居民卷入了此次灾难性的事故中,这些人均出现了不同程度的社会失能现象,现已有 25 人出院,1 人因申请放弃人格权而未通过自愿性审核,出现精神问题,现已转至其他科室接受治疗。

此外,由于居民疏散及时,几乎未有任何因断电造成的经济损失。有 3 户人家的宠物因无人照顾而生病,现均无大碍,正在附近接受治疗。

4.2.2 对可穿戴国际第三开发部造成的损失

此次事故之后,1D-599 项目组整理了实验数据,归还了 1D-599-4,回收了全部的实验材料,在事实上消除了 1D-599-1 的存在。木村研究员认为,只有在安全措施完备的情况下才能再次展开实验。

虽然出现了如此意料之外的情况,但其他项目的紧急措施做得尚可,且因为不明原因,大楼没有断电,所以没有出现连带事故。因为缆线管理得当,大楼内部电子设备故障率约为 10%,且未造成任何重大或不可挽回的损失,或者文件损失。

从灾难中恢复过来的大多数人因为烈性春药的缘故,且均是赤身裸体,仍然在试图从其她人身上获得快感,甚至因此出现了多处群交行为,直到医护人员到来才逐渐停止。检查结果表明,无人留下了不可逆的健康性损害,且所有员工的治疗均已结束。此后的一段时间内,公司内部关于志愿成为实验材料、放弃人格权和要求重新开展或尽快商用化 1D-599 项目的讨论激增,员工之间的恋爱频率也比往常提高了约 40%。

综上所述,可穿戴国际(新亚)有限公司认为,本次事故造成的损失可以忽略。

4.3 类似事故的预防措施及将来的研究方向

4.3.1 事故预防措施

第三开发部决定开启全面的代码检查,并暂缓新的实验环境的设置,直到代码检查完成。此外,WearScript 最新的标准中,多线程模式也被更改为了手动启用,以适配开发者的思维习惯。

对于材料生产设备,开发部决定加入配额制,设立报警额度和停机额度,从而在防止大型事故的考量外,同时防止材料浪费与错误生产。(调查组注:这次事故中生产的节能材料只是碰巧比较好回收,如果生产了这么多难以/不可回收的材料,后果不堪设想)

对于 1D-599 项目中的五天无人操作自动停机的紧急措施,第三开发部表示高度赞许,并将此项措施作为强制要求,时间也缩短至三天。

4.3.2 展望

前文已经多次提到,在事故中,第三开发部的大楼连续五天没有断电,随后调查发现这是由于触手结构通过某种方式从人体内部和向阳处获取能源,并输送至大楼的供电总线的缘故。目前,对电能的来源已经有了一些猜想。项目组将以此方向作为主要的攻关方向。一旦完成,不仅可以节省贞操带的电力,还可以发展新的能源开发方向。

此外,触手结构在此次事故中表现出了惊人的韧性、延展性和泛用性,这说明触手材料的应用不仅在色情产业。公司内部有很多人提出了关于触手应用的设想,比如完全由触手构成的城市、紧急情况下的发电设备,乃至星际殖民的基础设施等。公司决定,在不久后启动研究数据和方法公开的工作。