Main no longer opens desktop business SQLite. A single utility-process
storage owner holds the Assistant, Knowledge, attachment, document-result,
remote-binding and native model-ledger databases and runs whole domain
transactions; Main and Runtime callers use explicit async domain operations.
- Remove the Main readWithFallback path and the supervision worker's
separate business write connection; manifests are scanned read-only and
committed by the sole writer.
- Remote events are ACKed only after commit; process loss reports
unconfirmed writes instead of replaying them.
- Use native utilityProcess messaging with one in-flight bound (32) and
ordered waiting instead of capacity rejection and retries.
- Start the storage process before the window so startup overlaps.
- Keep short tool output in memory and store full output once in owned
storage; paging, branching, restart and deletion reuse that copy.
- Put required runtime launch files under goodbuddy-prefixed owned temp
directories and reclaim confirmed stale ones; stop writing duplicate
parsed.md.
- Add lint guards for SQLite ownership and architecture, concurrency
acceptance fixtures, and maintenance/architecture documentation.
Validation: typecheck and lint pass. Alternating baseline (edf019aa) vs
candidate runs show no regression on single-session, C01, C02, C04 and a
5-minute C06; Main p99 drops from ~21 ms to ~16.7 ms under concurrency.
Fresh portable copy (1.75M events) upgrade content unchanged; real-model
output paging passes with 4 external requests. Full npm test runs had
1-9 different timing-sensitive failures per run that pass when rerun.
Not covered: C03 review publication, C07 source body, app-level C05.
219 lines
6.9 KiB
TypeScript
219 lines
6.9 KiB
TypeScript
import type { RuntimeSessionBindingStore } from '../agent/runtime-session-binding-store'
|
|
import type { ResolvedModelProfile } from '../runtime-settings-store'
|
|
import type {
|
|
AgentRuntimeSelection,
|
|
RuntimeSelectionLayer
|
|
} from '../../shared/runtime-selection-contracts'
|
|
import type { SshHostStore } from '../ssh/ssh-host-store'
|
|
import {
|
|
resolveBundledRemoteRuntimeResourcePaths,
|
|
type BundledRemoteRuntimeResourcePaths
|
|
} from './bundled-remote-runtime-resources'
|
|
import { ManagedRemoteProjectRuntimeValidator } from './managed-remote-project-runtime-validator'
|
|
import {
|
|
createManagedRemoteAcpRuntime,
|
|
type ManagedRemoteAcpRuntimeOptions
|
|
} from './managed-remote-acp-runtime'
|
|
import { ManagedRemoteWorkspaceAccessFactory } from './managed-remote-workspace-access-factory'
|
|
import type { RemoteAgentServices } from './remote-agent-services'
|
|
import { RemoteProjectSaveService } from './remote-project-save-service'
|
|
import {
|
|
RemoteRuntimeInstallationManager,
|
|
type RemoteRuntimeActivator
|
|
} from './remote-runtime-installation-manager'
|
|
import {
|
|
createManagedModelBridge
|
|
} from './managed-model-bridge'
|
|
import { boundedDiagnostic } from './bounded-diagnostic'
|
|
|
|
export type ManagedRemoteExecutionServicesOptions = {
|
|
bindingStore: RuntimeSessionBindingStore
|
|
sshHostStore: SshHostStore
|
|
agentServices: Pick<
|
|
RemoteAgentServices,
|
|
| 'targetResolver'
|
|
| 'sshPool'
|
|
| 'installationManager'
|
|
| 'connectionManager'
|
|
| 'controllerState'
|
|
>
|
|
appPath: string
|
|
resourcesPath: string
|
|
packaged: boolean
|
|
resolveModelProfile(
|
|
selection: AgentRuntimeSelection
|
|
): Promise<ResolvedModelProfile | undefined>
|
|
resolveRuntimeSelection(
|
|
layer: RuntimeSelectionLayer | undefined
|
|
): Promise<AgentRuntimeSelection>
|
|
}
|
|
|
|
/**
|
|
* Main-only lifecycle owner for verified remote execution primitives.
|
|
* Construction performs no SSH or provider work.
|
|
*/
|
|
export class ManagedRemoteExecutionServices {
|
|
readonly runtimeResourcePaths: BundledRemoteRuntimeResourcePaths
|
|
readonly runtimeInstallationManager: RemoteRuntimeInstallationManager
|
|
readonly runtimeValidator: ManagedRemoteProjectRuntimeValidator
|
|
readonly workspaceAccessFactory: ManagedRemoteWorkspaceAccessFactory
|
|
readonly bindingStore: RuntimeSessionBindingStore
|
|
|
|
#disposePromise?: Promise<void>
|
|
readonly #readiness: Promise<void>
|
|
readonly #resolveRuntimeSelection: ManagedRemoteExecutionServicesOptions['resolveRuntimeSelection']
|
|
readonly #sshHosts: SshHostStore
|
|
readonly #agentServices:
|
|
ManagedRemoteExecutionServicesOptions['agentServices']
|
|
|
|
constructor(options: ManagedRemoteExecutionServicesOptions) {
|
|
this.#agentServices = options.agentServices
|
|
this.#resolveRuntimeSelection = options.resolveRuntimeSelection
|
|
this.#sshHosts = options.sshHostStore
|
|
this.runtimeResourcePaths =
|
|
resolveBundledRemoteRuntimeResourcePaths({
|
|
appPath: options.appPath,
|
|
resourcesPath: options.resourcesPath,
|
|
packaged: options.packaged
|
|
})
|
|
const activate: RemoteRuntimeActivator = async (
|
|
lease,
|
|
runtimeId,
|
|
bundleDigest,
|
|
architecture,
|
|
currentAgentInstallationId,
|
|
signal
|
|
) => {
|
|
const agentInstallationId =
|
|
currentAgentInstallationId ??
|
|
(
|
|
await options.agentServices.installationManager.activateInstalled(
|
|
lease.identity.hostId,
|
|
{ signal }
|
|
)
|
|
).installationId
|
|
signal.throwIfAborted()
|
|
if (runtimeId !== 'opencode' && runtimeId !== 'continue') {
|
|
throw new Error(
|
|
'Remote Runtime identity is unsupported'
|
|
)
|
|
}
|
|
const result = await lease.runAgentRuntimeAction(
|
|
agentInstallationId,
|
|
{
|
|
kind: 'runtime-activate',
|
|
runtimeId,
|
|
bundleDigest,
|
|
architecture
|
|
},
|
|
signal
|
|
)
|
|
if (result.exitCode !== 0) {
|
|
const detail = boundedDiagnostic(
|
|
`${result.stderr}\n${result.stdout}`
|
|
)
|
|
throw new Error(
|
|
detail.length > 0
|
|
? `Remote Runtime activation failed: ${detail}`
|
|
: `Remote Runtime activation failed (exit ${String(result.exitCode)})`
|
|
)
|
|
}
|
|
}
|
|
this.runtimeInstallationManager =
|
|
new RemoteRuntimeInstallationManager({
|
|
resolver: options.agentServices.targetResolver,
|
|
sshPool: options.agentServices.sshPool,
|
|
activate
|
|
})
|
|
this.runtimeValidator = new ManagedRemoteProjectRuntimeValidator({
|
|
installationManager: this.runtimeInstallationManager,
|
|
resolveModelProfile: options.resolveModelProfile
|
|
})
|
|
this.workspaceAccessFactory =
|
|
new ManagedRemoteWorkspaceAccessFactory({
|
|
connectionManager: options.agentServices.connectionManager,
|
|
installationManager:
|
|
options.agentServices.installationManager
|
|
})
|
|
this.bindingStore = options.bindingStore
|
|
this.#readiness = Promise.resolve()
|
|
}
|
|
|
|
createProjectSaveService(
|
|
options: Pick<
|
|
ConstructorParameters<typeof RemoteProjectSaveService>[0],
|
|
'database' | 'notify'
|
|
>
|
|
): RemoteProjectSaveService {
|
|
return new RemoteProjectSaveService({
|
|
database: options.database,
|
|
sshHosts: this.#sshHosts,
|
|
installationManager:
|
|
this.#agentServices.installationManager,
|
|
connectionManager: this.#agentServices.connectionManager,
|
|
resolveRuntimeSelection: this.#resolveRuntimeSelection,
|
|
runtimeValidator: this.runtimeValidator,
|
|
...(options.notify ? { notify: options.notify } : {})
|
|
})
|
|
}
|
|
|
|
async initialize(): Promise<void> {
|
|
await this.#readiness
|
|
}
|
|
|
|
invalidateHost(hostId: string): void {
|
|
this.runtimeInstallationManager.invalidateHost(hostId)
|
|
}
|
|
|
|
async createRuntime(
|
|
options: Pick<
|
|
ManagedRemoteAcpRuntimeOptions,
|
|
'executionSpace' | 'selection' | 'usage'
|
|
> & {
|
|
modelProfile: ResolvedModelProfile
|
|
}
|
|
) {
|
|
await this.#readiness
|
|
const modelBridge = createManagedModelBridge({
|
|
profile: options.modelProfile
|
|
})
|
|
return createManagedRemoteAcpRuntime({
|
|
...options,
|
|
modelBridge,
|
|
agentServices: {
|
|
connectionManager: this.#agentServices.connectionManager,
|
|
controllerState: this.#agentServices.controllerState,
|
|
installationManager:
|
|
this.#agentServices.installationManager
|
|
},
|
|
runtimeInstallationManager: this.runtimeInstallationManager,
|
|
bindingStore: this.bindingStore
|
|
})
|
|
}
|
|
|
|
dispose(): Promise<void> {
|
|
this.#disposePromise ??= this.#dispose()
|
|
return this.#disposePromise
|
|
}
|
|
|
|
async #dispose(): Promise<void> {
|
|
const errors: unknown[] = []
|
|
const settle = async (
|
|
operation: () => void | Promise<void>
|
|
): Promise<void> => {
|
|
try {
|
|
await operation()
|
|
} catch (error) {
|
|
errors.push(error)
|
|
}
|
|
}
|
|
await settle(() => this.runtimeInstallationManager.dispose())
|
|
if (errors.length > 0) {
|
|
throw new AggregateError(
|
|
errors,
|
|
'Managed remote execution services failed to dispose completely'
|
|
)
|
|
}
|
|
}
|
|
}
|