Skip to content

fix(website): Queen explorer cards in the address, skill labels, six-step ladder, lang toggle, phone core - #1014

Merged
gHashTag merged 7 commits into
mainfrom
fix/queen-embedded-explorers-address
Sep 14, 2026
Merged

gHashTag merged 7 commits into
mainfrom
fix/queen-embedded-explorers-address

Conversation

@gHashTag

Copy link
Copy Markdown
Owner

Description

Five defects found by the live sweep of the Queen after #1002/#1008, fixed in
separate commits:

  1. Embedded Explorers own their card in the Queen address. Seven Queen
    tabs frame an Explorer, and each kept its card only in the frame's hash: a
    reload opened the default, ?tab=specs&spec=… stayed on hello_world, a
    PROJECT chapter jump was lost, and a ladder link inside the agents frame
    navigated the frame under a rail that still said AGENTS. The address now
    names the card (skill=, cron=, agent=, function=, tool=, spec=,
    chapter=), a pick writes it with replace, and an outside hash change or
    Back moves the frame with location.replace.
  2. Skill Explorer labels say what is counted: whether a skill declares a
    spec binding ("Unbound" / "Без привязки"), not "No spec".
  3. One ladder of six steps wherever the site draws or names it:
    Specs → Skills → Crons → Agents → Tools → Functions.
  4. The Queen language toggle writes ?lang=, so a reload keeps the language.
  5. Shared core can be tapped on a phone (it measured 0x0 at 390px).

Closes #1013

Related Issue

#1013. Rebased onto #1011 (TRI tab); the one conflict was the shell's tab
write in Queen.tsx: it now builds from the live hash as TRI requires and
drops or writes the Explorer card as this branch requires. The last commit
keeps that write in the literal form qa/tri-screens-contract.mjs pins (the
first merge read the hash into a local and failed check:tri).

Changes Made

  • src/lib/queenEmbed.ts, src/lib/queenFrame.ts (imports nothing, so the
    entry chunk grows by 1.1 kB), src/components/useQueenExplorerFrame.ts;
    QueenAgents.tsx, QueenSpecs.tsx, useHashParams.ts, main.tsx,
    SpecExplorer.tsx (follows a later ?spec= only inside a Queen frame).
  • SkillExplorer.tsx label copy (en/ru), CronExplorer/SkillExplorer
    LayerLadder, FunctionExplorer caption.
  • scripts/agents-from-specs.mjs, scripts/docs-from-specs.mjs and the
    regenerated spec-skills.json, spec-crons.json, system-docs.json (each
    keeps its generatedAt; a separate commit first regenerates
    system-docs.json from the committed catalogs, which was stale on main).
  • Queen.tsx toggleLang and the tab write; QueenUniverse.css phone head.
  • qa/queen-embed-address-contract.mjs (npm run check:queen-embed),
    agents-spec and docs-spec contracts and the docs generator test.

🔥 TOXIC VERDICT

What Works

  • Embed contract: 23 of 24 checks fail on the unmodified build, each for its
    own reason; 24 of 24 pass on this branch, before and after the rebase onto
    feat(website): TRI tab, the app at app.t27.ai inside the Queen #1011 (with the TRI contract 14 of 14 and the tabs probe 50 of 50).
  • Each smaller fix has a before/after browser probe: labels, ladder (explorers
    and docs), ?lang= after toggle and reload, and Shared core 0x0 → 93x26 and
    tappable at 390x844.

What Doesn't Work / Limits

  • The vendored t27 chapter still says "The five-layer system" next to the
    six-row table; that text lives in gHashTag/t27.
  • A plain Queen tab visit now writes the Explorer's default card into the
    address once the frame loads.
  • Shared core is 93x26 on a phone, under a 44px touch-target guideline.
  • The embed contract takes 25-30 minutes on this machine and is not in CI.

Overall Assessment: APPROVE. Self-Score: 7/10.

🌳 TECH TREE Options

  1. Change the t27 layers chapter upstream and re-vendor it. ★★★★☆
  2. Put the embed contract in CI with a shorter matrix. ★★★☆☆
  3. Grow phone head controls to 44px without breaking the one-screen layout. ★★☆☆☆
{
  "version": 1,
  "head_sha": "3db210c7fd819263ef483aac38517d3862f425ce",
  "summary": "Queen tabs that frame an Explorer now carry the selected card in the Queen address, the Skill Explorer labels name the spec binding they count, the site states one six-step ladder, the language toggle writes ?lang=, and Shared core is tappable on a phone.",
  "changes": [
    "apps/website/src/lib/queenEmbed.ts, src/lib/queenFrame.ts, src/components/useQueenExplorerFrame.ts and the Explorer pages: the card of each embedded Explorer is written to and read from the Queen address.",
    "apps/website/src/pages/SkillExplorer.tsx: label copy in en and ru names the declared spec binding.",
    "apps/website/scripts/agents-from-specs.mjs, scripts/docs-from-specs.mjs and regenerated public data: one six-step ladder in the catalogs, figure, table and copy.",
    "apps/website/src/pages/Queen.tsx: the language toggle writes ?lang= and the tab write builds from the live hash while dropping or writing the Explorer card.",
    "apps/website/src/pages/QueenUniverse.css: Shared core stays visible and tappable in the phone head.",
    "apps/website/qa/queen-embed-address-contract.mjs and updated agents-spec and docs-spec contracts."
  ],
  "tests": [
    {
      "command": "node qa/queen-embed-address-contract.mjs --origin=<local build of 429499e662>",
      "status": "failed",
      "result": "Control, expected to fail: 23 of 24 checks fail, every card check for its own reason; only no uncaught exceptions passes.",
      "evidence": "Session scratchpad embed-addr fix run on port 8751"
    },
    {
      "command": "node qa/queen-embed-address-contract.mjs --origin=<local build of the branch before rebase>",
      "status": "passed",
      "result": "24 of 24 checks pass.",
      "evidence": "Session scratchpad embed-addr fix run on port 8752"
    },
    {
      "command": "After rebasing onto #1011: node qa/queen-tri-contract.mjs --no-build; node qa/queen-embed-address-contract.mjs --origin=<local build>; PROBE_SKIP_FRAMES=1 node live-tabs-probe.mjs <local build>",
      "status": "passed",
      "result": "On the rebased build (index-CUMd8JcR.js): TRI contract 14 of 14, embed address contract 24 of 24, tabs probe 50 of 50 with the thirteenth tab; check:tri passes after the literal-form commit.",
      "evidence": "Session scratchpad ea-embed-contract.log and ea-tabs-probe.json from the rebased worktree"
    },
    {
      "command": "node repro/f2-skill-labels.mjs, f3-ladder.mjs, f4-lang.mjs, f5-phone.mjs on both builds",
      "status": "passed",
      "result": "Each fails on the unmodified build and passes on the branch: labels, six-step ladder in explorers and docs, ?lang= kept after toggle and reload, Shared core 93x26 and tappable.",
      "evidence": "Session scratchpad embed-addr repro logs"
    },
    {
      "command": "npm run typecheck:ratchet; eslint on changed files; check:docs; check:agents; check:explorer-languages; queen-language-contract; both generators --check",
      "status": "passed",
      "result": "179 type errors against a baseline of 179, no new eslint error, all contracts and generator checks pass.",
      "evidence": "Local runs in the fix/queen-embedded-explorers-address worktree"
    },
    {
      "command": "node qa/queen-viewport-contract.mjs --no-build on both builds",
      "status": "failed",
      "result": "Fails identically on the unmodified and the fixed build (the same 30 size and view combinations), so the failures predate this change.",
      "evidence": "Session scratchpad embed-addr viewport runs"
    }
  ],
  "limitations": [
    "The vendored t27 layers chapter still names five layers next to the six-row table until gHashTag/t27 changes it.",
    "A plain Queen tab visit writes the embedded Explorer's default card into the address after the frame loads.",
    "The embed contract is slow on this machine and not wired into CI; Shared core is below a 44px touch target on phones."
  ],
  "tags": [
    "Website",
    "Queen",
    "Routing"
  ],
  "blog": {
    "title": "Every card has an address",
    "summary": "Queen tabs that frame an Explorer now write the selected card into the game's address, and four smaller inconsistencies found in the same sweep are fixed.",
    "outline": [
      "The symptom: inside the Queen, a picked skill, spec or chapter lived only in the embedded frame, so a reload, Back or a shared link lost it.",
      "The contract: the frame reports each card to the Queen, the Queen writes it with replace, and an outside change moves the frame without adding history.",
      "The edge cases: refused ids fall back to the default, unknown ids keep the Explorer's own not-found card, and a bare tab adopts what is on screen.",
      "The small fixes: honest skill labels, one six-step ladder, a language toggle that updates the address, and a phone button that had shrunk to nothing.",
      "What remains: the upstream t27 chapter text, a slow contract outside CI, and a small phone touch target."
    ]
  }
}

🤖 Generated with Claude Code

gHashTag and others added 7 commits September 15, 2026 01:27
public/docs/system-docs.json had drifted from the catalogs it is generated
from: check:docs failed at 429499e with "public/docs/system-docs.json is
stale or hand-edited" (the committed ladder said tools 91 while
public/tools/spec-tools.json holds 92). This is scripts/docs-from-specs.mjs as
committed, run on the committed catalogs, with the file's own generatedAt
(2026-09-12T12:30:15.363Z) passed through generate({ generatedAt }), so the
stamp keeps its milliseconds; the CLI's SOURCE_DATE_EPOCH takes whole seconds.

No new content, only what the catalogs already said: the mcp/inngest-dev row in
the tools table, a third tool for agent T in the ring and the bindings graph,
tools 91 -> 92 in the ladder and its figures, the external and per-repository
MCP lists, the tool counts in the witnesses table, and the sha256 of the source
files read at generation time. It goes first so the ladder change that follows
shows only its own rows.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
On /?lang=ru#/queen?tab=functions the HUD toggle switched the page to English
but left ?lang=ru in the address, so a reload came back in Russian. The
header's LanguageSwitcher already writes ?lang= with replaceState; the Queen's
toggle (the HUD tool button and the menu entry) now does the same, keeping
history.state, where HashRouter keeps its entry index.

Measured on local builds in headless Chrome (CDP, 1440x900):
before: after the toggle the search is still ?lang=ru with the document in en,
  and a reload is ru again (address agrees: false; reload keeps it: false).
after: the search is ?lang=en after the toggle, and a reload stays en.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…they count

#/skills counted "No spec 23", and a card said "No spec declared yet", for
skills whose own card shows witness spec+code and a spec at
specs/skills/<id>.t27 (t27/wave-audit, for one). The filter and the chip
measure whether a skill declares the spec it stands on -- a binding the build
checks -- not whether a card spec exists. The labels now say that; the data and
the counts are unchanged.

EN: No spec -> Unbound; No spec declared yet -> No spec binding declared yet;
Skills without a spec -> Skills that declare no spec binding;
"without a spec: {n}" -> "unbound: {n}".
RU: Со спекой -> С привязкой; Без спеки -> Без привязки;
Спека ещё не объявлена -> Привязка к спеке ещё не объявлена;
Скилы без спеки -> Скилы, не объявившие привязку к спеке;
"без спеки: {n}" -> "без привязки: {n}".

Measured on local builds in headless Chrome, #/skills?skill=t27%2Fwave-audit
in en and ru: before, the chip read "No spec" / "Без спеки" and the filters
"No spec 23" / "Без спеки 23"; after, "Unbound" / "Без привязки" with the same
counts (Bound 3, Unbound 23, Broken 0). check:explorer-languages passes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
At 390x844 (touch emulation) on #/queen the worlds nav in the HUD head showed
only the world select and the connect button: QueenUniverse.css hid the last
nav button (Shared core) and the one before it (Game home) below 640px, and
inside the head the nav is display: contents, so the hidden buttons measured
0x0 and view=core had no way in on a phone. Shared core now stays. Inside the
shell's head the world select is capped at 150px, which frees the width the
button needs, so the head keeps its height. Game home and the T27 shortcut
stay hidden on a phone, as before.

The variant was chosen by injecting candidate CSS into the unmodified build
before any source change: unhiding the button alone pushed it onto a second
row (head 110px -> 142px, field 32px shorter); unhiding it and capping the
select kept the head at 110px.

Measured on local builds in headless Chrome at 390x844 with touch, #/queen and
#/queen?tab=crons: before, Shared core measured 0x0 and a tap could not reach
view=core; after, it is 93x26 and tappable, a tap opens view=core, the head is
110px tall and the document is still 390x844 (one screen), with every nav
control inside the viewport.

qa/queen-viewport-contract.mjs --no-build reports the same on both builds: the
same 30 size/view combinations fail with the same messages (COUNT commands=12,
STATUS SLOT MISSING: alerts, undeclared scrollers such as .queen27-hud-intel),
390x844 included, so those failures predate this change and it adds none.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…s it

The layer ladder was stated several ways. On #/docs the figure said "The
five-layer ladder: Specs → Skills → Crons → Agents → Tools" and the
ladder-counts table had five rows; the PROJECT copy (queenModules.ts, the
Queen's PROJECT directive) and the docs meta description said "five-layer
ladder"; the Agent, Tool and Function Explorers drew six steps ending
Functions 28, with the Function Explorer's caption naming a ladder without
Tools; and the Skill and Cron Explorers drew no ladder at all.

Now one statement: Specs → Skills → Crons → Agents → Tools → Functions.
- scripts/agents-from-specs.mjs writes the ladder into spec-skills.json and
  spec-crons.json as well; the Skill and Cron Explorers draw it (LayerLadder,
  en/ru keys), and the Function Explorer's caption reads "ladder" like the rest.
- scripts/docs-from-specs.mjs counts functions in docs.ladder and adds a
  Functions row to the ladder-counts table; LadderFigure draws a sixth step and
  its caption says six steps, in en and ru.
- "six-step ladder" in the PROJECT copy (queenModules.ts, Queen.tsx) and in
  the docs meta description, in en and ru.
- The contracts follow: agents-spec-contract (the skills and crons catalogs
  carry the agents' ladder), docs-spec-contract and docs-from-specs.test
  (functions in the ladder and in the table).

The data is regenerated with the repository's generators, each file keeping
its generatedAt to the millisecond: spec-skills.json and spec-crons.json gain
only `ladder` (and a new contentSha256); spec-agents, spec-tools and
spec-functions come out byte-identical; system-docs.json gains the functions
count, the table row and the figure step.

Not changed here: the chapter's own title and prose, "The five-layer system"
and "Specs -> Skills -> Crons -> Agents -> Tools", are vendored from
gHashTag/t27 (public/t27/files/docs/system/layers.md and
specs/docs/chapters/layers.t27, pinned by sha256 in the docs contract), and
upstream still says five (its only commit to layers.md is 61241e1bc9). The
Russian title and body in i18n/docs.ru.json translate that vendored chapter
and stay with it. Until t27 changes layers.md, that chapter's prose names five
layers next to a six-row table.

Measured on local builds in headless Chrome: before, #/skills and #/crons drew
no ladder, #/functions captioned it "Specs → Skills → Crons → Agents →
Functions", the figure on #/docs/project had five steps under a five-layer
caption (ru: "Пятислойная лестница") and the table on #/docs/layers five rows.
After, all five Explorers draw the same six steps under the caption "ladder",
the figure has six steps ending "6. functions" under a six-step caption in en
and ru, and the table has a Functions row. check:docs, check:agents, both
generators' --check, their node --test suites and check:explorer-languages
pass.

qa/explorer-viewport-contract.mjs --no-build passes on both builds (6 sizes x 7
explorers) with the same 26 warnings: the Skill and Cron Explorers gain six
controls (the ladder links; 56 -> 62 at 1280x800) and no new warning, and at
390x844 both stay one phone pane with one scroller.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…er shows

Every Queen tab has its own address, and the tabs that frame an Explorer now
carry that Explorer's card in it too. Seven Queen tabs frame an Explorer, and
each kept its card only in the frame's own hash. Measured on t27.ai and on a
local build of 429499e: a pick in #/queen?tab=skills changed the frame, not
the address, so a reload opened the default skill;
?tab=specs&spec=specs/tri/tri_cli.t27 stayed on hello_world; a PROJECT chapter
jump was lost on reload; the language toggle reloaded the frame on its default;
and the ladder link Skills inside #/queen?tab=agents navigated the frame to the
Skill Explorer under a rail and an address that still said AGENTS.

The Queen address now names the card: skill=, cron=, agent=, function=, tool=,
spec= and chapter= (lib/queenEmbed SELECTION_KEY).
- Frame side, lib/queenFrame, which imports nothing so the entry chunk grows by
  1.1 kB: a page whose window the Queen named t27-queen-explorer posts each card
  it writes to its address (useHashParams.set, the Spec Explorer's pick) and
  hands a plain click on a link to an Explorer route to the Queen instead of
  following it. Frames the Queen did not name (the Spec Explorer in a skill
  card, the landing previews) post nothing and keep their links.
- Host side, components/useQueenExplorerFrame, used by QueenAgents and
  QueenSpecs: a message counts only from this origin and this frame. The frame
  boots on the address's card. A pick writes the address with replace, as tab=
  is written. An outside hash change, Back, or a frame load moves the frame with
  location.replace, which adds no history entry. A link to another Explorer
  switches the Queen tab, so the rail, the address, the frame title and the
  frame agree. The language toggle boots a new frame on the same card. Leaving
  a tab drops its card.
- Ids go through the Explorers' own *ExplorerHash helpers. A refused id is no
  card: the frame opens its default and the address takes that default. An id
  the helper accepts but the catalog lacks gets the Explorer's own not-found
  card, as on its own page, and the address keeps it -- no silent swap to a
  different card. The docs page has no such card and opens the first chapter;
  in a frame it writes the chapter it opened, so the address names it.
- An address that names no card of its tab (a link or Back to the bare tab)
  takes the frame's card, since the Explorers keep the open card on such a
  hash, so a reload opens what was on screen. A booting frame's report waits
  for its load event, and a report the frame has since been moved past is
  dropped as stale.
- The Spec Explorer, in a frame only, follows a later ?spec=; as with a list
  click, that discards an unsaved draft. On its own page it still reads its
  address once, as before (measured: a later ?spec= leaves the page on its spec
  on both builds).

Behaviour to know: a plain Queen tab visit writes the Explorer's default card
into the address once the frame has loaded (#/queen?tab=skills becomes
same inside its own frame. A hash without a card written inside the frame
changes nothing, since the frame still shows its card.

qa/queen-embed-address-contract.mjs (npm run check:queen-embed; --origin= for
a build served elsewhere) checks this in headless Chrome against the live DOM
of the Queen and the frame.
Results in headless Chrome at 1440x900, on a heavily loaded machine:
- build of 429499e, served locally: FAIL, 23 of 24. Every card check
  fails, each for its own reason (the default card under a deep link, no
  card in the address after a pick, skill= left behind after a tab switch,
  chapter=zz kept while chapter 1 shows); only "no uncaught exceptions"
  passes. The ?lang= check in D fails there too; that fix is an earlier
  commit.
- build of this commit: PASS, 24 of 24.
Also on this build: the live tabs probe (PROBE_SKIP_FRAMES=1) passes 47 of 47
(every tab still writes and follows its address by click, key, outside hash
and Back); standalone #/skills picks and ladder links behave as before; the
entry chunk is 309347 bytes against 308218 at 429499e. The typecheck
ratchet adds no errors; eslint reports only the react-refresh error that
main.tsx already had.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…t pins

Rebasing onto #1011 merged two writers of the shell's tab: TRI builds the
address from the live hash (tabAddress(window.location.hash, next)) and this
branch drops or writes the embedded Explorer's card. The merge first read the
hash into a local, which qa/tri-screens-contract.mjs does not recognise as the
live-hash write it pins. Same behaviour, the literal form restored.

Refs #1013

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@gHashTag
gHashTag merged commit 10ce3d5 into main Sep 14, 2026
29 of 35 checks passed
github-actions Bot added a commit that referenced this pull request Sep 14, 2026
fix(website): Queen explorer cards in the address, skill labels, six-step ladder, lang toggle, phone core (#1014)

* chore(website): regenerate system-docs.json from the committed catalogs

public/docs/system-docs.json had drifted from the catalogs it is generated
from: check:docs failed at 429499e with "public/docs/system-docs.json is
stale or hand-edited" (the committed ladder said tools 91 while
public/tools/spec-tools.json holds 92). This is scripts/docs-from-specs.mjs as
committed, run on the committed catalogs, with the file's own generatedAt
(2026-09-12T12:30:15.363Z) passed through generate({ generatedAt }), so the
stamp keeps its milliseconds; the CLI's SOURCE_DATE_EPOCH takes whole seconds.

No new content, only what the catalogs already said: the mcp/inngest-dev row in
the tools table, a third tool for agent T in the ring and the bindings graph,
tools 91 -> 92 in the ladder and its figures, the external and per-repository
MCP lists, the tool counts in the witnesses table, and the sha256 of the source
files read at generation time. It goes first so the ladder change that follows
shows only its own rows.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(website): the Queen's language toggle writes ?lang= to the address

On /?lang=ru#/queen?tab=functions the HUD toggle switched the page to English
but left ?lang=ru in the address, so a reload came back in Russian. The
header's LanguageSwitcher already writes ?lang= with replaceState; the Queen's
toggle (the HUD tool button and the menu entry) now does the same, keeping
history.state, where HashRouter keeps its entry index.

Measured on local builds in headless Chrome (CDP, 1440x900):
before: after the toggle the search is still ?lang=ru with the document in en,
  and a reload is ru again (address agrees: false; reload keeps it: false).
after: the search is ?lang=en after the toggle, and a reload stays en.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(website): the Skill Explorer's link labels name the spec binding they count

#/skills counted "No spec 23", and a card said "No spec declared yet", for
skills whose own card shows witness spec+code and a spec at
specs/skills/<id>.t27 (t27/wave-audit, for one). The filter and the chip
measure whether a skill declares the spec it stands on -- a binding the build
checks -- not whether a card spec exists. The labels now say that; the data and
the counts are unchanged.

EN: No spec -> Unbound; No spec declared yet -> No spec binding declared yet;
Skills without a spec -> Skills that declare no spec binding;
"without a spec: {n}" -> "unbound: {n}".
RU: Со спекой -> С привязкой; Без спеки -> Без привязки;
Спека ещё не объявлена -> Привязка к спеке ещё не объявлена;
Скилы без спеки -> Скилы, не объявившие привязку к спеке;
"без спеки: {n}" -> "без привязки: {n}".

Measured on local builds in headless Chrome, #/skills?skill=t27%2Fwave-audit
in en and ru: before, the chip read "No spec" / "Без спеки" and the filters
"No spec 23" / "Без спеки 23"; after, "Unbound" / "Без привязки" with the same
counts (Bound 3, Unbound 23, Broken 0). check:explorer-languages passes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(website): Shared core can be tapped on a phone

At 390x844 (touch emulation) on #/queen the worlds nav in the HUD head showed
only the world select and the connect button: QueenUniverse.css hid the last
nav button (Shared core) and the one before it (Game home) below 640px, and
inside the head the nav is display: contents, so the hidden buttons measured
0x0 and view=core had no way in on a phone. Shared core now stays. Inside the
shell's head the world select is capped at 150px, which frees the width the
button needs, so the head keeps its height. Game home and the T27 shortcut
stay hidden on a phone, as before.

The variant was chosen by injecting candidate CSS into the unmodified build
before any source change: unhiding the button alone pushed it onto a second
row (head 110px -> 142px, field 32px shorter); unhiding it and capping the
select kept the head at 110px.

Measured on local builds in headless Chrome at 390x844 with touch, #/queen and
#/queen?tab=crons: before, Shared core measured 0x0 and a tap could not reach
view=core; after, it is 93x26 and tappable, a tap opens view=core, the head is
110px tall and the document is still 390x844 (one screen), with every nav
control inside the viewport.

qa/queen-viewport-contract.mjs --no-build reports the same on both builds: the
same 30 size/view combinations fail with the same messages (COUNT commands=12,
STATUS SLOT MISSING: alerts, undeclared scrollers such as .queen27-hud-intel),
390x844 included, so those failures predate this change and it adds none.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(website): one ladder of six steps wherever the site draws or names it

The layer ladder was stated several ways. On #/docs the figure said "The
five-layer ladder: Specs → Skills → Crons → Agents → Tools" and the
ladder-counts table had five rows; the PROJECT copy (queenModules.ts, the
Queen's PROJECT directive) and the docs meta description said "five-layer
ladder"; the Agent, Tool and Function Explorers drew six steps ending
Functions 28, with the Function Explorer's caption naming a ladder without
Tools; and the Skill and Cron Explorers drew no ladder at all.

Now one statement: Specs → Skills → Crons → Agents → Tools → Functions.
- scripts/agents-from-specs.mjs writes the ladder into spec-skills.json and
  spec-crons.json as well; the Skill and Cron Explorers draw it (LayerLadder,
  en/ru keys), and the Function Explorer's caption reads "ladder" like the rest.
- scripts/docs-from-specs.mjs counts functions in docs.ladder and adds a
  Functions row to the ladder-counts table; LadderFigure draws a sixth step and
  its caption says six steps, in en and ru.
- "six-step ladder" in the PROJECT copy (queenModules.ts, Queen.tsx) and in
  the docs meta description, in en and ru.
- The contracts follow: agents-spec-contract (the skills and crons catalogs
  carry the agents' ladder), docs-spec-contract and docs-from-specs.test
  (functions in the ladder and in the table).

The data is regenerated with the repository's generators, each file keeping
its generatedAt to the millisecond: spec-skills.json and spec-crons.json gain
only `ladder` (and a new contentSha256); spec-agents, spec-tools and
spec-functions come out byte-identical; system-docs.json gains the functions
count, the table row and the figure step.

Not changed here: the chapter's own title and prose, "The five-layer system"
and "Specs -> Skills -> Crons -> Agents -> Tools", are vendored from
gHashTag/t27 (public/t27/files/docs/system/layers.md and
specs/docs/chapters/layers.t27, pinned by sha256 in the docs contract), and
upstream still says five (its only commit to layers.md is 61241e1bc9). The
Russian title and body in i18n/docs.ru.json translate that vendored chapter
and stay with it. Until t27 changes layers.md, that chapter's prose names five
layers next to a six-row table.

Measured on local builds in headless Chrome: before, #/skills and #/crons drew
no ladder, #/functions captioned it "Specs → Skills → Crons → Agents →
Functions", the figure on #/docs/project had five steps under a five-layer
caption (ru: "Пятислойная лестница") and the table on #/docs/layers five rows.
After, all five Explorers draw the same six steps under the caption "ladder",
the figure has six steps ending "6. functions" under a six-step caption in en
and ru, and the table has a Functions row. check:docs, check:agents, both
generators' --check, their node --test suites and check:explorer-languages
pass.

qa/explorer-viewport-contract.mjs --no-build passes on both builds (6 sizes x 7
explorers) with the same 26 warnings: the Skill and Cron Explorers gain six
controls (the ladder links; 56 -> 62 at 1280x800) and no new warning, and at
390x844 both stay one phone pane with one scroller.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(website): the Queen's address names the card each embedded Explorer shows

Every Queen tab has its own address, and the tabs that frame an Explorer now
carry that Explorer's card in it too. Seven Queen tabs frame an Explorer, and
each kept its card only in the frame's own hash. Measured on t27.ai and on a
local build of 429499e: a pick in #/queen?tab=skills changed the frame, not
the address, so a reload opened the default skill;
?tab=specs&spec=specs/tri/tri_cli.t27 stayed on hello_world; a PROJECT chapter
jump was lost on reload; the language toggle reloaded the frame on its default;
and the ladder link Skills inside #/queen?tab=agents navigated the frame to the
Skill Explorer under a rail and an address that still said AGENTS.

The Queen address now names the card: skill=, cron=, agent=, function=, tool=,
spec= and chapter= (lib/queenEmbed SELECTION_KEY).
- Frame side, lib/queenFrame, which imports nothing so the entry chunk grows by
  1.1 kB: a page whose window the Queen named t27-queen-explorer posts each card
  it writes to its address (useHashParams.set, the Spec Explorer's pick) and
  hands a plain click on a link to an Explorer route to the Queen instead of
  following it. Frames the Queen did not name (the Spec Explorer in a skill
  card, the landing previews) post nothing and keep their links.
- Host side, components/useQueenExplorerFrame, used by QueenAgents and
  QueenSpecs: a message counts only from this origin and this frame. The frame
  boots on the address's card. A pick writes the address with replace, as tab=
  is written. An outside hash change, Back, or a frame load moves the frame with
  location.replace, which adds no history entry. A link to another Explorer
  switches the Queen tab, so the rail, the address, the frame title and the
  frame agree. The language toggle boots a new frame on the same card. Leaving
  a tab drops its card.
- Ids go through the Explorers' own *ExplorerHash helpers. A refused id is no
  card: the frame opens its default and the address takes that default. An id
  the helper accepts but the catalog lacks gets the Explorer's own not-found
  card, as on its own page, and the address keeps it -- no silent swap to a
  different card. The docs page has no such card and opens the first chapter;
  in a frame it writes the chapter it opened, so the address names it.
- An address that names no card of its tab (a link or Back to the bare tab)
  takes the frame's card, since the Explorers keep the open card on such a
  hash, so a reload opens what was on screen. A booting frame's report waits
  for its load event, and a report the frame has since been moved past is
  dropped as stale.
- The Spec Explorer, in a frame only, follows a later ?spec=; as with a list
  click, that discards an unsaved draft. On its own page it still reads its
  address once, as before (measured: a later ?spec= leaves the page on its spec
  on both builds).

Behaviour to know: a plain Queen tab visit writes the Explorer's default card
into the address once the frame has loaded (#/queen?tab=skills becomes
same inside its own frame. A hash without a card written inside the frame
changes nothing, since the frame still shows its card.

qa/queen-embed-address-contract.mjs (npm run check:queen-embed; --origin= for
a build served elsewhere) checks this in headless Chrome against the live DOM
of the Queen and the frame.
Results in headless Chrome at 1440x900, on a heavily loaded machine:
- build of 429499e, served locally: FAIL, 23 of 24. Every card check
  fails, each for its own reason (the default card under a deep link, no
  card in the address after a pick, skill= left behind after a tab switch,
  chapter=zz kept while chapter 1 shows); only "no uncaught exceptions"
  passes. The ?lang= check in D fails there too; that fix is an earlier
  commit.
- build of this commit: PASS, 24 of 24.
Also on this build: the live tabs probe (PROBE_SKIP_FRAMES=1) passes 47 of 47
(every tab still writes and follows its address by click, key, outside hash
and Back); standalone #/skills picks and ladder links behave as before; the
entry chunk is 309347 bytes against 308218 at 429499e. The typecheck
ratchet adds no errors; eslint reports only the react-refresh error that
main.tsx already had.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(website): keep the shell's tab write in the shape the TRI contract pins

Rebasing onto #1011 merged two writers of the shell's tab: TRI builds the
address from the live hash (tabAddress(window.location.hash, next)) and this
branch drops or writes the embedded Explorer's card. The merge first read the
hash into a local, which qa/tri-screens-contract.mjs does not recognise as the
live-hash write it pins. Same behaviour, the literal form restored.

Refs #1013

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
@gHashTag

Copy link
Copy Markdown
Owner Author

Verified live on https://t27.ai after the publisher run ("Publish assets/index-CPB82kK5.js from trinity 10ce3d5"; the merge tree equals the reviewed branch tree, f37af003).

On index-CPB82kK5.js, headless Chrome against the live site:

  • qa/queen-embed-address-contract.mjs --origin=https://t27.ai: 24 of 24 (deep links for all seven Explorer tabs, pick writes the address without a history entry, reload, outside hash, Back, language toggle with ?lang=, ladder and chip links switch the Queen tab, PROJECT chapters, refused and unknown ids, no uncaught exceptions).
  • Queen tab probe: 50 of 50 (all thirteen tabs by click, key, outside hash, Back, reload).
  • TRI tab probe: 11 of 11 (the TRI tab from feat(website): TRI tab, the app at app.t27.ai inside the Queen #1011 still works after this merge, including no Authorization from the frame with a fake tab session seeded).

The same embed contract failed 23 of 24 on a local build of 429499e before these changes.

Not verified live: Shared core on a real phone (measured at 390x844 in headless Chrome only); the vendored t27 chapter still says "five-layer".

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.

Queen: embedded Explorer selection in the address, skill labels, ladder wording, lang toggle, phone core button

1 participant