Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions ROADMAP.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ authorization always belong to the game Host.
offers, cancellation, acknowledgements, progress, and outcomes.
- MCP and Host APIs share stable Operation IDs, Epoch/Observation bindings, and
the exact Host-authored Offer.
- Hosts publish one `decision_authority` that hands an Actor between internal
control and one exact external Principal; revisions fence stale turns.
- External controllers can long-poll redacted Actor state and submit Actor
speech plus an exact Offer selection under one `turn_id`.
- An exclusive state lock, stale timeline rejection, orphan expiry, and bounded
recovery.
- A dedicated [`api/control-openapi.json`](api/control-openapi.json) contract and
Expand Down Expand Up @@ -124,10 +128,16 @@ through cross-repository tests.
exists, and cooldown permits; there is no unbounded background polling.
- [x] A character can initiate contextual dialogue, propose one reviewable small
goal, and refuse unsafe action.
- [x] One actor has one write-control lease at a time; in-game, internal AI, and
MCP contention returns an explicit busy or handoff result.
- [x] Autonomous and external paths share the control service, Capability, and
exact offers; world action is proposed before acceptance.
- [x] One Actor has one decision source: the internal runtime or an external
agent bound to one exact Principal. Authority revisions stale unaccepted old
turns.
- [x] An external agent can wait for state changes, speak as the Actor, and
select a Host Offer; dialogue and action may share one `turn_id`.
- [x] `character-bound` and `agent-avatar` distinguish the Host character from
an external agent persona; Rin does not copy private memory across sources.
- [x] Autonomous and external paths share Capability, exact Offers, and final
Host authorization while semantic decisions remain separate from per-tick
execution.
- [ ] Quiet hours, daily limits, and richer autonomous goals wait for human
evidence that the current initiative adds value.

Expand Down
15 changes: 12 additions & 3 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ Rin 不是游戏引擎、通用自动化平台或模型代理服务。渲染、
ACK、进度和 Outcome。
- MCP 和 Host API 共用稳定 Operation ID、Epoch/Observation Binding 与精确
Host Offer。
- Host 发布单一 `decision_authority`,在内部控制与一个精确外部 Principal 之间
转交;修订号会隔离旧回合。
- 外部控制器可以长轮询脱敏 Actor 状态,并以同一 `turn_id` 提交角色对白和精确
Offer 选择。
- 状态目录独占锁、旧时间线失效、孤儿操作过期和有界恢复。
- 独立 [`api/control-openapi.json`](api/control-openapi.json) 契约及官方 MCP
Conformance 的能力匹配门禁。
Expand Down Expand Up @@ -95,9 +99,14 @@ Rin 不是游戏引擎、通用自动化平台或模型代理服务。渲染、
- [x] 主动对话默认关闭,并可配置主动级别、冷却和连续主动回合上限。
- [x] Dormant Actor 仅在主人在线、存在可继续话题且满足冷却时唤醒,不做无限后台轮询。
- [x] 角色可以发起有上下文对白、提出一个可审核小目标,并拒绝不安全动作。
- [x] 同一 Actor 同一时刻只有一个写控制租约;游戏内、内部 AI 和 MCP 竞争时给出
明确的忙碌或转交结果。
- [x] 自动行为与外部入口共用控制服务、Capability 和精确 Offer;世界动作先提议后确认。
- [x] 同一 Actor 只有一个决策控制源:内部 Runtime,或绑定一个精确 Principal 的
外部 Agent;控制权修订会使尚未接受的旧回合失效。
- [x] 外部 Agent 可以等待状态变化、作为角色说话并选择 Host Offer;对白和动作可用
同一个 `turn_id` 关联。
- [x] `character-bound` 与 `agent-avatar` 明确区分角色人格和外部 Agent 人格;
Rin 不在控制源之间复制私有记忆。
- [x] 自动行为与外部入口共用 Capability、精确 Offer 和 Host 最终授权;语义决策
与逐 Tick 执行保持分层。
- [ ] 安静时段、每日上限和更丰富的自主目标等待真人确认当前主动性有价值后再做。

### 5. 有界世界任务
Expand Down
213 changes: 212 additions & 1 deletion api/control-openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,36 @@
}
}
},
"/control/v1/client/wait-actor": {
"post": {
"operationId": "control_client_wait_actor",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WaitActorInput"
}
}
}
},
"responses": {
"200": {
"description": "Latest principal-visible actor state after a bounded wait",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ActorUpdate"
}
}
}
},
"default": {
"$ref": "#/components/responses/Error"
}
}
}
},
"/control/v1/client/offers": {
"post": {
"operationId": "control_client_list_offers",
Expand Down Expand Up @@ -490,6 +520,36 @@
}
}
},
"/control/v1/client/utterance": {
"post": {
"operationId": "control_client_submit_utterance",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ActorUtteranceInput"
}
}
}
},
"responses": {
"200": {
"description": "Queued externally authored Actor utterance",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/OperationView"
}
}
}
},
"default": {
"$ref": "#/components/responses/Error"
}
}
}
},
"/control/v1/client/execute-offer": {
"post": {
"operationId": "control_client_execute_offer",
Expand Down Expand Up @@ -1067,6 +1127,44 @@
}
}
},
"DecisionAuthority": {
"type": "object",
"additionalProperties": false,
"required": [
"source",
"revision",
"persona_mode"
],
"properties": {
"source": {
"type": "string",
"enum": [
"internal",
"external"
]
},
"controller_principal_id": {
"$ref": "#/components/schemas/Identifier"
},
"revision": {
"allOf": [
{
"$ref": "#/components/schemas/JSONSafeUnsignedInteger"
},
{
"minimum": 1
}
]
},
"persona_mode": {
"type": "string",
"enum": [
"character-bound",
"agent-avatar"
]
}
}
},
"ActorPublication": {
"type": "object",
"additionalProperties": false,
Expand Down Expand Up @@ -1103,6 +1201,9 @@
"epoch": {
"$ref": "#/components/schemas/Epoch"
},
"decision_authority": {
"$ref": "#/components/schemas/DecisionAuthority"
},
"state": {
"type": "object"
},
Expand Down Expand Up @@ -1205,7 +1306,8 @@
"additionalProperties": false,
"required": [
"epoch",
"observation_seq"
"observation_seq",
"authority_revision"
],
"properties": {
"epoch": {
Expand All @@ -1220,6 +1322,16 @@
"minimum": 1
}
]
},
"authority_revision": {
"allOf": [
{
"$ref": "#/components/schemas/JSONSafeUnsignedInteger"
},
{
"minimum": 1
}
]
}
}
},
Expand Down Expand Up @@ -1261,9 +1373,13 @@
"enum": [
"message",
"directive",
"utterance",
"offer"
]
},
"turn_id": {
"$ref": "#/components/schemas/Identifier"
},
"text": {
"type": "string",
"minLength": 1,
Expand Down Expand Up @@ -1549,6 +1665,56 @@
}
}
},
"WaitActorInput": {
"type": "object",
"additionalProperties": false,
"required": [
"host_id",
"world_id",
"actor_id",
"after_observation_seq",
"after_authority_revision",
"wait_millis"
],
"properties": {
"host_id": {
"$ref": "#/components/schemas/Identifier"
},
"world_id": {
"$ref": "#/components/schemas/Identifier"
},
"actor_id": {
"$ref": "#/components/schemas/Identifier"
},
"after_observation_seq": {
"$ref": "#/components/schemas/JSONSafeUnsignedInteger"
},
"after_authority_revision": {
"$ref": "#/components/schemas/JSONSafeUnsignedInteger"
},
"wait_millis": {
"type": "integer",
"minimum": 0,
"maximum": 25000
}
}
},
"ActorUpdate": {
"type": "object",
"additionalProperties": false,
"required": [
"actor",
"changed"
],
"properties": {
"actor": {
"$ref": "#/components/schemas/ActorView"
},
"changed": {
"type": "boolean"
}
}
},
"ActorTextInput": {
"type": "object",
"additionalProperties": false,
Expand Down Expand Up @@ -1579,6 +1745,40 @@
}
}
},
"ActorUtteranceInput": {
"type": "object",
"additionalProperties": false,
"required": [
"request_id",
"host_id",
"world_id",
"actor_id",
"turn_id",
"text"
],
"properties": {
"request_id": {
"$ref": "#/components/schemas/Identifier"
},
"host_id": {
"$ref": "#/components/schemas/Identifier"
},
"world_id": {
"$ref": "#/components/schemas/Identifier"
},
"actor_id": {
"$ref": "#/components/schemas/Identifier"
},
"turn_id": {
"$ref": "#/components/schemas/Identifier"
},
"text": {
"type": "string",
"minLength": 1,
"maxLength": 300
}
}
},
"ExecuteOfferInput": {
"type": "object",
"additionalProperties": false,
Expand All @@ -1604,6 +1804,9 @@
},
"offer_id": {
"$ref": "#/components/schemas/Identifier"
},
"turn_id": {
"$ref": "#/components/schemas/Identifier"
}
}
},
Expand Down Expand Up @@ -1662,6 +1865,7 @@
"display_name",
"observation_seq",
"epoch",
"decision_authority",
"state",
"online",
"lease_expires_at_unix_millis"
Expand All @@ -1688,6 +1892,9 @@
"epoch": {
"$ref": "#/components/schemas/Epoch"
},
"decision_authority": {
"$ref": "#/components/schemas/DecisionAuthority"
},
"state": {
"type": "object"
},
Expand Down Expand Up @@ -1765,9 +1972,13 @@
"enum": [
"message",
"directive",
"utterance",
"offer"
]
},
"turn_id": {
"$ref": "#/components/schemas/Identifier"
},
"status": {
"$ref": "#/components/schemas/OperationStatus"
},
Expand Down
1 change: 1 addition & 0 deletions cmd/rin-control/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ func containsAnyControlScope(scopes []string) bool {
controlplane.ScopeActorRead,
controlplane.ScopeActorConverse,
controlplane.ScopeActorDirect,
controlplane.ScopeActorSpeak,
controlplane.ScopeActorExecute,
controlplane.ScopeOperationCancel,
controlplane.ScopeHostAdmin,
Expand Down
Loading
Loading