Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion specs/OWNERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
| `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_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/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 |
| `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; the server's JavaScript is I/O glue and holds no rule |
| `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/<id>.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 |

Each subtree with substantial churn should keep a local **`OWNERS.md`** (see below).
Expand Down
101 changes: 101 additions & 0 deletions specs/t27mcp/spec_brief.t27
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// SPDX-License-Identifier: Apache-2.0
; specs/t27mcp/spec_brief.t27 -- the brief spec row and the "why does it fail" decision of the t27 MCP server
; (gHashTag/t27-mcp). See the epic #10066.
; --
; t27_specs, t27_spec and t27_grep answer with a spec row. The whole manifest record is about 860 bytes (AST node
; kinds, emitted bytes per backend, tags, a summary), and a model that only wants "does it compile, and if not
; why" pays for all of it on every row. This spec holds the two decisions that were JavaScript in the server:
; - BRIEF_FIELDS / ONE_FIELDS: which manifest fields a brief row keeps. The server copies those keys and nothing
; else; `fields: true` on the tool returns the whole record instead.
; - why_mask(): `health: "fail"` covers unrelated events. A spec that never parsed reports loss 0, tcErrors 0 and
; no failed backend, not because it is clean but because nothing downstream of the parser ran. why_mask turns
; the observable counters into a bit set; WHY_TEXT holds one template per bit, `{}` marks the number or list
; the server fills in. A spec that is not "fail" gets no reasons at all.
; The mask adds no claim of its own: it reads the counters the manifest already records.
; phi^2 + 1/phi^2 = 3 | TRINITY

module T27mcpSpecBrief;

pub const BRIEF_FIELDS : [8]str = [
"path",
"repo",
"name",
"health",
"lines",
"loss",
"tcErrors",
"failedBackends"
];

/// t27_spec keeps the brief fields and what a reader asks next about one file.
pub const ONE_FIELDS : [14]str = [
"path",
"repo",
"name",
"health",
"lines",
"loss",
"tcErrors",
"failedBackends",
"category",
"bytes",
"tokens",
"nodes",
"summary",
"tags"
];

pub const W_NOT_PARSED : u32 = 1;
pub const W_BACKEND : u32 = 2;
pub const W_TYPECHECK : u32 = 4;
pub const W_LOSS : u32 = 8;
pub const W_UNKNOWN : u32 = 16;

/// One template per bit, in bit order. `{}` is the count or the backend list.
pub const WHY_TEXT : [5]str = [
"not-parsed: the manifest records no AST, so no backend ran",
"backend: {} returned nothing",
"typecheck: {} error(s)",
"round-trip loss: {}",
"unknown: marked fail with no counter to explain it"
];

/// The reasons a spec fails, as a bit set. `is_fail` is 1 for health "fail"; the rest are the manifest counters
/// (nodes of the AST, number of failed backends, type-check errors, round-trip loss).
pub fn why_mask(is_fail: u32, nodes: u32, nfailed: u32, tc: u32, loss: u32) -> u32 {
if (is_fail == 0) { return 0; }
var m : u32 = 0;
if (nodes == 0) { m = m + W_NOT_PARSED; }
if (nfailed > 0) { m = m + W_BACKEND; }
if (tc > 0) { m = m + W_TYPECHECK; }
if (loss > 0) { m = m + W_LOSS; }
if (m == 0) { m = W_UNKNOWN; }
return m;
}

test "why_mask: a spec that is not failing has no reasons" {
assert why_mask(0, 0, 0, 0, 0) == 0;
assert why_mask(0, 120, 3, 2, 1) == 0;
}

test "why_mask: a spec that never parsed is not-parsed, not unexplained" {
assert why_mask(1, 0, 0, 0, 0) == W_NOT_PARSED;
}

test "why_mask: each counter sets its own bit, and bits add" {
assert why_mask(1, 50, 2, 0, 0) == W_BACKEND;
assert why_mask(1, 50, 0, 3, 0) == W_TYPECHECK;
assert why_mask(1, 50, 0, 0, 7) == W_LOSS;
assert why_mask(1, 50, 1, 2, 0) == W_BACKEND + W_TYPECHECK;
assert why_mask(1, 0, 1, 0, 1) == W_NOT_PARSED + W_BACKEND + W_LOSS;
}

test "negative control: a fail with no counter is W_UNKNOWN alone, never silent" {
assert why_mask(1, 50, 0, 0, 0) == W_UNKNOWN;
assert why_mask(1, 50, 0, 0, 0) != 0;
}

test "why_mask: all four counters at once leave W_UNKNOWN out" {
assert why_mask(1, 0, 2, 3, 4) == W_NOT_PARSED + W_BACKEND + W_TYPECHECK + W_LOSS;
assert why_mask(1, 0, 2, 3, 4) < W_UNKNOWN;
}
Loading