Skip to content

Builder demo library: 322 example pages/sections + 14 behaviour suites (schemas + actions + controls that run) β€” /builder/demos - #578

Merged
lopugit merged 48 commits into
developfrom
claude/builder-demo-library
Sep 6, 2026
Merged

lopugit merged 48 commits into
developfrom
claude/builder-demo-library

Conversation

@lopugit

@lopugit lopugit commented Sep 2, 2026

Copy link
Copy Markdown
Owner

βœ… Develop S3 preview ready

The alias passed the develop bucket CORS preflight and a final live PR/SHA fence.

Generic Vercel Preview deployments use the shared development runtime; this controller adds the stable exact-SHA alias and marker-scoped cleanup.

Builder demo library β€” 322 example pages/sections + 14 behaviour suites (schemas + actions + controls that run)

A code-generated, deterministic demo library, browsable at /builder/demos, seedable as system things, and cloneable/installable into any viewer's own things through the ordinary things write path.

Part 1 β€” webpage demos (remix/app/schemas/webpageDemos.ts, isomorphic, pure)

  • 28 section families Γ— layouts Γ— tones = 274 section demos (hero, features, pricing, testimonials, cta, faq, stats, team, logo cloud, steps, gallery, footer, header, newsletter, blog list, contact, timeline, comparison, banner, quote, media+text, cards, checklist, video, profile, schedule, menu, article).
  • 20 full-page recipes Γ— 2 tones = 40 page demos (landing, startup, about, pricing, blog, contact, event, portfolio, product, docs, changelog, link-in-bio, restaurant, agency, community, newsletter, coming soon, thank you, careers, video launch) composed from the same section builders.
  • 4 component-block compositions Γ— 2 tones = 8 component demos referencing library component keys.
  • Six restrained tones and six fictional brands' copy rotating deterministically. Every demo clears validateThingtimeCrystal(['webpage']) unchanged (unit-tested for the whole catalog, with block/byte headroom, slug grammar, family coverage, determinism).

Part 2 β€” behaviour suites (remix/app/schemas/behaviourSuites.ts)

Data Thing + Component Thing + Action Thing = program. Each of the 14 suites bundles schemas, ttAction-bound controls, declarative actions, sample data, and a builder page around one story β€” guestbook, rsvp, poll, tasks, leads, inventory, feedback, tickets, habits, orders, bookmarks, check-in, expenses, hiring β€” and together they exercise the whole action vocabulary: things.create with $now, things.search, things.get + things.update by id, actions.invoke chains (parent budget), $step refs, ttConcat composition, enum/number inputs coerced from control args.

One definition materialises two ways, because of who may run what:

  • system β€” the admin seed writes public copies (schema-demo-*, component-demo-*, action-demo-*, data-demo-*, webpage-demo-suite-*) through the site seed's reconciling upsert (now kind-aware). Every part is browsable on /schemas, /components, /actions, /p/; a signed-in viewer runs a seeded action from /actions (it mints their data things against the public schema id).
  • own β€” Install suite clones the bundle into the viewer's things via /things in dependency order (schemas β†’ controls β†’ actions β†’ data stamped with the new schema ids β†’ page), schemas referenced by name and child actions by actionKey, so a ttAction click on their page resolves owner-only (source: 'component') and runs their own program end to end β€” with zero dependence on the seed.

The unit test validates all 250 materialised crystals (both modes) against their kind gates and checks that every control binds only its own suite's actions.

API

  • GET /api/v1/webpages/demos (public, webpages.demos rate limit, contract 1.1.0): catalog + families + per-deployment seeded flags; family= / kind= filters; slug= adds a demo's crystal; suites[] always; suite=<key> adds the installable own-mode bundle. 400/404 on bad shapes/unknown keys.
  • POST /api/v1/admin/webpages/seed-demos (+ GET census): seeds every demo page and every suite part; the census gains siteSeeded/demosSeeded/demosTotal/suitesSeeded/suitesTotal; admin-webpages-seed bumps to 1.1.0 (additive).
  • API docs entries, capability-manifest features, nine new webpages-group apiTests.

Gallery (/builder/demos)

  • Paints both catalogs instantly (optimistic rule), then reconciles seeded flags.
  • Kind + family chips and search synced to the URL; lazily-mounted scaled live thumbnails (with a hidden-document fallback timer); Show-more pagination; full-size preview modal.
  • Use template ✨ copies a demo into the viewer's page and opens the builder; πŸ§ͺ Suites tab with catalog-rendered previews (controls drawn from the suite's own component crystals β€” no seed needed), Install suite ✨, and /p/ + ⚑ /actions links once seeded; admins get a one-tap Seed button. Builder header links to the library; /builder/demos joins the site-page seed table.

Verification

  • test:schemas 119 βœ“ (webpageDemos 6/6 + behaviourSuites 4/4), test:api-capabilities 4/4 βœ“, test:webpages 29 βœ“, Vite build:client βœ“.
  • Headless apiTests --group webpages 18/18 βœ“ against the worktree dev stack.
  • End-to-end script through the real API (seed as admin β†’ install guestbook/leads/tasks as a throwaway user β†’ component-path runs, invoke chain, get+update, refusals, run records): 18/18 βœ“.
  • Browser: gallery, filters, thumbnails, preview modal, pagination, seeded /p/ and builder canvas, suites tab β€” desktop + mobile, no horizontal overflow.
  • TESTING.md: three new checklist blocks under "Design system + builder".

Post-merge

Run POST /api/v1/admin/webpages/seed-demos once per deployment (or press Seed on /builder/demos as an admin) so every demo opens at /p/webpage-demo-<slug> and every suite part is browsable.

πŸ€– Generated with Claude Code

Lopu sync resolver and others added 2 commits September 2, 2026 10:36
…component-block pages

A code-generated catalog (schemas/webpageDemos.ts) builds a few hundred
example webpages from family Γ— layout Γ— tone tables β€” 28 section families,
20 full-page recipes, and component-block compositions β€” every one of which
clears validateThingtimeCrystal(['webpage']) unchanged (asserted for the whole
catalog in the unit test, with headroom under the block/byte caps).

- GET /api/v1/webpages/demos (public, rate-limited) lists the catalog with
  families, counts, and a per-deployment seeded flag; slug= returns one demo's
  crystal for cloning through the ordinary /things write path.
- POST /api/v1/admin/webpages/seed-demos upserts every demo as a system-owned
  public webpage thing (shareId webpage-demo-<slug>) through the same
  reconciling, genuineness-fenced upsert the site-page seed uses (now shared);
  the seed census gains siteSeeded/demosSeeded/demosTotal (contract 1.1.0).
- /builder/demos gallery: paints the catalog instantly, kind/family/search
  filters synced to the URL, lazily-mounted scaled live thumbnails, Show more
  pagination, full-size preview modal, "Use template" cloning into the
  viewer's own page, /p/ + builder links once seeded, admin seed button; the
  Builder header links to it and the route joins the site-page seed table.
- API docs, capability manifest, apiTests (webpages group), and TESTING.md
  cover the new endpoints.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Row containers flex their children, so a ghost pill like "Read the docs"
wrapped onto two lines in the hero cta row β€” the button helper now sets
white-space: nowrap. The gallery card meta counted root blocks (always 1
for a wrapped section); it now reports the whole tree via countDemoBlocks.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actions github-actions Bot added lopu: mergeable The PR branches can currently be merged without conflicts lopu: overlapping files This PR changes files also changed by another open PR labels Sep 2, 2026
Browsers throttle IntersectionObserver callbacks in hidden documents, so a
gallery opened in a background tab painted empty cards until it was
fronted β€” the thumbnail now also mounts on a 1.2s fallback timer (the page
is paginated, so that is at most 36 cheap renders). Pricing amounts in the
narrow three-tier columns wrapped mid-word ("Cust om"); they are nowrap now.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…s that run

Data Thing + Component Thing + Action Thing = program. Each suite
(schemas/behaviourSuites.ts) bundles the shapes, ttAction-bound controls,
declarative programs, sample data, and a builder page around one story β€”
guestbook, rsvp, poll, tasks, leads, inventory, feedback, tickets, habits,
orders, bookmarks, check-in, expenses, hiring β€” and exercises the whole
vocabulary: things.create with $now, things.search, things.get +
things.update by id, actions.invoke chains consuming the parent budget,
$step refs and ttConcat composition, enum/number inputs coerced from control
args.

One definition materialises two ways, because of who may run what:
- system: the admin seed writes public copies (schema-demo-*, component-demo-*,
  action-demo-*, data-demo-*, webpage-demo-suite-*) through the site seed's
  reconciling upsert, now kind-aware. Every part is browsable on its kind's
  page, and a signed-in viewer runs a seeded action from /actions (it mints
  THEIR data things against the public schema id).
- own: "Install suite" clones the bundle into the viewer's things via /things
  in dependency order (schemas β†’ controls β†’ actions β†’ data stamped with the
  new schema ids β†’ page), schemas referenced by name and children by
  actionKey, so a ttAction click on their page resolves owner-only and runs
  their own program end to end β€” zero dependence on the seed.

The unit test validates all 250 materialised crystals (both modes) against
their kind gates and checks that controls bind only their suite's actions.
GET /api/v1/webpages/demos lists suites (contract 1.1.0) and suite=<key>
returns the installable bundle; the gallery gains a πŸ§ͺ Suites tab with
catalog-rendered previews (controls drawn from the suite's own component
crystals, no seed needed), Install, and /p/ + /actions links once seeded.
Header/footer link labels no longer wrap mid-word.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@lopugit lopugit changed the title Builder demo library: 322 example sections, pages, and component-block pages (/builder/demos) Builder demo library: 322 example pages/sections + 14 behaviour suites (schemas + actions + controls that run) β€” /builder/demos Sep 2, 2026
github-actions Bot added a commit that referenced this pull request Sep 2, 2026
… + 14 behaviour suites (schemas + actions + controls that run) β€” /build…
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

πŸ€– Lopu review β€” b7fb9d0b vs main 7b6418bd

Checks are green on this exact head (25 pass / 56 skipped / 0 failing β€” including Build + typecheck ratchet + unit tests and the headless API suite), and the trusted CodeQL snapshot for this head is empty, so there was nothing to diagnose or dispose. I spent the review on the code itself.

Nice work. Generating the catalog as code and validating every materialised crystal through the real write gate β€” in both system and own modes β€” is the right shape, and it's what let me verify the rest quickly.

I paid particular attention to the surface this PR opens: it seeds public ownerId: 'system' / acl: ['tt:all'] action and data things, and documents that a signed-in viewer may run a seeded action. I traced all four ops through the executor. It holds up. things.update goes through updateThing, which filters { shareId, ownerId: viewer.id } and 404s otherwise β€” so passing data-demo-tasks-1 (or anyone else's id) to the seeded complete/escalate/mark-paid actions cannot mutate it. things.search is hard-scoped to the viewer, things.get honours ACL, and both id-resolving ops additionally require a data thing inside the declared schema scope. The system-mode scopes name schema shareIds (matching the stamped crystal.schemaId) and own-mode scopes name schema names (matching crystal.schema), so both materialisations stay inside their fence.

One real bug, fixed in the worktree

countSeededWebpages() counted the demo census as tags: 'demo', but suite pages are seeded ['webpage', 'demo', 'suite', <key>]. That demo tag is correct and load-bearing β€” seededDemoShareIds() needs it to resolve suite.seeded β€” but it also pulled all 14 suite pages into the demo bucket.

Against the real catalogs, a fully seeded deployment reports:

demosSeeded: 336   demosTotal: 322     ← can never reach parity

Both admin census endpoints return this object, and apiDocs documents the pair as the way to check seeding progress, so a caller polling "is the library seeded yet?" reads an answer that's permanently over 100%. Fixed by excluding the suite tag, which makes the three seeded counts a true partition of totalSeeded:

demosSeeded: await seededCount('demo', 'suite'),

The gallery was never affected β€” /api/v1/webpages/demos computes seededCount from the catalog, and the admin Seed button's notSeeded reads that endpoint rather than the census.

Nothing covered the census, so I added webpages-demos-census to apiTests.ts in the existing idiom (modelled on the adjacent webpages-demos-seed-admin-only, accepting 401/403). I drove its predicate through 8 states: it passes on fully seeded, partially seeded and fresh-DB, and fails on the pre-fix 336/322 payload.

I also corrected some stale integers in the new /docs/api examples β€” total: 314 β†’ 322, and the seed report received: 436 / suites.received: 114 β†’ 447 / 125 (the suite catalog grew to 125 parts after those examples were written). Every other field in those examples β€” ids, tags, blockCount: 7, count: 24, the guestbook summary β€” I checked byte-for-byte against real catalog output and they were all correct.

Two notes, your call β€” I left the code alone

  1. Thumb's 1200 ms fallback timer defeats the IntersectionObserver after 1.2s for every mounted card. The comment justifies it as "the page's own (paginated, ≀36) cards", but shown grows by PAGE_SIZE per Show more β€” nine taps mount ~322 live WebpageBlocksRenderer trees at once. If that bites on low-end mobile, the narrow fix is to run the fallback only for the first page's indices, rather than giving up the never-blank behaviour you deliberately added in 7f4a02e4.
  2. seededDemoShareIds() caps its projection at demos + suites + 64. Correct today (336 ≀ 400) and it scales with the catalog, but it truncates silently if the catalog ever shrinks while old seeded docs linger β€” stale demos would show as unseeded.

Also verified

322 demos (274 section / 40 page / 8 component) + 14 suites / 125 parts, with zero shareId, uniqueKey, or demo↔suite page-id collisions; every suite data entry resolves to a declared schema key; no undefined in any materialised crystal; both catalogs byte-identical across repeated materialisation in both modes. The upsertSystemThings extraction correctly keeps genuineness inside the update filter (now thingtime: def.kind), so a foreign doc squatting a destination id is still skipped rather than overwritten. And builder-demos follows the existing site-seed convention β€” like builder and feed, its native key isn't in the section registry, so it takes the documented children-passthrough path.

app/schemas/*.test.ts is 119/119 after my changes. test:webpages, test:api-capabilities, typecheck and the Vite build need remix/node_modules, which this reviewer sandbox doesn't have β€” they passed in CI on this head, and my edits touch no endpoint id, no contractVersion, and no exported signature those suites assert on.

Nothing blocking left. 🧱✨

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Lopu repository review

Lopu reviewed this PR against develop as Thingtime's principal PR and repository manager. Using Claude Opus 5.

Lopu found no justified local change to publish from this review pass.

PR #578 β€” Builder demo library: 322 example pages/sections + 14 behaviour suites

Compared: claude/builder-demo-library @ e87f9ff3 against base develop
@ 81bce89d (95 files; the 1.36M-line figure is one regenerated
graphify-out/ snapshot β€” the real change is ~8,000 lines of source plus
~19,500 lines of astro/pokedex content JSON).

Checks at review time: no failures. CodeQL /
control-plane / Analyze (javascript-typescript) still pending. CodeQL alert
snapshot for this head is empty (0 open alerts); disposition stays [].

What I reviewed

The v2 action vocabulary in remix/app/api/utils/actions/execute.ts
(+242/βˆ’53) and its save-time twin in schemas/registry.ts, the new
packs/ (astro + pokeworld), the webpage demo/suite seeding, and the
useTtActionClicks / ActionRunConfirm client path.

Findings

I found no correctness or security defect worth changing. The parts most
likely to go wrong are handled deliberately, and I verified each rather than
taking the comments at their word:

  • Mongo operator injection through the new where/match filters is
    closed by scalarFilterValue, which refuses anything that is not a string,
    number, or boolean. Without it, where: { field: { $ne: null } } would be a
    working operator injection.
  • Regex injection / ReDoS through match is closed by escapeRegExp
    before the needle becomes { $regex, $options: 'i' }, and the needle is
    truncated to MAX_ACTION_SEARCH_MATCH_CHARS.
  • Query-key injection is structurally impossible: every user-influenced key
    is prefixed (crystal.${field}), and sort.field is either the
    createdAt/updatedAt allowlist or a prefixed crystal field.
  • Save-time validation independently bounds limit, offset
    (MAX_ACTION_SEARCH_OFFSET β€” so no unbounded .skip()), where/match key
    counts, field-name pattern + banned segments, and sort.dir. It explicitly
    refuses schema/schemaId as filter fields, which is what stops a program
    filtering its way out of its own schema scope. Cross-owner scopes
    (public/system) are required to name a schema, so they can never be "the
    whole corpus".
  • 'system' is not an alias for 'public'. The reasoning in the code is
    correct and non-obvious: crystal.schema is free-form on the open data
    crystal, so any signed-in account can publish a public data thing stamped
    with a platform schema β€” and under the default newest-first sort, that forged
    row sorts above the seeded one. Restricting platform reads to
    ownerId: 'system' is the right boundary.
  • Termination. One shared budget per root invocation (deadline, ops, depth,
    child actions, expression nodes) is threaded through both actions.invoke
    and the new each, so A→B→A terminates by construction rather than by
    luck.
  • The things.update patch copy ({ ...values }) is a real bug fix, not
    cosmetics: values is only a fresh object when the program wrote an object
    literal. A whole-value ref like values: "$step.2.crystal" hands back the
    live object in scope.steps, and stamping schema/schemaId onto it in place
    would retroactively rewrite an earlier step's recorded result.

astronomy-engine@2.1.19 is declared in remix/package.json and present in
pnpm-lock.yaml β€” the new dependency is not undeclared.

Validation

node --import tsx --test \
  app/api/utils/actions/packs/*.test.ts app/api/utils/actions/packs/*/*.test.ts \
  app/components/Actions/*.test.ts app/schemas/*.test.ts \
  app/api/utils/webpages/*.test.ts app/components/Builder/*.test.ts
# pass 345 | fail 0

(First pass reported 5 failures, all Cannot find module for
astronomy-engine, react, react-router, @chakra-ui/react in my scratch
dependency tree β€” not PR defects. Installing them cleared all 5.)

Observations (no change made)

No changes were needed; I made none.

View Lopu workflow run

@github-actions
github-actions Bot changed the base branch from main to develop September 2, 2026 02:46
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

πŸ€– Lopu review β€” approve; base retargeted main β†’ develop

Change I made

This PR was opened against main. AI_ALL.md is explicit:

All pull requests must target the develop branch, not main. […] When you find an open PR still based on main that is not an authorized promotion PR, retarget it to develop.

This is a feature PR, not an authorized develop β†’ main promotion, so I retargeted it. Zero-risk at the moment it was done β€” main and develop are both at 7b6418bd, so the merge base and the diff are byte-identical before and after, and the PR is still MERGEABLE/CLEAN. Nothing else changed. (Likely just because main is this repo's default branch, so a PR opened without an explicit base lands there.)

Review

Endpoint conventions β€” the FUNDAMENTALS.md three-place rule is satisfied for both new endpoints: route files, the server/routes/api/[...].ts import map, and apiDocs.ts (which is what Nitro's route table derives from).

POST /api/v1/admin/webpages/seed-demos β€” correct shape for a privileged mutation: requireAdmin first, wrapped in withAdminPrivateResponse, then enforceRateLimit(…, { failClosed: true }). Fail-closed is the right choice and the comment says why. Both seed passes short-circuit on ok === false with their own status instead of collapsing to a 500, and notes is capped at 40 so a bad seed can't return an unbounded payload.

GET /api/v1/webpages/demos β€” public read, rate-limited per user or anonymously; no user input reaches a collection name or a query operator.

Catalog β€” keeping webpageDemos.ts/behaviourSuites.ts pure and isomorphic is what lets the tests assert the whole catalog rather than a sample: every demo clearing validateThingtimeCrystal(['webpage']) unchanged, plus block/byte headroom, slug grammar, family coverage and determinism. That's the right way to test code-generated content.

TESTING.md updated in the same change, per AI_ALL.md. πŸ‘

No correctness, security, compatibility or crash findings. Two non-blocking observations: the ~2 900 lines of generated-shaped catalog source in app/schemas/ is fine at this size but worth watching given the repository-weight pressure documented in #291/#554; and if the demo count grows an order of magnitude, the seeded census on the public endpoint is the thing to cache.

Validation: static review plus convention verification β€” the sandbox has no installed dependencies, so the unit suites couldn't run here; your live checks cover them and are green. CodeQL: 0 open alerts on this head.

github-actions Bot added a commit that referenced this pull request Sep 2, 2026
… + 14 behaviour suites (schemas + actions + controls that run) β€” /build…
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

πŸ€– Lopu review β€” 5e772c21 vs develop 7b6418bd

Checks are green on this exact head (25 pass / 56 skipping / 0 failing, including the typecheck ratchet job and the headless API suite) and the trusted CodeQL snapshot for this head is empty, so there was nothing to diagnose or dispose. I spent the pass on the code.

This is a lot of well-shaped work β€” the reconciling upsert is genuinely safe (genuineness lives in the update filter), both new queries are index-covered, the own/system materialisation matches how resolveActionProgram actually resolves, and the catalog is properly code-split into its own lazy chunk. I enumerated all 475 seeded docs (site pages, global, 322 demos, 125 suite parts) and found zero shareId or uniqueKey collisions, and no actionKey/componentKey/schema-name collisions across the 14 suites.

I did find one real, user-visible break, plus three smaller things. All four are fixed in the worktree.


1. πŸ› Four of the six library componentKeys don't exist

COMPONENT_DEMO_REFS named thingtime-card, thingtime-badge, thingtime-input, thingtime-avatar. The platform library names every entry <library>-<family>-<variant>, so those are family stems, not componentKeys. Checked against the live library:

ref exists? real key
thingtime-button-solid βœ… β€”
thingtime-button-outline βœ… β€”
thingtime-card ❌ thingtime-card-basic
thingtime-badge ❌ thingtime-badge-solid
thingtime-input ❌ thingtime-input-text
thingtime-avatar ❌ thingtime-avatar-status

The comment on that constant says an unresolved ref "renders as edit-chrome placeholders" β€” it doesn't. ComponentBlockView returns null when there's no chrome, so for a viewer an unresolved ref draws nothing:

if (!component || !crystal?.render) {
    // live viewers see nothing β€” the "not found" card is edit chrome
    if (!chrome) return null;

So on a seeded deployment /p/webpage-demo-components-cards-{paper,ink} would have shown a heading and no cards at all, and the form/mixed demos would have lost their inputs, badge and avatar β€” 6 of the 8 component-block demos visibly broken.

Fixed: pointed the refs at the six real componentKeys (all confirmed public as component-<key>), corrected the avatar block's args (thingtime-avatar-status takes initials, not name β€” small monogram() helper), and rewrote the comment to say what actually happens. Slugs are unchanged, so the seed just refreshes the eight docs in place. Added a unit test that pins every component block to COMPONENT_DEMO_REFS and rejects a family stem β€” verified load-bearing (reverting one key fails it with 'thingtime-card looks like a family stem, not a seeded componentKey').

2. πŸ› The gallery never resolved component refs at all

DemoCard passed no componentsByRef to Thumb, and previewComponents was {} for demo previews. Suite cards already solve this with suiteComponentsByRef, but library components live in the DB, not in code β€” so the whole 🧩 Component blocks chip previewed as empty frames, thumbnail and modal, even for the two keys that did resolve.

Fixed in the idiom already here: exported resolveBlockComponents(viewer, blocks) from webpages.ts (the existing batched resolver, for a block list that isn't a stored page), returned components[] + refs from GET /api/v1/webpages/demos, and folded them client-side through the existing buildComponentsByRef helper. Resolved anonymously on purpose so the endpoint keeps its documented "nothing here is per-viewer" contract β€” one extra bounded query (≀48 docs), after validation. New webpages-demos-library-components apiTest asserts resolution is all-or-nothing: where the library is seeded every ref must resolve (so a future dangling key fails), and on a fresh CI DB none do, which passes.

3. Typecheck ratchet was +1 over baseline

The PR head alone measures 109 vs baseline 108. The new error is in this PR's own test: assert.equal(validated.ok, true, …) from node:assert/strict narrows via asserts actual is T, which makes the following if (validated.ok === false) continue; provably dead (TS2367). Swapped to assert.ok(validated.ok, …), which narrows the union and makes the guard unnecessary. Back at baseline (108).

4. Two react-hooks/rules-of-hooks errors

const useTemplate = async (demo) => … is a plain function, but the use prefix makes ESLint treat it as a hook, so both call sites errored. Renamed to copyTemplate β€” the button still reads "Use template ✨". Lint isn't wired into CI today, so this was latent rather than failing.


Left for you to call

  • The seed is 447 sequential documents in one admin POST β€” a converged re-run costs ~894 Mongo round trips (447 upserts + 447 findOne). It's idempotent and self-healing so a serverless timeout is just "press Seed again", but there's no maxDuration in vercel.json, and a bulkWrite batch would collapse this to a handful of round trips if a deployment ever does time out.
  • Response size β€” unfiltered GET /webpages/demos was ~141 KB, ~156 KB with the component crystals, on a public 120/min limit, while the gallery only consumes the seeded flags and the components. A seeded-slugs-only projection would cut ~90%. Left alone: "one endpoint, whole catalog" is the documented contract and the apiTests assert demos.length === total.
  • Thumb's 1.2 s fallback timer mounts every card regardless of viewport, defeating the IntersectionObserver for off-screen cards β€” bounded by PAGE_SIZE today but it grows with each "Show more". Gating it on document.visibilityState === 'hidden' keeps the hidden-document guarantee without the blanket mount.
  • Seeded suite pages are look-but-don't-touch β€” clicking a control on /p/webpage-demo-suite-<key> 404s for anyone who hasn't installed. That's the right posture (delegated ttAction resolution is owner-only) but the page gives no hint; a line of copy pointing at Install suite would close the loop.
  • contractVersion: '1.1.0' on the brand-new webpages-demos endpoint β€” a new capability normally starts at 1.0.0. Nothing consumes it yet, so harmless; left as your choice. (admin-webpages-seed's 1.0.0 β†’ 1.1.0 is correctly additive.)
  • The behaviourSuites test validates materialized.data[].crystal, but seed and install both write it with schemaId stamped on top. I checked the real seed-shaped crystal for all 14 suites against the data gate β€” all pass, and every data.schema names a declared suite schema β€” so no live defect, but worth folding into the test.

Validation

Installed the worktree's deps and ran, after the changes: test:schemas 120 βœ“, test:webpages 29 βœ“, test:api-capabilities 4 βœ“, test:components 16 βœ“, test:things 24 βœ“, typecheck ratchet at baseline (108), eslint clean on all 8 touched files, vite build βœ“ with the catalog still absent from the entry chunk (builder-demos chunk 119 809 B). Also confirmed out-of-band that all six replacement componentKeys resolve to public component-<key> system things β€” the exact arm resolveComponents matches for an anonymous viewer.

Nice work. With the component refs pointing at real keys and the gallery actually resolving them, the 🧩 category finally shows what it's advertising.

β€” Lopu, Thingtime's PR and repository steward

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

🧹 Develop S3 preview removed

The PR-specific alias and every workflow-created develop deployment were removed when this PR closed.

The ordinary generated Vercel Preview remains available on the shared development runtime.

@github-actions
github-actions Bot temporarily deployed to develop-pr-578 September 2, 2026 03:53 Destroyed
… thumb fallback

The seed upserted ~450 documents one at a time β€” two Mongo round trips
each, which at serverless-to-Atlas latency is a multi-minute request a
function timeout would cut short. It now reads every destination id in
one query and writes one unordered bulkWrite (inserts for missing docs,
genuineness-filtered updates for drifted ones), keeping the same
created/refreshed/unchanged/skipped accounting: a refresh whose filter
matched nothing lost a race to a foreign doc and counts as skipped, a
duplicate-key insert lost a race to a concurrent seed and counts as
unchanged. Locally 447 docs converge in 0.18s (was 3.2s).

Suite pages carry a visible callout that their controls run the viewer's
OWN programs and point at Install suite, since a seeded copy is
look-but-don't-touch (delegated ttAction resolution is owner-only). The
thumbnail fallback timer now arms only while the document is hidden, so
a visible gallery keeps lazy mounting for off-screen cards. The new
webpages-demos endpoint starts at contract 1.0.0. The suites test now
validates the schemaId-stamped data crystal the seed and installer
actually write.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@lopugit

lopugit commented Sep 2, 2026

Copy link
Copy Markdown
Owner Author

Follow-up to the review's "left for you to call" list β€” pushed as edf17545d:

  • Seed round trips β€” taken. upsertSystemThings now does one find over every destination id plus one unordered bulkWrite (inserts for missing docs, genuineness-filtered updates for drifted ones), same created/refreshed/unchanged/skipped accounting (filter-miss β†’ skipped, dup-key insert β†’ unchanged). Local: 447 docs converge in 0.18s (was 3.2s); verified converged re-run (447 unchanged), content change refreshes exactly the touched docs (20), and re-insert after deleting three docs (created 3).
  • Thumb fallback timer β€” taken: arms only while document.visibilityState === 'hidden'; visible documents keep the lazy observer path.
  • Seeded suite pages give no hint β€” taken: every suite page now carries a callout above its controls saying they run the viewer's own programs and pointing at Install suite.
  • contractVersion β€” taken: webpages-demos starts at 1.0.0.
  • Data crystal with schemaId β€” taken: the suites test validates the stamped shape and that every data entry names a declared suite schema.
  • Response size β€” left as is, per the documented "one endpoint, whole catalog" contract.

Checks: test:schemas 120, test:api-capabilities 4, test:webpages 29, headless --group webpages 20/20 against the worktree stack.

@github-actions
github-actions Bot temporarily deployed to develop-pr-578 September 2, 2026 04:01 Destroyed
… layout sweep to zero

Thumbnails: the gallery canvas is laid out at 760px and scaled to the card;
a fixed 0.42 clipped the right edge in any grid column under 319px. The
scale now follows the measured card width (ResizeObserver).

Buttons do something. Text blocks gain an optional `href`: the registry
gate screens it like a media src plus mailto:/tel: (javascript:, data:,
plain http and protocol-relative refused), the renderer wraps the styled
text in an anchor (external targets drop the opener, the edit canvas never
navigates), the inspector gets a Link field, and every demo pill links
(solid β†’ /register, ghost β†’ /docs) with nav labels linking to their slugs.

Suite controls run or install. useTtActionClicks gains onUnowned: when the
executor refuses a delegated click because the viewer owns no such action,
a demo surface may install the suite and answer true, and the SAME click
re-runs (pure runDelegatedAction, unit-tested; owner-only resolution and
every other failure path untouched). Seeded suite pages β€” detected by the
reserved webpage-demo-suite- id, since system docs project no author β€” are
live for signed-in viewers, as is the gallery preview modal; both use one
shared installSuite helper with the Install button.

Layout sweep across all 322 demos and 14 suites, driven by a DOM audit
(wrapped pills by text-node line count, overflow by scrollWidth, uncentered
wide pills): Main's `* { white-space: pre-wrap }` beat block css on the
text element, so the renderer forwards white-space to the text (important);
the row model flexes every child equally, so pills and row labels opt out
with flex: 0 0 auto; standalone pills shrink-wrap via align (pricing-card
buttons are intentionally full-width with centered labels). 86 flagged
cards β†’ 0.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@lopugit

lopugit commented Sep 2, 2026

Copy link
Copy Markdown
Owner Author

Round 2 β€” thumbnails, working buttons, layout sweep

Thumbnails: the gallery canvas is laid out at 760px and scaled to the card; the scale was fixed (0.42), so any grid column narrower than 319px clipped the right edge. It now follows the measured card width (ResizeObserver), so every column width fits exactly.

Buttons do something (builder/actions architecture, additive):

  • Text blocks gain an optional href β€” registry gate (https / site-relative / mailto: / tel:; javascript:, data:, plain http: and protocol-relative refused, size-bounded), client type, renderer (styled text becomes an anchor; external targets _blank + noopener; the edit canvas never navigates), a Link field in the inspector, gate tests. Every demo pill now links (solid β†’ /register, ghost β†’ /docs) and every nav/footer label links to its slug.
  • Run-or-install for suite controls: useTtActionClicks gains an onUnowned(action, inputs) fallback (pure runDelegatedAction, unit-tested 6/6). When the executor refuses a delegated click because the viewer owns no such action, a demo surface may install the suite and answer true β€” the same click re-runs. It never widens what a click can run (owner-only resolution is untouched; other failures never trigger it).
  • Seeded suite pages are live for signed-in viewers (/p/webpage-demo-suite-<key> β€” detected by the reserved id prefix, since system docs project no author): a click installs the suite into their things, re-runs, then opens their own copy. The gallery preview modal does the same. Shared installSuite helper (components/Builder/installSuite.ts) is what both surfaces and the Install button use β€” and what the pokeworld app-suite work imports.
  • Foreign user pages stay inert for non-owners (unchanged trust rule).

Layout sweep (all 322 demos + 14 suites): root causes were (1) Main's * { white-space: pre-wrap } beating block CSS on the text element β€” the renderer now forwards white-space to the text (marked important), (2) the row model giving every child an equal flex share β€” pills and row labels opt out with flex: 0 0 auto, (3) standalone pills stretching to 100% β€” pills carry align (shrink-wrap; pricing-card buttons are intentionally full-width with centered labels), plus per-demo fixes (banner pill, 2-up library cards, price rows). A DOM audit (wrapped pills by text-node line count, overflow by scrollWidth, uncentered wide pills) now reports 0 defects across 322/322 mounted cards; it was 86 flagged before.

Verification: test:schemas 121 (href gate cases), test:webpages 29, test:actions 48 (new hook test), test:api-capabilities 4, typecheck ratchet βœ“, build:client βœ“, headless --group webpages 20/20, suites e2e 18/18; browser: gallery desktop/mobile, /p/ demo pills are anchors, seeded suite page exposes its controls.

Coordination: the pokeworld session (Pokeworld + StarsAlign app suites on this PR) owns the executor + action grammar; nothing here touches those. It will merge this push and build on installSuite, onUnowned, and the system-page interactive rule.

Lopu sync resolver and others added 2 commits September 2, 2026 14:52
…en, filtered search + astro pack

Apps-on-Thingtime groundwork for the Pokeworld + StarsAlign suites:

- registry: closed step vocabulary gains `compute`, `things.delete`
  (new `things.delete` capability), `each` (child action per element,
  `$item`/`$index` bound, ≀20), `fail` (authored refusal) and a per-step
  `when` guard (falsy skips; a guarded `return` is an early exit). Step
  values accept `{ ttExpr: [fn, …args] }` over the closed function
  catalogue in schemas/actionExpressions.ts (math, logic, text, list with
  lambdas, object, date, random, domain packs). `things.search` gains
  scope own|public (public requires a schema), where/match/sort/offset.
  New refs `$viewer.id|username`. Caps: 40 steps, 100 ops ceiling.
- executor: implements the above; expression budget shared per run; pack
  calls count as ops; seeded system schemas resolve by name.
- actionInspect: describes the new ops; "No deletes" only when the program
  declares no things.delete.
- componentTemplate: nested scope with dotted-path tokens, ttEach (per
  element, ≀160), ttIf ops, ttFormat; HtmlThingRenderer allowlists named
  form fields + svg text/g and renders fields uncontrolled.
- webpages: `/p/<pageKey>` resolves the viewer's own twin ahead of the
  system page; component blocks accept a `source` action binding; pages
  carry `suiteKey`.
- behaviourSuites: multi-page `pages` + `app` metadata, APP_SUITES registry.
- packs/astro: the StarsAlign ephemeris/engine/school ported server-side
  (astronomy-engine), 47 tests.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…o claude/pokeworld-starsalign-thingtime-40cd5f
@github-actions
github-actions Bot temporarily deployed to develop-pr-578 September 2, 2026 04:52 Destroyed
An authored grid column count is the desktop layout: a 3–4 column
section on a phone squeezed every cell to a few characters wide. The
renderer now folds grids to one column below the sm breakpoint and at
most two below md, keeping the authored count from md up. Suite pages lay
their controls out as a wrapping row (each at least 300px) instead of a
two-column grid, so they stack on narrow screens.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

πŸ€– Lopu detected merge conflicts

Status: Work detected β€” Lopu is taking ownership.

Current phase: Entering Lopu's serialized PR-resolution queue.

Estimated completion: around 11:07 UTC (~20 minutes; this adjusts as the queue moves).

Next automatic check-in: within 10 minutes while work remains active. You can stay on this PR; there is no need to find the Actions run.

Time conversion (UTC source)

Moment UTC Los Angeles Melbourne
Updated 2026-09-03 10:47 UTC (UTC+00:00) 2026-09-03 03:47 PDT (UTC-07:00) 2026-09-03 20:47 AEST (UTC+10:00)
Estimated finish 2026-09-03 11:07 UTC (UTC+00:00) 2026-09-03 04:07 PDT (UTC-07:00) 2026-09-03 21:07 AEST (UTC+10:00)

Los Angeles and Melbourne use their real IANA time zones, so PDT/PST and AEST/AEDT offsets change automatically.

Lopu queue and PR pulse

Scope Metric Count
Repository Open PRs 17
Repository Conflicting 5
Repository Out-of-date with target 5
Repository GitHub state unknown 2
Repository Part of an open stack 0
Repository Touch files changed by another open PR 9
Repository Target a non-root branch without an open parent PR 0
This resolver batch Admitted snapshots 10
This resolver batch Currently resolving 0
This resolver batch Waiting 10
This resolver batch Finished 0

Related PR context

  • Stack: No open parent or child PR currently links to this branch.
  • Target: develop is a repository root/integration branch.
  • Changed-file overlap: 14 changed files are also touched by #10, #291, #295, #554, #560, #564, #595, #601.

Exact branch pair: develop β†’ claude/builder-demo-library.

Timeline

  • 10:47 UTC β€” Detected conflicts between develop and claude/builder-demo-library; assigning the exact snapshot to the resolver queue.

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

πŸ€– Lopu detected merge conflicts

Status: Work detected β€” Lopu is taking ownership.

Current phase: Entering Lopu's serialized PR-resolution queue.

Estimated completion: around 12:12 UTC (~20 minutes; this adjusts as the queue moves).

Next automatic check-in: within 10 minutes while work remains active. You can stay on this PR; there is no need to find the Actions run.

Time conversion (UTC source)

Moment UTC Los Angeles Melbourne
Updated 2026-09-03 11:52 UTC (UTC+00:00) 2026-09-03 04:52 PDT (UTC-07:00) 2026-09-03 21:52 AEST (UTC+10:00)
Estimated finish 2026-09-03 12:12 UTC (UTC+00:00) 2026-09-03 05:12 PDT (UTC-07:00) 2026-09-03 22:12 AEST (UTC+10:00)

Los Angeles and Melbourne use their real IANA time zones, so PDT/PST and AEST/AEDT offsets change automatically.

Lopu queue and PR pulse

Scope Metric Count
Repository Open PRs 16
Repository Conflicting 4
Repository Out-of-date with target 5
Repository GitHub state unknown 1
Repository Part of an open stack 0
Repository Touch files changed by another open PR 9
Repository Target a non-root branch without an open parent PR 0
This resolver batch Admitted snapshots 9
This resolver batch Currently resolving 0
This resolver batch Waiting 9
This resolver batch Finished 0

Related PR context

  • Stack: No open parent or child PR currently links to this branch.
  • Target: develop is a repository root/integration branch.
  • Changed-file overlap: 63 changed files are also touched by #10, #291, #295, #554, #560, #564, #592, #595.

Exact branch pair: develop β†’ claude/builder-demo-library.

Timeline

  • 11:52 UTC β€” Detected conflicts between develop and claude/builder-demo-library; assigning the exact snapshot to the resolver queue.

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

πŸ€– Lopu detected merge conflicts

Status: Work detected β€” Lopu is taking ownership.

Current phase: Entering Lopu's serialized PR-resolution queue.

Estimated completion: around 13:08 UTC (~20 minutes; this adjusts as the queue moves).

Next automatic check-in: within 10 minutes while work remains active. You can stay on this PR; there is no need to find the Actions run.

Time conversion (UTC source)

Moment UTC Los Angeles Melbourne
Updated 2026-09-03 12:48 UTC (UTC+00:00) 2026-09-03 05:48 PDT (UTC-07:00) 2026-09-03 22:48 AEST (UTC+10:00)
Estimated finish 2026-09-03 13:08 UTC (UTC+00:00) 2026-09-03 06:08 PDT (UTC-07:00) 2026-09-03 23:08 AEST (UTC+10:00)

Los Angeles and Melbourne use their real IANA time zones, so PDT/PST and AEST/AEDT offsets change automatically.

Lopu queue and PR pulse

Scope Metric Count
Repository Open PRs 17
Repository Conflicting 3
Repository Out-of-date with target 5
Repository GitHub state unknown 1
Repository Part of an open stack 0
Repository Touch files changed by another open PR 9
Repository Target a non-root branch without an open parent PR 0
This resolver batch Admitted snapshots 10
This resolver batch Currently resolving 0
This resolver batch Waiting 10
This resolver batch Finished 0

Related PR context

  • Stack: No open parent or child PR currently links to this branch.
  • Target: develop is a repository root/integration branch.
  • Changed-file overlap: 13 changed files are also touched by #10, #291, #295, #554, #560, #564, #595, #606.

Exact branch pair: develop β†’ claude/builder-demo-library.

Timeline

  • 12:48 UTC β€” Detected conflicts between develop and claude/builder-demo-library; assigning the exact snapshot to the resolver queue.

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

πŸ€– Lopu detected merge conflicts

Status: Work detected β€” Lopu is taking ownership.

Current phase: Entering Lopu's serialized PR-resolution queue.

Estimated completion: around 13:59 UTC (~20 minutes; this adjusts as the queue moves).

Next automatic check-in: within 10 minutes while work remains active. You can stay on this PR; there is no need to find the Actions run.

Time conversion (UTC source)

Moment UTC Los Angeles Melbourne
Updated 2026-09-04 13:39 UTC (UTC+00:00) 2026-09-04 06:39 PDT (UTC-07:00) 2026-09-04 23:39 AEST (UTC+10:00)
Estimated finish 2026-09-04 13:59 UTC (UTC+00:00) 2026-09-04 06:59 PDT (UTC-07:00) 2026-09-04 23:59 AEST (UTC+10:00)

Los Angeles and Melbourne use their real IANA time zones, so PDT/PST and AEST/AEDT offsets change automatically.

Lopu queue and PR pulse

Scope Metric Count
Repository Open PRs 19
Repository Conflicting 3
Repository Out-of-date with target 5
Repository GitHub state unknown 1
Repository Part of an open stack 2
Repository Touch files changed by another open PR 13
Repository Target a non-root branch without an open parent PR 0
This resolver batch Admitted snapshots 11
This resolver batch Currently resolving 0
This resolver batch Waiting 11
This resolver batch Finished 0

Related PR context

Exact branch pair: develop β†’ claude/builder-demo-library.

Timeline

  • 13:39 UTC β€” Detected conflicts between develop and claude/builder-demo-library; assigning the exact snapshot to the resolver queue.

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

πŸ€– Lopu is rebasing this stack β€” work started at 15:23 UTC.

Expected to finish around 15:38 UTC (most rebases still land in 5-15 minutes; the hosted-runner ceiling is 360). On success this branch is force-pushed onto its new base and a result comment follows β€” no manual action is needed meanwhile.

Live status

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

⚠️ The AI PR/stack rebase workflow did not complete. The workflow stopped before it attempted its force-with-lease push.

ai-rebase-paused was added for this exact ref/topology snapshot; review the run, then use a manual PR-number run to retry.

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

πŸ€– Lopu detected merge conflicts

Status: Work detected β€” Lopu is taking ownership.

Current phase: Entering Lopu's serialized PR-resolution queue.

Estimated completion: around 06:41 UTC (~20 minutes; this adjusts as the queue moves).

Next automatic check-in: within 10 minutes while work remains active. You can stay on this PR; there is no need to find the Actions run.

Time conversion (UTC source)

Moment UTC Los Angeles Melbourne
Updated 2026-09-05 06:21 UTC (UTC+00:00) 2026-09-04 23:21 PDT (UTC-07:00) 2026-09-05 16:21 AEST (UTC+10:00)
Estimated finish 2026-09-05 06:41 UTC (UTC+00:00) 2026-09-04 23:41 PDT (UTC-07:00) 2026-09-05 16:41 AEST (UTC+10:00)

Los Angeles and Melbourne use their real IANA time zones, so PDT/PST and AEST/AEDT offsets change automatically.

Lopu queue and PR pulse

Scope Metric Count
Repository Open PRs 25
Repository Conflicting 1
Repository Out-of-date with target 0
Repository GitHub state unknown 7
Repository Part of an open stack 2
Repository Touch files changed by another open PR 14
Repository Target a non-root branch without an open parent PR 0
This resolver batch Admitted snapshots 13
This resolver batch Currently resolving 0
This resolver batch Waiting 13
This resolver batch Finished 0

Related PR context

Exact branch pair: develop β†’ claude/builder-demo-library.

Timeline

  • 06:21 UTC β€” Detected conflicts between develop and claude/builder-demo-library; assigning the exact snapshot to the resolver queue.

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

πŸ€– Lopu detected merge conflicts

Status: Work detected β€” Lopu is taking ownership.

Current phase: Entering Lopu's serialized PR-resolution queue.

Estimated completion: around 07:21 UTC (~20 minutes; this adjusts as the queue moves).

Next automatic check-in: within 10 minutes while work remains active. You can stay on this PR; there is no need to find the Actions run.

Time conversion (UTC source)

Moment UTC Los Angeles Melbourne
Updated 2026-09-05 07:01 UTC (UTC+00:00) 2026-09-05 00:01 PDT (UTC-07:00) 2026-09-05 17:01 AEST (UTC+10:00)
Estimated finish 2026-09-05 07:21 UTC (UTC+00:00) 2026-09-05 00:21 PDT (UTC-07:00) 2026-09-05 17:21 AEST (UTC+10:00)

Los Angeles and Melbourne use their real IANA time zones, so PDT/PST and AEST/AEDT offsets change automatically.

Lopu queue and PR pulse

Scope Metric Count
Repository Open PRs 22
Repository Conflicting 5
Repository Out-of-date with target 0
Repository GitHub state unknown 7
Repository Part of an open stack 2
Repository Touch files changed by another open PR 16
Repository Target a non-root branch without an open parent PR 0
This resolver batch Admitted snapshots 12
This resolver batch Currently resolving 0
This resolver batch Waiting 12
This resolver batch Finished 0

Related PR context

Exact branch pair: develop β†’ claude/builder-demo-library.

Timeline

  • 07:01 UTC β€” Detected conflicts between develop and claude/builder-demo-library; assigning the exact snapshot to the resolver queue.

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

πŸ€– Lopu detected merge conflicts

Status: Work detected β€” Lopu is taking ownership.

Current phase: Entering Lopu's serialized PR-resolution queue.

Estimated completion: around 15:09 UTC (~20 minutes; this adjusts as the queue moves).

Next automatic check-in: within 10 minutes while work remains active. You can stay on this PR; there is no need to find the Actions run.

Time conversion (UTC source)

Moment UTC Los Angeles Melbourne
Updated 2026-09-05 14:49 UTC (UTC+00:00) 2026-09-05 07:49 PDT (UTC-07:00) 2026-09-06 00:49 AEST (UTC+10:00)
Estimated finish 2026-09-05 15:09 UTC (UTC+00:00) 2026-09-05 08:09 PDT (UTC-07:00) 2026-09-06 01:09 AEST (UTC+10:00)

Los Angeles and Melbourne use their real IANA time zones, so PDT/PST and AEST/AEDT offsets change automatically.

Lopu queue and PR pulse

Scope Metric Count
Repository Open PRs 25
Repository Conflicting 13
Repository Out-of-date with target 1
Repository GitHub state unknown 4
Repository Part of an open stack 4
Repository Touch files changed by another open PR 18
Repository Target a non-root branch without an open parent PR 0
This resolver batch Admitted snapshots 11
This resolver batch Currently resolving 0
This resolver batch Waiting 11
This resolver batch Finished 0

Related PR context

Exact branch pair: develop β†’ claude/builder-demo-library.

Timeline

  • 14:49 UTC β€” Detected conflicts between develop and claude/builder-demo-library; assigning the exact snapshot to the resolver queue.

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

⚠️ The AI PR/stack rebase workflow did not complete. The workflow stopped before it attempted its force-with-lease push.

ai-rebase-paused was added for this exact ref/topology snapshot; review the run, then use a manual PR-number run to retry.

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

πŸ€– Lopu detected merge conflicts

Status: Work detected β€” Lopu is taking ownership.

Current phase: Entering Lopu's serialized PR-resolution queue.

Estimated completion: around 02:44 UTC (~20 minutes; this adjusts as the queue moves).

Next automatic check-in: within 10 minutes while work remains active. You can stay on this PR; there is no need to find the Actions run.

Time conversion (UTC source)

Moment UTC Los Angeles Melbourne
Updated 2026-09-06 02:24 UTC (UTC+00:00) 2026-09-05 19:24 PDT (UTC-07:00) 2026-09-06 12:24 AEST (UTC+10:00)
Estimated finish 2026-09-06 02:44 UTC (UTC+00:00) 2026-09-05 19:44 PDT (UTC-07:00) 2026-09-06 12:44 AEST (UTC+10:00)

Los Angeles and Melbourne use their real IANA time zones, so PDT/PST and AEST/AEDT offsets change automatically.

Lopu queue and PR pulse

Scope Metric Count
Repository Open PRs 27
Repository Conflicting 10
Repository Out-of-date with target 4
Repository GitHub state unknown 4
Repository Part of an open stack 4
Repository Touch files changed by another open PR 19
Repository Target a non-root branch without an open parent PR 0
This resolver batch Admitted snapshots 12
This resolver batch Currently resolving 0
This resolver batch Waiting 12
This resolver batch Finished 0

Related PR context

Exact branch pair: develop β†’ claude/builder-demo-library.

Timeline

  • 02:24 UTC β€” Detected conflicts between develop and claude/builder-demo-library; assigning the exact snapshot to the resolver queue.

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

πŸ€– Lopu detected merge conflicts

Status: Work detected β€” Lopu is taking ownership.

Current phase: Entering Lopu's serialized PR-resolution queue.

Estimated completion: around 03:31 UTC (~20 minutes; this adjusts as the queue moves).

Next automatic check-in: within 10 minutes while work remains active. You can stay on this PR; there is no need to find the Actions run.

Time conversion (UTC source)

Moment UTC Los Angeles Melbourne
Updated 2026-09-06 03:11 UTC (UTC+00:00) 2026-09-05 20:11 PDT (UTC-07:00) 2026-09-06 13:11 AEST (UTC+10:00)
Estimated finish 2026-09-06 03:31 UTC (UTC+00:00) 2026-09-05 20:31 PDT (UTC-07:00) 2026-09-06 13:31 AEST (UTC+10:00)

Los Angeles and Melbourne use their real IANA time zones, so PDT/PST and AEST/AEDT offsets change automatically.

Lopu queue and PR pulse

Scope Metric Count
Repository Open PRs 28
Repository Conflicting 12
Repository Out-of-date with target 3
Repository GitHub state unknown 4
Repository Part of an open stack 4
Repository Touch files changed by another open PR 19
Repository Target a non-root branch without an open parent PR 0
This resolver batch Admitted snapshots 13
This resolver batch Currently resolving 0
This resolver batch Waiting 13
This resolver batch Finished 0

Related PR context

Exact branch pair: develop β†’ claude/builder-demo-library.

Timeline

  • 03:11 UTC β€” Detected conflicts between develop and claude/builder-demo-library; assigning the exact snapshot to the resolver queue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

last preview built 03/09 19:59 AEST #578 tt-pv1:578:develop:e87f9ff3e77ec4e27ef443c32f8de0dddd53bf8b:1788429563037 preview: develop removed tt-preview-state:v1:develop:removed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant