Get started
Refactor van de ACP-levenscyclus
De ACP-levenscyclus werkt momenteel, maar te veel ervan wordt achteraf afgeleid.
Procesopschoning reconstrueert eigenaarschap op basis van PID's, commandoreeksen, wrapper-
paden en de live procestabel. Sessiezichtbaarheid reconstrueert eigenaarschap
op basis van sessiesleutelreeksen plus secundaire sessions.list({ spawnedBy })-lookups.
Dat maakt gerichte fixes mogelijk, maar zorgt er ook voor dat randgevallen gemakkelijk worden gemist:
PID-hergebruik, commando's met aanhalingstekens, kleinkinderen van adapters, statusroots met meerdere Gateways,
cancel versus close, en tree versus all-zichtbaarheid worden allemaal afzonderlijke
plekken om dezelfde eigendomsregels opnieuw te ontdekken.
Deze refactor maakt eigenaarschap eersteklas. Het doel is geen nieuw ACP-productoppervlak; het is een veiliger intern contract voor het bestaande ACP- en ACPX-gedrag.
Doelen
- Opschoning stuurt nooit een signaal naar een proces tenzij huidig live bewijs overeenkomt met een lease die eigendom is van OpenClaw.
cancel,closeen opruimen bij opstarten hebben afzonderlijke levenscyclusintenties.sessions_list,sessions_history,sessions_senden statuscontroles gebruiken hetzelfde sessiemodel dat eigendom is van de aanvrager.- Installaties met meerdere Gateways kunnen elkaars ACPX-wrappers niet opruimen.
- Oude ACPX-sessierecords blijven werken tijdens migratie.
- De runtime blijft eigendom van de Plugin; de kern leert geen ACPX-pakketdetails.
Niet-doelen
- ACPX vervangen of het openbare
/acp-commando-oppervlak wijzigen. - Leveranciersspecifiek ACP-adaptergedrag naar de kern verplaatsen.
- Vereisen dat gebruikers handmatig status opschonen voordat ze upgraden.
- Ervoor zorgen dat
cancelherbruikbare ACP-sessies sluit.
Doelmodel
Gateway-instantie-identiteit
Elk Gateway-proces zou een stabiele runtime-instantie-id moeten hebben:
type GatewayInstanceId = string;
Die kan worden gegenereerd bij het opstarten van de Gateway en worden bewaard in de status voor de levensduur van die installatie. Het is geen beveiligingsgeheim; het is een eigendomsdiscriminator die wordt gebruikt om te voorkomen dat ACP-processen van de ene Gateway worden verward met processen van een andere Gateway.
ACP-sessie-eigenaarschap
Elke gespawnde ACP-sessie zou genormaliseerde eigendomsmetadata moeten hebben:
type AcpSessionOwner = {
sessionKey: string;
spawnedBy?: string;
parentSessionKey?: string;
ownerSessionKey: string;
agentId: string;
backend: "acpx";
gatewayInstanceId: GatewayInstanceId;
createdAt: number;
};
De Gateway zou deze velden moeten retourneren op sessierijen waar ze bekend zijn. Zichtbaarheidsfiltering zou een pure controle over rijmetadata moeten zijn:
canSeeSessionRow({
row,
requesterSessionKey,
visibility,
a2aPolicy,
});
Dat verwijdert verborgen secundaire sessions.list({ spawnedBy })-aanroepen uit
zichtbaarheidscontroles. Een gespawnd cross-agent ACP-kind is eigendom van de aanvrager omdat
de rij dat zegt, niet omdat een tweede query het toevallig vindt.
ACPX-procesleases
Elke gegenereerde wrapperstart zou een leaserecord moeten maken:
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";
};
Het wrapperproces zou de lease-id en Gateway-instantie-id in zijn omgeving moeten ontvangen:
OPENCLAW_ACPX_LEASE_ID=...
OPENCLAW_GATEWAY_INSTANCE_ID=...
Wanneer het platform dit toestaat, zou verificatie de voorkeur moeten geven aan live procesmetadata die niet door commando-aanhalingstekens kunnen worden verward:
- root-PID bestaat nog
- live wrapperpad valt onder
wrapperRoot - procesgroep komt overeen met de lease wanneer beschikbaar
- omgeving bevat de verwachte lease-id wanneer leesbaar
- commandohash of uitvoerbaar pad komt overeen met de lease
Als het live proces niet kan worden geverifieerd, faalt opschoning gesloten.
Levenscycluscontroller
Introduceer één ACPX-levenscycluscontroller die procesleases en opschoningsbeleid beheert:
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>;
}
cancelTurn vraagt alleen annulering van de beurt aan. Het mag herbruikbare wrapper-
of adapterprocessen niet opruimen.
closeSession mag opruimen, maar alleen na het laden van het sessierecord,
het laden van de lease en het verifiëren dat de live procesboom nog bij die
lease hoort.
reapStartupOrphans begint bij open leases in de status. Het mag de procestabel
gebruiken om descendants te vinden, maar het zou niet eerst willekeurige commando's
moeten scannen die op ACP lijken en daarna beslissen dat ze waarschijnlijk van ons zijn.
Wrappercontract
Gegenereerde wrappers moeten klein blijven. Ze moeten:
- de adapter starten in een procesgroep waar ondersteund
- normale beëindigingssignalen doorsturen naar de procesgroep
- overlijden van de ouder detecteren
- bij overlijden van de ouder SIGTERM sturen en vervolgens de wrapper in leven houden totdat de SIGKILL- fallback wordt uitgevoerd
- root-PID en procesgroep-id terugrapporteren aan de levenscycluscontroller wanneer dat beschikbaar is
Wrappers moeten geen sessiebeleid bepalen. Ze handhaven alleen lokale opschoning van procesbomen voor hun eigen adaptergroep.
Sessiezichtbaarheidscontract
Zichtbaarheid moet genormaliseerd rijeigenaarschap gebruiken:
type SessionVisibilityInput = {
requesterSessionKey: string;
row: {
key: string;
agentId: string;
ownerSessionKey?: string;
spawnedBy?: string;
parentSessionKey?: string;
};
visibility: "self" | "tree" | "agent" | "all";
a2aPolicy: AgentToAgentPolicy;
};
Regels:
self: alleen de aanvragersessie.tree: aanvragersessie plus rijen die eigendom zijn van of gespawnd zijn vanuit de aanvrager.all: alle rijen van dezelfde agent, a2a-toegestane cross-agent-rijen en door de aanvrager beheerde gespawnde cross-agent-rijen, zelfs wanneer algemene a2a is uitgeschakeld.agent: alleen dezelfde agent, tenzij een expliciete eigendomsrelatie zegt dat de rij bij de aanvrager hoort.
Dit maakt tree en all monotoon: all mag geen eigendomskind verbergen dat
tree zou tonen.
Migratieplan
Fase 1: Identiteit En Leases Toevoegen
- Voeg
gatewayInstanceIdtoe aan Gateway-status. - Voeg een ACPX-leasestore toe onder de ACPX-statusmap.
- Schrijf een lease voordat een gegenereerde wrapper wordt gespawnd.
- Sla
leaseIdop in nieuwe ACPX-sessierecords. - Behoud bestaande PID- en commandovelden voor oude records.
Fase 2: Lease-Eerste Opschoning
- Wijzig sluitopschoning om eerst
leaseIdte laden. - Verifieer live proceseigenaarschap tegen de lease voordat signalen worden gestuurd.
- Behoud de huidige root-PID- en wrapper-root-fallback alleen voor legacy-records.
- Markeer leases als
closedna geverifieerde opschoning. - Markeer leases als
lostwanneer het proces vóór opschoning verdwenen is.
Fase 3: Lease-Eerst Opruimen Bij Opstarten
- Opruimen bij opstarten scant open leases.
- Verifieer voor elke lease het rootproces en verzamel descendants.
- Ruim geverifieerde bomen kinderen-eerst op.
- Laat oude
closed- enlost-leases verlopen met een begrensde retentieperiode. - Behoud scannen met commandomarkers alleen als tijdelijke legacy-fallback, bewaakt door wrapper-root en Gateway-instantie waar mogelijk.
Fase 4: Sessierijen Voor Eigenaarschap
- Voeg eigendomsmetadata toe aan Gateway-sessierijen.
- Leer ACPX-, subagent-, achtergrondtaak- en sessiestore-schrijvers om
ownerSessionKeyofspawnedByte vullen. - Zet sessiezichtbaarheidscontroles om naar gebruik van rijmetadata.
- Verwijder secundaire
sessions.list({ spawnedBy })-lookups tijdens zichtbaarheidscontrole.
Fase 5: Legacy-Heuristieken Verwijderen
Na één releaseperiode:
- stop met vertrouwen op opgeslagen root-commandoreeksen voor niet-legacy ACPX-opschoning
- verwijder commandomarker-scans bij opstarten
- verwijder fallback-listlookups voor zichtbaarheid
- behoud defensief fail-closed-gedrag voor ontbrekende of niet-verifieerbare leases
Tests
Voeg twee tabelgestuurde suites toe.
Simulator voor proceslevenscyclus:
- PID hergebruikt door niet-gerelateerd proces
- PID hergebruikt door wrapper-root van een andere Gateway
- opgeslagen wrappercommando is shell-gequote, live
ps-commando is dat niet - adapterkind sluit af, kleinkind blijft in de procesgroep
- SIGTERM-fallback bij overlijden van ouder bereikt SIGKILL
- proceslijst niet beschikbaar
- verouderde lease met ontbrekend proces
- opstartwees met wrapper, adapterkind en kleinkind
Matrix voor sessiezichtbaarheid:
self,tree,agent,all- a2a ingeschakeld en uitgeschakeld
- rij van dezelfde agent
- cross-agent-rij
- door aanvrager beheerde gespawnde cross-agent ACP-rij
- gesandboxte aanvrager beperkt tot
tree - lijst-, geschiedenis-, verzend- en statusacties
De belangrijke invariant: een door de aanvrager beheerd gespawnd kind is zichtbaar overal waar
de geconfigureerde zichtbaarheid de sessieboom van de aanvrager omvat, en all is niet
minder capabel dan tree.
Compatibiliteitsnotities
Oude sessierecords hebben mogelijk geen leaseId. Ze moeten het legacy
fail-closed-opschoningspad gebruiken:
- vereis een live rootproces
- vereis wrapper-root-eigenaarschap wanneer een gegenereerde wrapper wordt verwacht
- vereis commando-overeenkomst voor niet-wrapper-roots
- stuur nooit signalen alleen op basis van verouderde opgeslagen PID-metadata
Als een legacy-record niet kan worden geverifieerd, laat het dan met rust. Startup-leaseopschoning en de volgende releaseperiode zouden de fallback uiteindelijk moeten uitfaseren.
Succescriteria
- Het sluiten van een oude of verouderde ACPX-sessie kan geen proces van een andere Gateway doden.
- Overlijden van de ouder laat geen hardnekkige adapterkleinkinderen actief.
cancelbreekt de actieve beurt af zonder herbruikbare sessies te sluiten.sessions_listkan door de aanvrager beheerde cross-agent ACP-kinderen tonen onder zoweltreealsall.- Opschoning bij opstarten wordt aangestuurd door leases, niet door brede scans van commandoreeksen.
- De gerichte proces- en zichtbaarheidsmatrixtests dekken elk randgeval dat eerder eenmalige reviewfixes vereiste.