Skip to content

Feat/sign in gate pilot - #17

Merged
pip-install-python merged 3 commits into
mainfrom
feat/sign-in-gate-pilot
Aug 20, 2026
Merged

Feat/sign in gate pilot#17
pip-install-python merged 3 commits into
mainfrom
feat/sign-in-gate-pilot

Conversation

@pip-install-python

Copy link
Copy Markdown
Owner

No description provided.

pip-install-python and others added 3 commits August 19, 2026 15:32
leaflet pilots the network's sign-in gate. Clerk was already here and
satellite-correct; what was missing was the enforcement seam, and this
repo had a second problem the template does not: two parallel access
systems that could disagree about the same page.

`tier:` and `visibility:` were independent frontmatter keys naming the
same four values, feeding two independent ledgers. A page could declare
`visibility: auth`, be enforced as public, and show a control-board row
that said otherwise, with nothing logged. One declared value now feeds
both; `tier:` is canonical and `visibility:` is an accepted alias that
warns only when the two disagree.

The unification keeps the half of the old system that was working
production UX. lib/page_visibility.py is demoted to the control board's
override store — live toggles, /var/data persistence, its cards — and
lib/access.py resolves the verdict from the board's override first, the
frontmatter registration underneath, and the hub's ceiling on top, which
only ever restricts. What did NOT come across is that module's
resolve_access, which fell open for admin as well as docs; the new seam
keeps the boilerplate's split posture (docs open without Clerk, admin
closed) and tests/test_access.py pins it against a future re-port.

Two lanes, deliberately different. resolve_page_access answers what a
BROWSER gets — lib/gate_layouts.py renders the card, whose #auth-gate-*
buttons carry the current page in the return trip and so fix the
existing card's returnTo leak. check answers what a MACHINE fetch gets
and honours ?key= plus the llms_public axis, so /<page>/llms.txt, the
crawler document and the prerender keep serving prose through the
30-day window while humans meet the card. A key never unlocks a layout.

The legacy llms.txt stub swap is retired with the same reasoning: with
a policy wired, registering the real prose and letting the check decide
is strictly better, because the check can honour the hub, a key and the
axis, and an unauthorised reader gets a document that says how to
unlock it rather than a stub. The swap survives only for a boot where
no policy could be wired at all.

run.py forces the wiring on (force=True) even though every tier is
public, which is the whole shipping-dark idea: the verdict path and the
prerender's use of it run in production before PAGE_DEFAULT_TIER=auth
turns them on, and setting it back to public is the rollback. /,
/llms-small.txt and /llms-full.txt are pinned public on both ledgers so
that flip cannot take the funnel's front door or the corpus with it.

Verified locally: 169 passed on flask, 168 + 1 skip on fastapi (was
111), smoke_test 72/72, flake8 clean. Under PAGE_DEFAULT_TIER=auth with
a faked Clerk session: gated page renders the card with no docs DOM,
llms.txt serves full prose, a canary page pinned llms_public=false
serves the gate doc at 200 and shows it — not the prose — inside
#dimll-prerender, a keyed fetch resolves allow and carries ?key= onto
same-origin links, a board toggle to hidden reaches both lanes, and
/api/agent-key answers 204 with private, no-store.

Not verifiable offline: the real Clerk round trip to 2plot.ai and back,
and the hub's /api/page-tiers ceiling (no CROSS_APP_WEBHOOK_SECRET) —
both are prod acceptance boxes in X402-SYNC-REPORT.md.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Applied to this working tree by the boilerplate session on 2026-08-20 and
committed here unchanged; recorded separately from the stage-3 work so the
gate pilot's diff stays about the gate.

The presence beacon is a second, faster loop beside the rollup, and the two
are not interchangeable: presence is display-only and ephemeral hub-side
(the live "active now" number), while the rollup remains the only source of
the daily figures. It derives its count the way the hub does — distinct
human visitor keys inside the session window — so the two can never disagree
about what "active" means. 60s default, 30s floor, 0 disables, fail-silent.

`SATELLITE_APP_KEY` keeps this repo's deviation and its reason: unlike some
satellites it is NOT chained to AD_APP_ID, because this host historically ran
AD_APP_ID=dash-leaflet2 against directory key "leaflet", and setting one for
the ad network must never silently rename this app's traffic series.

lib/network_directory.py is re-copied from the boilerplate verbatim, which
resolves this file's own standing instruction: it carried a temporary
divergence commenting out pannellum and emojimart while they were NXDOMAIN,
with a note saying to re-copy rather than un-comment once they resolved.
They have. Twelve peers now, self-exclusion still leaves eleven here.

SATELLITE_REPORT_INTERVAL_S=900 in render.yaml — the fleet is on paid
instances and the hub board reads near-real-time; the code default stays
hourly for anyone running this elsewhere.

Verified: 176 passed on flask with these alone, flake8 clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Floor to dash-improve-my-llms >= 2.6.0, which is load-bearing rather than
routine — pages/markdown.py now passes `lastmod=` unconditionally, and that
argument only exists from 2.6.0.

SITEMAP HONESTY. Every entry used to carry a <lastmod> of "today",
regenerated on every crawl. A sitemap asserting that 27 pages changed daily
is one a search engine learns to discard wholesale, which costs more than
having no dates at all. 2.6.0 emits frontmatter `lastmod:` verbatim and omits
the tag entirely when a page declares none. All 27 pages are stamped with
their real `git log -1 --format=%cs` date — 26 on 2026-07-28, home on
2026-08-01. Deliberately bare YAML dates, not quoted strings: that puts the
field validator on the live path, where it belongs, because YAML hands
pydantic a datetime.date and Optional[str] rejects it. Never script these
from mtimes, which reset on every Docker build and would re-create the exact
lie the floor removes.

ICONS. This app has never called configure_seo, so its crawler document
carried ZERO icons while browsers got six from templates/index.html — the
crawler/browser identity drift in its most complete form. 2.6.0 discovers
them from the assets tree (favicon_io/ is a covered directory name) and this
site's own art becomes its crawler-head identity with nothing declared:
verified as six links, all under favicon_io/, none of them template art.
Discovery fails SOFT by design, so a renamed directory would take the icons
away in silence — tests/test_seo_icons.py is the alarm, and it also pins that
the emitted hrefs actually resolve.

Found while wiring lastmod through, and fixed in the same call because it is
the same defect: the crawler document also had NO og:image (browsers had one)
and typed every documentation page as a bare schema.org WebPage. The record
now carries title, image_url, schema_type and lastmod, so the two heads agree
on identity — content may differ between them, identity may not. Passing
`title` was measured, not assumed: it does not double the brand, because the
package composes its own "<page> · <site>" only when nothing is declared.

The metadata had to be REMEMBERED, not passed once: apply_llms_state
re-registers the whole record on every control-board toggle, so lib/
page_visibility.py stores an `extra` dict alongside the prose rather than
letting a re-registration depend on the package's merge semantics holding.

Still pending, and not blocking: normalized favicon art from CDN source
through the boilerplate's scripts/make_favicons.py (absent here). Discovery
already serves this site's own favicon_io art, and the webmanifest already
carries leaflet's name, description and #2f9e44 theme colour.

Verified: 182 passed on flask, 181 + 1 skip on fastapi, smoke 72/72, flake8
clean, against dimll 2.6.0 installed from the local wheel (the sandbox has no
PyPI access; the deploy resolves it from the index).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@pip-install-python
pip-install-python merged commit 8b877c8 into main Aug 20, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant