ACP lifecycle refactor
기준일: 2026-07-26
공식 기준: ACP lifecycle refactor
ACP lifecycle refactor 문서는 OpenClaw 공식 문서(refactor/acp)를 한국어로 정리한 가이드입니다. Migration plan for making ACP session and ACPX process ownership explicit 명령·설정 키·코드 예시는 공식 문서를 그대로 보존하며, 해석과 절차 안내는 한국어로 제공합니다. 최종 동작은 설치된 CLI 버전과 공식 원문을 확인하세요.
핵심 요약
Migration plan for making ACP session and ACPX process ownership explicit
한국어 가이드 범위: refactor/acp 경로의 설정·명령·제약·예시를 학습용으로 재구성합니다.
문서 구성
공식 문서의 주요 섹션은 다음과 같습니다.
- Goals
- Non-goals
- Target Model
- Gateway Instance Identity
- ACP Session Ownership
- ACPX Process Leases
- Lifecycle Controller
- Wrapper Contract
- Session Visibility Contract
- Migration Plan
- Phase 1: Add Identity And Leases
- Phase 2: Lease-First Cleanup
- Phase 3: Lease-First Startup Reaping
- Phase 4: Session Ownership Rows
- Phase 5: Remove Legacy Heuristics
- Tests
- Compatibility Notes
- Success Criteria
상세 내용
본문
ACP lifecycle currently works, but too much of it is inferred after the fact. Process cleanup reconstructs ownership from PIDs, command strings, wrapper paths, and the live process table. Session visibility reconstructs ownership from session-key strings plus secondary sessions.list({ spawnedBy }) lookups. That makes narrow fixes possible, but it also makes edge cases easy to miss: PID reuse, quoted commands, adapter grandchildren, multi-gateway state roots, cancel versus close, and tree versus all visibility all become separate places to rediscover the same ownership rules.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
Goals
주요 항목:
- Cleanup never signals a process unless current live evidence matches an
cancel,close, and startup reaping have distinct lifecycle intents.sessions_list,sessions_history,sessions_send, and status checks use- Multi-gateway installs cannot reap each other's ACPX wrappers.
- Old ACPX session records keep working during migration.
- The runtime remains plugin-owned; core does not learn ACPX package details.
Non-goals
주요 항목:
- Replacing ACPX or changing the public
/acpcommand surface. - Moving vendor-specific ACP adapter behavior into core.
- Requiring users to manually clean state before upgrading.
- Making
cancelclose reusable ACP sessions.
Target Model
이 섹션의 세부 항목은 공식 문서 Target Model를 참고하세요.
Gateway Instance Identity
Each Gateway process should have a stable runtime instance id:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
type GatewayInstanceId = string;
ACP Session Ownership
Every spawned ACP session should have normalized ownership metadata:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
type AcpSessionOwner = {
sessionKey: string;
spawnedBy?: string;
parentSessionKey?: string;
ownerSessionKey: string;
agentId: string;
backend: "acpx";
gatewayInstanceId: GatewayInstanceId;
createdAt: number;
};
canSeeSessionRow({
row,
requesterSessionKey,
visibility,
a2aPolicy,
});
ACPX Process Leases
Every generated wrapper launch should create a lease record:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
- root PID still exists
- live wrapper path is under
wrapperRoot - process group matches the lease when available
- arguments contain the expected lease id
- command hash or executable path matches the lease
type AcpxProcessLease = {
leaseId: string;
gatewayInstanceId: GatewayInstanceId;
sessionKey: string;
wrapperRoot: string;
wrapperPath: string;
rootPid: number;
processGroupId?: number;
commandHash: string;
startedAt: number;
state: "open" | "closing" | "closed" | "lost";
};
--openclaw-acpx-lease-id ... --openclaw-gateway-instance-id ...
Lifecycle Controller
Introduce one ACPX lifecycle controller that owns process leases and cleanup policy:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
interface AcpxLifecycleController {
ensureSession(input: AcpRuntimeEnsureInput): Promise<AcpRuntimeHandle>;
cancelTurn(handle: AcpRuntimeHandle): Promise<void>;
closeSession(input: {
handle: AcpRuntimeHandle;
discardPersistentState?: boolean;
reason?: string;
}): Promise<void>;
reapStartupOrphans(): Promise<void>;
verifyOwnedTree(lease: AcpxProcessLease): Promise<OwnedProcessTree | null>;
}
Wrapper Contract
Generated wrappers should stay small. They should:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
- start the adapter in a process group where supported
- forward normal termination signals to the process group
- detect parent death
- on parent death, send SIGTERM, then keep the wrapper alive until the SIGKILL
- report root PID and process group id back to the lifecycle controller when
Session Visibility Contract
Visibility should use normalized row ownership:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
self: only the requester session.tree: requester session plus rows owned by or spawned from the requester.all: all same-agent rows, a2a-allowed cross-agent rows, and requester-ownedagent: same agent only, unless an explicit owner relationship says the row
type SessionVisibilityInput = {
requesterSessionKey: string;
row: {
key: string;
agentId: string;
ownerSessionKey?: string;
spawnedBy?: string;
parentSessionKey?: string;
};
visibility: "self" | "tree" | "agent" | "all";
a2aPolicy: AgentToAgentPolicy;
};
Migration Plan
이 섹션의 세부 항목은 공식 문서 Migration Plan를 참고하세요.
Phase 1: Add Identity And Leases
주요 항목:
- Add
gatewayInstanceIdto Gateway state. - Add an ACPX lease store under the ACPX state directory.
- Write a lease before spawning a generated wrapper.
- Store
leaseIdon new ACPX session records. - Keep existing PID and command fields for old records.
Phase 2: Lease-First Cleanup
주요 항목:
- Change close cleanup to load
leaseIdfirst. - Verify live process ownership against the lease before signaling.
- Keep the current root PID and wrapper-root fallback only for legacy records.
- Mark leases
closedafter verified cleanup. - Mark leases
lostwhen the process is gone before cleanup.
Phase 3: Lease-First Startup Reaping
wrapper root and Gateway instance where possible.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
- Startup reaping scans open leases.
- For each lease, verify the root process and collect descendants.
- Reap verified trees children-first.
- Expire old
closedandlostleases with a bounded retention window. - Keep command-marker scanning only as a temporary legacy fallback, guarded by
Phase 4: Session Ownership Rows
주요 항목:
- Add ownership metadata to Gateway session rows.
- Teach ACPX, subagent, background-task, and session-store writers to populate
- Convert session visibility checks to use row metadata.
- Remove visibility-time secondary
sessions.list({ spawnedBy })lookups.
Phase 5: Remove Legacy Heuristics
주요 항목:
- stop relying on stored root command strings for non-legacy ACPX cleanup
- remove command-marker startup scans
- remove visibility fallback list lookups
- keep defensive fail-closed behavior for missing or unverifiable leases
Tests
The important invariant: a requester-owned spawned child is visible wherever the configured visibility includes the requester session tree, and all is not less capable than tree.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
- PID reused by unrelated process
- PID reused by another Gateway's wrapper root
- stored wrapper command is shell-quoted, live
pscommand is not - adapter child exits, grandchild remains in the process group
- parent death SIGTERM fallback reaches SIGKILL
- process listing unavailable
- stale lease with missing process
- startup orphan with wrapper, adapter child, and grandchild
self,tree,agent,all- a2a enabled and disabled
- same-agent row
- cross-agent row
- requester-owned spawned cross-agent ACP row
- sandboxed requester clamped to
tree - list, history, send, and status actions
Compatibility Notes
Old session records may not have leaseId. They should use the legacy fail-closed cleanup path:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
- require a live root process
- require wrapper-root ownership when a generated wrapper is expected
- require command agreement for non-wrapper roots
- never signal based only on stale stored PID metadata
Success Criteria
previously required one-off review fixes.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
- Closing an old or stale ACPX session cannot kill another Gateway's process.
- Parent death does not leave stubborn adapter grandchildren running.
cancelaborts the active turn without closing reusable sessions.sessions_listcan show requester-owned cross-agent ACP children under both- Startup cleanup is driven by leases, not broad command-string scans.
- The focused process and visibility matrix tests cover every edge case that
실습 체크리스트
- 공식 문서와 로컬 버전을 대조합니다:
https://docs.openclaw.ai/refactor/acp - 관련 CLI는
openclaw --help및 하위 명령--help로 옵션을 확인합니다. - 설정 변경 시
openclaw config/openclaw doctor로 유효성을 검사합니다. - Gateway·채널·플러그인 변경 후에는 필요 시 Gateway를 재시작합니다.
자주 쓰는 명령·설정 예시
type GatewayInstanceId = string;
type AcpSessionOwner = {
sessionKey: string;
spawnedBy?: string;
parentSessionKey?: string;
ownerSessionKey: string;
agentId: string;
backend: "acpx";
gatewayInstanceId: GatewayInstanceId;
createdAt: number;
};
canSeeSessionRow({
row,
requesterSessionKey,
visibility,
a2aPolicy,
});
type AcpxProcessLease = {
leaseId: string;
gatewayInstanceId: GatewayInstanceId;
sessionKey: string;
wrapperRoot: string;
wrapperPath: string;
rootPid: number;
processGroupId?: number;
commandHash: string;
startedAt: number;
state: "open" | "closing" | "closed" | "lost";
};
--openclaw-acpx-lease-id ... --openclaw-gateway-instance-id ...
interface AcpxLifecycleController {
ensureSession(input: AcpRuntimeEnsureInput): Promise<AcpRuntimeHandle>;
cancelTurn(handle: AcpRuntimeHandle): Promise<void>;
closeSession(input: {
handle: AcpRuntimeHandle;
discardPersistentState?: boolean;
reason?: string;
}): Promise<void>;
reapStartupOrphans(): Promise<void>;
verifyOwnedTree(lease: AcpxProcessLease): Promise<OwnedProcessTree | null>;
}
관련 링크
- 공식 원문: refactor/acp
- OpenClaw 문서 홈
이 가이드는 공식 문서를 한국어 학습용으로 재구성한 것입니다. 옵션 기본값·플래그 이름은 설치 버전에 따라 달라질 수 있습니다.