使用 GC
仅在调用者明确选择时使用 Gas City。将其视为一个可替换的执行适配器,而不是正确性或完成度的边界。该适配器不能选择 AgentOps 语义、发布约束性结论,或将工厂完成度转化为交付或验证证明。
首先选择工厂
AgentOps 同时支持 Gas City 和 Agentic Coding Flywheel 作为外部软件工厂运行时。只有在处理 Gas City 时才使用此技能。如果调用者选择了 Flywheel,请切换到 using-flywheel 及其原生工作流,而不是将其包装在 Gas City 中。
AgentOps 为任一工厂提供技能和证据合约。它不需要自己的 Gas City 配方或角色包。在启动 worker 之前,将 AgentOps 技能安装或链接到提供者运行时中;上游的 Mayor、协调器和 worker 随后可以正常发现并选择 plan、implement、test、validate 以及其他 AgentOps 技能。
Gas City 1.4 运行模型
Gas City 1.4 以运行为中心。管理服务器提供仪表盘以及类型化、分页的会话/运行 API。每个拥有图的 city 或 rig 作用域都需要自己的 core.control-dispatcher;这个确定性 worker 负责推进配方控制信标。Agent worker 接收路由过来的工作。上游的 gc.mayor 技能是引导协调器;gc.run-operator 负责启动和监督管理配方。
标准的 AgentOps 路径是:
- 安装并锁定上游的
gascity工作流和 rig-role 导入。 - 将项目添加为 rig,准备其标准的 maintainer 运行时,并使 AgentOps 技能对其提供者会话可见。
- 创建一个由调用者拥有的源意图信标 (intent bead),并将其 id 交给 Mayor,Mayor 负责编写工作流信标并调度与可用工件匹配的上游
build-basic、continuation、review 或 implementation 配方。 - 读取运行、会话、信标、工件和结论状态。完成度绝不能从聊天或窗格文本中推断。
在首次构建之前,使用附带的 AgentOps CLI(无需代码仓库检出)准备并验证 rig:
ao gc prepare --city /path/to/city --rig /path/to/rig
ao gc check --city /path/to/city --rig /path/to/rig
该命令会验证确切的官方工作流和角色锁定,将上游验证脚本和模式原封不动地快照到 rig 的 .gc 运行时中,仅在配方检查路径安装小型的 AgentOps 拥有的包装器,选择一个可以导入 PyYAML 的现有 Python,并将 AgentOps 技能链接到 city 和 rig 的 Codex 接收器。技能来自外层的 AgentOps 检出目录(如果存在),否则来自已安装的技能根目录;传递 --skills-source 可以指定其他目录。它绝不会修改 GC 二进制文件、缓存、配方、角色或上游包。check 仅执行原生检查命令,不写入任何适配器文件,并且在模型开销产生之前,如果该运行时合约缺失或发生漂移,则会失败。
prepare 还会为其运行时存在的每个 Codex 会话目录预植信任——包括 city 和 rig 根目录、每个 .gc/agents/** 会话主目录以及每个 rig 工作树根目录——以便在这些目录中的 Codex 会话不会阻塞在交互式信任对话框上。这两个持久化层都会被植入 $CODEX_HOME/config.toml:工作区信任([projects."<dir>"] trust_level = "trusted"),缺少它 Codex 会静默地报告该目录根本没有钩子;以及每个钩子的信任([hooks.state."<hooks.json>:<event>:<m>:<h>"] trusted_hash = "sha256:..."),这正是包中每个提供者的 .codex/hooks.json 否则会提示的内容。钩子摘要从 Codex 自身的 hooks/list 读取,绝不重新计算。
信任是通过值来判断的,而不是通过表的存在与否。prepare 仅追加缺失的条目,并且当一个条目存在但不授予信任时——例如显式的 trust_level = "untrusted"、Codex 报告已更改的钩子、Codex 仍然拒绝的已记录钩子,或者记录为 enabled = false 的钩子(禁用的钩子不是可信的工作钩子)——它会拒绝并明确指出该条目。它绝不会覆盖操作员的决定,重新运行是无操作的。如果 Codex 返回一个空或无法识别的钩子列表,它也会失败而不是继续。信任存储本身永远不会被原地编辑:合并后的内容先在内存中解析,然后使用 CLI 的持久性原子写入器进行安装,因此没有失败路径会留下部分写入的 Codex 配置。
ao gc check 仅从本地状态验证相同的预植——它不运行任何 Codex 子进程也不写入任何内容,从目录自身的 hooks.json 派生每个预期的钩子键——并使用与 prepare 植入时相同的规则来命名具体缺失的目录或钩子。
两个已命名的限制。
check无法检测到过期的哈希值。 因为它从不询问 Codex,一个记录的trusted_hash即使不再匹配钩子当前的内容,也会被读取为已满足,并在实际会话中仍然弹出信任对话框。只有prepare会看到这一点——Codex 报告钩子已更改,然后prepare会拒绝。因此,绿色的check意味着“信任已被记录”,而不是“信任是最新的”。prepare之后创建的会话主目录不会被覆盖。 发现机制基于文件系统标记,因此保证只覆盖prepare时存在的会话目录。Gas City 稍后 物化的会话主目录在其首次启动时仍然会携带不受信任的钩子;prepare会指出没有主目录的已配置代理。
由此得出的操作规则是:运行 prepare,启动 city,然后在调度之前再次运行 prepare(它是幂等的)。
首选包和注册表
内置的 main 注册表收录官方包。社区注册表是可选的配置:
gc pack registry list
gc pack registry refresh
gc pack registry search --all
gc pack registry show main:gascity
gc pack registry add community https://registry.gascity.com/registry.toml
gc pack registry search --registry community --all
search 读取本地注册表缓存;show 报告发布来源和准确的导入命令。gc import add 声明一个来源/版本,gc import install 将其解析到 packs.lock 中。为了可复现的 city,首选使用精确接受的版本。
AgentOps 偏好官方的 gascity 构建包,即公共 Maintainer City 工厂中可见的工作流家族。当前接受的参考版本是 gascity 0.1.6,提交号为 3b3b89f2011e06d84459aa7bea1552382f13930a:
- 仪表盘:
https://factory.gascity.com; - 工作流:
build-basic、build-from-*、implement、review、issue 和 PR 流程; - 标准 rig 角色:
gc.run-operator、gc.implementation-worker、规划者、审查者和发布者; - 作用域本地配方控制:
core.control-dispatcher; - 引导协调:上游的
gc.mayor技能。
按照 gc pack registry show main:gascity 返回的确切命令,在 city 作用域安装工作流包,并在每个执行工作的 rig 上安装其兄弟角色包。保留标准的 gc.* 命名空间;不要将角色嵌套或重命名到 AgentOps 包后面。
工作通过 Mayor 进入 city。调用者创建一个包含验收条件的源意图信标,然后将它的 id 交给 Mayor——Mayor 分解、编写工作流信标并进行调度。调用者永远不要自己运行 gc sling;操作员发送的运行绕过了拥有该工作流重试、重新调度和照料责任的协调器。
gc bd create "为 export 命令添加一个 --json 标志"
gc mail send mayor -s "构建 ago-XXXX" \
-m "为信标 ago-XXXX 分解并启动 build-basic,设置 push=true open_pr=true。" --notify
或者,在交互式 Mayor 会话中:
使用技能 gc.mayor
直接的 gc sling 仍然是一个调试工具,用于没有活跃 Mayor 的 city;以这种方式启动的运行没有协调器,操作员需要继承其照料工作。
AgentOps 技能是对这些工厂代理可用的工具,而不是替代性的工作流。当需要其行为时,在信标或提示中明确命名一个技能。当前的上游分解不会自动将从调用者拥有的源信标中的自由格式 Required Skills 部分传播到每个生成的工作项中。在实施前检查分解结果;当使用某个技能是验收条件时,将其名称放在实际的工作项或 worker 提示中。技能的存在和技能的调用是两个不同的事实。
将现有 city 升级到 1.4
在启动其编排器之前,为每个 city 运行一次:
gc doctor --fix
gc import install
gc supervisor stop --wait # macOS 上,当旧的直接管理服务器仍然存在时
gc start
然后确认:
gc version从预期的路径报告1.4.0;gc doctor没有阻塞性失败;- 每个拥有图的 rig 都有一个未暂停的
core.control-dispatcher; - imports 和
packs.lock解析成功; ao gc check接受包含的 maintainer 运行时和 AgentOps 技能链接;- 在 macOS 上,管理服务器 LaunchAgent 解析到与所选
gc二进制文件相同的可执行文件; - 旧的独立仪表盘书签或反向代理已被移除。
一个过时的已注册 city 可能会阻塞每次启动。使用 gc doctor --fix 修复该 city,或者如果它被有意废弃,则显式注销它。
通过确切的注册名称或路径来废弃旧的 HQ/canary,而无需停止其替代品所需的机器范围的管理服务器:
gc cities --json
gc stop /path/to/old-city --timeout 45s
gc unregister /path/to/old-city
gc cities --json
unregister 会在静默接受未知目标时报错。保留 city 目录,直到其信标状态被备份或确认可丢弃。从上游 Gas City 模板创建替代 city,安装其锁定的 imports,并通过 gc cities --json、gc --city <new-city> status 和 gc --city <new-city> doctor --json 进行验证。
通过 Mayor 编排:照料循环
将意图交给 Mayor 后,编排器运行五个动作。每个动作有一个所有者;跨越所有者是本节所要阻止的常见错误模式。
| 动作 | 所有者 | 界面 |
|---|---|---|
| 监视 | 编排器 | 按固定节奏轮询 $API/runs/census 和 $API/runs/<run-id>,加上 gc mail inbox 获取 Mayor 回复。census 中的 failed > 0、处于 failed/canceled 状态的运行,或未读的 Mayor 邮件是行动信号;其他一切都是心跳。 |
| 观察 | 编排器 | 收到行动信号后,按顺序检查各可见性层级——census、运行详情、信标图、会话名册、窗格真实状态——并在第一个能解释问题的层级停止。不要从窗格真实状态开始。 |
| 轻推 | 编排器(一次) | 一个 ready 状态的信标:调度一次到其 gc.run_target。一个已路由且有活跃会话的信标:gc session wake <run_target> 一次。对同一个主题进行第二次轻推意味着诊断错误——应改为发送邮件给 Mayor。 |
| 重定向 | Mayor | 优先级、作用域、取消或模型/提供者的变更通过带信标/运行 id 的邮件传递。编排器从不重新调度、编辑工作流信标或修补正在运行的运行。 |
| 返工 | 先是 GC,然后是 Mayor | 失败的审查发现通过其原生的修复循环(review_fix_formula,默认为 fix-loop-base)重新进入运行;有界门控重试是 gc converge 循环。只有处于 TERMINAL failed/canceled 状态的运行——或者一个已完成但其结果不符合调用者验收条件的运行——才会回到起点:将运行 id 和失败证据通过邮件发送给 Mayor,以便重新分解和重新启动。 |
编排器手动执行的返工(编辑失败运行的工作树、重新调度其配方、关闭其信标)会为同一个意图创建第二个不协调的参与者;Mayor 的重新启动将与之发生竞争。
停滞协议
首先对信标分类。
-
仍然
ready状态:调度一次到其gc.run_target,然后停止并检查。 -
已路由/进行中:重新调度是 无效操作。唤醒其所属 worker 一次:
gc session wake <run_target>
然后,捕获会话状态指定的确切 tmux 窗格,并运行 gc doctor。
切勿在该 city 内部修复该 city。
切勿手动创建由包拥有的会话。gc session new 对于一个单例或规模代理(core.control-dispatcher、角色 workers)会创建一个作用域错误的会话,该会话会占用 start-pending 状态下的规范名称,并阻塞协调器生成真正的会话——从而延长正在修复的停滞。会话生命周期属于协调器和需求伸缩。
当 city 本身需要照料时(协调器停滞、会话从不离开 draining 状态、模型或提供者重新配置),将请求发送给 Mayor:
gc mail send mayor -s "<主题>" -m "<包含信标 id 的请求>" --notify
上游包可能会将一个未来的亲和性绑定步骤分配给一个已经确认 drain 完毕的会话。只能从 city 外部诊断此问题:
ao gc recover-affinity --city /path/to/city --rig /path/to/rig
默认是试运行。如果列出的每个分配都是正确的,则添加 --apply 再次运行。有限制的修复仅清除当前 ready 配方信标上的接收者,该信标的 gc.session_affinity=require 会话已不再活跃。它不进行调度、重试、关闭、重启或选择工作。
可见性:四个层级
-
管理服务器/运行状态——
gc dashboard、运行详情、gc status和gc session list --json。运行详情统一了阶段阶梯、结构化转录文本、令牌速率和预估消耗速率。即使提供者阻塞,名册仍可能报告为活跃。编程式运行状态来自管理服务器的类型化运行 API——与仪表盘渲染的数据相同。
gc status打印 API 基础地址;gc status --json或任何其他 CLI 子命令都不携带运行对象。API="http://127.0.0.1:<port>/v0/city/<city-name>" curl -s "$API/runs/<run-id>" # {run_id, title, status, target, scope, started_at, updated_at} curl -s "$API/runs/census" # {status_counts: {pending: <n>, active: <n>, ...}} -
信标图——
gc bd graph显示步骤依赖、状态和分配。完整的工作流状态是信标图,而不是仪表盘上的一个绿色徽章。 -
会话名册——
gc session list --json输出每个活跃会话的运行时、角色和分配。当运行时计数不匹配期望的角色时,一个问题会话会在名册中显现出来,然后才在窗格文本中显现。 -
窗格真实状态——
gc session attach <run_target>进入 worker 的 tmux 窗格。如果诊断依赖于窗格真实状态,则说明前三个层级被跳过了。