Skip to content

proposal(runtime): create Session follow-ups from actionable external conditions #3726

Description

@somewan820

Parent roadmap: #2469

Let a Session subscribe to a typed external condition and create one safe follow-up Turn when that condition becomes actionable. The core remains provider-neutral; GitHub is only the first adapter.

Problem

Maka preserves a Session's context across turns and restarts, but work often cannot continue until a fact changes outside Maka.

Examples include:

  • a maintainer answers a design question;
  • a pull-request review or CI run reaches an actionable result;
  • a Linear issue changes state;
  • a deployment succeeds or fails;
  • a required Slack reply arrives;
  • an external artifact becomes available.

Today the user must inspect the external system, decide whether the change matters, and manually carry the information back into the correct Session.

The Session already owns the work context. The missing capability is a durable and safe bridge from an actionable external condition back to that Session.

This proposal is a concrete follow-up to #2469's product requirement that users should be able to distinguish work that is waiting for an external condition. It does not propose another task, execution, or event authority.

Desired outcome

Allow a user to explicitly subscribe a Session to a typed external condition. When the external provider confirms that the condition has been satisfied or invalidated, Maka creates exactly one bounded follow-up Turn in the associated Session.

The initial product promise is:

Stop requiring users to manually relay external state changes before a Session can continue analyzing its work.

A subscription authorizes observation and follow-up. It does not automatically authorize code changes or external side effects.

Provider-neutral architecture

The core Runtime should not contain GitHub-specific concepts such as pull requests, reviews, comments, or required checks. It should own only the provider-neutral lifecycle:

external resource
-> subscription
-> event receipt
-> condition evaluation
-> freshness/action gate
-> one Session follow-up

A minimal shared contract could be:

interface ExternalResourceRef {
  providerId: string;
  connectionId: string;
  resourceType: string;
  resourceId: string;
}

interface ExternalConditionSpec {
  typeId: string;
  version: number;
  parameters: PersistedValue;
}

interface ExternalSubscription {
  id: string;
  sessionId: string;
  resource: ExternalResourceRef;
  condition: ExternalConditionSpec;
  mode: 'notify' | 'analyze';
  status: 'active' | 'satisfied' | 'paused' | 'cancelled';
  revision: number;
}

type ExternalConditionEvaluation =
  | { outcome: 'pending' }
  | { outcome: 'satisfied'; evidence: ExternalEvidenceRef[] }
  | { outcome: 'invalidated'; evidence: ExternalEvidenceRef[] };

Each provider adapter owns:

  • authentication and connection lifecycle;
  • external resource identity;
  • webhook, polling, or stream ingestion;
  • event decoding and deduplication identity;
  • supported condition types and parameter validation;
  • provider-specific author and role semantics;
  • freshness, ordering, and stable-state rules;
  • conversion into a bounded condition evaluation.

The core does not interpret arbitrary provider payloads or persist an unrestricted JSONPath or natural-language predicate.

Example providers

Provider Example condition
GitHub maintainer replied, review changed, required CI settled
Linear issue assigned, state changed, blocker removed
Slack reply from a selected person or channel arrived
Deployment rollout succeeded, failed, or was rolled back
Artifact store requested artifact became available
Calendar a selected meeting ended or reached its start time

GitHub would be the first adapter, not the definition of the architecture.

Concrete GitHub journey

While working on apache/maka#2290, the Agent determines that implementation cannot proceed until a maintainer answers the migration questions. After user confirmation, Maka creates a subscription:

Resource: github/apache/maka/issues/2290
Condition: github.issue.maintainer_reply.v1
Mode: analyze

When a matching reply arrives, the GitHub adapter validates the event and evaluates the condition. The core then checks that the subscription remains active and creates one external-follow-up Turn in the original Session. The Agent analyzes the reply and reports the resulting implementation boundary.

Wake invariant

A follow-up Turn may be created only when:

verified provider event
+ matching active subscription
+ condition satisfied or invalidated
+ fresh resource/version identity
+ actionable for this Session
= one follow-up Turn

A stable event is not necessarily relevant. For example, successful CI must not wake a Session whose condition is waiting for a maintainer decision.

Provider adapters own provider-specific stable-state rules. For GitHub:

  • a required failure may satisfy the condition immediately;
  • required-check success waits for all required checks;
  • optional checks normally update projection only;
  • a check result for an older head SHA is stale.

Authority boundaries

Concern Authority
External resource facts External provider
Provider-specific event meaning Provider adapter
What condition is being awaited External subscription
Work identity and conversation Session
Execution results AgentRun / RuntimeEvent
Code and revision freshness Git, filesystem, external provider
Permission to modify or publish Existing permission/action policy
WorkHub display Rebuildable projection

I do not propose adding waiting_for_external to SessionStatus initially. External waiting can be projected from active subscriptions.

Safety

External payloads are untrusted input, not instructions.

The initial analyze mode may refresh state, inspect evidence, and report, but must not modify code, commit, push, merge, or perform external side effects.

Any future automatic-action mode requires a separate deterministic Action Gate covering permissions, repository scope, current revision, dirty worktrees, stale events, idempotency, and scope expansion.

Relationship to existing mechanisms

This is distinct from:

  • Scheduled Tasks: time-based triggers;
  • Goal continuation: continuation from internal terminal Turns;
  • Runtime Resume: recovery of interrupted execution;
  • WorkHub: conversational routing and coordination;
  • Work Board: user-owned deferred work;
  • SessionTodo: model-authored local progress.

The feature should reuse existing Session admission, execution, recovery, and permission mechanisms. A satisfied external condition should normally create a new root Turn with typed external-event provenance.

Proposed MVP

  • provider-neutral subscription and delivery core;
  • GitHub as the first production adapter;
  • a fake provider used in contract tests to prove core independence;
  • explicit user-confirmed, one-shot subscriptions;
  • GitHub issue comments, reviews, required CI, close/reopen/merge;
  • analyze-only follow-ups;
  • durable receipts, cursors, deduplication, and restart recovery;
  • polling allowed as the first transport;
  • visible subscription state and cancellation;
  • no automatic code modification.

A second provider should be addable without changing the core subscription schema or Session wake protocol.

Alternatives or workarounds

  • Manual relay: the user continues checking external systems and pasting updates into the Session. This is the current behavior and the coordination burden this proposal aims to remove.
  • Scheduled polling Turns: a recurring Agent Turn checks the external resource. This consumes work while nothing changed and still needs durable deduplication, relevance, and freshness semantics.
  • GitHub-specific watcher: faster initially, but it would couple Session continuation to GitHub resource types and make each later provider repeat the subscription and delivery lifecycle.
  • Natural-language conditions evaluated by a model: flexible, but too weak as the durable authority for deduplication, stable-state decisions, and safe wake admission.

Non-goals

  • A universal workflow engine.
  • Arbitrary natural-language or JSONPath conditions.
  • Automatically subscribing every mentioned resource.
  • Waking every Session that references the same resource.
  • Treating semantic matching as execution authorization.
  • Automatic code modification, commit, push, or merge.
  • Modeling all providers with one lossy universal event vocabulary.

Open questions

  1. Is this product promise useful for ordinary Sessions?
  2. Should the subscription and delivery authority live in Runtime Host?
  3. Should providers register versioned condition schemas and evaluators?
  4. Should a satisfied condition use the existing root-Turn admission path?
  5. Is GitHub polling an acceptable first transport?
  6. Should the first version support only one-shot subscriptions?
  7. Where should subscriptions be created and inspected?
  8. Which second adapter would best prove that the core is genuinely provider-neutral?

I would like to settle the product contract and ownership boundary before proposing a storage schema or implementation PR.

简体中文

问题

Maka 能跨 Turn 和重启保存 Session 上下文,但很多工作必须等待 Maka 之外的事实发生变化后才能继续。例如 maintainer 回复设计问题、PR review 或 CI 得出结果、Linear issue 状态变化、部署完成、Slack 中收到关键回复,或者外部产物生成完成。

目前仍需要用户查看外部系统、判断变化是否重要,再把信息搬回正确的 Session。缺失的能力是:从可行动的外部条件安全、持久地回到原 Session。

这个提案是 #2469 中“用户应该能够识别正在等待外部条件的工作”这一产品要求的具体后续。它不新增另一套 Task、执行或事件权威。

目标

允许用户明确地为 Session 订阅一个强类型外部条件。当外部 provider 确认条件已经满足或失效时,Maka 在关联 Session 中只创建一个受限的 follow-up Turn。

订阅只授权观察和唤醒,不自动授权修改代码或产生外部副作用。

通用架构

核心 Runtime 不应该理解 GitHub 的 PR、评论、review 或 CI。核心只负责:

外部资源
-> 订阅
-> 事件收件
-> 条件评估
-> 新鲜度与行动门禁
-> 一次 Session follow-up

每个 provider adapter 负责认证、资源身份、事件接收、去重、条件类型、参数校验、作者角色、事件顺序、新鲜度以及稳定状态判定。

GitHub 只是第一个 adapter,而不是整个架构的定义。相同核心以后可以接入 Linear、Slack、部署平台、Artifact Store 或 Calendar。

核心不应直接解释任意 provider payload,也不应保存无限制的 JSONPath 或自然语言条件。自然语言可以帮助用户准备条件,但最终应落为经过 adapter 校验的版本化条件契约。

GitHub 示例

在处理 apache/maka#2290 时,Agent 判断只有 maintainer 回答迁移问题后才能安全规划实现。经用户确认后,Maka 创建一次性 analyze 订阅。

回复到达后,GitHub adapter 验证事件并评估条件;核心检查订阅仍有效、事件没有过期,然后在原 Session 中创建一个 follow-up Turn。Agent 分析回复并报告实现边界。

唤醒条件

只有同时满足以下条件才能创建 follow-up Turn:

来源可信
+ 匹配有效订阅
+ 条件满足或失效
+ 资源版本仍然最新
+ 对当前 Session 可行动
= 一次 follow-up Turn

稳定事件不一定相关。例如 Session 等待 maintainer 决策时,CI 成功不能唤醒它。

权威边界

外部 provider 持有外部事实;provider adapter 解释事件;subscription 持有等待条件;Session 持有工作身份和对话;AgentRun/RuntimeEvent 持有执行结果;现有权限策略决定是否允许修改或发布。

第一版不新增 waiting_for_external Session 状态,而是从有效订阅投影“正在等待外部条件”,避免出现第二份状态权威。

安全

外部 payload 是不可信输入,不是指令。

第一版只支持 analyze:刷新状态、检查证据和报告结论,不允许自动修改代码、commit、push 或 merge。未来自动行动必须经过独立的确定性 Action Gate。

与现有机制的关系

它不同于按时间触发的 Scheduled Tasks、消费内部 Turn 的 Goal continuation、恢复中断执行的 Runtime Resume、负责对话路由的 WorkHub、用户拥有的 Work Board,以及模型自报进度的 SessionTodo。

它应该复用现有 Session admission、执行、恢复和权限机制,而不是建立新的执行引擎。

MVP

  • provider-neutral 的 subscription/delivery 核心;
  • GitHub 作为首个生产 adapter;
  • 使用 fake provider 测试核心确实不依赖 GitHub;
  • 用户明确确认的一次性订阅;
  • 支持评论、review、required CI、close/reopen/merge;
  • analyze-only;
  • 持久化 receipt、cursor、去重和重启恢复;
  • 第一版允许 polling;
  • 可以查看和取消订阅;
  • 不自动修改代码。

第二个 provider 应能在不修改核心 subscription schema 和 Session 唤醒协议的情况下接入。

非目标

  • 通用工作流引擎;
  • 任意自然语言或 JSONPath 条件;
  • 自动订阅所有被提到的资源;
  • 唤醒所有引用同一资源的 Session;
  • 把语义匹配当成执行授权;
  • 自动修改代码、commit、push 或 merge;
  • 用一套有损的通用事件词汇抹平所有 provider 差异。

待确认问题

  1. 普通 Session 是否需要这个产品承诺?
  2. subscription/delivery 权威是否属于 Runtime Host?
  3. provider 是否应该注册版本化 condition schema 和 evaluator?
  4. 条件满足后是否复用现有 root-Turn admission?
  5. GitHub-first 是否可以先使用 polling?
  6. 第一版是否只支持一次性订阅?
  7. 用户在哪里创建和查看订阅?
  8. 第二个 provider 选什么,最能验证通用性?

在设计存储 schema 或实现 PR 之前,我希望先确认产品契约和所有权边界。

AI assistance disclosure: Codex helped structure and draft this proposal from a product and architecture discussion. I reviewed it and own the problem statement, proposal, and final decisions.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions