宪法
宪法
宪法的源文件在它的版目录 constitution/<YYYY-MM>/ 下,目前是 constitution/2026-10/:一个 index.toml,以及 articles/ 下每条一个目录。目录以版命名,草案获批准后也不改名;状态只记在 index.toml 里。工具把 constitution/ 下唯一一个含有 index.toml 的目录当作版目录,一个都没有或者不止一个时报错,所以工具里任何地方都不写这个目录名。
宪法由 uv run constitution-build 从这些源文件编译,它是 workspace 成员 tools/compiler (只用 Python 标准库)。它为 index.toml 里的每种语言向版目录的 generated/ 写两个文件:constitution.<lang>.md (完整版) 和 constitution.<lang>.agent.md (agent 版,见「agent 版」一节),两者都提交进仓库,从不手改;--check 不写任何文件,只运行检查,检查项见检查程序。
constitution/2026-10/
index.toml
articles/
05-boundary-rule/
article.toml
01-must-ask.toml
02-decide-yourself.toml
generated/
constitution.en.md constitution.en.agent.md
constitution.zh.md constitution.zh.agent.mdindex.toml:
status:在人第一次批准这份文本之前是draft,之后是active。edition:这一版的名字,即委托人批准它生效的年月,YYYY-MM;必填。草案写它准备成为的那一版的名字,也就是计划批准的月份;如果在别的月份批准,届时给这一版改名。一版是一份完整的文本,就像以通过年份命名的宪法。制定新的一版本身就是一次修正案,需要委托人批准,而且一个月内至多制定一版,所以不会有两版同名;同一版内编号永不改变 (见「编号」一节),新的一版可以随意重新编号。revision:一个字符串,即这一版内的修订号:草案是0.<n>,每份草案 (第一版的和以后各版的) 的<n>都从 1 起算;一版第一次获批准的文本是1,每采纳一次修正案就加一,新的一版重新从1起算。构建 manifest 会记下它。同一版内,宪法文字改了,修订号就增加;文字没改,修订号也不变 (检查程序,第 7 项检查)。languages:语言代码,第一个是默认语言。每种语言在构建脚本里都必须有一条渲染条目 (一张表LANGUAGES存放所有因语言而异的内容:文件头,标题、编号和引用的形式,废止说明)。增加一种语言,就是在那里加一条条目,并给每张文本表加一个键。[title]:标题,每种语言一行;构建在它后面加上版名 (见「编号」一节)。[front]:标题和第一条之间的 Markdown (草案说明、## Preamble及其正文),每种语言一份。其中可以有引用。
一条是一个目录 articles/<NN>-<id>/:条的编号 (两位数字,从 01 起)、一个连字符和条的 ID。目录里的 article.toml 存放 id (等于去掉编号的目录名)、[title]、可选的 [intro] (标题与第一款之间的那段文字),以及只在整条废止时才有的 repealed = "YYYY-MM"。
每一款是所在条目录里的一个文件 <NN>[a-z]-<id>.toml:款的编号 (两位数字,从 01 起,可以带一个小写字母)、一个连字符、款的 ID 和 .toml。款属于存放它的那个目录所代表的条,没有专门的字段记录这一点。文件里存放 id (等于去掉编号和 .toml 的文件名)、status (draft、active 或 repealed)、恰好在状态为 repealed 时才有的 repealed = "YYYY-MM"、可选的 audience = "maintainers" (唯一可取的值,用于讲宪法本身怎样制定、编排和修改的条文),以及 [content],即这一款每种语言的正文:第一行是款号之后的那句话,后面的行、嵌套列表和空行原样跟在后面,构建把它们缩进到列表项之下。
列了项的款,每一项在款的文件里有一张 [[items]] 表:id、number (1、2、2a,在款内编号)、status、repealed 和 audience (与款相同),以及 [items.content],即这一项每种语言的正文。这时款的 [content] 只放引导语;构建把各项按编号顺序渲染在它下面。
id = "must-ask"
status = "draft"
[content]
en = '''
**Must go through a principal** whose authority covers the item ({@explicit-yes}).
'''
zh = '''
**必须经过委托人**,即由权限覆盖该事项的委托人同意 ({@explicit-yes})。
'''
[[items]]
id = "capital"
number = "1"
status = "draft"
[items.content]
en = '''
Capital: allocating, spending, ...
'''
zh = '''
资本:资金和其他有价资源的配置……
'''条、款、项的顺序只由编号决定,没有另外的列表。index.toml 是 draft 时,每一款、每一项和每条规定都是 draft,没有任何内容被废止;一旦它变成 active,每一款和每一项就是 active 或 repealed。
编号
编号不是根据位置推算的。条的编号是它目录名的前缀,款的编号是它文件名的前缀,只写在那里,别处不写;项的编号是它的 number 字段。款或项的编号是一个整数,可以带一个小写字母后缀 (2、2a),后缀表示后来插在 2 和 3 之间的那一个;条只会追加在末尾,不带后缀。只有在宪法的文本第一次获批准之后,插入的条文才带后缀 (<NN>a-<id>.toml);宪法还是草案时,新条文按顺序取下一个编号,其后的条文依次重新编号。名字前缀就是把这个编号写成两位数字 (02、02a),这样文件按阅读顺序排列。排序先按整数,再按后缀:2 < 2a < 2b < 3。在同一个范围内 (全部条;一条的各款;一款的各项),编号唯一;草案的编号不必连续。
自宪法的文本第一次获批准起,同一版内的编号遵守 stable-numbers;检查 --check --base <git-ref> 对照同一版的一个基准提交来强制这一点 (见检查程序,第 7 项检查):把目录或文件改名为新的编号,或者把一款移到另一条的目录里,都是错误。废止的条文渲染为一行说明,代替它的正文 (见下表)。宪法还是草案时,或者开始新的一版时,编号可以改变,目录和文件随之改名,检查只说明它没有做比对。
渲染示例:must-ask 是第四条的第一款,capital 是这一款的第三项,authority 是这一条的 ID;表中把 <a id="must-ask"></a> 写作 ⟨must-ask⟩:
| 内容 | en | zh |
|---|---|---|
| 标题 | # Agent Constitution (2026-10 Edition),即 edition |
# Agent 宪法 (2026-10 版) |
| 条的标题 | ## ⟨authority⟩Article IV. <Title> |
## ⟨authority⟩第四条 <标题> |
| 款 | - ⟨must-ask⟩**§1** <content> |
- ⟨must-ask⟩**第一款** <content> |
| 项 | - ⟨must-ask.capital⟩(**3**) <content> |
- ⟨must-ask.capital⟩(**三**) <content> |
| 引用条 | [Art. IV][authority] |
[第四条][authority] |
| 引用款 | [Art. IV §1][must-ask] |
[第四条第一款][must-ask] |
| 引用项 | [Art. IV §1(3)][must-ask.capital] |
[第四条第一款第三项][must-ask.capital] |
| 后缀 | §1a、(3a)、Art. IV §1(3a) |
第一款之一、(三之一)、第四条第一款第三项之一 (a 是 之一,b 是 之二) |
| 废止的款 | - ⟨…⟩**§3** (repealed November 2026) |
- ⟨…⟩**第三款** (2026 年 11 月废止) |
| 废止的项 | - ⟨…⟩(**3**) (repealed November 2026) |
- ⟨…⟩(**三**) (2026 年 11 月废止) |
| 废止的条 | ## ⟨…⟩Article IV (repealed November 2026),下面没有内容 |
## ⟨…⟩第四条 (2026 年 11 月废止) |
| 相邻项的引用 | Art. IV §1(2) or (4)、Art. IV §1(1) to (7)、Art. IV §1(1), (2) and (4) |
第四条第一款第二项或第四项、第四条第一款第一项至第七项、第四条第一款第一项、第二项和第四项 |
| 相邻款的引用 | Art. IV §1 and §2、Art. IV §1 to §3、Art. IV §1, §2 and §4 |
第四条第一款和第二款、第四条第一款至第三款、第四条第一款、第二款和第四款 |
列表标记补足到四个字符宽,一款或一项后面的行 (包括嵌套列表和段落) 都缩进到它正文所在的列:款缩进四个空格,项缩进八个。正文里有空行的款或项,后面跟一个空行。Python-Markdown 只把缩进四个空格的内容当作嵌套,还会把列表行并进紧挨在它上面的段落;按这种排法,只要源文字自己的嵌套块缩进四个空格、段落之后的列表行前面有空行,输出在 Python-Markdown 和 CommonMark (GitHub) 里就渲染得一样。违反其中任何一条的源文字,在 Python-Markdown 里仍会渲染错;宪法目前没有这样的文字。
当一个项的引用前面恰好只有一个连接词,再往前是同一款中另一项的引用时,它渲染成简短形式,只写项的编号 ((4)、(2a);第四项、第二项之一)。款的引用同理:前面是一个连接词,再往前是同一条中另一款的引用时,渲染成只写款的编号 (§2、§1a;第二款、第一款之一)。英文的连接词是 or、and、, 和 to,中文是 或、和、、 和 至;范围在源文件里写成首尾两个引用之间加 to 或 至。别的款中的项、别的条中的款、紧跟在上一级或下一级引用之后的引用 (条和它的款,款和它的项),以及前面有其他任何文字的引用,都保留完整路径。源文件里始终写完整路径。
每一条、每一款、每一项都以一个用 ID 而不是编号命名的锚点开头:<a id="<article-id>">、<a id="<section-id>"> 和 <a id="<section-id>.<item-id>"> (ID)。锚点在每种语言里都相同,重新编号后也不变;条和款的 ID 在整部宪法内唯一,所以不会冲突。引用是指向其条文锚点的链接,简短形式也一样:[Art. IV §1][must-ask] and [§2][…],每个编号各自是一个链接。这些链接是引用式链接,每个被引用的条文在文件末尾有一行定义 [<ref>]: #<ref>,按第一次引用的顺序排列:因为 limae 会把内联链接 […](#…) 的 ) 后面紧跟中文字符的情况,当作一个需要空格的括号 (limae 0.13.3,2026-10 查阅)。款的编号加粗;项的编号在括号内加粗,因为 limae 要求在 ** 和括号之间加空格。
每份输出都以一段纯文本开头,用它自己的语言写:这是生成文件,不要编辑,改源文件;然后是 revision,status 为 draft 时后面跟 (draft) ((草案)),以及语言;在完整版里,如果有部分带星号 (标给维护者的条文,或者序言的标题),还要说明星号的意思:带星号的部分是写给人看的背景,讲宪法从哪里来、怎样组织、怎样修改,agent 版不收录这些部分。输出为 UTF-8 编码,用 LF 换行,末尾有换行符,不带时间戳;同样的源文件得到逐字节相同的输出。
agent 版
agent 通过编译出的指令读宪法,那里每个 token 都很宝贵;序言,以及讲宪法本身怎样制定和修改的条文,对维护宪法的人和起草修正案的 agent 才有用,而起草修正案的 agent 读的是完整版。所以构建为每种语言再写一个文件 constitution.<lang>.agent.md,它与完整版的区别如下:
- 文件头一行说明这是 agent 版,不含写给人类读者的那些条文的正文。
- 不收录
[front](草案说明和序言),所以在完整版里,其中的每个标题 (## Preamble) 后面都带星号。代替它的位置是构建脚本自己的一段说明,每种语言一句,写在LANGUAGES里:说明这是 agent 版;index.toml为draft时,说明宪法是草案,可以试行但尚未定稿,变成active之后,说明每个 agent 都必须遵守它;说明序言以及写给人类读者、讲宪法怎样组织和修改的条文正文都没有收录,原处只留一个指向完整版的提示;还说明 agent 在修改宪法或构建它的工具之前,要先读完整版,并写出完整版的路径。这段说明不是宪法的正文 (见文件结构)。 - 带
audience = "maintainers"的款或项保留编号,用一句说明代替正文:- **§2** (see the full text)、- **第二款** (见完整版);已废止的照常显示废止说明。在完整版里,同一条文保留正文,编号后面带星号**§2**<sup class="omitted">*</sup>,由文件头一行解释。 - 没有锚点,也没有链接定义:引用就是它的标签,以纯文本显示 (
Art. VIII §6、第八条第六款),在完整版里用简短形式的地方,这里也用简短形式。