From 1cbb38d6c42619d881002656913d5ab19236d43e Mon Sep 17 00:00:00 2001 From: alex-mextner <111590326+alex-mextner@users.noreply.github.com> Date: Sat, 7 Nov 2026 15:34:12 +0000 Subject: [PATCH] docs(reports): link verified native Conloca stages and recordings (Refs #6) --- .github/workflows/ci.yml | 3 + reports/conloca-2026-10/index.html | 6 +- .../conloca-2026-10/native-stage-proof.json | 37 +++++++ scripts/ci/check-media-report.py | 2 +- scripts/ci/check-native-stage-proof.py | 104 ++++++++++++++++++ scripts/ci/check-own-results.py | 5 +- 6 files changed, 152 insertions(+), 5 deletions(-) create mode 100644 reports/conloca-2026-10/native-stage-proof.json create mode 100644 scripts/ci/check-native-stage-proof.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 77601c0..ce0bd84 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,6 +31,9 @@ jobs: - name: Verify screenshots, original requests and recordings run: python3 scripts/ci/check-media-report.py + - name: Verify the native-stage proof block and record + run: python3 scripts/ci/check-native-stage-proof.py + - name: Install dependencies run: npm ci diff --git a/reports/conloca-2026-10/index.html b/reports/conloca-2026-10/index.html index 37f6eb9..ac21662 100644 --- a/reports/conloca-2026-10/index.html +++ b/reports/conloca-2026-10/index.html @@ -11,7 +11,7 @@
-

Conloca: October 2026

Editor fixes, workspace safety, content integrity, the production How it works page

Ultra / Mextner · October 2026

Overview

Conloca is a visual CMS for Astro sites: editors change pages in the browser and the content is committed to Git. In October Ultra / Mextner delivered fixes across the editor, invites and sign-in, content and media handling, and the production site.

The documentation theme picker is implemented and checked but awaits team review, so it is shown separately below.

397.6 → 0 px
How it works image movement during delayed hydration, in the browser test of #342
33.6 MB
snapshot that now imports in bounded parts of at most 16 MiB (#259)
409
answer to a write from an editor tab whose repository, branch or site differs, given before any billing, storage or Git work (#192, #224)

What we delivered

Editor and page actions

Dragging blocks into a page, Undo after adding a block and the Dashboard New Page button now work. A disabled Preview button explains why it is unavailable. Never-published pages read Draft in the Pages list and on the Dashboard. A route or schema error shows a CMS error page or notice instead of the developer screen, and the branch-name field formats as you type. These were everyday actions that did nothing or showed the wrong state.

Owner request (excerpt)

Original request (RU)

все баги которые никто не делает и почини по tdd в параллельных ворктри и влей через gh ship
Важны максимально реалистичные е2е тесты
В задачи поставь меня исполнителем
Приложи пруфами скриншоты до и после

English translation

all the bugs nobody is working on, and fix them with TDD in parallel worktrees and merge through gh ship. Maximally realistic e2e tests are important. Put me as the assignee in the tasks. Attach screenshots from before and after as proof.

Source. Ultra / Mextner · Ultra's omp prompt history, project conloca · no message id · 22 October 2026, 10:39 UTC. Sender: the owner's own prompt history; it has no per-message author field, so attribution is by account. Full-message SHA-256 1ea5051957cda4839152034111af4c51789e7761deb61386ab53bc2627c82c4d.

The opening words of the message and the link to the private bug database are left out.

Owner request (excerpt)

Original request (RU)

И параллельно в новом вт почини

English translation

And in parallel, in a new worktree, fix [the linked bug-database entry “Dashboard New page button bug”].

Source. Ultra / Mextner · Ultra's omp prompt history, project conloca · no message id · 22 October 2026, 18:09 UTC. Sender: the owner's own prompt history; it has no per-message author field, so attribution is by account. Full-message SHA-256 7669ba062bc44797708bedd3cc4b6cbc332f79d389145bf379003cdf2ee20979.

Owner request (excerpt)

Original request (RU)

еще задача: Cannot drag blocks onto an empty page. no block is added and the canvas remains empty. No error messages or guidance is displayed.

English translation

one more task: [English bug text, as pasted from the bug database:] Cannot drag blocks onto an empty page. no block is added and the canvas remains empty. No error messages or guidance is displayed.

Source. Ultra / Mextner · Ultra's omp prompt history, project conloca · no message id · 22 October 2026, 23:45 UTC. Sender: the owner's own prompt history; it has no per-message author field, so attribution is by account. Full-message SHA-256 e3869c29e076499fd4a50480adf8214b79b44f05f6143248f2f1db6ae57f3d9f.

Owner request (excerpt)

Original request (RU)

и еще одна: Pages - Status badges don’t reflect real status. All pages are always showing published. Even when I just created one.

English translation

and one more: [English bug text, as pasted from the bug database:] Pages - Status badges don’t reflect real status. All pages are always showing published. Even when I just created one.

Source. Ultra / Mextner · Ultra's omp prompt history, project conloca · no message id · 22 October 2026, 23:46 UTC. Sender: the owner's own prompt history; it has no per-message author field, so attribution is by account. Full-message SHA-256 f2437f51dc49ba9358e730e76d4e740c178b5d078d72d5653d554744d4a7d06c.

New branch field: original request and production recording

Owner request (excerpt)

Original request (RU)

и вот эту возьми: New branch - Branch name formatting problem. Problem:

SPACE can’t be used in a branch name, but we still allow users to type it and then show error.

Solution:

We need to automatically format the user inputed text like following: enforce lowercase, automatically type - when user uses SPACE.

English translation

and take this one too: [English bug text, as pasted from the bug database:] New branch - Branch name formatting problem. Problem: SPACE can’t be used in a branch name, but we still allow users to type it and then show error. Solution: We need to automatically format the user inputed text like following: enforce lowercase, automatically type - when user uses SPACE.

Source. Ultra / Mextner · Ultra's omp prompt history, project conloca · no message id · 22 October 2026, 23:51 UTC. Sender: the owner's own prompt history; it has no per-message author field, so attribution is by account. Full-message SHA-256 fdf731854e8a0dd58796a4e33ebfdc825f582d5f60d945a7fed1d64f4b204e3a.

The recording is footage of the production CMS made by the team and attached to pull request #316. This page shows a cropped copy of the New branch form. It checks only that the caret stays in place while the text is formatted.

Recorded production browser check New branch field keeps the caret while formatting. Footage recorded by the team on the production site and attached to the pull request. It is not a CI or end-to-end test run and not full acceptance. MP4 file
Page
the New branch form in the production CMS
Pull request
#316 (merged), the original recording shows a signed-in workspace and stays in the private repository; this page shows a cropped copy of the New branch form only
Recorded
29 October 2026, 15:00 UTC (attached to the pull request on 3 November), 10 seconds; real Chrome against the production CMS, signed in; the form was exercised without submitting
What it shows
Typing in the Branch name field while the caret sits after a Greek sigma. The pull request reports five DOM-backed checks passing for this scenario. It is not branch creation or release sign-off.
File
600×460, 10.05 s, 100 frames, no audio. MP4 SHA-256 175ed0005255fa6b785d89339335211cda5760fd74ba0f45ecd38630a0455a8d, WebM alternate SHA-256 8f160203355c2076ac9eedc6b893fc30effaf35460d3a51e2aa58565ccffae71. This is a derived copy: the original recording is not republished; it was cropped to the form (region 300×230 px at 182,40, scaled ×2). Original SHA-256 ce25011c07367aff2de27d53927b8212f55af2815cf55b72c731146268f84c86.

Sign-in divider in the dark theme

Merged, pull request #220 Single capture: after only.

Sign-in divider in dark theme: the lines and the word or are visible against the dark card
Frame of the recording Frame at 3.9 s of the production recording below: the sign-in divider in the dark theme. Full-size original (1280×800 PNG)
  1. The divider lines and the word “or” are visible against the dark card.

A frame of the production recording of pull request #220 shown below, at 3.9 seconds, 1280×800. The recording has no before capture.

Sign-in divider: production browser checks, desktop and phone width

Footage of the production sign-in page made by the team and attached to pull request #220. Each clip starts in the light theme and switches to the dark theme.

Recorded production browser check Sign-in divider, desktop, light then dark. Footage recorded by the team on the production site and attached to the pull request. It is not a CI or end-to-end test run and not full acceptance. MP4 file
Page
the production sign-in page
Pull request
#220 (merged), attached to the pull request in the private repository conloca/private (access required)
Recorded
3 November 2026 (comment date), 4.1 seconds; real Chrome against production, 1280×800, no account signed in
What it shows
The divider colour in the light and then the dark theme. It is not an accessibility audit and not a pixel baseline.
File
1280×800, 4.1 s, 41 frames, no audio. MP4 SHA-256 330c04b0fbeaef98ad798bbf28e8d1da629bf2361b991f2fb8cb398bcb6fa486, WebM alternate SHA-256 757c84c56eb00c37b637d52b7b098391a008aba6102266a50eb7ca31f2b4b37d.
Recorded production browser check Sign-in divider, phone width, light then dark. Footage recorded by the team on the production site and attached to the pull request. It is not a CI or end-to-end test run and not full acceptance. MP4 file
Page
the production sign-in page
Pull request
#220 (merged), attached to the pull request in the private repository conloca/private (access required)
Recorded
3 November 2026 (comment date), 4.1 seconds; real Chrome against production, 390×844, no account signed in
What it shows
The divider colour in the light and then the dark theme at phone width.
File
390×844, 4.1 s, 41 frames, no audio. MP4 SHA-256 da4c5ba19643cd24c82add4cf54016982a0ceb5c220de52909a15f09a6ade046, WebM alternate SHA-256 d6a59fe733578ce1962f2ec756aa2f0b655585a465922deb9b1743c841e7c491.
Technical detail
  • Puck ignores a press on a real <button>, so the block-list item is a div role="button" again, and an empty page says how to add a block (#299). Undo and Redo remove and restore a block added by drag or double-click (#306).
  • The Dashboard New Page button opens the create-page dialog in place (#302). One pageStatusOf() and a LocaleVersion.unpublished marker decide page status, and saving a new translation keeps a never-published page a draft (#296, #307).
  • A route that fails to render shows RouteErrorPage, and a site schema that is not a generated host schema shows a notice instead of crashing the CMS (#301, #293, #295). The disabled Preview button shows its explanation when clicked (#262).
  • The New branch field lowercases, hyphenates and keeps the caret in place as you type (#297, #316). The editor opens pages with no English variant (#196), and draft previews parse records with each collection’s schema so dates and defaults match the build (#248).
  • Frontmatter keys such as __proto__.polluted cannot mutate Object.prototype, while own-data keys, including legitimate constructor and prototype names, are kept (#239). The sign-in divider is readable in dark mode; login-theme.spec.ts checks light and dark at 390 and 1280 px (#220).

Key pull requests: #299 · #306 · #302 · #296 · #301 · #297 · 15 pull requests in this group, all in the source record · CI run for #299 · CI run for #302 · CI run for #296

Invites, tabs and sign-in stay in the right place

Accepting an invite lands in the invited workspace, from both the in-app button and the emailed link. Each editor tab sends its repository, branch and site with every write, and the server rejects a mismatch with a 409 instead of writing to the wrong place. Tabs of one browser origin that refresh at the same moment share one token rotation instead of revoking the whole token family.

Owner request

Original request (RU)

Задача: When inviting someone to a workspace, they don't always get redirected to the invited workspace when clicking accept invite in a received mail

English translation

Task: [English bug text, as pasted from the bug database:] When inviting someone to a workspace, they don't always get redirected to the invited workspace when clicking accept invite in a received mail

Source. Ultra / Mextner · Ultra's omp prompt history, project conloca · no message id · 22 October 2026, 13:27 UTC. Sender: the owner's own prompt history; it has no per-message author field, so attribution is by account. Full-message SHA-256 59a3431d16bdddc2b358f19a80548dfcf20b9e974aeed17282ce6a3d534902aa.

Technical detail
  • Mutations carry X-Conloca-Editor-Repo, -Branch and -Site headers. The worker answers 409 workspace-mismatch before any billing, storage or Git work, and the tab re-enters its own branch and retries once (#192, #224).
  • Accept waits at most 5 seconds for the membership flush and the Org Durable Object’s alarm delivers the rest; an invite screen that would stay on “accepting” is released after 20 seconds (#292, #305). A deployed-stage proof, invite-landing.spec.ts, covers an invitee who already has a workspace (#294).
  • A second use of a refresh cookie within 10 seconds gets the live token from the rotation chain, and the browser refreshes under a Web Lock so same-origin tabs send one request per rotation (#240). An OAuth failure shows its failure screen instead of looping (#225).
  • Splitting the sign-in and Members screens into props-only views fixed a double submit that requested two sign-in links and a double click that sent two invitations (#253, #223).
  • Cloudflare Access configuration fails closed with 401 when only one of its two settings is present (#191). Overlay rows for pages deleted in Git are pruned (#188). Workspace and flag types are narrowed instead of cast (#222).

Key pull requests: #288 · #289 · #192 · #224 · #240 · #225 · 14 pull requests in this group, all in the source record · CI run for #288 · CI run for #289 · CI run for #192

Scoped content commits, safe asset moves and correct write-back

CMS commits include only content files, so other people’s staged work is left out, and an asset move claims its destination instead of overwriting an existing file. Draft images render in the canvas before Publish, and a docs-root page is written back to the file it was read from. The hosted preview shows pages committed after its build, and a site snapshot over Cloudflare’s 32 MiB call limit imports in bounded parts.

Technical detail
  • CMS commits build their tree in a private index seeded from HEAD and move HEAD by compare-and-swap with update-ref, so a concurrent commit is not reverted. Asset moves run one at a time and claim the destination with a hard link. Tests use real temporary repositories: foreign staged files, two concurrent instances, a held index.lock and concurrent moves racing for one name (#197).
  • Draft images are served from /api/v1/assets/draft/<folder>/<file> while stored data keeps the canonical /assets/... reference (#243). A docs-root MDX page used to be written to a shadow file; mdx-pages-root.test.ts covers edit, delete, create-after-delete and a collision (#235).
  • The hosted preview records its own buildCommit and sends it as ?build=; the worker diffs that commit against the branch head and matches entries by blob id. A deployed-stage test commits a title without redeploying and expects the new heading (#247, spec change #228).
  • The depth-1 snapshot of one pull request packs to about 33.6 MB, over the 32 MiB RPC limit. It now lands in parts of at most 16 MiB with the tree and commit last, and a live check against github.com imported the full closure of 4,836 objects (#259). A missing base tree is fetched by object id instead of failing the import (#256).
  • Org import now always retries the tracker reconcile when a ref already matches upstream, so a stale preview session recovers (#177). Only three of Ultra’s 29 commits in #177 are credited: the repair, its at-head regression test and the browser publication proof. The vocabulary sample stays off the Git lookup behind the unpublished marker (#308).

Key pull requests: #197 · #243 · #235 · #247 · #259 · #177 · 9 pull requests in this group, all in the source record · CI run for #197 · CI run for #247 · CI run for #259

The finished How it works page is on conloca.com

The production How it works page uses the completed design: a four-step flow with MDX, JSON and editor visuals, twelve responsive images and an install banner that survives 200% text. The design is by Saba; our work is the integration into the production site and its checks. In the pull request’s delayed-hydration test, images moved 397.6 px before the fix and 0 px after it.

How it works on production: browser check

Footage of the production page made by the team and attached to pull request #342. The page is public. There is no before footage.

Recorded production browser check How it works page on production. Footage recorded by the team on the production site and attached to the pull request. It is not a CI or end-to-end test run and not full acceptance. MP4 file
Page
https://conloca.com/how-it-works
Pull request
#342 (merged 27 October 2026), attached to the pull request in the private repository conloca/private (access required)
Recorded
28 October 2026, 20:14 to 20:15 UTC; real Chrome against production, viewport 1348×936, no cuts or speed changes
What it shows
Hero, the four-step flow, the layered visual, the cards, the install banner, the pnpm, npm and bun tab selection, and the footer Docs link, on desktop only.
File
1364×936, 16.939 s, 165 frames, no audio. MP4 SHA-256 5628cd2e6f68945643b61506d45eafa00a8ff45e68ef9796e6199fc04857af7c, WebM alternate SHA-256 7fc70c7839e6a94e60afb3731601f153f81acfb919f4a0db993d6f3291ce76f2.
Technical detail
  • The twelve PNGs were imported byte for byte, with SHA-256 and byte lengths checked on the preview. Existing routes, app links, docs links and install tabs are kept, and text is darkened where the original failed contrast (#342).
  • The test measured 397.587 px of movement before and 0 px across 53 frames after. Twenty-one website targets and 50 browser checks were rerun.
  • The merge to the main branch ran Validate, deployed-stage browser tests and Deploy Production, all successful. Locally, the split-port development stack redirects backend landings to the app and keeps published media on local origins (#231).

Key pull requests: #342 · #231 · CI run for #342 · conloca.com/how-it-works

Browser and story coverage for the editor

The CMS and the app each build a static Storybook catalogue in CI, and state stories cover save, sync and workspace status, the page list and the conflict dialogs. Deployed-stage browser tests walk every CMS route, create a branch through the Branch menu, confirm a new page reads Draft and check that typed text survives reopening the editor in both themes. CI keeps the proof folder of every deployed-stage run.

Technical detail
  • State stories render the real components with fixtures that stop at HostClient and the content API fetch, so nothing reaches the network. Counts: SaveSlot 6 plus phone, SyncStatusSlot 8 plus phone, WorkspaceStatusSlot 8 plus phone, CmsHostPlaceholder 9 (#244). CI saves a screenshot of every story at 1280 × 800 and 390 × 844. The app Storybook runner now compiles Tailwind, because classes such as max-sm:hidden were missing from all app examples.
  • A flaky failure in the Several Locales scenario, caused by a viewport resize landing mid-play, is gone: resizes during play went from 30 and 11 to 0 and 0 in the probe runs (#257).
  • The deployed-stage job keeps its proof folder on every run and the Playwright report on failed runs (#320). A manual staging proof workflow adds two new legs (#261), and the emitted billing deploy bundle runs in CI (#238).
  • Real-engine and typed tests for Git paths, billing identity mapping, workspace recovery and memory behaviour were added or made deterministic (#198, #234, #221, #236, #201, #254). Branch creation and the Draft check are in #229 and #309, and the editor-reopen check is in #226.

Key pull requests: #217 · #244 · #304 · #229 · #300 · #320 · 17 pull requests in this group, all in the source record · CI run for #229 · CI run for #300

A pull-request stage environment that keeps working

Pull-request stages are cleaned up on a schedule with capacity reporting and stage leases, which brought the Cloudflare namespace count to 386 of 500 after the first eviction run. Each stage uses one Durable Object namespace fewer, and each deployment attempt gets its own preview fixture without resetting drafts. Before this, Deploy Stage was failing account-wide with Cloudflare error 10067 after about 170 namespaces leaked from closed pull requests.

Technical detail
  • A scheduled workflow runs every six hours, reports capacity and fails above 400 of 500 namespaces. Drafts hold a stage for 24 hours and ready pull requests for 72 hours; keep-stage and evict-stage override that. tooling/pr-stage-gc.test.ts checks that only closed same-repo pull requests are selected (#200).
  • Deleting the unused EventLogDO takes each stage from 10 namespaces to 9, which the pull request estimates moves live capacity from about 48 to about 53 stages (#241).
  • Readiness rejects dirty overlays and divergent session heads, and older attempt orgs are retired after 24 hours (#169). A read-only inventory of legacy preview resources deletes nothing (#155). A Deploy Production failure on a missing generated contracts module was fixed (#258), and E2E runs leave branches clean (#193).

Key pull requests: #200 · #241 · #169 · #155 · 7 pull requests in this group, all in the source record

Typed project validation

Project validation moved from hand-written Zod schemas to validators generated from the TypeScript types with Typia. The editor builds its forms from the generated schema metadata, and the loader reports field paths. We adapted the existing generated-contract work to the editor, loader, CLI and sites.

Technical detail
  • Site schemas become HostSchema<T>: a generated validator with JSON Schema metadata. The editor builds its forms from that metadata, and the loader reports field paths. content-api drops zod and conformance rule A76 forbids it in every workspace package (#251).

Key pull request: #251 · 28 pull requests in this group, most of them build, test and CI changes, all in the source record

Before and after in numbers

Each row compares the state before the change with the state after it. Figures are taken from the pull request named in the last column.

MeasureBeforeAfterSource
Image movement on How it works during delayed hydration (browser test)397.587 px0 px across 53 frames#342 body
PR-stage Durable Object namespaces after the first eviction runAbout 170 leaked; Deploy Stage failing with error 10067386 of 500#200 body
Durable Object namespaces per stage109#241 body
CMS site snapshot import33.6 MB in one call, over the 32 MiB limitParts of at most 16 MiB#259 body
Resize events during a story play30 and 110 and 0#257 body

Awaiting team review: theme picker

Opened in November and separate from the October merges above. Implemented and checked, not merged.

IMPLEMENTED · NOT MERGED

Documentation theme picker

The documentation site’s native Auto dropdown is replaced by Light, Dark and System controls with a visible selection, keyboard navigation and touch targets. The head of the pull request passed its deployed-stage browser tests, and the preview site is live. The change awaits team review.

#489 · Preview · Deployed E2E

Before and after

The theme control on production and on the pull request #489 preview, both captured at 1440 px on 5 November. Each crop cuts the header where the control sits. Click a crop to open the full capture. The before image is production and the after image is the preview of an open pull request that is not merged.

Documentation theme control

Open pull request, not merged Before and after: same window, same region, same scale.

Header of conloca.com getting started on production: the theme control is a native select reading Auto
Before · production Production conloca.com, captured 5 November 2026: the theme control is a native select. Full-size original (1440×1000 PNG)
  1. It is a native select that opens an operating-system menu.
Same header on the pull request 489 preview stage: the theme control is a segmented control with Light, Dark and System, and System is highlighted
After · PR preview Pull request #489 preview stage, same page, viewport and crop: Light, Dark and System as a visible control. Full-size original (1440×1000 PNG)
  1. Three visible choices; the active one, System, is highlighted.

Same page (getting-started), viewport 1440×1000 and crop, captured two seconds apart on 5 November 2026. The before image is production conloca.com. The after image is the pull request #489 preview stage, a different deployment of an open pull request.

Proof

Recordings. The four clips on this page are production browser checks recorded by the team and attached to pull requests. They are not CI or end-to-end test runs and not full acceptance. The repository’s CI keeps no video or trace artifact, and a CI job page is not a recording, so none is presented as one.

Owner priority (excerpt)

Original request (RU)

Полностью рабочая конлока в нашем продукте, подтвержденная е2е тестами и скриншотами

English translation

A fully working Conloca in our product, confirmed by e2e tests and screenshots.

Source. Ultra / Mextner · Telegram, private chat between Ultra and the assistant bot · Telegram message id 180834 · 18 August 2026, 17:54 UTC. Sender: incoming Telegram message from the owner's account (not the assistant, not another person). Full-message SHA-256 d65be6db2be49447aa7b6467294c830b9bbc2c0007f3f48de41a7a4d7ccf4618.

18 August 2026, before the October period of this report; kept because it states the owner's standing priority.

Hosted CI runs for the final commit of each pull request, or for the merge commit where noted.

Work by Ultra / Mextner (GitHub alex-mextner, Alex Ultra). Pull requests merged 1 to 31 October 2026 are credited by commit authorship, and 92 merged pull requests are counted, one of them for named commits only. Status checked 6 November. Source links may require repository access.

Attribution: every commit in these pull requests is by Ultra, except #177. #167, #168 and #169 were opened from the smoothbricker account and merged by alex-mextner. #177 is credited only for three of Ultra’s 29 commits there: the stale preview-session repair, its at-head regression test and the browser publication proof. Pull requests whose commits are by other authors are counted only in aggregate in the source record.

All merged pull requests counted here are listed with their authors and merge commits in the source record.

+

Conloca: October 2026

Editor fixes, workspace safety, content integrity, the production How it works page

Ultra / Mextner · October 2026

Overview

Conloca is a visual CMS for Astro sites: editors change pages in the browser and the content is committed to Git. In October Ultra / Mextner delivered fixes across the editor, invites and sign-in, content and media handling, and the production site.

The documentation theme picker is implemented and checked but awaits team review, so it is shown separately below.

397.6 → 0 px
How it works image movement during delayed hydration, in the browser test of #342
33.6 MB
snapshot that now imports in bounded parts of at most 16 MiB (#259)
409
answer to a write from an editor tab whose repository, branch or site differs, given before any billing, storage or Git work (#192, #224)

What we delivered

Editor and page actions

Dragging blocks into a page, Undo after adding a block and the Dashboard New Page button now work. A disabled Preview button explains why it is unavailable. Never-published pages read Draft in the Pages list and on the Dashboard. A route or schema error shows a CMS error page or notice instead of the developer screen, and the branch-name field formats as you type. These were everyday actions that did nothing or showed the wrong state.

Owner request (excerpt)

Original request (RU)

все баги которые никто не делает и почини по tdd в параллельных ворктри и влей через gh ship
Важны максимально реалистичные е2е тесты
В задачи поставь меня исполнителем
Приложи пруфами скриншоты до и после

English translation

all the bugs nobody is working on, and fix them with TDD in parallel worktrees and merge through gh ship. Maximally realistic e2e tests are important. Put me as the assignee in the tasks. Attach screenshots from before and after as proof.

Source. Ultra / Mextner · Ultra's omp prompt history, project conloca · no message id · 22 October 2026, 10:39 UTC. Sender: the owner's own prompt history; it has no per-message author field, so attribution is by account. Full-message SHA-256 1ea5051957cda4839152034111af4c51789e7761deb61386ab53bc2627c82c4d.

The opening words of the message and the link to the private bug database are left out.

Owner request (excerpt)

Original request (RU)

И параллельно в новом вт почини

English translation

And in parallel, in a new worktree, fix [the linked bug-database entry “Dashboard New page button bug”].

Source. Ultra / Mextner · Ultra's omp prompt history, project conloca · no message id · 22 October 2026, 18:09 UTC. Sender: the owner's own prompt history; it has no per-message author field, so attribution is by account. Full-message SHA-256 7669ba062bc44797708bedd3cc4b6cbc332f79d389145bf379003cdf2ee20979.

Owner request (excerpt)

Original request (RU)

еще задача: Cannot drag blocks onto an empty page. no block is added and the canvas remains empty. No error messages or guidance is displayed.

English translation

one more task: [English bug text, as pasted from the bug database:] Cannot drag blocks onto an empty page. no block is added and the canvas remains empty. No error messages or guidance is displayed.

Source. Ultra / Mextner · Ultra's omp prompt history, project conloca · no message id · 22 October 2026, 23:45 UTC. Sender: the owner's own prompt history; it has no per-message author field, so attribution is by account. Full-message SHA-256 e3869c29e076499fd4a50480adf8214b79b44f05f6143248f2f1db6ae57f3d9f.

Owner request (excerpt)

Original request (RU)

и еще одна: Pages - Status badges don’t reflect real status. All pages are always showing published. Even when I just created one.

English translation

and one more: [English bug text, as pasted from the bug database:] Pages - Status badges don’t reflect real status. All pages are always showing published. Even when I just created one.

Source. Ultra / Mextner · Ultra's omp prompt history, project conloca · no message id · 22 October 2026, 23:46 UTC. Sender: the owner's own prompt history; it has no per-message author field, so attribution is by account. Full-message SHA-256 f2437f51dc49ba9358e730e76d4e740c178b5d078d72d5653d554744d4a7d06c.

New branch field: original request and production recording

Owner request (excerpt)

Original request (RU)

и вот эту возьми: New branch - Branch name formatting problem. Problem:

SPACE can’t be used in a branch name, but we still allow users to type it and then show error.

Solution:

We need to automatically format the user inputed text like following: enforce lowercase, automatically type - when user uses SPACE.

English translation

and take this one too: [English bug text, as pasted from the bug database:] New branch - Branch name formatting problem. Problem: SPACE can’t be used in a branch name, but we still allow users to type it and then show error. Solution: We need to automatically format the user inputed text like following: enforce lowercase, automatically type - when user uses SPACE.

Source. Ultra / Mextner · Ultra's omp prompt history, project conloca · no message id · 22 October 2026, 23:51 UTC. Sender: the owner's own prompt history; it has no per-message author field, so attribution is by account. Full-message SHA-256 fdf731854e8a0dd58796a4e33ebfdc825f582d5f60d945a7fed1d64f4b204e3a.

The recording is footage of the production CMS made by the team and attached to pull request #316. This page shows a cropped copy of the New branch form. It checks only that the caret stays in place while the text is formatted.

Recorded production browser check New branch field keeps the caret while formatting. Footage recorded by the team on the production site and attached to the pull request. It is not a CI or end-to-end test run and not full acceptance. MP4 file
Page
the New branch form in the production CMS
Pull request
#316 (merged), the original recording shows a signed-in workspace and stays in the private repository; this page shows a cropped copy of the New branch form only
Recorded
29 October 2026, 15:00 UTC (attached to the pull request on 3 November), 10 seconds; real Chrome against the production CMS, signed in; the form was exercised without submitting
What it shows
Typing in the Branch name field while the caret sits after a Greek sigma. The pull request reports five DOM-backed checks passing for this scenario. It is not branch creation or release sign-off.
File
600×460, 10.05 s, 100 frames, no audio. MP4 SHA-256 175ed0005255fa6b785d89339335211cda5760fd74ba0f45ecd38630a0455a8d, WebM alternate SHA-256 8f160203355c2076ac9eedc6b893fc30effaf35460d3a51e2aa58565ccffae71. This is a derived copy: the original recording is not republished; it was cropped to the form (region 300×230 px at 182,40, scaled ×2). Original SHA-256 ce25011c07367aff2de27d53927b8212f55af2815cf55b72c731146268f84c86.

Sign-in divider in the dark theme

Merged, pull request #220 Single capture: after only.

Sign-in divider in dark theme: the lines and the word or are visible against the dark card
Frame of the recording Frame at 3.9 s of the production recording below: the sign-in divider in the dark theme. Full-size original (1280×800 PNG)
  1. The divider lines and the word “or” are visible against the dark card.

A frame of the production recording of pull request #220 shown below, at 3.9 seconds, 1280×800. The recording has no before capture.

Sign-in divider: production browser checks, desktop and phone width

Footage of the production sign-in page made by the team and attached to pull request #220. Each clip starts in the light theme and switches to the dark theme.

Recorded production browser check Sign-in divider, desktop, light then dark. Footage recorded by the team on the production site and attached to the pull request. It is not a CI or end-to-end test run and not full acceptance. MP4 file
Page
the production sign-in page
Pull request
#220 (merged), attached to the pull request in the private repository conloca/private (access required)
Recorded
3 November 2026 (comment date), 4.1 seconds; real Chrome against production, 1280×800, no account signed in
What it shows
The divider colour in the light and then the dark theme. It is not an accessibility audit and not a pixel baseline.
File
1280×800, 4.1 s, 41 frames, no audio. MP4 SHA-256 330c04b0fbeaef98ad798bbf28e8d1da629bf2361b991f2fb8cb398bcb6fa486, WebM alternate SHA-256 757c84c56eb00c37b637d52b7b098391a008aba6102266a50eb7ca31f2b4b37d.
Recorded production browser check Sign-in divider, phone width, light then dark. Footage recorded by the team on the production site and attached to the pull request. It is not a CI or end-to-end test run and not full acceptance. MP4 file
Page
the production sign-in page
Pull request
#220 (merged), attached to the pull request in the private repository conloca/private (access required)
Recorded
3 November 2026 (comment date), 4.1 seconds; real Chrome against production, 390×844, no account signed in
What it shows
The divider colour in the light and then the dark theme at phone width.
File
390×844, 4.1 s, 41 frames, no audio. MP4 SHA-256 da4c5ba19643cd24c82add4cf54016982a0ceb5c220de52909a15f09a6ade046, WebM alternate SHA-256 d6a59fe733578ce1962f2ec756aa2f0b655585a465922deb9b1743c841e7c491.
Technical detail
  • Puck ignores a press on a real <button>, so the block-list item is a div role="button" again, and an empty page says how to add a block (#299). Undo and Redo remove and restore a block added by drag or double-click (#306).
  • The Dashboard New Page button opens the create-page dialog in place (#302). One pageStatusOf() and a LocaleVersion.unpublished marker decide page status, and saving a new translation keeps a never-published page a draft (#296, #307).
  • A route that fails to render shows RouteErrorPage, and a site schema that is not a generated host schema shows a notice instead of crashing the CMS (#301, #293, #295). The disabled Preview button shows its explanation when clicked (#262).
  • The New branch field lowercases, hyphenates and keeps the caret in place as you type (#297, #316). The editor opens pages with no English variant (#196), and draft previews parse records with each collection’s schema so dates and defaults match the build (#248).
  • Frontmatter keys such as __proto__.polluted cannot mutate Object.prototype, while own-data keys, including legitimate constructor and prototype names, are kept (#239). The sign-in divider is readable in dark mode; login-theme.spec.ts checks light and dark at 390 and 1280 px (#220).

Key pull requests: #299 · #306 · #302 · #296 · #301 · #297 · 15 pull requests in this group, all in the source record · CI run for #299 · CI run for #302 · CI run for #296

Invites, tabs and sign-in stay in the right place

Accepting an invite lands in the invited workspace, from both the in-app button and the emailed link. Each editor tab sends its repository, branch and site with every write, and the server rejects a mismatch with a 409 instead of writing to the wrong place. Tabs of one browser origin that refresh at the same moment share one token rotation instead of revoking the whole token family.

Owner request

Original request (RU)

Задача: When inviting someone to a workspace, they don't always get redirected to the invited workspace when clicking accept invite in a received mail

English translation

Task: [English bug text, as pasted from the bug database:] When inviting someone to a workspace, they don't always get redirected to the invited workspace when clicking accept invite in a received mail

Source. Ultra / Mextner · Ultra's omp prompt history, project conloca · no message id · 22 October 2026, 13:27 UTC. Sender: the owner's own prompt history; it has no per-message author field, so attribution is by account. Full-message SHA-256 59a3431d16bdddc2b358f19a80548dfcf20b9e974aeed17282ce6a3d534902aa.

Technical detail
  • Mutations carry X-Conloca-Editor-Repo, -Branch and -Site headers. The worker answers 409 workspace-mismatch before any billing, storage or Git work, and the tab re-enters its own branch and retries once (#192, #224).
  • Accept waits at most 5 seconds for the membership flush and the Org Durable Object’s alarm delivers the rest; an invite screen that would stay on “accepting” is released after 20 seconds (#292, #305). A deployed-stage proof, invite-landing.spec.ts, covers an invitee who already has a workspace (#294).
  • A second use of a refresh cookie within 10 seconds gets the live token from the rotation chain, and the browser refreshes under a Web Lock so same-origin tabs send one request per rotation (#240). An OAuth failure shows its failure screen instead of looping (#225).
  • Splitting the sign-in and Members screens into props-only views fixed a double submit that requested two sign-in links and a double click that sent two invitations (#253, #223).
  • Cloudflare Access configuration fails closed with 401 when only one of its two settings is present (#191). Overlay rows for pages deleted in Git are pruned (#188). Workspace and flag types are narrowed instead of cast (#222).

Key pull requests: #288 · #289 · #192 · #224 · #240 · #225 · 14 pull requests in this group, all in the source record · CI run for #288 · CI run for #289 · CI run for #192

Scoped content commits, safe asset moves and correct write-back

CMS commits include only content files, so other people’s staged work is left out, and an asset move claims its destination instead of overwriting an existing file. Draft images render in the canvas before Publish, and a docs-root page is written back to the file it was read from. The hosted preview shows pages committed after its build, and a site snapshot over Cloudflare’s 32 MiB call limit imports in bounded parts.

Technical detail
  • CMS commits build their tree in a private index seeded from HEAD and move HEAD by compare-and-swap with update-ref, so a concurrent commit is not reverted. Asset moves run one at a time and claim the destination with a hard link. Tests use real temporary repositories: foreign staged files, two concurrent instances, a held index.lock and concurrent moves racing for one name (#197).
  • Draft images are served from /api/v1/assets/draft/<folder>/<file> while stored data keeps the canonical /assets/... reference (#243). A docs-root MDX page used to be written to a shadow file; mdx-pages-root.test.ts covers edit, delete, create-after-delete and a collision (#235).
  • The hosted preview records its own buildCommit and sends it as ?build=; the worker diffs that commit against the branch head and matches entries by blob id. A deployed-stage test commits a title without redeploying and expects the new heading (#247, spec change #228).
  • The depth-1 snapshot of one pull request packs to about 33.6 MB, over the 32 MiB RPC limit. It now lands in parts of at most 16 MiB with the tree and commit last, and a live check against github.com imported the full closure of 4,836 objects (#259). A missing base tree is fetched by object id instead of failing the import (#256).
  • Org import now always retries the tracker reconcile when a ref already matches upstream, so a stale preview session recovers (#177). Only three of Ultra’s 29 commits in #177 are credited: the repair, its at-head regression test and the browser publication proof. The vocabulary sample stays off the Git lookup behind the unpublished marker (#308).

Key pull requests: #197 · #243 · #235 · #247 · #259 · #177 · 9 pull requests in this group, all in the source record · CI run for #197 · CI run for #247 · CI run for #259

The finished How it works page is on conloca.com

The production How it works page uses the completed design: a four-step flow with MDX, JSON and editor visuals, twelve responsive images and an install banner that survives 200% text. The design is by Saba; our work is the integration into the production site and its checks. In the pull request’s delayed-hydration test, images moved 397.6 px before the fix and 0 px after it.

How it works on production: browser check

Footage of the production page made by the team and attached to pull request #342. The page is public. There is no before footage.

Recorded production browser check How it works page on production. Footage recorded by the team on the production site and attached to the pull request. It is not a CI or end-to-end test run and not full acceptance. MP4 file
Page
https://conloca.com/how-it-works
Pull request
#342 (merged 27 October 2026), attached to the pull request in the private repository conloca/private (access required)
Recorded
28 October 2026, 20:14 to 20:15 UTC; real Chrome against production, viewport 1348×936, no cuts or speed changes
What it shows
Hero, the four-step flow, the layered visual, the cards, the install banner, the pnpm, npm and bun tab selection, and the footer Docs link, on desktop only.
File
1364×936, 16.939 s, 165 frames, no audio. MP4 SHA-256 5628cd2e6f68945643b61506d45eafa00a8ff45e68ef9796e6199fc04857af7c, WebM alternate SHA-256 7fc70c7839e6a94e60afb3731601f153f81acfb919f4a0db993d6f3291ce76f2.
Technical detail
  • The twelve PNGs were imported byte for byte, with SHA-256 and byte lengths checked on the preview. Existing routes, app links, docs links and install tabs are kept, and text is darkened where the original failed contrast (#342).
  • The test measured 397.587 px of movement before and 0 px across 53 frames after. Twenty-one website targets and 50 browser checks were rerun.
  • The merge to the main branch ran Validate, deployed-stage browser tests and Deploy Production, all successful. Locally, the split-port development stack redirects backend landings to the app and keeps published media on local origins (#231).

Key pull requests: #342 · #231 · CI run for #342 · conloca.com/how-it-works

Browser and story coverage for the editor

The CMS and the app each build a static Storybook catalogue in CI, and state stories cover save, sync and workspace status, the page list and the conflict dialogs. Deployed-stage browser tests walk every CMS route, create a branch through the Branch menu, confirm a new page reads Draft and check that typed text survives reopening the editor in both themes. CI keeps the proof folder of every deployed-stage run.

Technical detail
  • State stories render the real components with fixtures that stop at HostClient and the content API fetch, so nothing reaches the network. Counts: SaveSlot 6 plus phone, SyncStatusSlot 8 plus phone, WorkspaceStatusSlot 8 plus phone, CmsHostPlaceholder 9 (#244). CI saves a screenshot of every story at 1280 × 800 and 390 × 844. The app Storybook runner now compiles Tailwind, because classes such as max-sm:hidden were missing from all app examples.
  • A flaky failure in the Several Locales scenario, caused by a viewport resize landing mid-play, is gone: resizes during play went from 30 and 11 to 0 and 0 in the probe runs (#257).
  • The deployed-stage job keeps its proof folder on every run and the Playwright report on failed runs (#320). A manual staging proof workflow adds two new legs (#261), and the emitted billing deploy bundle runs in CI (#238).
  • Real-engine and typed tests for Git paths, billing identity mapping, workspace recovery and memory behaviour were added or made deterministic (#198, #234, #221, #236, #201, #254). Branch creation and the Draft check are in #229 and #309, and the editor-reopen check is in #226.

Key pull requests: #217 · #244 · #304 · #229 · #300 · #320 · 17 pull requests in this group, all in the source record · CI run for #229 · CI run for #300

A pull-request stage environment that keeps working

Pull-request stages are cleaned up on a schedule with capacity reporting and stage leases, which brought the Cloudflare namespace count to 386 of 500 after the first eviction run. Each stage uses one Durable Object namespace fewer, and each deployment attempt gets its own preview fixture without resetting drafts. Before this, Deploy Stage was failing account-wide with Cloudflare error 10067 after about 170 namespaces leaked from closed pull requests.

Technical detail
  • A scheduled workflow runs every six hours, reports capacity and fails above 400 of 500 namespaces. Drafts hold a stage for 24 hours and ready pull requests for 72 hours; keep-stage and evict-stage override that. tooling/pr-stage-gc.test.ts checks that only closed same-repo pull requests are selected (#200).
  • Deleting the unused EventLogDO takes each stage from 10 namespaces to 9, which the pull request estimates moves live capacity from about 48 to about 53 stages (#241).
  • Readiness rejects dirty overlays and divergent session heads, and older attempt orgs are retired after 24 hours (#169). A read-only inventory of legacy preview resources deletes nothing (#155). A Deploy Production failure on a missing generated contracts module was fixed (#258), and E2E runs leave branches clean (#193).

Key pull requests: #200 · #241 · #169 · #155 · 7 pull requests in this group, all in the source record

Typed project validation

Project validation moved from hand-written Zod schemas to validators generated from the TypeScript types with Typia. The editor builds its forms from the generated schema metadata, and the loader reports field paths. We adapted the existing generated-contract work to the editor, loader, CLI and sites.

Technical detail
  • Site schemas become HostSchema<T>: a generated validator with JSON Schema metadata. The editor builds its forms from that metadata, and the loader reports field paths. content-api drops zod and conformance rule A76 forbids it in every workspace package (#251).

Key pull request: #251 · 28 pull requests in this group, most of them build, test and CI changes, all in the source record

Before and after in numbers

Each row compares the state before the change with the state after it. Figures are taken from the pull request named in the last column.

MeasureBeforeAfterSource
Image movement on How it works during delayed hydration (browser test)397.587 px0 px across 53 frames#342 body
PR-stage Durable Object namespaces after the first eviction runAbout 170 leaked; Deploy Stage failing with error 10067386 of 500#200 body
Durable Object namespaces per stage109#241 body
CMS site snapshot import33.6 MB in one call, over the 32 MiB limitParts of at most 16 MiB#259 body
Resize events during a story play30 and 110 and 0#257 body

Awaiting team review: theme picker

Opened in November and separate from the October merges above. Implemented and checked, not merged.

IMPLEMENTED · NOT MERGED

Documentation theme picker

The documentation site’s native Auto dropdown is replaced by Light, Dark and System controls with a visible selection, keyboard navigation and touch targets. The head of the pull request passed its deployed-stage browser tests, and the preview site is live. The change awaits team review.

#489 · Preview · Deployed E2E

Before and after

The theme control on production and on the pull request #489 preview, both captured at 1440 px on 5 November. Each crop cuts the header where the control sits. Click a crop to open the full capture. The before image is production and the after image is the preview of an open pull request that is not merged.

Documentation theme control

Open pull request, not merged Before and after: same window, same region, same scale.

Header of conloca.com getting started on production: the theme control is a native select reading Auto
Before · production Production conloca.com, captured 5 November 2026: the theme control is a native select. Full-size original (1440×1000 PNG)
  1. It is a native select that opens an operating-system menu.
Same header on the pull request 489 preview stage: the theme control is a segmented control with Light, Dark and System, and System is highlighted
After · PR preview Pull request #489 preview stage, same page, viewport and crop: Light, Dark and System as a visible control. Full-size original (1440×1000 PNG)
  1. Three visible choices; the active one, System, is highlighted.

Same page (getting-started), viewport 1440×1000 and crop, captured two seconds apart on 5 November 2026. The before image is production conloca.com. The after image is the pull request #489 preview stage, a different deployment of an open pull request.

Native stage proof, 7 November

Dated 7 November 2026 and separate from the October results above: it is not counted in any October number.

DEPLOYED ON PR404; NOT MERGED

Native Cloudflare stage for pull request #404

The pull request builds its own stage on Cloudflare. Three direct links, sign-in with normal Conloca repository access may be required for Storybook:

The deployed-stage checks of that run passed: 53 end-to-end tests against the deployed stage, and 4 Storybook checks (sign-in, readiness and two catalogue journeys). They are not the four product journeys and not full product acceptance. No trace, replay or visual diff was produced.

Recordings. That run recorded two WebM videos of the deployed stage, a desktop view of the CMS dashboard and a 390 px view of the app, with four PNG captures and provenance files. They sit in a private CI artifact, a download that needs GitHub access to the repository. Label: ACCESS-RESTRICTED and temporary, it expires on 2026-11-21 and is not a permanent video archive. Nothing is embedded or rehosted on this page. The CI run page is the stable link and is not a recording.

Technical detail
  • Pull request head 9d469170dbe5504704dae7b6a32d4825cdb11765, stage build ce4948f9558870dce11f07102a643e2807c73395, run 42375596312, artifact 13576130686.
  • Artifact: 519359 bytes, SHA-256 85cef4edb76cfb7f3292c93c060e57e1e9cdb6625ea5738be4cc5d5ce1859cf5, expires 2026-11-21T13:18:03Z.
  • CMS recording: 1280×800, 5.600 s, 140 frames, story components-cms dashboard overview, SHA-256 7c7739c6526730c3ea906b852e7f2ce7a0d7df39d218a6147954b6cea2257f2a.
  • App recording: 390×844, 4.880 s, 122 frames, story app-cms host placeholder, preparing branch, SHA-256 1fcf67580aec5acd7bd74c70b20d565b229f5d1f9c9f92ea53e2baa181105e00.
  • Both case records name the same head and build before and after the recording; that is identity, not a before and after of the interface. Verified 7 November 2026 by downloading the artifact and decoding both videos in full. Record: native-stage-proof.json. Human browser approval and a permanent main stage are not verified.

Proof

Recordings. The four clips on this page are production browser checks recorded by the team and attached to pull requests. They are not CI or end-to-end test runs and not full acceptance. They predate the November native-stage check below, whose two CI recordings are linked there. A CI job page is not a recording, and the run page is never presented as one.

Owner priority (excerpt)

Original request (RU)

Полностью рабочая конлока в нашем продукте, подтвержденная е2е тестами и скриншотами

English translation

A fully working Conloca in our product, confirmed by e2e tests and screenshots.

Source. Ultra / Mextner · Telegram, private chat between Ultra and the assistant bot · Telegram message id 180834 · 18 August 2026, 17:54 UTC. Sender: incoming Telegram message from the owner's account (not the assistant, not another person). Full-message SHA-256 d65be6db2be49447aa7b6467294c830b9bbc2c0007f3f48de41a7a4d7ccf4618.

18 August 2026, before the October period of this report; kept because it states the owner's standing priority.

Hosted CI runs for the final commit of each pull request, or for the merge commit where noted.

Work by Ultra / Mextner (GitHub alex-mextner, Alex Ultra). Pull requests merged 1 to 31 October 2026 are credited by commit authorship, and 92 merged pull requests are counted, one of them for named commits only. Status checked 6 November. Source links may require repository access.

Attribution: every commit in these pull requests is by Ultra, except #177. #167, #168 and #169 were opened from the smoothbricker account and merged by alex-mextner. #177 is credited only for three of Ultra’s 29 commits there: the stale preview-session repair, its at-head regression test and the browser publication proof. Pull requests whose commits are by other authors are counted only in aggregate in the source record.

All merged pull requests counted here are listed with their authors and merge commits in the source record.

diff --git a/reports/conloca-2026-10/native-stage-proof.json b/reports/conloca-2026-10/native-stage-proof.json new file mode 100644 index 0000000..604ca85 --- /dev/null +++ b/reports/conloca-2026-10/native-stage-proof.json @@ -0,0 +1,37 @@ +{ + "purpose": "Verification record for the 7 November native-stage proof block of the Conloca October report; a private temporary artifact, not a public rehost.", + "verifiedAt": "2026-11-07T13:45:00Z", + "head": "9d469170dbe5504704dae7b6a32d4825cdb11765", + "build": "ce4948f9558870dce11f07102a643e2807c73395", + "stageUrls": [ + "https://site.pr404.conloca.com/", + "https://app.pr404.conloca.com/", + "https://storybook.pr404.conloca.com/" + ], + "runUrl": "https://github.com/conloca/private/actions/runs/42375596312", + "runId": 42375596312, + "artifactId": 13576130686, + "artifactUrl": "https://github.com/conloca/private/actions/runs/42375596312/artifacts/13576130686", + "artifactSha256": "85cef4edb76cfb7f3292c93c060e57e1e9cdb6625ea5738be4cc5d5ce1859cf5", + "artifactSize": 519359, + "artifactExpiresAt": "2026-11-21T13:18:03Z", + "videos": [ + { + "id": "cms", + "width": 1280, + "height": 800, + "durationSeconds": 5.6, + "frames": 140, + "sha256": "7c7739c6526730c3ea906b852e7f2ce7a0d7df39d218a6147954b6cea2257f2a" + }, + { + "id": "app", + "width": 390, + "height": 844, + "durationSeconds": 4.88, + "frames": 122, + "sha256": "1fcf67580aec5acd7bd74c70b20d565b229f5d1f9c9f92ea53e2baa181105e00" + } + ], + "kind": "private-temporary-ci-artifact-not-embedded" +} diff --git a/scripts/ci/check-media-report.py b/scripts/ci/check-media-report.py index 6cbdbac..5fe5f5f 100644 --- a/scripts/ci/check-media-report.py +++ b/scripts/ci/check-media-report.py @@ -429,7 +429,7 @@ def test_public_record_and_pages_hold_no_private_identifiers(self): self.assertNotIn(b, blob, b) def test_links_on_the_pages_stay_on_allowed_origins(self): - allowed = ("https://github.com/", "https://tasks.glide.vc/", "https://conloca.com", "https://site.pr489.conloca.com/", "https://linear.app/") + allowed = ("https://github.com/", "https://tasks.glide.vc/", "https://conloca.com", "https://site.pr489.conloca.com/", "https://site.pr404.conloca.com/", "https://app.pr404.conloca.com/", "https://storybook.pr404.conloca.com/", "https://linear.app/") for key, page in self.pages.items(): for url in Links(page).urls: if url.startswith("http"): diff --git a/scripts/ci/check-native-stage-proof.py b/scripts/ci/check-native-stage-proof.py new file mode 100644 index 0000000..e1b2eba --- /dev/null +++ b/scripts/ci/check-native-stage-proof.py @@ -0,0 +1,104 @@ +"""Contract for the 7 November native-stage proof block on the Conloca October report. + +The block and reports/conloca-2026-10/native-stage-proof.json must agree. The October period and the +October counts stay untouched; the November addendum is a separate, dated block. + +Run: python3 scripts/ci/check-native-stage-proof.py +""" + +import json +import re +import sys +import unittest +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).resolve().parent)) +from _report_html import Links, VisibleText # noqa: E402 + +ROOT = Path(__file__).resolve().parents[2] +DIR = ROOT / "reports/conloca-2026-10" +HEAD = "9d469170dbe5504704dae7b6a32d4825cdb11765" +RUN = "https://github.com/conloca/private/actions/runs/42375596312" +ARTIFACT = "https://github.com/conloca/private/actions/runs/42375596312/artifacts/13576130686" +STAGES = ["https://site.pr404.conloca.com/", "https://app.pr404.conloca.com/", "https://storybook.pr404.conloca.com/"] + + +class NativeStageProof(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls.raw = (DIR / "index.html").read_text(encoding="utf-8") + cls.rec = json.loads((DIR / "native-stage-proof.json").read_text(encoding="utf-8")) + cls.block = cls.raw.split('id="native-stage-proof"', 1)[1].split("", 1)[0] + cls.text = VisibleText(cls.block).raw + + def test_three_direct_stage_links_and_nothing_else_for_stages(self): + urls = [u for u in Links(self.block).urls if "pr404.conloca.com" in u] + self.assertEqual(urls, STAGES) + self.assertEqual(self.rec["stageUrls"], STAGES) + for label in ("Landing", "CMS app", "Storybook"): + self.assertIn(label, self.text) + + def test_run_and_artifact_links_are_distinct_and_exact(self): + urls = Links(self.block).urls + self.assertIn(RUN, urls) + self.assertIn(ARTIFACT, urls) + self.assertNotEqual(self.rec["runUrl"], self.rec["artifactUrl"]) + self.assertEqual((self.rec["runUrl"], self.rec["artifactUrl"]), (RUN, ARTIFACT)) + self.assertEqual(self.rec["runId"], 42375596312) + self.assertEqual(self.rec["artifactId"], 13576130686) + self.assertIn("https://github.com/conloca/private/pull/404", urls) + + def test_artifact_is_labelled_private_and_temporary_and_not_embedded(self): + low = self.text.casefold() + for word in ("access-restricted", "temporary", "2026-11-21", "not full product acceptance", "deployed on pr404; not merged"): + self.assertIn(word, low) + self.assertIn("not a permanent video archive", low) + self.assertNotRegex(self.block, r".*?', "", page, flags=re.S) + for url in Links(page).urls: if "/actions/runs/" in url: self.assertIn(url, receipts)