ASTER CODE / 内核原理
Run 的事实驱动执行
FactRun 的身份、模型提案、权限判定、工具回执、运行控制与结束边界。
一次执行有原始身份与原始依据
AgentSession 表示持续的会话。
一次接纳的任务执行对应一个 Run。
FactRun 组织该次执行的事实驱动路径。
底层组件从日志计算当前状态与后续动作。
- 01模型只提出下一步
模型读取当前上下文,再提出工具调用或最终答复。
fact_control.rsL126 ↗ - 02执行前先检查权限
Ask 等待准确的确认回答。Deny 返回拒绝结果。
- 03用事实检查能否结束
工具回执进入日志。完成门禁核对修改、验证和未决事项。
harness_loop.rsL1591 ↗
例如,修复日期函数的运行会读取文件。 模型随后提出修改和检查调用。 每次调用都有自己的身份与参数。 后续判断使用该次调用留下的原始结果。
FactRun 在准入时固定哪些内容
| 内容 | 用途 | 后续文本能否替换 |
|---|---|---|
| 原始日志写入器 | 序列化事实写入 | 不能用聊天摘要替代 |
| 会话对应的 thread | 隔开同工作区中的会话 | 不能借另一会话的记录 |
| 已准入工具集合 | 约束本次暴露的能力 | 后来的提示词不能扩大集合 |
| 已准入权限策略 | 判定具体调用 | 模型声明不会改变策略 |
| 完成门禁 | 检查结束依据 | 宿主组件不能清除内核要求 |
| 当前目标与取消令牌 | 关联目标步骤和控制 | 控制仍指向原始运行 |
这些字段见 FactRun L126 ↗。
从模型提案到实际效果
模型调用返回文本或工具提案。 工具入口先核对调用身份、参数与权限。 Allow 进入受控执行,Deny 返回拒绝。 Ask 停在确认等待点。 匹配的确认回答到达后,原调用才能继续判断。
工具结果包含输出、退出码和效果元数据。 输出文本解释观察结果。 效果回执记录实际执行与工作区变化。 这两类材料分别支持模型理解与运行治理。
源码漫游
事实驱动执行源码漫游
从一次 Run 的权威状态看到工具与结束检查。
pub struct FactRun {dir: PathBuf,/// The Run's shared fact-log writer. Constructed here as a default and/// replaced by the session constructors with the instance the run's/// tool contexts already hold, so actor appends and Run-owned background/// readers serialize through one instance mutex (a second `FileLog`/// handle over the same directory races duplicate seqs).log: Arc<FileLog>,thread: String,actor: a3s_effect::Actor<CodingServices, CodingView>,services: Arc<CodingServices>,limit: Option<u32>,/// Tool names exposed when this run was admitted. A later posture does not rewrite them.admitted_tools: Vec<String>,/// Copied from [`crate::meta_harness::KernelPolicy::admit`]. Hosts cannot clear it.completion_gate: bool,/// Permission policy frozen at admission, including posture allow rules.admitted_permission: PermissionPolicy,/// Digest admitted for this run. Legacy opens leave this empty.standing_digest: Option<String>,current_goal: Option<crate::goal_control::DurableGoalDefinitionV1>,/// Host cancel for this run. Interactive sessions share [`SessionSurface::cancel`].cancel: tokio_util::sync::CancellationToken,}/// Optional host mounts for Meta Harness admission.#[derive(Default)]pub struct FactRunHostMounts<'a> {pub compose: Option<&'a crate::meta_harness::HarnessComposeOptions>,pub registry: Option<&'a dyn crate::meta_harness::HostHarnessRegistry>,
pub(super) fn run_execution_cycle(surface: &SessionSurface,facts: &[a3s_effect::Fact],) -> Result<Option<receipts::ExecutionCycle>, ActorError> {let threshold = surface.agent.duplicate_tool_threshold();if surface.agent.is_child_run() {return Ok(receipts::child_execution_cycle(facts, threshold));}let Some(run_id) = surface.run_id.as_deref() else {return Ok(None);};let binding = surface.agent.checkpoint_capability_binding().ok_or_else(|| {ActorError::Schema("tool_effect_admission_missing: original Run has no capability binding".into(),)})?;let digest = crate::content_digest::digest_json("a3s.code.tool-admission-binding.v1", binding).map_err(|error| ActorError::Schema(error.to_string()))?;Ok(receipts::execution_cycle(facts,&thread_for_session(&surface.session_id),run_id,&digest,threshold,))}pub(super) fn interrupted_response() -> crate::llm::LlmResponse {crate::llm::LlmResponse {
pub enum RunControlCommand {/// Add a new user direction without starting a second turn.Steer { input: String },/// Stop the current run. `force` is advisory: the runtime remains/// cooperative and will never skip cleanup or governance boundaries.Interrupt {reason: Option<String>,#[serde(default)]force: bool,},}impl RunControlCommand {pub fn operation(&self) -> RunControlOperation {match self {Self::Steer { .. } => RunControlOperation::Steer,Self::Interrupt { .. } => RunControlOperation::Interrupt,}
pub(crate) fn decide_with_contracts(ledger: &MutationLedger,reports: &[VerificationReport],waivers: &[CompletionWaiverV1],allow_continuation: bool,observations: &[crate::external_observation::ExternalObservationV1],contracts: &[crate::verification::VerificationContractV1],) -> CompletionGate {if let Some(error) = ToolEffectUnresolved::from_ledger(ledger) {return CompletionGate::Incomplete {message: error.to_string(),};}let open = crate::external_observation::still_open(observations, waivers, ledger.digest());if crate::external_observation::blocks_success(&open) {let digest = open.iter().map(|observation| observation.digest.as_str()).collect::<Vec<_>>().join(",");let message = format!(
源码与本文版本一致,保留原始行号。
事实日志与界面事件怎样分工
事实日志用于重建控制状态。 实时事件用于更新宿主界面。 界面显示“命令完成”时,也应保留原始调用 ID。 重连后的显示状态要与原运行记录核对。
ACP 会把文本和工具事件映射为协议更新。 映射不会产生第二次工具执行。 相关适配过程见 ACP 事件投影。
用户中途补充要求时怎样处理
- 01指向准确的一次运行
请求携带 Run ID、请求 ID 和可选版本条件。
run_control.rsL56 ↗ - 02接纳后等待安全点
Accepted 表示进入收件箱。Applied 表示已作用于目标运行。
- 03中断仍需收尾
interrupt 停止新增工作,并保留取消与资源收尾。
run_control.rsL56 ↗
steer 把用户补充送入当前 Run。
补充在安全点应用,随后写入用户输入事实。
它不会建立另一个并发主任务。
模型、工作区和权限边界仍沿用原次准入。
控制请求包含 request_id 和 run_id。
宿主还支持提交预期轮次与版本。
旧版本请求或已关闭运行会得到明确拒绝。
| 回执概念 | 表示什么 | 宿主应怎样理解 |
|---|---|---|
| Accepted | 请求已进入控制路径 | 仍要等待应用结果 |
| Applied | 请求已作用于目标运行 | 核对目标与控制版本 |
| Rejected | 请求未生效 | 显示具体拒绝原因 |
| Settled | 控制请求已结清 | 保留原始处理记录 |
interrupt 为什么仍需要等待
interrupt 请求停止新增工作。
正在执行的操作需要协作取消或完成收尾。
force 字段也只是控制提示。
运行仍保留治理与清理边界。
取消成功不证明之前的外部效果已撤销。 若操作结果不明,恢复流程仍需核实。 详见恢复与未决效果。
为什么最终答复还不能直接结束
模型最终答复只是候选终态。 完成门禁检查未决效果、子任务和完整修改。 有修改时,验证依据要绑定当前摘要。 资源结清后,宿主才能把该次运行视为结束。
一次 Run 结束后,长期目标仍可能有剩余步骤。 接下来阅读长期任务。