项目启动那天,一切看起来都井然有序。
他说他负责前端,后端我们俩一起写。我后端经验多一些,自然多担待后端的主干工作。主动划分了项目的功能模块之后,我说了我正在做的模块,让他自己选择可以开发的独立模块,我们共用同一个后端代码仓库,各自推进,偶尔同步,像两条并行的铁轨,朝着同一个方向延伸。
第一个月还算平静。代码在长,功能在添,周报写起来也充实。然后他忽然发来消息,说换了后端项目的代码仓库地址,让我重新推送。我没多想——重构、迁移,都是项目里常有的事——便照做了。推送完之后,我等着他在新仓库里继续提交代码,但一连几天,静悄悄的。他的那个文件夹里,什么也没有。
我没吭声,继续在老仓库里写我的逻辑。
第二个月,同样的事情又来了一遍。他又换了一个地址,我又推了一次。这一次他总算有所动作——在项目里加了一个AI框架的readme.md文件。几百字,像个占位的旗帜插在一片空地上。
我盯着那个readme看了一会儿,心里隐约浮起一点说不清的异样。但很快就被手头的任务压下去了。
第三个月,他第三次更新了git仓库地址。
这一次我没有再跟着推。我选择留在老仓库里,继续写代码、改bug、搭环境。那条轨道虽然旧了些,但我知道它通向哪里。三个月来我所有的提交记录、所有的逻辑设计、所有的调试痕迹,都安安静静地躺在那里。我没有理由抛弃它们。
直到后端部署测试成功的那一天,他终于坦白了。
他说他搞了一个新的后端,自己从头搭了一套。他说两个功能版本会对比着看,但他的那套还不完善,功能也不全。
我坐在屏幕前,把这几句话读了两遍。
三个月。他换了三次仓库地址,每一次都让我把代码推过去,每一次他自己都没有实质性的贡献。他让我做这些动作的时候,自己的新后端已经在暗中搭建了。而我像一个人来回搬运砖石的人,每一次都被指引到一片新地基前,放下砖,抬头一看——工地上仍然只有我一个人。
然后他丢下一句“两个版本对比着看”,像是一个技术决策,轻描淡写。
老仓库里那三个月的心血,在他口中变成了“付出了心血的老代码确实有些可惜”。但可惜完了,也就完了。
周一的时候,他又发来了几条消息。
“我想了一下,觉得在我新的代码上继续应该是工作量最小的,你依然作为控制层的负责人,就是实际当中,对于bug和新功能让AI从头到尾直接改,这样效率最高。付出了心血的老代码确实有些可惜,不过我现在的代码除了文档之外也都是新的,之前的也都放弃了。目前还缺不少功能,还有很多bug,一起完善吧。你觉得如何?”
“代码可以各自拉一套,各自修改,及时push,及时同步,有冲突及早merge,应该会一切顺利的。”
“周报继续按照你的节奏写,不用提具体变化。”
我读完这几条,慢慢理清了他话里的结构。
“工作量最小”——是对我说的,意思是让我接受这个方案,不要抗拒。“控制层的负责人”——头衔还在,听起来我仍然是核心角色。“AI从头到尾直接改”——把技术手段摆出来,显得理性、高效。“之前的也都放弃了”——轻描淡写地把三个月归零。“周报不用提具体变化”——这一条最耐人寻味。
我试着理解他的逻辑:我的老代码要被放弃了,我要转到他的新代码上继续工作,但这件事不能写进周报。那么周报里写什么?写“修复了一个bug”?写“新增了一个功能”?这些功能和bug是在谁的代码上?是在他的新项目上。他的项目,他的代码,他的仓库。我像一个进入别人工地帮忙的工人,每天干完活,却不能提自己换了工地。
我回复他:“我明白你的意思,但我更新你的代码却不体现在周报里,那我周报写什么呢?毕竟老代码是要逐步废弃的,更新会越来越好,周报主要会以你的项目需求为主。”
这段话我写得很慢。每一个字都在克制。我不是在质问他,我是在陈述一个基本事实——如果你的代码替代了我的代码,而我不能写我在做你的代码,那我周报里到底有什么?
他又回复了:“写哪个功能OK了,写在改哪个方面的bug就可以了。”
这句话让我彻底看清了他的逻辑框架。在他的认知里,周报只是一份“做了什么动作”的清单,不涉及“在谁的代码上做”“基于什么基础做”“替代了什么做”。只要动作描述存在,周报就是合格的。至于这些动作的上下文、归属、历史——不重要。
这不是疏忽,这是刻意的模糊化。
他接着说:“我理解,我也想了很久分工问题,就是现在的vibe coding,其实AI擅长从头到尾一起解决,强制划分层次,反而增加很多工作量。最好就是按最终功能划分,但是这方面我还说不清楚还有多少功能要做。”
“我觉得merge难题对于AI来说反倒是小问题。”
这两句话让我看到了一种非常典型的当代技术人格:把一切问题都交给工具去弥合。分工不清?AI会处理冲突。历史代码被废弃?AI会生成新的。责任边界模糊?AI会“从头到尾一起解决”。工具成了万能的缝合剂,用来缝合他自己不愿面对的架构决策和协作伦理。
我最后回了一句:“那就一起梳理下,正好沟通一下进度。”
他说:“好的??”
一个表情符号,结束了这场对话。
事情说完了。但真正让我坐在这里、一字一句写下这些的,不是那三个月的代码迁移,不是仓库地址的反复更换,甚至不是他另起炉灶的决定。
是那句话——“周报不用提具体变化”。
这句话像一把极薄的刀片,精准地切开了一个口子,让我看到了整件事的结构。他不是在搞技术架构,他是在搞信息架构。他控制代码仓库的地址,就控制了代码的归属;他控制周报的叙事,就控制了工作的呈现。当一个人的代码贡献可以被“不提具体变化”地抹去,当三个月的持续交付可以被“之前的也都放弃了”一句话归零,那么最终呈现在上级面前的,是谁的成果?谁的投入?
这是一个非常老练的操作。甚至不需要恶意,只需要一种习以为常的、对他人劳动的钝感。
我把这件事翻来覆去地想了好久。
他为什么要换三次仓库地址?第一次,可能确实是技术调整。第二次,他的新后端大概已经开始搭建了,他需要我的代码推过去,不是为了合并,而是为了“存在”——让那个新仓库看起来有内容,有历史,有人维护。第三次,他已经不需要我的代码了,但他仍然让我推,因为这样他的新仓库会持续有提交记录,而我老仓库里的三个月,会自然地被时间掩埋。
每一次让我“重新推送”,都是一次对劳动归属的重新锚定。
而他最后给出的“控制层的负责人”这个头衔,不过是一张漂亮的包装纸。里面包着的,是一个已经被掏空了的实际权限和责任边界。
他今年四五十几岁了。在这个IT日新月异行业里,我见过太多人,经历过太多项目。年轻的时候,遇到这种事会愤怒,会觉得不公平,会想找人说清楚。现在不会了。现在我更多的是困惑,是一种沉甸甸的、说不出口的疲惫。
我理解不了的是——你把前人的树拔了也就拔了,你还要把年轻人自己种的树也拔了,然后张冠李戴,说这棵树是你从头养到大的。
到底职场上这种人的存在意义是什么?恶心别人,成全自己?
遇见恶人多了,有时候会恍惚,好像所有人都是脏的。这不是一种理性的判断,这是一种被反复摩擦之后产生的条件反射。更可悲的是,这种人还不是一般的多,多到大家都习以为常了。好像职场本来就是这样的——上面的没参与要冠名,下面参与的连个署名都没有。
我有时候会想,这种行为如果放在别的领域,算不算某种形式的侵占?但似乎没有人会这样类比。因为代码是“虚的”,劳动是“看不见的”,git提交记录里的名字,好像也不具备真正的证明力。
可悲。可叹。非我所及。
我甚至向上苍许了一个不切实际的愿望——职场上拒绝这种蛀虫。不是因为他们能力不行,而是因为他们影响风气,也影响人心。一个团队里如果有一个人靠这种方式获得认可,那么其他人只有两种选择:要么也变成那样,要么沉默地承担双倍的劳动。
善良在这种环境里,真的会变成一种奢侈品。
但光愤怒没有用。光写记叙文也没有用。我得把这件事拆开,看清楚每一个关节,然后找到应对的策略。不是为了报复,是为了以后不再被同样的手法困住。
下面是我复盘之后,对这类操作的拆解和对策。
一、识别“仓库迁移”类操作的实质
这类操作有一个非常明显的特征:频繁变更底层基础设施的归属,并要求你配合迁移,但对方自身没有实质贡献。