/** * The slice of `createApps`' closure its modules read. * * `createApps` is an ASSEMBLER: every door it returns, and every helper those * doors lean on, lives in a module beside its contract and is handed the pieces * of the closure it needs. Every one of them names its dependencies as a `Pick` * of this one type, and returns a `Pick` of it too, which keeps a single * description of what the closure offers and lets `createRuntimeContext` below * wire them in dependency order. * * Internal — not exported from the package root. */ import { type AccessLevel, type AppId, type Json, type RunContext, type VendoRecord } from "@vendoai/core"; import type { AppDocument, AdmissionOrigin } from "../../contract/index.js"; import { type EngineOps } from "../persistence/engine.js"; import { createAutomationLane } from "../automation/lane.js"; import { type AppCaller } from "../persistence/call.js"; import type { GenerationDependencies } from "../generation/engine.js"; import { type AppHistoryAccess } from "../persistence/history.js"; import { type AppInterchange } from "../persistence/interchange.js"; import { type AppSqlAccess } from "../persistence/app-sql.js"; import { createAppOpener } from "../persistence/open.js"; import { type ParkedActions } from "../persistence/parked-action.js"; import { type ParkedBuilds } from "../persistence/parked-build.js"; import { type BuildDoor } from "../doors/build-door.js"; import { type PlacementRow, type PlacementStore } from "../persistence/placements.js"; import { type SlotRegistry } from "../persistence/slots.js"; import type { AppsConfig, AppsRuntime, EditResult, PlacementEntry, VersionEntry } from "./types.js"; export interface AppsRuntimeContext { config: AppsConfig; /** Vendo's own drawers, by name — `vendo_apps` above all (engine.ts). */ engine: EngineOps; /** Placement rows — "show this app in that slot" (placements.ts). */ placementRows: PlacementStore; /** The host's mounted slots, reported by the surfaces that render them * (slots.ts). Beside placementRows because it answers the other half of the * same question: which slots EXIST, not which app is in one. */ slots: SlotRegistry; /** The app's own SQL database, when one is composed (app-sql.ts). */ sql: AppSqlAccess | undefined; /** The capped version log and its pin-intent trail (history.ts). */ history: AppHistoryAccess; /** W0 — the undecided in-app actions the guard parked (parked-action.ts). */ parkedActions: ParkedActions; /** S3 — the builds that have been OFFERED and not answered (parked-build.ts). */ parkedBuilds: ParkedBuilds; /** S3 — propose/resume/seal. Built before the approval flow, which subscribes * to the decision that fires `resume` (build-door.ts). */ build: BuildDoor; /** Export/import of an app and its documents (interchange.ts). */ interchange: AppInterchange; /** The guard-bound caller every query and action rides. */ caller: AppCaller; /** The one read path a client opens an app through (open.ts). */ opener: ReturnType; /** Bounded read-mutate-CAS on the app row. */ updateAppDocument(appId: AppId, mutate: (doc: AppDocument) => AppDocument): Promise; /** Build contract §9.3 — the ONE permission check. */ holds(appId: AppId, ctx: RunContext, level: AccessLevel, known?: VendoRecord | null): Promise; /** The document, when this caller holds it at `level` — otherwise null. */ owned(appId: AppId, ctx: RunContext, level?: AccessLevel): Promise; /** §9.4's posture: unviewable stays `not-found`, a denied viewer gets `forbidden`. */ requireOwned(appId: AppId, ctx: RunContext, level?: AccessLevel): Promise; /** The app rows this caller reaches WITHOUT owning them (§9.3). */ grantedRecords(ctx: RunContext, already: Set): Promise; /** An app-lifecycle audit event under an explicit subject. */ reportGuard(principalSubject: string, appId: AppId, ctx: Pick, detail: Record): Promise; /** The `app-lifecycle` audit kind, under the calling principal. */ reportLifecycle(operation: "create" | "delete" | "fork" | "seed" | "reseed" | "machine-provision" | "place" | "unplace", appId: AppId, ctx: RunContext, extra?: Record): Promise; /** The layer ladder, derived from the document (never a stored rung). */ rungFor(app: AppDocument, declared?: VersionEntry["rung"]): VersionEntry["rung"]; /** 06-apps §8 — every edit result over a drifted app carries the drift report. */ /** An edit result that persisted nothing, with the drift report attached. */ failedEdit(app: AppDocument, instruction: string, issues: string[], retryable?: boolean): EditResult; /** The ONE document write: version append, optimistic concurrency, row put. */ persistEdit(previous: AppDocument, app: AppDocument, version: VersionEntry, subject: string, options: { origin: AdmissionOrigin; }): Promise; /** Build contract §9.9 — the ONE announcement every change to what an app IS. */ reportDocumentEdit(previous: AppDocument, next: AppDocument, subject: string): Promise; /** Drop a version the write it was appended FOR never landed for. */ discardVersion(appId: AppId, versionId: string): Promise; /** The 50-version cap, applied once the newest version's write has landed. */ pruneHistory(appId: AppId): Promise; /** The person's own words for a save THIS runtime asked the assembler for. */ editIntents: Map; /** The version row an edit's own save APPENDED, keyed by app. */ editVersions: Map; /** Why an edit's own save did NOT land, keyed by app. */ editRefusals: Map; /** The source a RE-SEED's replay starts from, published for that replay only. */ replaySources: Map; /** THIS edit's captured row, or nothing. */ takeEditVersion(appId: AppId, instruction: string): VersionEntry | undefined; /** THIS replay's starting source, or nothing — gone once read. */ takeReplaySource(appId: AppId): string | undefined; /** ONE instruction through the ONE builder. */ assembleEdit(appId: AppId, instruction: string, ctx: RunContext): Promise<{ kind: "assembled"; app: AppDocument; say?: string; } | { kind: "escalate"; why: string; } | { kind: "failed"; issues: string[]; }>; /** The host tool list and the live shape cards a generation runs against. */ generationToolContext(ctx: RunContext): Promise>; /** Author one automation onto a STORED app: plan, land, arm, audit. */ authorAutomation: ReturnType; /** A host-authored slot name, checked at the one place every caller passes. */ requireSlot(slot: string): string; /** B1 — claim the slot the moment the app id EXISTS. */ claimSlot(appId: AppId, slot: string, ctx: RunContext): Promise; /** The terminal record for an id no engine will ever land. */ markUnbuilt(appId: AppId, name: string, reason: string, ctx: RunContext): Promise; /** An assembler run has started for this id, for this person — * `AppDocument.building`, and the app-database door's mid-mint owner. */ beginBuild(appId: AppId, subject: string): void; /** Whether one is running right now, which is what makes a screen's first * painting save a BUILD's rather than a harness's. */ buildingNow(appId: AppId): boolean; /** Whether THIS caller is the one building this id right now — the only owner * an app that has no row yet can have. */ buildingFor(appId: AppId, ctx: RunContext): boolean; /** The assembler came back, so the row may mount — `AppDocument.building`. */ settleBuild(appId: AppId): Promise; /** Where a placed app's build stands, read off its record every time. */ entryFor(row: PlacementRow, ctx: RunContext): Promise; /** * The finished runtime, as a thunk. A surface is constructed while the * `AppsRuntime` object literal is still forming, so the public doors one of * them re-enters (`pins.fork` runs an ordinary `edit`) resolve on call. */ runtime(): AppsRuntime; } /** 06-apps §1 — `createApps`' closure, wired in dependency order. */ export declare const createRuntimeContext: (config: AppsConfig, runtime: () => AppsRuntime) => AppsRuntimeContext; //# sourceMappingURL=runtime-context.d.ts.map