diff --git a/.claude/skills/t27f/SKILL.md b/.claude/skills/t27f/SKILL.md index b5a46919b2..edfca2f22c 100644 --- a/.claude/skills/t27f/SKILL.md +++ b/.claude/skills/t27f/SKILL.md @@ -1,10 +1,10 @@ --- id: t27f -name: T27F Visual Spec -description: T27F is the visual spec of a .t27 file -- one spec, one synchronized model, many views (source, architecture, data flow, dependencies, tests and benchmarks), every node labelled exact, derived, suggested or unknown and linked to its source span (gHashTag/trinity#1648, RFC gHashTag/trinity#1649). Use when the user says "t27f", "visual spec", "show / visualize / draw this spec", or opens a .t27 file to see its structure. Also runs the topic-map application built on T27F (gHashTag/trinity#1677) when the user gives a topic or a client brief. +name: T27F Frontend +description: T27F is t27's frontend -- the one tool through which t27 shows anything visual, made through several tools (spec graph and outline, honeycomb map stills, the t27.ai graph page, particle reels and stills, the hot-reload stream, the claw/t27f check-run), with its surfaces, their status and the intent-to-surface routing in specs/t27f/frontend.t27. Its core is the visual spec of a .t27 file (gHashTag/trinity#1648, RFC gHashTag/trinity#1649). TRI CLAW serves its MCP tools. Use when the user says "t27f", "visual", "visual spec", "show / visualize / draw this spec", "reel", "still", or opens a .t27 file to see its structure. Also runs the topic-map application (gHashTag/trinity#1677) when the user gives a topic or a client brief. --- -# T27F Visual Spec +# T27F Frontend > **Only t27: everything is written in `.t27`.** (Owner hard rule 2026-10-05; budget #7371; restated in every skill per #7588.) @@ -17,45 +17,65 @@ description: T27F is the visual spec of a .t27 file -- one spec, one synchronize ## What T27F is -**This section is the one home of the definition.** `CLAUDE.md`, `specs/OWNERS.md`, the skill card -`specs/skills/t27-t27f.t27` and the spec headers point here; they do not restate it. - -T27F is the **visual spec of `.t27`**: every t27 specification has a first-class visual form, an -interactive, inspectable diagram built from reusable widgets. Sources: epic gHashTag/trinity#1648 -("native generative UI and visual application engine") and RFC gHashTag/trinity#1649 ("specs as -executable visual diagrams"). - -- **One spec -> one synchronized source model -> many views**: source, architecture diagram, data - flow, dependency graph, tests/benchmarks, docs. Every view is derived from the real spec - (AST/IR plus metadata), never a hand-drawn picture that can drift from the code. -- **Graph IR**: versioned, typed nodes (module, function, step, input/output/parameter/constant, - type/numeric format, branch/loop, operator, dependency, test/invariant/oracle, benchmark/hardware, - paper/dataset, opaque region) and typed edges (data flow, control flow, calls/depends on, - produces/consumes, constrains, tested by, measured by, implemented by, cited by). The full lists - are in #1649. -- **Every node carries one inference label**: `exact` (present in the AST/IR), `derived` (safe from - symbol and type resolution), `suggested` (a model's explanation, visibly marked, linked to source - ranges) or `unknown`. A model's guess is never drawn as a verified property of the program. -- **Bidirectional source mapping**: select a node, see its source span; select a line, see its - node. Generation is deterministic for a fixed source and toolchain, and two revisions produce a - graph diff. -- **Read-only viewer first.** Editing comes after the schema survives two structurally different - specs. GF16 (`specs/numeric/gf16.t27`) is a *candidate* pilot pending the comparison in #1651. -- **The pipeline (#1648)**: intent -> versioned system description -> domain model and computation - -> renderer-neutral UI plan (trusted widget ids, bindings, layout, actions, theme, a11y, - provenance) -> T27F renderer -> verification loop. A model never ships code to the renderer: no - eval, no generated JS, only widgets from an allowlist. -- **In the map** (#1648 comments, 2026-10-16): zooming into a honeycomb cell opens that cell's spec - as a navigable program, linked to source, tests, issues and real task status; each cell is both a - spec and a learning entry point. +**This section is the one home of the definition.** `CLAUDE.md`, `AGENTS.md`, `specs/OWNERS.md`, +the skill card `specs/skills/t27-t27f.t27` and the spec headers point here; they do not restate it. + +T27F is **t27's frontend: its native visualization, made through several tools.** Everything t27 +shows -- a spec as a diagram, a topic as a map, a lesson as a particle reel, a report as a still, a +pull request as a check-run -- is a T27F surface. Owner, 2026-10-18: everything visual is gathered +into T27F as one tool, and T27F goes into TRI CLAW. + +**The law is `specs/t27f/frontend.t27`.** It lists the surfaces, what draws each today (LIVE, LAB, +PARTIAL, BLOCKED, SPEC), which surface answers an intent (`route`), the stand-in when the wanted one +cannot be made this turn (`pick`), the rule that nothing undrawn is claimed made (`claim_ok`), and +which surfaces TRI CLAW serves (`claw_serves`). Read the table there; this section does not copy it. +The rules of each surface stay in the spec that decides it. + +The surfaces, by family: + +- **Spec diagram (the core).** Every t27 specification has a first-class visual form, an + interactive, inspectable diagram (epic gHashTag/trinity#1648, RFC gHashTag/trinity#1649). Drawn as + SVG by `t27f_graph`, as text by `t27f_outline`, and on t27.ai/t27f/graph/ and the Spec Explorer. + - **One spec -> one synchronized source model -> many views**: source, architecture, data flow, + dependencies, tests/benchmarks, docs. Every view is derived from the real spec (AST/IR plus + metadata), never a hand-drawn picture that can drift from the code. + - **Graph IR**: versioned, typed nodes and edges; the full lists are in #1649 and + `specs/t27f/spec_graph.t27`. + - **Every node carries one inference label**: `exact`, `derived`, `suggested` (a model's + explanation, visibly marked) or `unknown`. A model's guess is never drawn as a verified property. + - **Bidirectional source mapping**, deterministic generation, graph diffs between revisions. + - **Read-only viewer first.** GF16 (`specs/numeric/gf16.t27`) is a *candidate* pilot (#1651). + - **The pipeline (#1648)**: intent -> system description -> domain model -> renderer-neutral UI + plan (trusted widget ids only, `specs/t27f/ui_plan.t27`) -> T27F renderer -> verification. A model + never ships code to the renderer. +- **Maps.** The 27-cell honeycomb (`specs/t27f/reel.t27`, look `deck.t27`): stills by `t27f_view` + today; the video and live player are spec only. +- **Particle reels and stills.** The token_floor world (`token_floor*.t27`, `lesson_reel.t27`, + `reel_particles*.t27`, `particle_engine.t27`): every pixel is a sum a spec computes and every motion + a step of an integrator. Rendered on the Railway lab; a still is one frame of a reel. T27F Live + (`particle_field.t27`) is the same physics driven by an agent's events, spec only. +- **Live editing and review.** The hot-reload stream (`hot.t27`, `build.t27`), the `claw/t27f` + check-run the TRI CLAW App posts on a pull request (`specs/claw/t27f_gate.t27`), the PR preview + (`specs/claw/preview.t27`). +- **Health.** The MCP dashboard (`specs/t27mcp/dashboard.t27`, tool `t27_dashboard`). + +**In TRI CLAW.** `specs/t27mcp/service.t27` gives every `t27_` and `t27f_` tool to the t27 home and +mounts it into TRI CLAW's `/mcp`. `frontend.t27` checks that every T27F tool lands there and names +the drawing set TRI CLAW's chat agent carries (`claw_visual_tool`), next to the coder persona's +`CODER_TOOLS`. Whether the deployed `/mcp` mounts them today is not measured. **What T27F is not:** it is not the topic-to-value engine. gHashTag/trinity#1677 (topic or client -brief -> 27-lesson map -> Bee -> verified artifact) is an *application* built on T27F, and so are -the reels. Describing T27F as #1677 is the error this section exists to stop (owner correction, -2026-10-17). +brief -> 27-lesson map -> Bee -> verified artifact) is an *application*: its decisions live in +`specs/t27f/topic_engine.t27`, and what it shows is drawn through T27F's map surface. T27F is also +not one diagram: an answer asked for "a T27F visual" picks the surface `frontend.t27` routes it to. +Owner corrections: 2026-10-17 (not the topic engine), 2026-10-18 (the frontend, through several +tools, reels included). ## What exists and what does not +The status of every surface is `SURFACE_STATUS` in `specs/t27f/frontend.t27`. The rows below give +the diagram core in detail, then the other surfaces and the topic-map application. + | Layer | Where | State | |---|---|---| | Spec -> graph IR schema (the core) | `specs/t27f/spec_graph.t27` (t27#10020) | spec with tests: node / edge kinds, labels, spans, `validate_graph`, line -> node mapping, node -> ui_plan widget, one hand-read fixture (`specs/tutorial/08_modules_and_arrays.t27`) | @@ -65,14 +85,15 @@ the reels. Describing T27F as #1677 is the error this section exists to stop (ow | Graph IR derive pass | `specs/t27f/spec_graph_derive.t27` (t27#10191) | spec with tests: `derive_graph(g, src)` appends what the exporter must not claim and changes nothing it holds. R1 DERIVED `tested_by` = every EXACT CALLS edge from a test, invariant or bench to a fn read backwards (no line). R2 DERIVED `data_flow` = a const or `use` that an EXACT USES edge ties to a fn and that is named inside one of the fn's return statements (from `return` to the next `;`), on the line of the first such name. R3 UNKNOWN opaque node = an undeclared qualified call target of three or more segments (`std.testing.expectEqual(` names `std.testing`), spanning the lines that call through it. Exporter plus derive equal the tutorial 08 fixture as sets: 15 of 15 nodes, 16 of 16 edges, no special case. Limits: names matched as text; call results and flow through locals are not derived; R3 needs 3 or more segments (two cannot be told from a method call); a graph that does not validate, or a source of another line count, comes back unchanged; past 1024 nodes or 4096 edges the result is refused with the too-many verdict. Not wired to a host: the MCP tool does not call it | | UI plan IR + trusted widget catalog | `specs/t27f/ui_plan.t27` (t27#9962) | spec with tests; no renderer draws a plan yet | | Honeycomb focus+context geometry | `specs/t27f/reel.t27` | spec; stills drawn by the MCP tool `t27f_view` | -| Renderer in the Trinity UI | gHashTag/trinity | **missing**; no T27F widget is live | -| Application: topic map (#1677) | `specs/t27f/topic_engine.t27`, `topic_reel.t27` | spec; procedure below | -| Application: reels and deck | `specs/t27f/reel.t27`, `deck.t27`, `reel_*.t27` | spec; two reels | +| Renderer in the Trinity UI | gHashTag/trinity, t27.ai/t27f/graph/ and the Spec Explorer graph layer | live for the spec graph; it ignores a `src=` parameter, and no page draws a UI plan yet | +| Surface: particle reels and stills | `specs/t27f/token_floor*.t27`, `lesson_reel.t27`, `reel_particles*.t27` | rendered on the Railway lab (lesson 1 EN and RU); no renderer in the repo, no MCP tool yet | +| Surface: honeycomb map video and deck | `specs/t27f/reel.t27`, `deck.t27` | spec; stills only, through `t27f_view` | +| Application: topic map (#1677) | `specs/t27f/topic_engine.t27`, `topic_reel.t27` | spec; drawn through the map surface; procedure below | | Application: content factory (epic t27#10560) | `specs/t27f/reel_factory.t27` (t27#10561) | spec with tests: an item's code and title, read keyword by keyword, give 11 features. Those pick 1 of 12 scene archetypes (best pair first, cap 4, no repeat within 2 items, then the least-used generic scene) plus an accent, a motion, a layout and 8 output formats. No renderer draws a plan yet (R3), and `lesson_reel` still draws token_floor (R4). Lessons: read the plan's spread over the whole course before trusting it. A greedy walk in course order gave 7 lessons one scene. Code counts alone handed lesson 8 the tests scene over "A test block". Gate: `tri factory`. The plan prints from a separate module, `specs/t27f/reel_factory_plan.t27` (t27#10573): `t27c gen` it, then run the zig (t27c has no `run`). Names come from the factory's comma lists, so the law module keeps no `main`. Traps: the lab's `/root/t27` t27b can predate #10455 and refuse `std.debug.print` that master accepts, so build a fresh t27b in its own worktree with its own `CARGO_TARGET_DIR` before you call a print unsupported. `t27c seal --save` needs zig on PATH (`/opt/zig`). A base64 line fetched back from fs-lab merges with the Railway warning, so wrap it as `B64:...:END`. A new `tri` arm must start its own line (` name)`) or the documented-commands checker misses it | | Related | trinity#1647 dashboards, #1652 MVP research, #1653 three skills, #1655 evolution runtime | open | -When asked "how is T27F going", report against the core rows first. Progress on the applications -is not progress on the core. +When asked "how is T27F going", report against the core rows first, then the other surfaces. +Progress on a reel or on the topic map is not progress on the diagram core. **Trap: a name declared in two specs cannot be imported (t27#10556).** Measured on t27c 0.5.2: `use t27f::lesson_reel::phrase_start` returns `UNRESOLVED ... ambiguous, not spliced`, because diff --git a/.trinity/seals/igla_own_model.json b/.trinity/seals/igla_own_model.json index 74393654fd..016bdec301 100644 --- a/.trinity/seals/igla_own_model.json +++ b/.trinity/seals/igla_own_model.json @@ -1,5 +1,5 @@ { - "built_by": "t27c-bootstrap@0.5.2+fd332dfd5", + "built_by": "t27c-bootstrap@0.5.2+9448ab4be", "closure": [ { "spec": "specs/t27f/reel.t27", @@ -7,7 +7,7 @@ }, { "spec": "specs/t27f/topic_engine.t27", - "spec_hash": "sha256:95337a0fe59f32426db6ca3a9481151c28f2b9eaddfa346659782e6d70ae5ff0" + "spec_hash": "sha256:d117a894beb6dc97ee678f84a927a98a801783d101b8b4cd96a0875979a911be" }, { "spec": "specs/t27f/topic_reel.t27", @@ -22,7 +22,7 @@ "module": "own_model", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-18T13:33:41Z", + "sealed_at": "2026-10-18T17:03:43Z", "sealed_by": "t27c-bootstrap@0.5.2", "spec_hash": "sha256:2c3daec9e62ce9123e19cad921e57af75beb25a1870c234230ae5505a7d7ac79", "spec_path": "specs/igla/own_model.t27", diff --git a/.trinity/seals/igla_own_model_board.json b/.trinity/seals/igla_own_model_board.json index 20c6c66218..53f69640db 100644 --- a/.trinity/seals/igla_own_model_board.json +++ b/.trinity/seals/igla_own_model_board.json @@ -1,5 +1,5 @@ { - "built_by": "t27c-bootstrap@0.5.2+fd332dfd5", + "built_by": "t27c-bootstrap@0.5.2+9448ab4be", "closure": [ { "spec": "specs/igla/own_model.t27", @@ -11,7 +11,7 @@ }, { "spec": "specs/t27f/topic_engine.t27", - "spec_hash": "sha256:95337a0fe59f32426db6ca3a9481151c28f2b9eaddfa346659782e6d70ae5ff0" + "spec_hash": "sha256:d117a894beb6dc97ee678f84a927a98a801783d101b8b4cd96a0875979a911be" }, { "spec": "specs/t27f/topic_reel.t27", @@ -26,7 +26,7 @@ "module": "own_model_board", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-18T13:33:45Z", + "sealed_at": "2026-10-18T17:03:43Z", "sealed_by": "t27c-bootstrap@0.5.2", "spec_hash": "sha256:69e4e67d00d0a17aed8d5e9ed45d7c745c970d069388db37f7835ff39179adae", "spec_path": "specs/igla/own_model_board.t27", diff --git a/.trinity/seals/skills_skill_t27_t27f.json b/.trinity/seals/skills_skill_t27_t27f.json index 567e882a45..ece31cb6a4 100644 --- a/.trinity/seals/skills_skill_t27_t27f.json +++ b/.trinity/seals/skills_skill_t27_t27f.json @@ -1,17 +1,17 @@ { - "built_by": "t27c-bootstrap@0.5.2+d2c8e7d41", + "built_by": "t27c-bootstrap@0.5.2+9448ab4be", "closure": [], "config": "gen=c,rust,verilog,zig;tests=zig", - "gen_hash_c": "sha256:3856d97173c4f486b0e39ca00880e706976994e72287fe5b5c86b0b467fd540a", - "gen_hash_rust": "sha256:9b522f77f03668cd71a936b56a6e221891364aac68b7cd8fcea3763613c4ee54", - "gen_hash_verilog": "sha256:ba6e95d5187eb5620e250e96bd46b1d624e0cb7c613ad71a6e07f20f37c25f97", - "gen_hash_zig": "sha256:5eed1c29cede07e37e59db44b4cbb47f3641cd8da680aacf4695ecff39fad596", + "gen_hash_c": "sha256:ed65bd9f03e7c59dc32bfdb5e30f8cc9536670b1008f887db3c8021e757919d6", + "gen_hash_rust": "sha256:8ca96060be660b1e0045eca0c33d806a9ee34a167991d15a61053e4c2587b272", + "gen_hash_verilog": "sha256:9283f9562ad95ad1efb5de87fdb16369bad0ab2bb3ca8e16b89d302bc88a5cb6", + "gen_hash_zig": "sha256:a87168712386fd53b1d4cdf062115911e0c29d64714a2243bafffb281377a38b", "module": "skill_t27_t27f", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-18T05:07:15Z", + "sealed_at": "2026-10-18T17:03:24Z", "sealed_by": "t27c-bootstrap@0.5.2", - "spec_hash": "sha256:93a740f66c7db49fcf8fea13f52ccd449c810d08f89e161db72ee112ab330dcf", + "spec_hash": "sha256:3df4eafade88568e36f421a2dffb326a280810bced4bf67960befdd8d1968997", "spec_path": "specs/skills/t27-t27f.t27", "tests": { "failed": 0, diff --git a/.trinity/seals/t27f_T27fFrontend.json b/.trinity/seals/t27f_T27fFrontend.json new file mode 100644 index 0000000000..d269ef04b3 --- /dev/null +++ b/.trinity/seals/t27f_T27fFrontend.json @@ -0,0 +1,41 @@ +{ + "built_by": "t27c-bootstrap@0.5.2+9448ab4be", + "closure": [ + { + "spec": "specs/t27f/reel.t27", + "spec_hash": "sha256:c47b21cea1d7169da6528e321cf2d2c513d3f552c0cd04fe9d37bbd5314ccacf" + }, + { + "spec": "specs/t27mcp/service.t27", + "spec_hash": "sha256:3d7957837be8ac3de14b18ce1c0ecdde805f3f71d4d801b62d476b2e82f4a1ae" + }, + { + "spec": "specs/t27mcp/tool_schema.t27", + "spec_hash": "sha256:49528bd0537c12a9a7a288735d272ee974cf2d261a8f197eb5b17b78a2f9a89b" + } + ], + "config": "gen=c,rust,verilog,zig;tests=zig", + "gen_hash_c": "sha256:cb17d2d0955860474a7e522538691fe2efe5b3bf539497a5405349e2b830ee39", + "gen_hash_rust": "sha256:4b7f761fc91186cf4c9a8abb2a7c503407ddbeba06cbc34c7af51c811e1bde95", + "gen_hash_verilog": "sha256:7a71807e11de0cf1e85ccbf6fbe09c70ca7f8a84db78e7548eb9699ca3576777", + "gen_hash_zig": "sha256:bf142bb8a420fd242fc209833cb874d58a6ffffe23e6ea3121a4cc5cb1d16e9e", + "module": "T27fFrontend", + "ring": 12, + "seal_schema": 2, + "sealed_at": "2026-10-18T17:03:22Z", + "sealed_by": "t27c-bootstrap@0.5.2", + "spec_hash": "sha256:13cd46e9bdacfbae4f6ecd247f771ad6159166aa3a45cd56ce25b57be06de58c", + "spec_path": "specs/t27f/frontend.t27", + "tests": { + "failed": 0, + "failing": [], + "forced": false, + "passed": 7, + "total": 7, + "vacuous": 0 + }, + "toolchain": { + "test_runner": "sha256:1982ae948e24d00c5d221ccec12dfce1eb01204b53e37b0f857f93b16d64629d", + "zig": "0.16.0" + } +} \ No newline at end of file diff --git a/.trinity/seals/t27f_T27fTopicEngine.json b/.trinity/seals/t27f_T27fTopicEngine.json index 08d3c38ed7..61c1973613 100644 --- a/.trinity/seals/t27f_T27fTopicEngine.json +++ b/.trinity/seals/t27f_T27fTopicEngine.json @@ -1,5 +1,5 @@ { - "built_by": "t27c-bootstrap@0.5.2+093bf4713", + "built_by": "t27c-bootstrap@0.5.2+9448ab4be", "closure": [], "config": "gen=c,rust,verilog,zig;tests=zig", "gen_hash_c": "sha256:725bc9a3ec9380a91773719bba2bceaf604ff3f8661167869dac0cd91392d6ba", @@ -9,9 +9,9 @@ "module": "T27fTopicEngine", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-18T09:33:01Z", + "sealed_at": "2026-10-18T17:03:24Z", "sealed_by": "t27c-bootstrap@0.5.2", - "spec_hash": "sha256:95337a0fe59f32426db6ca3a9481151c28f2b9eaddfa346659782e6d70ae5ff0", + "spec_hash": "sha256:d117a894beb6dc97ee678f84a927a98a801783d101b8b4cd96a0875979a911be", "spec_path": "specs/t27f/topic_engine.t27", "tests": { "failed": 0, diff --git a/.trinity/seals/t27f_reel_gf16_nmse.json b/.trinity/seals/t27f_reel_gf16_nmse.json index 2fe74dd7d5..b2822c7af8 100644 --- a/.trinity/seals/t27f_reel_gf16_nmse.json +++ b/.trinity/seals/t27f_reel_gf16_nmse.json @@ -1,5 +1,5 @@ { - "built_by": "t27c-bootstrap@0.5.2+093bf4713", + "built_by": "t27c-bootstrap@0.5.2+9448ab4be", "closure": [ { "spec": "specs/t27f/reel.t27", @@ -7,7 +7,7 @@ }, { "spec": "specs/t27f/topic_engine.t27", - "spec_hash": "sha256:95337a0fe59f32426db6ca3a9481151c28f2b9eaddfa346659782e6d70ae5ff0" + "spec_hash": "sha256:d117a894beb6dc97ee678f84a927a98a801783d101b8b4cd96a0875979a911be" }, { "spec": "specs/t27f/topic_reel.t27", @@ -22,7 +22,7 @@ "module": "reel_gf16_nmse", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-18T09:33:00Z", + "sealed_at": "2026-10-18T17:03:41Z", "sealed_by": "t27c-bootstrap@0.5.2", "spec_hash": "sha256:4f0f49a4533666577fa9fa1e44558cb5e030801f6ed37605c3ca6e65e74c5f4d", "spec_path": "specs/t27f/reel_gf16_nmse.t27", diff --git a/.trinity/seals/t27f_reel_particles.json b/.trinity/seals/t27f_reel_particles.json index f3fc115a43..65cf4b6a8b 100644 --- a/.trinity/seals/t27f_reel_particles.json +++ b/.trinity/seals/t27f_reel_particles.json @@ -1,5 +1,5 @@ { - "built_by": "t27c-bootstrap@0.5.2+4ab200073", + "built_by": "t27c-bootstrap@0.5.2+9448ab4be", "closure": [ { "spec": "specs/t27f/reel_t27_basics.t27", @@ -7,7 +7,7 @@ }, { "spec": "specs/t27f/topic_engine.t27", - "spec_hash": "sha256:95337a0fe59f32426db6ca3a9481151c28f2b9eaddfa346659782e6d70ae5ff0" + "spec_hash": "sha256:d117a894beb6dc97ee678f84a927a98a801783d101b8b4cd96a0875979a911be" } ], "config": "gen=c,rust,verilog,zig;tests=zig", @@ -18,7 +18,7 @@ "module": "reel_particles", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-18T09:43:49Z", + "sealed_at": "2026-10-18T17:03:41Z", "sealed_by": "t27c-bootstrap@0.5.2", "spec_hash": "sha256:d84714fc328bdc56596cda456b0e8efdd4233cfdb593dcc014a06b92e5feefbe", "spec_path": "specs/t27f/reel_particles.t27", diff --git a/.trinity/seals/t27f_reel_t27_basics.json b/.trinity/seals/t27f_reel_t27_basics.json index 9943ff7137..a3742e55c2 100644 --- a/.trinity/seals/t27f_reel_t27_basics.json +++ b/.trinity/seals/t27f_reel_t27_basics.json @@ -1,5 +1,5 @@ { - "built_by": "t27c-bootstrap@0.5.2+093bf4713", + "built_by": "t27c-bootstrap@0.5.2+9448ab4be", "closure": [ { "spec": "specs/t27f/reel.t27", @@ -7,7 +7,7 @@ }, { "spec": "specs/t27f/topic_engine.t27", - "spec_hash": "sha256:95337a0fe59f32426db6ca3a9481151c28f2b9eaddfa346659782e6d70ae5ff0" + "spec_hash": "sha256:d117a894beb6dc97ee678f84a927a98a801783d101b8b4cd96a0875979a911be" }, { "spec": "specs/t27f/topic_reel.t27", @@ -22,7 +22,7 @@ "module": "reel_t27_basics", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-18T09:33:00Z", + "sealed_at": "2026-10-18T17:03:42Z", "sealed_by": "t27c-bootstrap@0.5.2", "spec_hash": "sha256:adc9acbff0ab032d55ec5e51023c24176d8ee1e4bcdbc08d1000f37395a221ec", "spec_path": "specs/t27f/reel_t27_basics.t27", diff --git a/.trinity/seals/t27f_t27f_quest.json b/.trinity/seals/t27f_t27f_quest.json index ddbd26f374..bd33ae0216 100644 --- a/.trinity/seals/t27f_t27f_quest.json +++ b/.trinity/seals/t27f_t27f_quest.json @@ -1,5 +1,5 @@ { - "built_by": "t27c-bootstrap@0.5.2+093bf4713", + "built_by": "t27c-bootstrap@0.5.2+9448ab4be", "closure": [ { "spec": "specs/queen/tasks.t27", @@ -15,7 +15,7 @@ }, { "spec": "specs/t27f/topic_engine.t27", - "spec_hash": "sha256:95337a0fe59f32426db6ca3a9481151c28f2b9eaddfa346659782e6d70ae5ff0" + "spec_hash": "sha256:d117a894beb6dc97ee678f84a927a98a801783d101b8b4cd96a0875979a911be" } ], "config": "gen=c,rust,verilog,zig;tests=zig", @@ -26,9 +26,9 @@ "module": "t27f_quest", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-18T09:32:59Z", + "sealed_at": "2026-10-18T17:03:25Z", "sealed_by": "t27c-bootstrap@0.5.2", - "spec_hash": "sha256:a2d65ddf0f22dd44ff2b56643c7896694a13b27f03a3d61e878ec7f708c06d93", + "spec_hash": "sha256:431cec2f0bee34c105bd8501237a26f85e6aa74168ef15e17e57d08f218362bf", "spec_path": "specs/t27f/quest.t27", "tests": { "failed": 0, diff --git a/.trinity/seals/t27f_t27f_spec_graph.json b/.trinity/seals/t27f_t27f_spec_graph.json index b92f8e9dbe..34778cda8e 100644 --- a/.trinity/seals/t27f_t27f_spec_graph.json +++ b/.trinity/seals/t27f_t27f_spec_graph.json @@ -14,9 +14,9 @@ "module": "t27f_spec_graph", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-18T07:05:29Z", + "sealed_at": "2026-10-18T17:03:26Z", "sealed_by": "t27c-bootstrap@0.5.2", - "spec_hash": "sha256:66020d5b18fc1957c48b138f243e26bb0f961b279dcb2b0a29975f193aae1a73", + "spec_hash": "sha256:110d07291552a9558ab192ff07ea6c3160e880306cbb847f89544ea7324c9d17", "spec_path": "specs/t27f/spec_graph.t27", "tests": { "failed": 0, diff --git a/.trinity/seals/t27f_t27f_spec_graph_derive.json b/.trinity/seals/t27f_t27f_spec_graph_derive.json index 6298a71082..8619359786 100644 --- a/.trinity/seals/t27f_t27f_spec_graph_derive.json +++ b/.trinity/seals/t27f_t27f_spec_graph_derive.json @@ -3,7 +3,7 @@ "closure": [ { "spec": "specs/t27f/spec_graph.t27", - "spec_hash": "sha256:66020d5b18fc1957c48b138f243e26bb0f961b279dcb2b0a29975f193aae1a73" + "spec_hash": "sha256:110d07291552a9558ab192ff07ea6c3160e880306cbb847f89544ea7324c9d17" }, { "spec": "specs/t27f/spec_graph_export.t27", @@ -18,7 +18,7 @@ "module": "t27f_spec_graph_derive", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-18T07:05:30Z", + "sealed_at": "2026-10-18T17:03:28Z", "sealed_by": "t27c-bootstrap@0.5.2", "spec_hash": "sha256:c33c91d9a66f5121cab332ebf832f95df019a38ad5a96d544456e6383a547e6e", "spec_path": "specs/t27f/spec_graph_derive.t27", diff --git a/.trinity/seals/t27f_t27f_spec_graph_export.json b/.trinity/seals/t27f_t27f_spec_graph_export.json index c4837982fa..f79e66d71e 100644 --- a/.trinity/seals/t27f_t27f_spec_graph_export.json +++ b/.trinity/seals/t27f_t27f_spec_graph_export.json @@ -3,7 +3,7 @@ "closure": [ { "spec": "specs/t27f/spec_graph.t27", - "spec_hash": "sha256:66020d5b18fc1957c48b138f243e26bb0f961b279dcb2b0a29975f193aae1a73" + "spec_hash": "sha256:110d07291552a9558ab192ff07ea6c3160e880306cbb847f89544ea7324c9d17" } ], "config": "gen=c,rust,verilog,zig;tests=zig", @@ -14,7 +14,7 @@ "module": "t27f_spec_graph_export", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-18T07:05:32Z", + "sealed_at": "2026-10-18T17:03:30Z", "sealed_by": "t27c-bootstrap@0.5.2", "spec_hash": "sha256:25fb426d6e03c1121a062b4fca9276f796b859bdf236a998e77d912e4d677b0a", "spec_path": "specs/t27f/spec_graph_export.t27", diff --git a/.trinity/seals/t27f_t27f_spec_graph_fold.json b/.trinity/seals/t27f_t27f_spec_graph_fold.json index 0a77847774..b6a5a0609b 100644 --- a/.trinity/seals/t27f_t27f_spec_graph_fold.json +++ b/.trinity/seals/t27f_t27f_spec_graph_fold.json @@ -3,11 +3,11 @@ "closure": [ { "spec": "specs/t27f/spec_graph.t27", - "spec_hash": "sha256:66020d5b18fc1957c48b138f243e26bb0f961b279dcb2b0a29975f193aae1a73" + "spec_hash": "sha256:110d07291552a9558ab192ff07ea6c3160e880306cbb847f89544ea7324c9d17" }, { "spec": "specs/t27f/spec_graph_view.t27", - "spec_hash": "sha256:662df660969b2ebccaf99129ea8d9eb41f38ded82ff34e085cf5e07b629e3089" + "spec_hash": "sha256:d4c318162bf52405208d4016d0505c8037cd648b58feb3ad5240a2695c6730fe" } ], "config": "gen=c,rust,verilog,zig;tests=zig", @@ -18,7 +18,7 @@ "module": "t27f_spec_graph_fold", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-18T07:05:41Z", + "sealed_at": "2026-10-18T17:03:39Z", "sealed_by": "t27c-bootstrap@0.5.2", "spec_hash": "sha256:998442ec0e9a80bdf07f77280e7090b59ce4e7d1d44a147f665dd17f215a44c1", "spec_path": "specs/t27f/spec_graph_fold.t27", diff --git a/.trinity/seals/t27f_t27f_spec_graph_outline.json b/.trinity/seals/t27f_t27f_spec_graph_outline.json index 91170b21c1..dd70dfe751 100644 --- a/.trinity/seals/t27f_t27f_spec_graph_outline.json +++ b/.trinity/seals/t27f_t27f_spec_graph_outline.json @@ -1,9 +1,9 @@ { - "built_by": "t27c-bootstrap@0.5.2+fdb6b28dd", + "built_by": "t27c-bootstrap@0.5.2+9448ab4be", "closure": [ { "spec": "specs/t27f/spec_graph.t27", - "spec_hash": "sha256:a3dbe0ec5110c48183ebea101109598e8542bb0ffdf9e061c672162d7da03fe7" + "spec_hash": "sha256:110d07291552a9558ab192ff07ea6c3160e880306cbb847f89544ea7324c9d17" } ], "config": "gen=c,rust,verilog,zig;tests=zig", @@ -14,7 +14,7 @@ "module": "t27f_spec_graph_outline", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-18T05:05:48Z", + "sealed_at": "2026-10-18T17:03:40Z", "sealed_by": "t27c-bootstrap@0.5.2", "spec_hash": "sha256:92e0bf52018e6eabebec1705d04a15450a2ebd8abe1b737891a9ad3c0991a1c7", "spec_path": "specs/t27f/spec_graph_outline.t27", diff --git a/.trinity/seals/t27f_t27f_spec_graph_view.json b/.trinity/seals/t27f_t27f_spec_graph_view.json index a90e96c199..dcb16fb23c 100644 --- a/.trinity/seals/t27f_t27f_spec_graph_view.json +++ b/.trinity/seals/t27f_t27f_spec_graph_view.json @@ -1,9 +1,9 @@ { - "built_by": "t27c-bootstrap@0.5.2+fdb6b28dd", + "built_by": "t27c-bootstrap@0.5.2+9448ab4be", "closure": [ { "spec": "specs/t27f/spec_graph.t27", - "spec_hash": "sha256:a3dbe0ec5110c48183ebea101109598e8542bb0ffdf9e061c672162d7da03fe7" + "spec_hash": "sha256:110d07291552a9558ab192ff07ea6c3160e880306cbb847f89544ea7324c9d17" }, { "spec": "specs/t27f/ui_plan.t27", @@ -18,9 +18,9 @@ "module": "t27f_spec_graph_view", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-18T05:05:46Z", + "sealed_at": "2026-10-18T17:03:27Z", "sealed_by": "t27c-bootstrap@0.5.2", - "spec_hash": "sha256:662df660969b2ebccaf99129ea8d9eb41f38ded82ff34e085cf5e07b629e3089", + "spec_hash": "sha256:d4c318162bf52405208d4016d0505c8037cd648b58feb3ad5240a2695c6730fe", "spec_path": "specs/t27f/spec_graph_view.t27", "tests": { "failed": 0, diff --git a/.trinity/seals/t27f_topic_reel.json b/.trinity/seals/t27f_topic_reel.json index e915a1fcf1..5d790e0ca3 100644 --- a/.trinity/seals/t27f_topic_reel.json +++ b/.trinity/seals/t27f_topic_reel.json @@ -1,5 +1,5 @@ { - "built_by": "t27c-bootstrap@0.5.2+093bf4713", + "built_by": "t27c-bootstrap@0.5.2+9448ab4be", "closure": [ { "spec": "specs/t27f/deck.t27", @@ -11,7 +11,7 @@ }, { "spec": "specs/t27f/topic_engine.t27", - "spec_hash": "sha256:95337a0fe59f32426db6ca3a9481151c28f2b9eaddfa346659782e6d70ae5ff0" + "spec_hash": "sha256:d117a894beb6dc97ee678f84a927a98a801783d101b8b4cd96a0875979a911be" } ], "config": "gen=c,rust,verilog,zig;tests=zig", @@ -22,7 +22,7 @@ "module": "topic_reel", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-18T09:33:02Z", + "sealed_at": "2026-10-18T17:03:40Z", "sealed_by": "t27c-bootstrap@0.5.2", "spec_hash": "sha256:2a8734246e5fbaa09984f38005f3566c7fe607875f98f30f59e2225ed381d2c8", "spec_path": "specs/t27f/topic_reel.t27", diff --git a/AGENTS.md b/AGENTS.md index 3a8a942272..314394b4e4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -157,11 +157,14 @@ App permission checks: write, accepting that permission, secret Adding a workflow file means adding its row to `gates.t27` in the same commit. The drift gate refuses anything else. -### T27F: the visual spec of every `.t27` - -One spec gives one graph model and many views: source, architecture, data flow, -dependencies and tests. Every node is labelled exact, derived, suggested or -unknown, and links back to its source lines. The definition lives in one place: +### T27F: t27's frontend + +T27F is how t27 shows anything visual, through several tools: spec diagrams, +map stills, particle reels and stills, the hot-reload stream and the +`claw/t27f` check-run. TRI CLAW serves its MCP tools. Its core is the visual +spec of every `.t27`: one graph model, many views, every node labelled exact, +derived, suggested or unknown. The surfaces and their status are +[`specs/t27f/frontend.t27`](specs/t27f/frontend.t27); the definition lives in [`.claude/skills/t27f/SKILL.md`](.claude/skills/t27f/SKILL.md), "What T27F is". - **Specs:** [`specs/t27f/`](specs/t27f/). The IR is `spec_graph.t27`. The diff --git a/CLAUDE.md b/CLAUDE.md index 1a61bb5a58..335c1e4d14 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -187,13 +187,14 @@ See [`docs/T27-CONSTITUTION.md`](docs/T27-CONSTITUTION.md#2--invariant-laws-neve **Repository:** Trinity S³AI — **t27** (spec-first ternary / TRI-27). **φ² + 1/φ² = 3 | TRINITY** -## T27F is the visual spec of `.t27` - -T27F means one thing: every `.t27` spec gets a visual form -- one spec, one synchronized model, -many views (source, architecture, data flow, dependencies, tests), every node labelled exact, -derived, suggested or unknown and linked to its source span (gHashTag/trinity#1648, RFC -gHashTag/trinity#1649). It is **not** the topic-to-value engine: gHashTag/trinity#1677 and the -reels are applications built on T27F. Owner correction, 2026-10-17. +## T27F is t27's frontend + +T27F is t27's native visualization, made through several tools: the spec diagram (its core, the +visual spec of `.t27`, gHashTag/trinity#1648, RFC gHashTag/trinity#1649), map stills, the graph +page, particle reels and stills, the hot-reload stream and the `claw/t27f` check-run. TRI CLAW +serves its MCP tools. Its surfaces, their status and which one answers an intent are the law in +`specs/t27f/frontend.t27`. It is **not** the topic-to-value engine: gHashTag/trinity#1677 is an +application drawn through T27F. Owner corrections, 2026-10-17 and 2026-10-18. This is a pointer. The definition, and what exists versus what is still missing, live in one place: `.claude/skills/t27f/SKILL.md`, section "What T27F is". diff --git a/docs/reports/t27b_expectations.json b/docs/reports/t27b_expectations.json index d5bfedc640..d929171736 100644 --- a/docs/reports/t27b_expectations.json +++ b/docs/reports/t27b_expectations.json @@ -209,6 +209,7 @@ {"path": "specs/claw/t27f_gate.t27", "t27b": "pass"}, {"path": "specs/claw/t27f_gate_pins.t27", "t27b": "pass"}, {"path": "specs/claw/text.t27", "t27b": "pass"}, + {"path": "specs/claw/token_shape.t27", "t27b": "pass"}, {"path": "specs/compiler/c_array_repeat_wrapper.t27", "t27b": "pass"}, {"path": "specs/compiler/c_fixed_array_return.t27", "t27b": "pass"}, {"path": "specs/compiler/codegen_conformance.t27", "t27b": "pass"}, @@ -1455,6 +1456,7 @@ {"path": "specs/t27f/deck.t27", "t27b": "pass"}, {"path": "specs/t27f/frame_cache.t27", "t27b": "pass"}, {"path": "specs/t27f/frame_shard.t27", "t27b": "blocked", "blocker": "type [N]T", "reason": "unimplemented"}, + {"path": "specs/t27f/frontend.t27", "t27b": "pass"}, {"path": "specs/t27f/hot.t27", "t27b": "pass"}, {"path": "specs/t27f/lesson_reel.t27", "t27b": "blocked", "blocker": "type [N]T", "reason": "unimplemented"}, {"path": "specs/t27f/outfit_atlas.t27", "t27b": "pass"}, diff --git a/specs/OWNERS.md b/specs/OWNERS.md index 9936d72acb..4ed09320e0 100644 --- a/specs/OWNERS.md +++ b/specs/OWNERS.md @@ -28,7 +28,7 @@ | `docs/` | **Z-Zeta** (with **T-Queen** for `chapters/queen.t27`) | The system documentation of `t27.ai/#/docs` as `.t27` specs (`docs/system.t27`, `KIND = "docs"`; `docs/chapters/.t27`, `KIND = "docs-chapter"`): chapter ids, sections, sources, the figure and table the site generates; English prose in `docs/system/.md`, Russian via `i18n/docs-ru.t27` | | `ui/` | **T-Queen** | The site's viewport contract as a `.t27` spec (`ui/viewport.t27`, `KIND = "viewport"`): tiers by CSS viewport width, panes per tier, the 44 px touch minimum, the six-size QA matrix and the Queen rail capacity read from `Queen.css`; the site (gHashTag/trinity) generates `viewport.generated.ts` / `.css` from a vendored copy and evaluates the spec's own test blocks; `ui/queen_evidence.t27` (`module ui_queen_evidence`): the evidence constants of the Queen's FFN and Ternary Check panel, from which the site generates `queenEvidence.generated.ts`; canonical here since S10, byte-identical to the copy the site carried alone | | `catalog/` | **T-Queen** | How the site's spec catalog and the Queen map find the repositories that write `.t27` (`catalog/discovery.t27`, `KIND = "discovery"`): the GitHub owners scanned, the exclusions, what makes a candidate qualify (a declaration in the compiler's AST, not a file extension) and the limits; the site (gHashTag/trinity) vendors a byte-identical copy and `scripts/discover-t27-worlds.mjs` reads it through the compiler wasm before touching GitHub | -| `t27f/` | **T-Queen** | T27F, the visual spec of a .t27 file (gHashTag/trinity#1648, RFC #1649; definition in `.claude/skills/t27f/SKILL.md`): `t27f/spec_graph.t27` (module `t27f_spec_graph`): the core graph IR a spec becomes -- node and edge kinds, inference labels, source spans, `validate_graph`, source mapping both ways and the node -> ui_plan widget binding, with one hand-read fixture; `t27f/spec_graph_export.t27` (module `t27f_spec_graph_export`): the exporter, a deterministic byte scanner from spec source to that graph -- declarations, brace-matched spans, exact calls/uses/constrains edges, refusal past the IR capacity, checked against the hand-read fixture; `t27f/spec_graph_derive.t27` (module `t27f_spec_graph_derive`): the derive pass, a second deterministic scan that appends DERIVED tested_by and data_flow edges and UNKNOWN opaque nodes for undeclared qualified call targets by three stated rules and never changes an exact fact -- exporter plus derive equal the tutorial 08 fixture; `t27f/spec_graph_view.t27` (module `t27f_spec_graph_view`): the graph view, a deterministic layout of a spec graph -- one column per node kind, style and row order from the inference label, UNKNOWN nodes drawn alone, every edge with a source line; numbers only, a host draws them; `t27f/spec_graph_fold.t27` (module `t27f_spec_graph_fold`): the same view for big specs -- columns taller than N rows wrap to near phi, a fold to one box per node kind with exact counts and kind-to-kind edge counts, expand one kind with its direct neighbours, and hit testing from a point to a node and its source lines; `t27f/ui_plan.t27` (module `t27f_ui_plan`): the renderer-neutral UI plan IR and the trusted widget catalog. Applications built on it: the topic-to-value map of gHashTag/trinity#1677 (`t27f/topic_engine.t27`, module `T27fTopicEngine`): the 3 x 9 = 27 lesson shape, intake and gap rules, keyword routing to one domain, the Bee dispatch cap, the evidence and approval gates, and progression that is never money; driven by the Claude Code skill `.claude/skills/t27f/SKILL.md` through the t27 MCP server; `t27f/reel.t27` (module `T27fReel`): the video format of a topic map and the still views of a Claude Code answer -- honeycomb geometry, focus+context camera, scene catalog, per-target limits, gap styling, the posting gate and the channel per host; numbers only, a host draws them; `t27f/deck.t27` (module `T27fDeck`): the default look of a reel, every scene a presentation slide -- layouts per scene, regions, type sizes, glass card, palette kept off the status colours, contrast and card fades | +| `t27f/` | **T-Queen** | T27F, t27's frontend (definition in `.claude/skills/t27f/SKILL.md`): `t27f/frontend.t27` (module `T27fFrontend`): the law of every T27F surface -- what draws it today, which surface answers an intent, the stand-in when it cannot be made, that nothing undrawn is claimed made, and which surfaces TRI CLAW serves. Its core is the visual spec of a .t27 file (gHashTag/trinity#1648, RFC #1649): `t27f/spec_graph.t27` (module `t27f_spec_graph`): the core graph IR a spec becomes -- node and edge kinds, inference labels, source spans, `validate_graph`, source mapping both ways and the node -> ui_plan widget binding, with one hand-read fixture; `t27f/spec_graph_export.t27` (module `t27f_spec_graph_export`): the exporter, a deterministic byte scanner from spec source to that graph -- declarations, brace-matched spans, exact calls/uses/constrains edges, refusal past the IR capacity, checked against the hand-read fixture; `t27f/spec_graph_derive.t27` (module `t27f_spec_graph_derive`): the derive pass, a second deterministic scan that appends DERIVED tested_by and data_flow edges and UNKNOWN opaque nodes for undeclared qualified call targets by three stated rules and never changes an exact fact -- exporter plus derive equal the tutorial 08 fixture; `t27f/spec_graph_view.t27` (module `t27f_spec_graph_view`): the graph view, a deterministic layout of a spec graph -- one column per node kind, style and row order from the inference label, UNKNOWN nodes drawn alone, every edge with a source line; numbers only, a host draws them; `t27f/spec_graph_fold.t27` (module `t27f_spec_graph_fold`): the same view for big specs -- columns taller than N rows wrap to near phi, a fold to one box per node kind with exact counts and kind-to-kind edge counts, expand one kind with its direct neighbours, and hit testing from a point to a node and its source lines; `t27f/ui_plan.t27` (module `t27f_ui_plan`): the renderer-neutral UI plan IR and the trusted widget catalog. The application drawn through it: the topic-to-value map of gHashTag/trinity#1677 (`t27f/topic_engine.t27`, module `T27fTopicEngine`): the 3 x 9 = 27 lesson shape, intake and gap rules, keyword routing to one domain, the Bee dispatch cap, the evidence and approval gates, and progression that is never money; driven by the Claude Code skill `.claude/skills/t27f/SKILL.md` through the t27 MCP server. Map surfaces: `t27f/reel.t27` (module `T27fReel`): the video format of a topic map and the still views of a Claude Code answer -- honeycomb geometry, focus+context camera, scene catalog, per-target limits, gap styling, the posting gate and the channel per host; numbers only, a host draws them; `t27f/deck.t27` (module `T27fDeck`): the default look of a reel, every scene a presentation slide -- layouts per scene, regions, type sizes, glass card, palette kept off the status colours, contrast and card fades | | `t27mcp/` | **T-Queen** | The decisions of the t27 MCP server (gHashTag/t27-mcp) as `.t27` specs, compiled to wasm that the server runs: `t27mcp/check_hints.t27` (module `T27mcpCheckHints`): which short "write this instead" hint a compiler message gets for foreign syntax (`in` as a name, `as u3`, `x++`, `a ? b : c`, `match`), and the line number a message names; `t27mcp/examples.t27` (module `T27mcpExamples`): which short slice of the published corpus, pinned to one commit, answers a question about clocked or combinational modules, `fn`, `test` blocks and the reset styles; `t27mcp/spec_brief.t27` (module `T27mcpSpecBrief`): which manifest fields a short spec row keeps and why a failing spec fails (a bit set of reasons plus their text templates); the server's JavaScript is I/O glue and holds no rule | | `trinity/` | **T-Queen** + **A-Architect** | The project manifest of gHashTag/trinity as `.t27` specs (`trinity/project.t27`, `KIND = "project"`; `trinity/capabilities/.t27`, `KIND = "capability"`): the pinned consumer revision, profiles, dispositions and evidence tags, dialect and build counts, dependency pins and the work packages of gHashTag/trinity#988; each card names its owner, canonical spec, implementation and generated paths, build targets, acceptance command and evidence; `tools/trinity_manifest.py` derives the inventory from a clean pinned checkout and holds the cards to it; `trinity/compiler_matrix.t27` (`KIND = "compiler-matrix"`) names the pinned compiler, the backends, the stages and the features of the executable subset with their fixtures under `bootstrap/tests/fixtures/trinity_matrix/`, and `tools/trinity_compiler_matrix.py` measures them; `trinity/build_graph.t27` (`KIND = "build-graph"`) declares the consumer's toolchain, pins, profiles, generated-file boundaries and receipt policy, and `tools/trinity_build_receipt.py` derives the graph, writes the receipts and judges drift; the consumer vendors a byte-identical copy and generates its manifest from it (S12). Shared contracts stay in their own subtrees (`numeric/`, `vsa/`, `queen/`, `tools/`, `docs/`, `ui/`) and are cited, never copied | diff --git a/specs/skills/t27-t27f.t27 b/specs/skills/t27-t27f.t27 index c9fd5f1309..6443540dc3 100644 --- a/specs/skills/t27-t27f.t27 +++ b/specs/skills/t27-t27f.t27 @@ -1,9 +1,9 @@ // SPDX-License-Identifier: Apache-2.0 ; specs/skills/t27-t27f.t27 -- skill t27/t27f ; Source of truth for the skill card on t27.ai (#/skills?skill=t27/t27f). -; The skill body lives in gHashTag/t27 at .claude/skills/t27f/SKILL.md. T27F is the visual spec of a -; .t27 file (gHashTag/trinity#1648, RFC gHashTag/trinity#1649); its UI plan IR is -; specs/t27f/ui_plan.t27. The topic-map application (gHashTag/trinity#1677) has its rules in +; The skill body lives in gHashTag/t27 at .claude/skills/t27f/SKILL.md. T27F is t27's frontend; its +; surfaces are specs/t27f/frontend.t27, its core is the visual spec of a .t27 file +; (gHashTag/trinity#1648, RFC gHashTag/trinity#1649), and its UI plan IR is specs/t27f/ui_plan.t27. The topic-map application (gHashTag/trinity#1677) has its rules in ; specs/t27f/topic_engine.t27. ; The JSON the site serves is generated from this file by the real compiler; ; nothing below is parsed with a regex. @@ -13,15 +13,16 @@ module skill_t27_t27f; pub const KIND : str = "skill"; pub const ID : str = "t27/t27f"; -pub const NAME : str = "T27F Visual Spec"; +pub const NAME : str = "T27F Frontend"; pub const REPO : str = "t27"; pub const SOURCE : str = "SKILL.md"; -pub const SUMMARY_EN : str = "Show a .t27 spec as one synchronized model with many views, every node labelled exact, derived, suggested or unknown"; +pub const SUMMARY_EN : str = "Show anything in t27 visually: spec diagrams, map stills, particle reels and stills, picked by intent and served by TRI CLAW"; ; The frontmatter id is the slash command. pub const COMMAND : str = "/t27f"; -; Specs this skill stands on: the T27F UI plan IR, then the topic-map application. -pub const SPECS : [2]str = ["specs/t27f/ui_plan.t27", "specs/t27f/topic_engine.t27"]; -pub const TAGS : [3]str = ["t27f", "visual-spec", "specs"]; +; Specs this skill stands on: the T27F surfaces and routing, the UI plan IR, then the topic-map +; application. +pub const SPECS : [3]str = ["specs/t27f/frontend.t27", "specs/t27f/ui_plan.t27", "specs/t27f/topic_engine.t27"]; +pub const TAGS : [3]str = ["t27f", "frontend", "visual-spec"]; pub const ENABLED : bool = true; ; Default budget; SKILL.md declares no timeout of its own. pub const TIMEOUT_MIN : u16 = 30; @@ -29,15 +30,16 @@ pub const TIMEOUT_MIN : u16 = 30; test basic_constants { assert KIND == "skill"; assert ID == "t27/t27f"; - assert NAME == "T27F Visual Spec"; + assert NAME == "T27F Frontend"; assert REPO == "t27"; assert COMMAND == "/t27f"; assert ENABLED == true; assert TIMEOUT_MIN == 30; assert TAGS[0] == "t27f"; - assert TAGS[1] == "visual-spec"; - assert TAGS[2] == "specs"; - assert SPECS.len == 2; - assert SPECS[0] == "specs/t27f/ui_plan.t27"; - assert SPECS[1] == "specs/t27f/topic_engine.t27"; + assert TAGS[1] == "frontend"; + assert TAGS[2] == "visual-spec"; + assert SPECS.len == 3; + assert SPECS[0] == "specs/t27f/frontend.t27"; + assert SPECS[1] == "specs/t27f/ui_plan.t27"; + assert SPECS[2] == "specs/t27f/topic_engine.t27"; } diff --git a/specs/t27f/frontend.t27 b/specs/t27f/frontend.t27 new file mode 100644 index 0000000000..ed4a180e49 --- /dev/null +++ b/specs/t27f/frontend.t27 @@ -0,0 +1,309 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/t27f/frontend.t27 -- T27F as t27's frontend: the one tool through which t27 shows anything +; visual, and the catalog of the surfaces it draws on. Issue gHashTag/t27#10537. +; Owner, 2026-10-18: T27F is t27's native visualization, made through several tools; everything +; visual is gathered into it as one tool, the t27 frontend; and T27F goes into TRI CLAW. +; The definition lives in .claude/skills/t27f/SKILL.md, "What T27F is". This spec is its law: which +; surfaces exist, what draws each today, which surface answers an intent, and which TRI CLAW serves. +; -- +; What this spec does not restate: +; - The rules of each surface. They stay in the spec that decides it (spec_graph*.t27, reel.t27, +; deck.t27, token_floor*.t27, lesson_reel.t27, hot.t27, claw/t27f_gate.t27, claw/preview.t27, +; particle_field.t27, ui_plan.t27, t27mcp/dashboard.t27). This spec names the surface only. +; - Tool names. A surface drawn by an MCP tool points at its row of specs/t27mcp/tool_schema.t27. +; - Which tool belongs to TRI CLAW. specs/t27mcp/service.t27 decides that by prefix (t27_ and t27f_ +; are the t27 module's, mounted into TRI CLAW's /mcp). This spec checks that every T27F tool is +; mounted there, and names the drawing set TRI CLAW's chat agent carries. +; - Where a file reaches the user, by host: channel_for in specs/t27f/reel.t27. +; -- +; Status, as measured on 2026-10-18 (inventory of gHashTag/t27, t27-mcp and trinity at master): +; - LIVE: a host draws it on request (an MCP tool or a t27.ai page). +; - LAB: made by hand on the Railway lab from its spec; no host makes it on request. +; - PARTIAL: a host runs and answers, but nothing shows what it answers. +; - BLOCKED: wired, but waiting on a permission only the owner can grant. +; - SPEC: a spec with tests; nothing draws it. +; A surface that is not LIVE or LAB cannot be made this turn. route() names the surface an intent +; wants, pick() gives the stand-in that can be made, and claim_ok() refuses a claim to have made one. +; Not measured: whether TRI CLAW's deployed /mcp mounts the t27 tools today. service.t27 is the law; +; the mount itself is code in gHashTag/999-multibots-telegraf. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module T27fFrontend; + +use t27f::reel; +use t27mcp::tool_schema; +use t27mcp::service::home_of; +use t27mcp::service::has_prefix; +use t27mcp::service::T27_PREFIXES; +use t27mcp::service::H_T27; + +/// The surfaces T27F draws on. +pub const SF_GRAPH : u32 = 0; // spec graph as SVG: spec_graph_export / _view, tool t27f_graph +pub const SF_OUTLINE : u32 = 1; // spec graph as compact text: spec_graph_outline, tool t27f_outline +pub const SF_MAP_STILL : u32 = 2; // honeycomb map still, deck look: reel.t27 + deck.t27, tool t27f_view +pub const SF_GRAPH_PAGE : u32 = 3; // t27.ai/t27f/graph/ and the Spec Explorer graph layer +pub const SF_HOT : u32 = 4; // hot-reload stream, hot.t27 + build.t27 (t27-mcp --watch) +pub const SF_CHECK : u32 = 5; // claw/t27f check-run, claw/t27f_gate.t27, posted by the TRI CLAW App +pub const SF_PREVIEW : u32 = 6; // PR preview deployment, claw/preview.t27 +pub const SF_PARTICLE_REEL : u32 = 7; // token_floor*.t27, lesson_reel.t27, reel_particles*.t27 +pub const SF_STILL : u32 = 8; // one frame of a particle reel +pub const SF_MAP_VIDEO : u32 = 9; // honeycomb reel as video and live player, reel.t27 +pub const SF_PARTICLE_LIVE : u32 = 10; // T27F Live, particle_field.t27 + particle_engine.t27 +pub const SF_UI_PLAN : u32 = 11; // trusted-widget UI plan, ui_plan.t27 +pub const SF_DASHBOARD : u32 = 12; // corpus and session health, t27mcp/dashboard.t27, tool t27_dashboard +pub const SF_COUNT : u32 = 13; +pub const SF_NONE : u32 = 255; + +pub const SURFACE_NAMES : str = "graph,outline,map_still,graph_page,hot,check,preview,particle_reel,still,map_video,particle_live,ui_plan,dashboard"; + +/// What draws a surface today. +pub const ST_LIVE : u8 = 0; +pub const ST_LAB : u8 = 1; +pub const ST_PARTIAL : u8 = 2; +pub const ST_BLOCKED : u8 = 3; +pub const ST_SPEC : u8 = 4; + +pub const SURFACE_STATUS : [13]u8 = [0, 0, 0, 0, 2, 3, 4, 1, 1, 4, 4, 4, 0]; + +/// Where a surface is made: an MCP tool, a t27.ai page, the Railway lab, the TRI CLAW App, nowhere. +pub const MK_MCP : u8 = 0; +pub const MK_SITE : u8 = 1; +pub const MK_LAB : u8 = 2; +pub const MK_APP : u8 = 3; +pub const MK_NONE : u8 = 4; + +pub const SURFACE_MAKER : [13]u8 = [0, 0, 0, 1, 0, 3, 3, 2, 2, 4, 4, 4, 0]; + +/// What a caller wants shown. +pub const I_SPEC_SHAPE : u32 = 0; // the structure of one spec +pub const I_SPEC_WORDS : u32 = 1; // a spec's decisions in a few lines +pub const I_TOPIC_MAP : u32 = 2; // a topic or a course as the 27-cell map +pub const I_LESSON : u32 = 3; // a lesson or a topic as a video +pub const I_REPORT : u32 = 4; // a report of a piece of work +pub const I_PR : u32 = 5; // a pull request that touches .t27 files +pub const I_EDITING : u32 = 6; // a spec redrawn while it is edited +pub const I_HEALTH : u32 = 7; // the state of the corpus and the session +pub const I_LIVE_AGENT : u32 = 8; // an agent's work as a live particle field +pub const I_APP : u32 = 9; // an application screen built from trusted widgets +pub const I_COUNT : u32 = 10; + +/// The drawing tools TRI CLAW's chat agent carries. service.t27 gives its coder persona CODER_TOOLS +/// for writing a spec; these are for showing one. +pub const CLAW_VISUAL_COUNT : u32 = 4; + +pub fn claw_visual_tool(k: u32) -> u32 { + if (k == 0) { + return T_GRAPH; + } + if (k == 1) { + return T_OUTLINE; + } + if (k == 2) { + return T_VIEW; + } + if (k == 3) { + return T_DASHBOARD; + } + return TOOL_COUNT; +} + +pub fn surface_ok(s: u32) -> bool { + return s < SF_COUNT; +} + +/// A surface can be made this turn when a host draws it or the lab recipe makes it. +pub fn makeable(s: u32) -> bool { + if (surface_ok(s) == false) { + return false; + } + return SURFACE_STATUS[s] == ST_LIVE or SURFACE_STATUS[s] == ST_LAB; +} + +/// The tool_schema.t27 row of the MCP tool that draws a surface, or TOOL_COUNT when no tool does. +pub fn surface_tool(s: u32) -> u32 { + if (s == SF_GRAPH) { + return T_GRAPH; + } + if (s == SF_OUTLINE) { + return T_OUTLINE; + } + if (s == SF_MAP_STILL) { + return T_VIEW; + } + if (s == SF_DASHBOARD) { + return T_DASHBOARD; + } + return TOOL_COUNT; +} + +/// The surface an intent wants. On t27.ai the graph is the live page, elsewhere the MCP tool's SVG. +pub fn route(intent: u32, host: u8) -> u32 { + if (intent == I_SPEC_SHAPE) { + if (host == HOST_SITE) { + return SF_GRAPH_PAGE; + } + return SF_GRAPH; + } + if (intent == I_SPEC_WORDS) { + return SF_OUTLINE; + } + if (intent == I_TOPIC_MAP) { + return SF_MAP_VIDEO; + } + if (intent == I_LESSON) { + return SF_PARTICLE_REEL; + } + if (intent == I_REPORT) { + return SF_STILL; + } + if (intent == I_PR) { + return SF_CHECK; + } + if (intent == I_EDITING) { + return SF_HOT; + } + if (intent == I_HEALTH) { + return SF_DASHBOARD; + } + if (intent == I_LIVE_AGENT) { + return SF_PARTICLE_LIVE; + } + if (intent == I_APP) { + return SF_UI_PLAN; + } + return SF_NONE; +} + +/// The surface that stands in for one that cannot be made this turn, or SF_NONE. +pub fn stand_in(s: u32) -> u32 { + if (makeable(s)) { + return s; + } + if (s == SF_MAP_VIDEO) { + return SF_MAP_STILL; + } + if (s == SF_CHECK or s == SF_PREVIEW or s == SF_HOT) { + return SF_GRAPH; + } + if (s == SF_PARTICLE_LIVE) { + return SF_PARTICLE_REEL; + } + return SF_NONE; +} + +/// What T27F shows for an intent on a host this turn. +pub fn pick(intent: u32, host: u8) -> u32 { + let want : u32 = route(intent, host); + if (want == SF_NONE) { + return SF_NONE; + } + return stand_in(want); +} + +/// An answer may say it made a surface only if that surface can be made. +pub fn claim_ok(s: u32, claimed_made: bool) -> bool { + if (claimed_made == false) { + return true; + } + return makeable(s); +} + +/// TRI CLAW serves a surface when an MCP tool draws it under a name service.t27 gives the t27 home: +/// admit() mounts every t27 tool the t27 side offers. admit() is not called here: its helper name_ok +/// shares a name with tool_schema.t27 name_ok, and the splicer refuses an ambiguous name. +pub fn claw_serves(s: u32) -> bool { + let t : u32 = surface_tool(s); + if (t >= TOOL_COUNT) { + return false; + } + return home_of(TOOLS[t].name) == H_T27; +} + +test every_intent_routes_to_a_known_surface { + var i : u32 = 0; + while (i < I_COUNT) { + assert surface_ok(route(i, HOST_CLAUDE_CODE_DESKTOP)); + assert surface_ok(route(i, HOST_SITE)); + i = i + 1; + } + assert route(I_COUNT, HOST_CLAUDE_CODE_DESKTOP) == SF_NONE; + assert pick(I_COUNT, HOST_CLAUDE_CODE_DESKTOP) == SF_NONE; +} + +test the_graph_is_the_page_on_the_site_and_the_tool_elsewhere { + assert route(I_SPEC_SHAPE, HOST_SITE) == SF_GRAPH_PAGE; + assert route(I_SPEC_SHAPE, HOST_CLAUDE_CODE_DESKTOP) == SF_GRAPH; + assert route(I_SPEC_SHAPE, HOST_CLAUDE_CODE_CLI) == SF_GRAPH; + assert route(I_SPEC_SHAPE, HOST_MCP_APPS) == SF_GRAPH; +} + +test a_report_is_a_particle_still_and_a_lesson_a_particle_reel { + assert pick(I_REPORT, HOST_CLAUDE_CODE_DESKTOP) == SF_STILL; + assert pick(I_LESSON, HOST_CLAUDE_CODE_DESKTOP) == SF_PARTICLE_REEL; + assert SURFACE_MAKER[SF_STILL] == MK_LAB; + assert SURFACE_MAKER[SF_PARTICLE_REEL] == MK_LAB; +} + +test what_cannot_be_made_has_a_stand_in_or_none { + assert pick(I_TOPIC_MAP, HOST_CLAUDE_CODE_DESKTOP) == SF_MAP_STILL; + assert pick(I_PR, HOST_CLAUDE_CODE_DESKTOP) == SF_GRAPH; + assert pick(I_EDITING, HOST_CLAUDE_CODE_DESKTOP) == SF_GRAPH; + assert pick(I_LIVE_AGENT, HOST_CLAUDE_CODE_DESKTOP) == SF_PARTICLE_REEL; + assert pick(I_APP, HOST_CLAUDE_CODE_DESKTOP) == SF_NONE; + var i : u32 = 0; + while (i < I_COUNT) { + let s : u32 = pick(i, HOST_CLAUDE_CODE_DESKTOP); + if (s != SF_NONE) { + assert makeable(s); + } + i = i + 1; + } +} + +test a_surface_nothing_draws_is_never_claimed_made { + assert claim_ok(SF_GRAPH, true); + assert claim_ok(SF_STILL, true); + assert claim_ok(SF_MAP_VIDEO, true) == false; + assert claim_ok(SF_CHECK, true) == false; + assert claim_ok(SF_UI_PLAN, true) == false; + assert claim_ok(SF_UI_PLAN, false); + assert claim_ok(SF_NONE, true) == false; +} + +test every_tool_surface_is_a_t27_name_tri_claw_mounts { + var s : u32 = 0; + var tools : u32 = 0; + while (s < SF_COUNT) { + let t : u32 = surface_tool(s); + if (t < TOOL_COUNT) { + assert SURFACE_MAKER[s] == MK_MCP; + assert has_prefix(TOOLS[t].name, "t27"); + assert home_of(TOOLS[t].name) == H_T27; + assert claw_serves(s); + tools = tools + 1; + } + s = s + 1; + } + assert tools == 4; + assert claw_serves(SF_STILL) == false; + assert claw_serves(SF_GRAPH_PAGE) == false; +} + +test tri_claw_carries_every_drawing_tool { + var k : u32 = 0; + var found : u32 = 0; + while (k < CLAW_VISUAL_COUNT) { + var s : u32 = 0; + while (s < SF_COUNT) { + if (surface_tool(s) == claw_visual_tool(k)) { + assert claw_serves(s); + found = found + 1; + } + s = s + 1; + } + k = k + 1; + } + assert found == CLAW_VISUAL_COUNT; + assert claw_visual_tool(CLAW_VISUAL_COUNT) == TOOL_COUNT; + assert TOOLS[claw_visual_tool(0)].name == "t27f_graph"; +} diff --git a/specs/t27f/quest.t27 b/specs/t27f/quest.t27 index 1c82062c14..a10ba66d9c 100644 --- a/specs/t27f/quest.t27 +++ b/specs/t27f/quest.t27 @@ -2,8 +2,8 @@ ; specs/t27f/quest.t27 -- one quest turn on a topic map: the Queen picks one cell and one relevant bee, ; the bee's evidence goes through the engine's gates, a progression event fires once, and anything ; high-impact waits for a human (gHashTag/t27#10030). -; This is an application built on T27F, like the topic map it walks (gHashTag/trinity#1677). It is -; not T27F: T27F is the visual spec of a .t27 file; the definition lives in +; This is an application drawn through T27F, like the topic map it walks (gHashTag/trinity#1677). It +; is not T27F: T27F is t27's frontend (specs/t27f/frontend.t27); the definition lives in ; .claude/skills/t27f/SKILL.md, "What T27F is". ; Every gate is read from specs/t27f/topic_engine.t27 with `use`; nothing here restates a constant, ; a bee list or a status rule. What this file adds is the turn around those gates: diff --git a/specs/t27f/spec_graph.t27 b/specs/t27f/spec_graph.t27 index 979705878b..1669b43088 100644 --- a/specs/t27f/spec_graph.t27 +++ b/specs/t27f/spec_graph.t27 @@ -1,8 +1,8 @@ // SPDX-License-Identifier: Apache-2.0 ; specs/t27f/spec_graph.t27 -- the T27F spec graph IR: what a .t27 file becomes before T27F draws ; it (RFC gHashTag/trinity#1649, epic gHashTag/trinity#1648, tracked in gHashTag/t27#10020). -; T27F is the visual spec of .t27; the definition lives in .claude/skills/t27f/SKILL.md, "What T27F -; is". This file is its core: one spec -> one graph -> many views. Every view (architecture, data +; T27F is t27's frontend and its core is the visual spec of .t27; the definition lives in +; .claude/skills/t27f/SKILL.md, "What T27F is". This file is that core: one spec -> one graph -> many views. Every view (architecture, data ; flow, dependencies, tests) is a projection of the same graph, and the graph is read from the ; spec's source, never drawn by hand. ; What this file decides, deterministically and without a language model: diff --git a/specs/t27f/spec_graph_view.t27 b/specs/t27f/spec_graph_view.t27 index 7123e243ee..46ae8e2ee2 100644 --- a/specs/t27f/spec_graph_view.t27 +++ b/specs/t27f/spec_graph_view.t27 @@ -1,7 +1,8 @@ // SPDX-License-Identifier: Apache-2.0 ; specs/t27f/spec_graph_view.t27 -- the T27F graph view: a deterministic layout of a spec graph -; (gHashTag/t27#10034; epic gHashTag/trinity#1648, RFC gHashTag/trinity#1649). T27F is the visual -; spec of .t27 (.claude/skills/t27f/SKILL.md, "What T27F is"): one spec -> one graph -> many views. +; (gHashTag/t27#10034; epic gHashTag/trinity#1648, RFC gHashTag/trinity#1649). T27F is t27's +; frontend; its core is the visual spec of .t27 (.claude/skills/t27f/SKILL.md, "What T27F is"): +; one spec -> one graph -> many views. ; The graph is specs/t27f/spec_graph.t27; this file is its first view, the one that shows the graph ; itself, not a topic map. It turns a SpecGraph into numbers a host draws, as specs/t27f/reel.t27 ; does for a reel frame: a box per node, a line per edge, colours as 0xRRGGBB. Nothing here draws diff --git a/specs/t27f/topic_engine.t27 b/specs/t27f/topic_engine.t27 index 9a26c5d740..9f6da1e8c8 100644 --- a/specs/t27f/topic_engine.t27 +++ b/specs/t27f/topic_engine.t27 @@ -1,7 +1,8 @@ // SPDX-License-Identifier: Apache-2.0 ; specs/t27f/topic_engine.t27 -- the topic-to-value application, phase 1 vertical slice -; (gHashTag/trinity#1677). It is an application built on T27F, not T27F itself: T27F is the visual -; spec of a .t27 file (gHashTag/trinity#1648, RFC gHashTag/trinity#1649); the definition lives in +; (gHashTag/trinity#1677). It is an application drawn through T27F, not T27F itself: T27F is t27's +; frontend (specs/t27f/frontend.t27), whose core is the visual spec of a .t27 file +; (gHashTag/trinity#1648, RFC gHashTag/trinity#1649); the definition lives in ; `.claude/skills/t27f/SKILL.md`. ; A topic or a client brief goes in; out come three lenses, a map of 27 lessons, one relevant Bee ; task, an artifact that is verified before it counts, and a progression event. The same functions