Add optional proofs for an exact human structure decision

Why: A model-visible flag cannot prove that a person confirmed one proposal revision and payload hash.
Evidence: go test ./pkg/extension ./internal/app ./internal/server -run 'HumanDecision|SurfaceSnapshot|ResolveHuman|NaturalLanguage' passed locally.
Impact: SurfaceVersion 2.22.0-experimental adds HumanDecisionVerifier. Existing Host methods stay unchanged, and the base does not consume the proof.
Refs: W4b human confirmation design r1
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
weichen
2026-10-15 02:33:37 +00:00
co-authored by Cursor
parent da4b8c9956
commit b740f8b6f6
14 changed files with 835 additions and 5 deletions
+4 -1
View File
@@ -52,7 +52,10 @@ import (
// X2 project audit capabilities on one Backend surface.
// 2.21.0-experimental: optional ProjectWorkObservationRegistry; host-origin
// work-source observations and project action decisions (X3 contract).
const SurfaceVersion = "2.21.0-experimental"
// 2.22.0-experimental: optional HumanDecisionVerifier. The host proves that
// this dispatch is an authenticated human response to one exact pending card.
// It does not consume the proof; the caller does that in its own transaction.
const SurfaceVersion = "2.22.0-experimental"
// ErrNotLinked 表示进程没有空白导入 link 包,Main 无法启动服务。
var ErrNotLinked = errors.New("extension: runner not linked; blank-import agent-system-backend/pkg/extension/link")
+52
View File
@@ -2,6 +2,7 @@ package extension
import (
"context"
"time"
core "agent-system-core"
)
@@ -46,6 +47,7 @@ type Handler func(ctx context.Context, h Host, req Request) (any, error)
// - SurfaceHost — EXT-17:页面保存/读取
// - WorkCompletionHost — X1:受信项目工作生成
// - WorkTaskHost — X1:分发期建立可恢复的受信项目任务绑定
// - HumanDecisionVerifier — 本次分发是否为认证人对确切待确认卡的响应
type Host interface {
// PluginID 返回注册处理器的插件标识(形如 rdm)。
PluginID() string
@@ -92,3 +94,53 @@ type Host interface {
}
// —— AdminProvider 定义移至本文件上方(Request 之后)——
// HumanDecisionAudienceStructure is the only audience this proof can authorize.
// Another plugin cannot reuse the same human response as its own confirmation.
const HumanDecisionAudienceStructure = "rdm.structure.decide"
// HumanDecisionBinding is the exact object a human must have confirmed.
// Callers pass it to the host; they do not carry a copyable secret.
type HumanDecisionBinding struct {
Audience string
Actor string
ProjectID string
ProposalID string
ProposalRevision int
PayloadHash string
Decision string
}
// HumanDecisionCard is the pending object a person confirms.
type HumanDecisionCard struct {
CardID string
Question string
ExpiresAt time.Time
}
// HumanDecisionProof is a read-only statement that a person already responded.
// ProofID is a consumption key for the caller. The host does not mark it used.
type HumanDecisionProof struct {
ProofID string
Issuer string
HumanActor string
Audience string
ProjectID string
ProposalID string
Revision int
PayloadHash string
Decision string
IssuedAt time.Time
ExpiresAt time.Time
ConversationID string
RunID string
HITLResponseRef string
}
// HumanDecisionVerifier is optional. A missing assertion means the capability
// is absent and the caller must refuse the write.
type HumanDecisionVerifier interface {
IssueHumanDecision(binding HumanDecisionBinding, question string) (HumanDecisionCard, error)
VerifyHumanDecision(expected HumanDecisionBinding) (HumanDecisionProof, error)
RevokeHumanDecision(cardID string) error
}
+8
View File
@@ -52,6 +52,14 @@ Host.TaskCreate
Host.TaskUpdate
HostAuditReceipt
HostClient
HumanDecisionAudienceStructure
HumanDecisionBinding
HumanDecisionCard
HumanDecisionProof
HumanDecisionVerifier
HumanDecisionVerifier.IssueHumanDecision
HumanDecisionVerifier.RevokeHumanDecision
HumanDecisionVerifier.VerifyHumanDecision
InProc
IntentSpec
Main