Brand kit release checks
The API and console are deployed to production; acceptance is partial as recorded below. Signed-in management and MCP read/edit checks pass; deployed font/media, provider and export checks remain incomplete. The local browser fixture uses real API routes, auth, database, validation and translation, with simulated storage, font cooking and extraction. Its successful callbacks and queued render payloads do not prove a deployed farm render, CDN access, TasteLabs timing or a commercial licence. Defaults:BRAND_KIT_MIN_PLAN is unset, BRAND_EXTRACTION_PROVIDER=framelane,
and PDF import is deferred. The user has confirmed the signed embedding Order is
obtained and filed; no contract or filing location was independently inspected.
TasteLabs remains disabled in production pending its deployed acceptance checks
and an explicitly authorized provider rollout.
Do not treat the plan’s historical farm commit or deployment document as proof of
the currently deployed image.
Current production status (2026-10-30)
The user explicitly requested merge, deploy and test again. That authorization superseded the earlier manual-GCP restriction for this release. API PR 59 and console PR 18 were merged and deployed. The deployment evidence records:- Initial API merge commit
65958eb803846aa5019b4507de6e6384ad61535d; Cloud Build945b251b-e8c1-4ee2-8c01-f2d3ce867e55succeeded with image digestsha256:304b8d2649ed1555194ada525a0042b3a95dcfa72528bc0c3e31fcc4da111b84. - Migration execution
framelane-migrate-hdqpdsucceeded from0022through0025. Initial Cloud Run revisionframelane-api-00115-5l7was deployed before the hotfix below. - API hotfix PR 61 merged as
06ec2578808c8781e62e4fd71e1608b95f01fa62. Cloud Build2229c81b-dc97-4c1d-9f08-65e1cc246c1asucceeded with image digestsha256:e96913109507cc35a3cb02ead1745871c3dc8456d600eaf4853e6651e480d8d5. Revisionframelane-api-00116-k8tnow serves 100% of traffic. No further migration was required beyond0025. - Console merge commit
53007cde3162d9ee76b2480fd64e6cea6c2f2f5f; Vercel deploymentdpl_BY6oUDaM4wH8PHztdfa2EsiuTsgfwas promoted tohttps://framelane.io. - API health and readiness returned HTTP 200, with database and Redis healthy. Live OpenAPI exactly matches the committed schema’s 59 paths. Three checked new feature routes exist and reject unauthenticated requests with HTTP 401.
- An HTML request to
https://framelane.io/brand-kitreturned HTTP 307 to/login, confirming the signed-out Clerk boundary. A non-HTML unauthenticated request can return 404 as authentication behavior; it is not evidence that the deployed page is absent.
ON CONFLICT predicate could no longer infer the partial
unique index when PostgreSQL reused a generic prepared plan. The failure was
reproduced against a disposable real PostgreSQL database. The hotfix uses the
same static predicate as the migration, while keeping user data parameterized.
Its 31 focused checks pass, including four real PostgreSQL checks and 21 generic
plan insert/reload executions that preserve one kit and its manual edits. Main
CI run 41035828066 passes 4,190 tests with 18 skips and all 10 upload-panel tests;
the image spec check confirms 59 OpenAPI paths.
Signed-in browser acceptance passed at 09:58 UTC after the hotfix:
- Eight concurrent workspace-kit reads returned one kit. An unsupported
font/woff2upload request returned422 unsupported_content_typewithout creating a font row or starting work. - Rename/reload/restore and colour add/remove/reload/re-add/cleanup passed. The empty font UI rendered, and an empty project’s Brand panel showed the persisted swatch and management link without changing its scene.
- There were no page errors or forbidden request attempts. Render and task lists were empty before and after; extraction usage stayed zero. No media/font bytes, cooking, extraction, preview, thumbnail or render submission was exercised.
get_brand_kit and
edit_brand_kit succeeded, REST independently verified persistence, and 20
repeated MCP reads succeeded. Initial values were restored. No MCP upload,
extraction or render calls were made.
A generated Clerk identity using a reserved example.com address with Null MX
0 . completed authentication and workspace sync; the earlier .invalid
rejection was not a blocker. The generated workspace and Clerk user were deleted,
and the test API key returned HTTP 401 afterward. The existing real user account
was untouched. Temporary credentials and browser-state files were removed.
At 09:59:16 UTC, the final bounded log checks returned zero error entries for
API revision framelane-api-00116-k8t and zero console errors after the fix at
09:52:02 UTC; the console log query exited successfully. The renderer group was
stable at target zero and the instance list was empty. This records the checked
revision and time window, not an assertion about all historical or future logs.
Licence evidence is user confirmation: the user instructed us to consider the
signed embedding Order obtained and filed. No contract or filing location has
been independently inspected.
The historical three-site live captures below remain complete.
Capacity and spending constraint: the user instructed us not to restore GPU
capacity because of cost. Capacity was briefly requested at one and immediately
returned to zero; the stable target is zero and the instance list was confirmed
empty. No font-processing, render or paid-provider jobs were submitted during
this deployment verification. Keep BRAND_EXTRACTION_PROVIDER=framelane, do not
restore capacity, and do not repeat paid captures. Deployed font cooking, farm
image inspection, new cooked-font CDN/browser checks and completed video exports
remain unproved and must wait for renewed authorization and available capacity.
The completed management and cleanup checks do not establish uploaded-object
cleanup, retained-font rendering, provider flow or alert delivery. Those checks
remain outstanding; deployment alone does not prove them.
Historical production authorization and preflight (2026-10-29)
This section records the state before the 30 October deployment. Its deployment and permission limitations are superseded by the current status above. The user authorized production for the remaining acceptance checks. Usehttps://api.framelane.io and a dedicated disposable acceptance workspace once
the feature is deployed. This replaces the earlier staging-only requirement for
kit, font, CDN and export checks. It does not enable TasteLabs for customers or
change the render-node instruction that the user runs every GCP command.
The read-only production probe
found API commit d0508d459335c6b8d9b75aee0544829eb89cfd40. Its OpenAPI schema
has only the older /v1/brand-kits and /v1/brand-kits/{brand_kit_id} routes;
workspace-kit and font routes are absent. https://framelane.io/brand-kit
returns 404. The app.framelane.io and console.framelane.io example hosts do
not resolve from this executor. Both feature PRs remain open drafts. Deploying
the reviewed API and console is the next prerequisite; no production writes
were performed during this preflight.
The version response reports renderer SHA
5bc7a6f5a2cb17092a69d775dcbd1699eda34d5a, taken from the latest completed or
cancelled render callback. This is useful provenance for that callback, not
proof of the currently running image or all active farm versions.
After deployment, use a new controlled acceptance email for POST /v1/signup
and /v1/signup/verify, or a separate Clerk test identity. Do not call signup
with an existing customer’s email: it rotates their keys and resets email
verification. A Clerk identity with the same verified test email can adopt that
workspace. Store its API key privately as FRAMELANE_API_KEY; record and verify
the dedicated workspace ID with GET /v1/workspace before mutations and cleanup.
Do not use the existing connected workspace for destructive acceptance tests.
Live provider evidence (2026-10-29)
A user-supplied test key completed the three planned provider captures with one submission per site: framelane.io in 180.019 seconds, stripe.com in 6.180 seconds, and linear.app in 6.158 seconds. Linear’s page and a fingerprinted Next CSS asset were independently fetched. All three reachedcompleted within five minutes.
TasteLabs reported two credits for each submission, including the Stripe and
Linear cache hits: six credits total. Free list/result reads recovered only these
submissions for asset verification; no additional extraction was submitted.
The live report links the sanitized
envelope sequences, elapsed times, response status counts and stylesheet proof.
The real shapes exposed nested typography.*.variants, semantic button-radius
labels, Primary logo roles and a brand colour also used for text. Mapper
regressions now preserve those values. Offline API persistence tests replay each
recorded shape, preserve manual name/heading edits, store the detected body font
and reuse the same URL without a second submission.
All three sites returned mirrored logos on sb.engine.thetaste.ai. One logo from
each was fetched through the actual DNS-pinned, byte-limited logo proxy: a PNG for
FrameLane and sanitized SVGs for Stripe and Linear. That exact host is the tested
storage allowlist candidate. Stripe also returned two direct URLs on
images.stripeassets.com; those are source-site assets and were not added to the
provider-storage allowlist. No signed URL, raw provider asset path or credential
is included in the evidence. The key was used only for this local test run.
These are live provider and proxy checks from the local executor. They do not
prove a deployed provider API/console flow, concurrent deployed pollers, alert
delivery, a completed video, or the signed embedding Order. The Order’s current
status is the user confirmation recorded above; the remaining deployed checks
are listed below, and the production provider default remains framelane.
Local cooker evidence (2026-10-28)
The machine-readable proof pins the cached amd64 image, cooker source and binary hashes, generated input hashes, metadata hashes and actual chunk hashes. This used imagesha256:6f7fb604936a93df5cdf36a4c18136fedb3f3926db3e739e60671c1e7ab37b7c
(tagged git-sha-90682fd1ccdee625324359c10e2e49e7feaab288; that tag does not
establish the currently deployed farm revision).
A generated TTF with a nonempty glyf outline and a generated OTF with a nonempty
CFF outline both ran through the image’s real process_user_font.py and legacy
slugfont binary. They completed in 1.340 s and 1.311 s respectively, each writing
V3 metadata and one 2,364-byte .slug chunk. The API’s actual validate_font and
verify_font_objects accepted both; the latter read the real output files through
a local signer shim, with no GCS requests. These tiny synthetic inputs establish
format and output-contract compatibility, not a full-font latency guarantee.
The containers used the explicit font-tool Python entrypoint, --network none,
--read-only, --cpus 1, --memory 512m, --pids-limit 64, --cap-drop ALL and
no-new-privileges. Only generated inputs and a temporary output directory were
mounted. No renderer worker, GPU, credentials or cloud connection was used.
The deployed callback, CDN and rendered-frame gates below remain outstanding.
Local Claude Code evidence (2026-10-28)
The S4 client proof records a real Claude Code 2.1.312 session over initialized Streamable HTTP on a separate local fixture at127.0.0.1:8039. Its strict MCP configuration connected only that
server; built-in tools and hooks were disabled, and only the four acceptance
tools were allowed. All four calls succeeded: get_brand_kit("workspace"),
edit_brand_kit, extract_brand_kit into the same kit, and inline font
create_upload using a generated TTF. An unauthenticated MCP request returned 401.
Independent REST and read-only SQLite checks confirmed one workspace kit, one
completed extraction job, preserved manual name/color/heading, filled body font
and logo suggestion, and the uploaded font ready after one attempt. Its stored
source bytes matched the generated input. The schema-budget suite passed all
16 tests. Reproduction steps
use a temporary directory and do not modify the user’s MCP configuration.
This closes the plan’s local Claude Code round-trip check. The fixture simulates
storage, font cooking, website DNS and TasteLabs; this evidence does not establish
Clerk OAuth, deployed callbacks, CDN access, paid extraction or rendered output.
The independent real CPU cooker proof above covers actual local cooking.
1. Deployment procedure (completed for the 2026-10-30 release)
The 30 October deployment was executed under the user’s explicit merge/deploy/test authorization; its results are recorded above. The commands below remain the reference procedure, not a request to repeat the completed deployment. The names come from the repository’s production deployment docs; verify them against the existing resources first. Preserve their database, network, service-account and secret configuration. Run from the reviewed, clean API feature checkout, after resolving any review changes. Cloud Build updates:latest as well as the commit tag; the migration and service use the commit tag.
Keep BRAND_EXTRACTION_PROVIDER=framelane and BRAND_KIT_MIN_PLAN unset.
0025,
and /v1/version response in the release evidence. Migration order is build,
migrate, deploy; do not execute the old migration job image. The existing README
has infrastructure setup instructions, but do not recreate production resources
to resolve a name mismatch. Deploy the console’s exact packed editor rc.24 after
the API is ready, then run the farm/browser checks below. Confirm the actual
console origin from that deployment before checking CORS.
2. Operator: farm, subscription and CDN evidence (S0/S2)
These checks remain incomplete. The current user instruction is to keep GPU capacity at zero; do not start a worker, upload a font that dispatches processing, or submit a preview/render job to advance them. Read-only subscription metadata can be inspected without restoring capacity. Running-container and new cooked-font checks must wait until the user authorizes capacity again. Use the operator-verified production names. The documented farm MIG below is a starting point, not live deployment evidence. Supply the actual push-subscription names; these read-only commands identify the template and filters:deployment_plan.md, use
an instance and its zone returned by the preceding list. The following commands
are for the operator to run, not evidence that an inspection has happened:
render-node in the documented deployment). Inspect only these fields; a full
container inspection would also disclose its environment:
gitSha together. The startup marker is emitted by the
running binary (src/offlineRenderer/main.cpp), unlike a mutable image tag.
If the logging driver does not expose docker logs, retrieve that same marker
from Cloud Logging for this instance and container start. If RepoDigests is
empty or the source marker is unknown, reconcile the inspected image ID with
the build/deployment provenance before declaring this gate passed. Repeat for
every active version during a rolling deployment; do not start another worker
or substitute the locally cached cooker image for a running instance.
Confirm the identified source contains processUserFont
(request field 107, response field 108). /v1/version exposes the latest render
completion/cancellation callback SHA; it does not identify the current image.
Confirm the result
push reaches /internal/metadata/complete and its filter permits font results.
Confirm object-finalize events reach /internal/gcs/notify. The API’s 60-second
font sweep is a fallback for a missing finalize event; it cannot replace a missing
farm result subscription. Fix any infrastructure filter using the operator’s
normal reviewed change process; do not guess a replacement filter.
Upload one licensed TTF and one CFF-outline OTF to the dedicated acceptance
workspace using the console. Both must reach ready within two minutes, return a
source URL plus chunk metadata, and render a frame showing the chosen face. Save
request/attempt IDs, timestamps, the output frame, and farm logs. There must be no
Can't process brandkit font ranges error. The API preserves canonical .json
and .slug objects under its exact first-party /fonts/ CDN prefix, so metadata
and relative chunks retain their public CDN base. Raw /uploads/ font sources
still rewrite to storage.googleapis.com for service-account reads. The current
farm downloader may itself convert CDN URLs to authenticated storage URLs and
fall back to CDN reads; verify both metadata and relative chunks on the deployed
farm. If a fetch fails, investigate its credentials/rewrite/CDN configuration;
the local fixture cannot validate this path. If CFF fails, restrict upload acceptance to
TTF and adjust the UI/docs before shipping rather than advertising unproven OTF.
Using URLs from that acceptance upload, test the console’s actual Origin/Referer and
a public chunk URL. The response must permit the console origin for sources and
public CORS reads for /fonts/:
FontFace load; a successful curl is insufficient for
browser CORS. Compare preview/export text metrics side by side. Tombstone the
font, reload the existing project, and confirm preview and export still use it;
it must disappear from the library/picker. A new live face with the same canonical
family must take precedence. In the disposable workspace, confirm simultaneous
first kit reads return one ID, upload membership appears, and asset/kit/workspace
deletes leave no owned rows. Workspace deletion removes source files and the
fonts/{workspace}/ prefix; check storage and cleanup logs, including late farm
callbacks. Copies owned by another workspace retain their document/history and
source kind, with the deleted source reference cleared.
Before deleting the test workspace, finish or cancel its outstanding render jobs,
save the accepted output and re-check GET /v1/workspace against the recorded
test ID. DELETE /v1/workspace removes all its rows, keys and owned files; never
run it with an existing customer workspace’s key. Keep this cleanup separate
from tombstone testing, which must retain the workspace and saved project until
the second export completes.
3. Operator: TasteLabs gates (S3, still separate from production core checks)
Keep trial credentials out of source control and use a separate production key after licensing. The signed Order must cover embedded use, stored mapped results, copying selected logos, rate/concurrency limits, DPA/subprocessor terms, separate environment keys and future PDF support. The plan contains a licence request draft; sending it is a separate user action. A test key was supplied for the 29 October local live checks above. On 30 October the user confirmed that the signed embedding Order is obtained and filed; this is user confirmation, not an independent review of the contract or its filing location. Deployed provider acceptance remains incomplete. Production test authorization does not make a global provider flag workspace-scoped. Keep the shared production API onframelane; no new paid checks are authorized under the current spending
constraint. Any later provider acceptance or rollout requires renewed scope for
that work. Core browser checks can proceed without changing the provider; font
and export checks also require the GPU constraint to be lifted.
Run the reviewed spec check and one deliberate fixture capture per approved test
site if another capture is required. The three 29 October captures already exist
and must not be repeated merely to regenerate fixtures. Each capture command
consumes a provider submission; never retry it
blindly after an unknown outcome. The script reads TASTELABS_API_KEY from the
operator’s environment without printing it and requires a new output directory.
fixture.example, so its saved sequence
cannot establish the real storage allowlist. During each authorized capture,
inspect the logo URLs in the provider’s response viewer or the controlled test
response inspection, and separately save only their non-secret hostnames,
the UTC observation time and capture-folder name in the release evidence. Do not
save signed URL paths/query strings, headers, keys or raw provider responses.
Confirm these are the exact HTTPS hosts serving the returned logos; use the
hostname without a scheme, path, port or wildcard in TASTELABS_STORAGE_HOSTS.
Do not infer a host from synthetic fixtures or allow all provider subdomains.
On an isolated internal deployment, enable tastelabs with
the trial key and require all three sites to reach ready within five minutes
through the API and console. Verify one apply under concurrent polls, one paid
submit per running kit, quota rejection, 24-hour reuse without a new paid submit,
usage totals and the provider flag switched back to framelane. Verify logo
preview/save produces an owned asset and never injects provider SVG as markup.
Only then, with the signed Order filed, approve production provider enablement.
Before that enablement, verify delivery of the dispatch-failure alert required by
the plan. The application emits brand_extraction.submit_failed at ERROR with
job_id and status_code, then attempts the heuristic fallback. A successful
fallback must not hide exhausted provider credits. Configure the existing
operator-owned log alert using this filter, replacing the service placeholder
with the actual isolated test service (and the production service on rollout):
4. Final acceptance evidence
Current status: deployment, signed-out authentication, signed-in kit management, MCP read/edit persistence and empty-workspace cleanup checks pass. Font/media, provider and export acceptance remains incomplete; farm-dependent checks are pending capacity authorization. The following is the remaining procedure, not evidence that those checks ran. Do not dispatch farm or paid-provider work under the current constraint. Keep API/console/editor commits, generated SDK versions, test reports and the deployment artifacts together. The local Claude Code check above covers workspace read,edit_brand_kit, extraction into that kit and font upload. The deployed MCP
read/edit subset now also passes; only exercise its remaining external-service
calls when separately authorized. Then complete the console acceptance flow to
add/delete/re-add image, video, audio and font,
then insert media, apply a colour, set a font, reload and export the composition.
A locally queued job is not an exported video. Confirm the upload licence notice
and Terms sentence are present. PDF import remains out of this release.

