11 KiB
Foundry service integration evidence
Status: steps 5 (service) and 6 (migration/delivery) completed; overall progress is 6/7. The complete Draft acceptance matrix, main integration and production deployment are not complete.
Verified revisions and environment
- Current delivered Endoleap consumer:
24c45920602378d52a42cda7e8ec2840864c8dbd. - Current Foundry:
5db2bf3c98f2627139cbb6d47afefa686b4c6547. - Foundry CI #1182:
job 1279 completed successfully, all seven steps successful, pinned to the
current delivered consumer. Its report has all document/resource/AI and
migration flags true,
aiExecutionCount: 3, and 75 transport calls. Same-commit PR CI #1183/job 1280 was still running at this audit. - Foundry CI #1180
and PR CI #1181:
completed successfully for consumer
26da326and Foundry3268c57; jobs 1277/1278, all seven steps successful. The original service scope audit also passed CI #1178 and #1179. - Existing
ces-controlrunner executes Go checks/build, schema migration and isolated PostgreSQL integration, then the pinned Node 24 consumer and HTTP smoke checks. No local backend build or Docker execution was used. - Local frontend: 802 Node tests and full TypeScript checking passed. Tests use the source modules; packaged SDK and application delivery remain separate gates.
What the checks actually prove
| Requirement | Authoritative entry and observed assertion |
|---|---|
| Explicit identity migration | TestCanonicalModelMigrationAndIncrementalLifecycle: GET does not migrate; retry returns the same identity map; implicit partitions become owning canvases; old snapshot writers are rejected. The real Node consumer also migrates and retries. |
| Migration admission and late rollback | TestCanonicalMigrationPermissionVersionAndRunGuards checks viewer denial, stale source versions, queued/running work and stable negative receipts after conditions change. TestCanonicalMigrationLateCancellationRollsBack observes the actual identity-map INSERT blocked after canonical/material/subgraph writes, cancels it, then checks all related rows, original legacy JSON and version before retrying the original key successfully. |
| Incremental writes and receipt identity | TestCanonicalModelMigrationAndIncrementalLifecycle verifies exact retries, unknown receipt semantics, logical ID coverage, participant versions, and zero writes/logical-ID consumption after a later batch condition fails. It checks canonical DB rows, not just HTTP status. |
| Canonical concurrent writers | TestCanonicalConcurrentMigrationAndOwnershipWrites races four identical migrations, then four identical edits, requiring identical receipts and one version advance. Two different requests then compete to move alternate endpoints and their common edge: exactly one wins, the loser has a queryable terminal version-conflict receipt, both canvas versions advance once, and the full ownership graph remains valid. Reusing the winning key with changed bytes is rejected without changing the model. |
| Real frontend coordination | TestHeadlessClientHTTPIntegration runs tests/headless/foundry.integration.mjs against authenticated HTTP and PostgreSQL. It verifies lost document ACK recovery without duplicate POST, atomic partition edits, deep copy with a parent-owned incoming edge, partial import and old stream-tail coordination. |
| Resources and authorization | The consumer verifies lost upload ACK, shared pending-image upload, original bytes, metadata, cross-project adoption and reopen. TestOnboardingAndSharing additionally revokes source access after warm reads, verifies no target model/version/binding changes, preserves the rejected receipt after permission restoration, and checks independent target access. |
| AI execution identity and controls | TestCanonicalAIAdmissionAndLifecycle covers admission/query/retry, zero-effect rejection, old incarnation callbacks, cancellation, managed image output, owner relocation, archived admission routes and execution after permission revocation. |
| Actual frontend RunPort | tests/headless/foundry-ai.integration.mjs exercises createFoundryRuns, the HTTP transport and ProjectEngine: successful admission response loss/reopen/query, queued cancellation response loss, generation-time content conflict, explicit apply response loss plus undo/reopen/redo, generated image metadata/original bytes/preview, and copy without a new run or upload. |
| Host identity migration coordination | canvas-migration.ts now drives the real consumer's initial migration: the server commits, the response is lost, a new coordinator reads the stored body/key and queries the original receipt without a second POST. A later intentional raw POST still checks backend idempotent retry. The coordinator's drain and lock ports are fixtures here; this does not prove the old editor's browser handoff gate is connected. |
| Browser legacy handoff | renderer.integration.mjs --migration-only exercises the actual GraphPage, legacy editor, upgrade panel and Next proxy with native Chrome input, localStorage and Web Locks. Dirty old PATCH ACK precedes migration; another editable view excludes migration; committed response loss survives reload without a second migration POST; uncommitted response loss reuses the original body/key, with terminal rejection followed by explicit fresh preparation; a different cached draft must be explicitly restored before migration. A draft modal cannot block receipt recovery; it becomes actionable after terminal rejection. The upstream is a protocol fixture, not the real Foundry service. |
The CI #1174 consumer report contains status: "ok", 72 HTTP transport calls,
all 14 prior document/resource flags true, plus runtimeAI, aiLostAdmission,
aiCancelReconciled, aiConflictApplyUndo, aiManagedImage, aiCopyNoRun true.
aiExecutionCount is exactly 3: text, retained conflict output, image. The queued
cancelled run never calls generation. Preview fetching is a separate authenticated
host fetch and is not included in the 72 transport calls.
CI #1178 repeated the same pinned consumer successfully with 71 transport calls
and the same flags/execution count. Timing-dependent poll counts are observations,
not an exact total-call contract; admission/action/upload duplication has separate
explicit assertions.
CI #1180 additionally reports migrationCoordinator and
migrationLostAckRecovered true, with 76 transport calls and the same document,
resource and AI results. The local coordinator suite covers 11 cases, including
quota/no-write behavior, uncommitted-request recovery, invalid receipt retention,
identity/abort fences and terminal rejection followed by explicit preparation.
Issues exposed by the real consumer
- The standalone AI client omitted the v2 Accept header. The Next proxy had
supplied it, hiding the omission in application-only testing.
canvas-v2negotiation now belongs to the AI adapter and shared transport; regression tests cover all three writes and receipt queries with original body/key/version. - Asset display URLs assumed the application's relative preview route. The
asset adapter now accepts a host
displayURL(id)callback. Canonical source identity and authority remain separate; preview bytes are not used as original file digest evidence. Authentication stays in the host fetch/transport.
The test harness also needed working controlled timers, a cancelled run's final event drain before the next admission, and actual copy-source file persistence. The adoption stage still asserts zero project-local file writes. The subsequent copy stage permits source checkpoints but rejects bitmap file duplication and asserts no extra upload or generation. Those fixes do not bypass busy, cursor, durability or resource-sharing checks.
Boundaries and remaining audit
The recovery store is an in-memory durable-batch fixture, and response loss is
injected after successful HTTP responses. Real IndexedDB/Web Locks/browser
acceptance is recorded separately in STEP4_ACCEPTANCE.md; this service run does
not combine every browser crash window with every server operation.
The migration coordinator uses a string-storage port before a canonical engine
exists. browser-canvas-migration.ts supplies localStorage, identity fences and
workspace-scoped native Web Locks. Every editable legacy view holds a shared
lease; upgrade first freezes and drains its writer, releases that lease, then
takes the exclusive lease and prepares again before creating a request. Pending
records block affected legacy views across reload. Unknown results retain the
original request; only a verified terminal rejection permits fresh preparation.
Upload/import/member-task and draft-recovery gates preserve the old editor's
content rather than converting in-memory work silently. A differing cached draft
is surfaced for explicit recovery, and the current draft is backed up before
waiting for its PATCH ACK. The account fence also covers old snapshot requests.
The browser fixture above proves the connected UI path, including actual native locking, and the separate real-service consumer proves server coordination. They do not combine a real browser and real PostgreSQL in one scenario. Full webpack and Turbopack application regressions each passed 51 checks; the migration entry adds five scenarios and three lock-lifetime unit tests. Unknown receipt/error states remain read-only with an export action. Unsupported Web Locks prevents upgrading, while existing legacy editing remains available when there is no pending migration. The stage 6 audit also inspected source/package exports, peer dependencies and documentation targets, then passed the actual 267-file unpacked package's Node/types, framework-peer, compiled browser storage and Worker checks. Together with CI #1182 and both browser bundlers this closes stage 6. The full requirement matrix remains stage 7; the two new scheduler clock-shift checks cover backward/forward wall time, dependency/unknown claims, stale timer callbacks and remaining wait calculation after recovery.
canvas_headless_worker_integration_test.go supplies deterministic generation
output over the actual worker HTTP protocol. Admission, claim, events, canonical
writes, image storage and action receipts use the real service/DB. Private worker
controls are registered only in the test assembly. Production's background queue
loop, external model availability, provider billing and real CLI authentication
are not proved by that fixture. TestCanvasAIRealWorker remains opt-in and skipped.
The CI log includes an early skip of TestHeadlessClientHTTPIntegration without
its opt-in environment and a later successful execution in the explicit Node/DB
phase. Those are different invocations. The latest log has 157 distinct PASS names
including subtests; that count is not 154 independent end-to-end scenarios.
The service audit covers the original stage requirements: target incremental and idempotent protocols, frontend/runtime/resource adapters, explicit legacy compatibility, identity mapping, source-version/permission/run admission barriers, and rollback after writes have begun. Migration/delivery now has the separate browser/package evidence above; the final requirement matrix remains. A green feature-branch run does not merge or deploy either repository. Foundry PR #19 remains open and Draft.