From 262946135c1c5dbdaf7d19195db7d57959b378c1 Mon Sep 17 00:00:00 2001 From: gHashTag Date: Sun, 13 Sep 2026 03:51:15 +0000 Subject: [PATCH 1/2] specs: the Queen holds the scheduler -- crons and skills as one Inngest app, tool mcp/inngest-dev, Tau TOOLS specs/automation/inngest-queen-scheduler.t27 states the app t27-queen (served by trios/agent-server at /api/inngest): one function per cron/skill card, dispatch derived from HOST (workflow-dispatch | tick-only), skills as queen-issue, THE MOVE order (fire seen -> schedule: removed -> CONTROL = inngest). specs/tools/mcp/inngest-dev.t27 is the tool card from the live tools/list (20 tools). specs/agents/t.t27 TOOLS gains it; catalog.t27 legacy table 63, MCP_CARDS 11. Bootstrap t27c: parse, typecheck, parse-complete ok. Closes #3594 --- ...ler-crons-and-skills-as-one-inngest-app.md | 12 +++ specs/agents/t.t27 | 4 +- specs/automation/inngest-queen-scheduler.t27 | 90 +++++++++++++++++++ specs/tools/README.md | 7 +- specs/tools/catalog.t27 | 10 +-- specs/tools/mcp/inngest-dev.t27 | 48 ++++++++++ 6 files changed, 161 insertions(+), 10 deletions(-) create mode 100644 docs/now/2026-09-13-the-queen-holds-the-scheduler-crons-and-skills-as-one-inngest-app.md create mode 100644 specs/automation/inngest-queen-scheduler.t27 create mode 100644 specs/tools/mcp/inngest-dev.t27 diff --git a/docs/now/2026-09-13-the-queen-holds-the-scheduler-crons-and-skills-as-one-inngest-app.md b/docs/now/2026-09-13-the-queen-holds-the-scheduler-crons-and-skills-as-one-inngest-app.md new file mode 100644 index 000000000..cd7fba1dd --- /dev/null +++ b/docs/now/2026-09-13-the-queen-holds-the-scheduler-crons-and-skills-as-one-inngest-app.md @@ -0,0 +1,12 @@ +# NOW -- The Queen holds the scheduler: crons and skills as one Inngest app (2026-09-13) + +## The Queen holds the scheduler: crons and skills as one Inngest app (Closes #3594) + +- `specs/automation/inngest-queen-scheduler.t27` (module `automation::inngest_queen_scheduler`, `KIND = "automation"`) states how the 33 cron cards and 26 skill cards of `specs/crons` and `specs/skills` become functions of one Inngest app, `APP_ID = "t27-queen"`, served by the Queen's runtime (gHashTag/BrowserOS `trios/agent-server`, `SERVE_PATH = "/api/inngest"`) against the self-hosted Inngest server of Railway project 999. Function identity from the card's `ID` (`cron-`, `skill-`), a tick event per cron (`cron/.tick`), an event per skill (`skill/.run`), `RUNS_FANOUT = true`. +- Dispatch is derived from the card's `HOST`, never from a name: `github-actions` -> `workflow-dispatch` on the repository's default branch as the API reports it; `inngest`, `timer`, `railway-cron` -> `tick-only` (the six 999 functions already carry their own schedule, a second one would fire them twice; the fourteen timers have no remote handle). A skill run is a `queen-issue` (`[skill] `, `## Success Criteria` + `## Boundary`, an open issue with the same title is reused), never a shell command. +- THE MOVE is ordered: a function is seen firing, then a PR removes the workflow's `schedule:` block, then `CONTROL` becomes `"inngest"`. No `CONTROL` field changes in this entry. Measured on the default branches: 9 of the 12 github-actions workflows declare `workflow_dispatch`; 999 `ci.yml`, 999 `security.yml` and t27 `formal-mutation.yml` do not. +- `specs/tools/mcp/inngest-dev.t27`: the tool card of the server's MCP face, written from the live `tools/list` (20 tools, their first description lines and input keys; the server marks 4 as deprecated), `TRANSPORT = "http"`, `ENV = ["INNGEST_SIGNING_KEY"]`. Measured without the key: `health`, `get_apps`, `list_runs` answer `REST API v2 returned HTTP 401: Authentication failed`; `list_docs` and `grep_docs` answer. `WITNESS = "help-output"` is the nearest word the catalog vocabulary has for "diffed against the server's own listing on a named host"; nothing claims runtime. +- `specs/agents/t.t27`: Tau (the Queen) `TOOLS` gains `mcp/inngest-dev`; the binding source is the scheduler spec's `OWNER = "T"` and `specs/OWNERS.md` (skills/ and crons/ under T-Queen). +- Checked with the bootstrap `t27c` (v0.2.0, this checkout): the three files parse, typecheck with 0 errors, `parse-complete` consumes all tokens, ASCII only. Under the trinity generator at schema 2 (gHashTag/trinity#991): tools 92 specs, mcp 11 servers, 255 tools, agents `with tools 5`, i18n tools 92/92 once the Russian row is in `apps/website/i18n/agents.ru.json`. +- `specs/tools/catalog.t27`: `LEGACY_IDS`/`LEGACY_TARGETS` gain the row (`[63]`), `LEGACY_COUNT = 63`, `MCP_CARDS = 11`; the invariant `the_legacy_table_covers_every_legacy_card` holds. `tools/trinity_tools_registry.py check` then reports one finding, `catalog MCP_CARDS is 11, the inventory measures 10`: `conformance/trinity/tools_inventory.json` is left at its 2026-09-12 measurement because `inventory` on this host reads the pinned consumer (976df517) as `table 0, mcp_enabled 0` and would replace a measured file with 54 findings of its own; the next run on a host that reads the table should pick up the eleventh card. +- Not claimed: no function of the app has been synced or fired yet; the host code is a separate PR in gHashTag/BrowserOS. diff --git a/specs/agents/t.t27 b/specs/agents/t.t27 index 8c6fe161b..fb4167bf6 100644 --- a/specs/agents/t.t27 +++ b/specs/agents/t.t27 @@ -39,8 +39,8 @@ pub const SKILLS : [2]str = ["t27/phi-loop", "t27/tri-pipeline"]; pub const SKILLS_NOTE : str = ".claude/agents/trinity.md, Phase 2 PLAN: \"Identify required skills (phi-loop, tri-pipeline)\"; Phase 4 VERIFY: \"Run conformance tests via tri-pipeline\". specs/OWNERS.md lists skills/ and crons/ under T-Queen, which is catalog ownership, not a held skill."; ; Tool IDs (specs/tools) the agent holds. Bound only where a source line names the command ; for this letter; TOOLS_NOTE cites that line or says why the list is empty. -pub const TOOLS : [2]str = ["tri/gen", "tri/test"]; -pub const TOOLS_NOTE : str = ".claude/agents/trinity.md:68 (5. Gen - Run tri gen) and :70 (7. Verify - Run tri test). No source binds tri loop or tri health to T."; +pub const TOOLS : [3]str = ["tri/gen", "tri/test", "mcp/inngest-dev"]; +pub const TOOLS_NOTE : str = ".claude/agents/trinity.md:68 (5. Gen - Run tri gen) and :70 (7. Verify - Run tri test); specs/automation/inngest-queen-scheduler.t27 OWNER = \"T\" binds the scheduler mcp/inngest-dev to the Queen (specs/OWNERS.md: skills/ and crons/ under T-Queen). No source binds tri loop or tri health to T."; ; Where the agent logs episodes (AGENTS_ALPHABET.md: "Logs to .trinity/experience/"). pub const EXPERIENCE_LOG : str = ".trinity/experience/"; pub const ENABLED : bool = true; diff --git a/specs/automation/inngest-queen-scheduler.t27 b/specs/automation/inngest-queen-scheduler.t27 new file mode 100644 index 000000000..b47ad739e --- /dev/null +++ b/specs/automation/inngest-queen-scheduler.t27 @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: Apache-2.0 +// specs/automation/inngest-queen-scheduler.t27 -- every cron and every skill card of this +// repository (specs/crons, specs/skills) held as one Inngest app that the Queen's runtime serves. +// Host: gHashTag/BrowserOS trios/agent-server apps/server/src/inngest/ (the app), mounted on the +// same Hono server that serves /queen/*; the Inngest server is the self-hosted `inngest` +// of Railway project 999 (private address INNGEST_BASE_URL), reachable to people and bees +// through the MCP face described by specs/tools/mcp/inngest-dev.t27. +// Nothing below is inferred from a file name: the host reads these cards with the compiler +// (t27_compiler.wasm, t27_analyze -> ConstDecl) and derives every function from declared fields. +// The cron cards keep their CONTROL field; it says "inngest" only after the step this spec +// calls THE MOVE has been done for that card and the function has been seen firing. +// phi^2 + 1/phi^2 = 3 | TRINITY + +module automation::inngest_queen_scheduler { + + pub const KIND : str = "automation"; + pub const ID : str = "inngest-queen-scheduler"; + pub const REPO : str = "BrowserOS"; + pub const HOST_PATH : str = "trios/agent-server/apps/server/src/inngest"; + pub const VERSION : u8 = 1; + // The agent letter that holds the scheduler (specs/agents/t.t27 TOOLS names mcp/inngest-dev). + pub const OWNER : str = "T"; + pub const TOOL : str = "mcp/inngest-dev"; + + // The app as the Inngest server sees it. + pub const APP_ID : str = "t27-queen"; + pub const SERVE_PATH : str = "/api/inngest"; + pub const ENV : [4]str = ["INNGEST_BASE_URL", "INNGEST_EVENT_KEY", "INNGEST_SIGNING_KEY", "INNGEST_SERVE_HOST"]; + // The GitHub token the host already carries for the Queen's reads; dispatch reuses it. + pub const TOKEN_ENV : str = "TRIOS_GITHUB_API_TOKEN"; + pub const GITHUB_OWNER : str = "gHashTag"; + + // Which cards become functions. Both directories, every *.t27, ENABLED or not. + pub const SCOPE : [2]str = ["specs/crons", "specs/skills"]; + // A card that does not typecheck, or lacks a required field, is refused: the app then serves + // the cards that pass and lists the refused ones; it never guesses a field. + pub const ON_BAD_CARD : str = "refuse-card-serve-rest"; + + // Function identity. slug(ID) = ID lower-cased with every run outside [a-z0-9] replaced by "-". + pub const CRON_FUNCTION_ID : str = "cron-"; + pub const SKILL_FUNCTION_ID : str = "skill-"; + // Every cron function also answers this event, so an operator can fire it by hand. + pub const CRON_TICK_EVENT : str = "cron/.tick"; + // A skill function is event-only: nothing schedules a skill directly. + pub const SKILL_RUN_EVENT : str = "skill/.run"; + // A cron whose RUNS names skill IDs sends one SKILL_RUN_EVENT per ID after its own dispatch. + pub const RUNS_FANOUT : bool = true; + + // What a cron function does when it fires, by the card's HOST field. + // github-actions: POST /repos///actions/workflows//dispatches + // with ref = the repository's default branch (read from the API, not assumed). + pub const DISPATCH_GITHUB_ACTIONS : str = "workflow-dispatch"; + // inngest: the card is already a function of the 999-multibots-telegraf app; registering a second + // schedule would fire it twice, so this app registers the tick event only. + pub const DISPATCH_INNGEST : str = "tick-only"; + // timer: a setInterval inside a 999 process with no remote handle; tick event only, no schedule. + pub const DISPATCH_TIMER : str = "tick-only"; + // railway-cron: Railway owns the schedule; tick event only. + pub const DISPATCH_RAILWAY_CRON : str = "tick-only"; + // A card with ENABLED = false or an empty SCHEDULE gets no cron trigger, only the tick event. + pub const DISABLED_CARD : str = "tick-only"; + // SCHEDULE is a five-field cron expression evaluated in the card's TZ. + pub const SCHEDULE_FIELDS : u8 = 5; + + // What a skill function does: one issue for the Queen's bees, never a shell command. + pub const SKILL_DISPATCH : str = "queen-issue"; + pub const SKILL_ISSUE_REPO : str = "/"; + pub const SKILL_ISSUE_TITLE : str = "[skill] "; + pub const SKILL_ISSUE_LABEL : str = "queen-skill"; + // The issue body carries the two sections the Queen's brief requires. + pub const SKILL_ISSUE_SECTIONS : [2]str = ["## Success Criteria", "## Boundary"]; + // An open issue with the same title is reused, not duplicated; the run reports its number. + pub const SKILL_ISSUE_DEDUP : str = "reuse-open-same-title"; + + // THE MOVE, per github-actions card, in this order and never the reverse: + // 1. the function is synced and seen firing (list_function_runs); + // 2. a PR to the card's REPO removes the `schedule:` block of SERVICE and keeps workflow_dispatch; + // 3. the card's CONTROL becomes "inngest". + pub const MOVE_STEPS : u8 = 3; + pub const CONTROL_AFTER_MOVE : str = "inngest"; + // Measured 2026-09-13 on the default branches: 9 of the 12 github-actions SERVICE files declare + // workflow_dispatch; 999 ci.yml, 999 security.yml and t27 formal-mutation.yml do not, so their + // dispatch answers 422 until a PR adds the trigger. + pub const WORKFLOWS_WITH_DISPATCH : u8 = 9; + pub const WORKFLOWS_TOTAL : u8 = 12; + + // Not claimed: no function of this app has fired yet at VERSION 1; the count of synced + // functions is read from the server (list_functions), not written here. + pub const ENABLED : bool = true; +} diff --git a/specs/tools/README.md b/specs/tools/README.md index a37d096ad..6ef738f97 100644 --- a/specs/tools/README.md +++ b/specs/tools/README.md @@ -101,9 +101,10 @@ Nothing in these files is typed by hand. Each file records where its text came f Every card carries three fields beyond its family's: `REPO` (`gHashTag/t27` or `gHashTag/trinity`), `QUALIFIED_ID` (`/:/`, unique across -repositories by construction) and `SCHEMA = 2`. The 62 cards written before schema 2 keep -their short `ID` (`tri/`, `mcp/`): the site route and the agents' `TOOLS` -arrays use it, and `QUALIFIED_ID = REPO:ID`. A card of the Trinity `tri` has +repositories by construction) and `SCHEMA = 2`. The 62 cards written before schema 2, and +`mcp/inngest-dev` (the Queen's scheduler, 2026-09-13, written with the same short form), keep +a short `ID` (`tri/`, `mcp/`): the site route and the agents' `TOOLS` +arrays use it, and `QUALIFIED_ID = REPO:ID`; `LEGACY_COUNT = 63` in `catalog.t27`. A card of the Trinity `tri` has `ID = QUALIFIED_ID` and no short form, so a same-named command (`fpga`, `test` at the pin; `COLLISIONS` in `catalog.t27`) can never be selected by the wrong repository. diff --git a/specs/tools/catalog.t27 b/specs/tools/catalog.t27 index 826d5dd46..93c30da6b 100644 --- a/specs/tools/catalog.t27 +++ b/specs/tools/catalog.t27 @@ -28,7 +28,7 @@ pub const FAMILIES : [2]str = ["tri-cli", "mcp"]; pub const REPOS : [2]str = ["gHashTag/t27", "gHashTag/trinity"]; pub const DIRECTORIES : [3]str = ["tri/.t27 (gHashTag/t27, FAMILY tri-cli)", "mcp/.t27 (either repository, FAMILY mcp)", "trinity/tri/.t27 (gHashTag/trinity, FAMILY tri-cli)"]; pub const QUALIFIED_ID_GRAMMAR : str = "/:/, for example gHashTag/t27:tri/gen and gHashTag/trinity:tri/gen; unique across repositories by construction"; -pub const LEGACY_ID_GRAMMAR : str = "/, for example tri/gen or mcp/needle: the ID of the 62 cards written before schema 2; the site route and the agents' TOOLS arrays use it"; +pub const LEGACY_ID_GRAMMAR : str = "/, for example tri/gen or mcp/needle: the ID of the 63 cards written at or before schema 2 (62 before it, mcp/inngest-dev after); the site route and the agents' TOOLS arrays use it"; pub const ID_RULE : str = "a legacy card keeps ID = / and adds QUALIFIED_ID = REPO:ID; a card of any other repository's tri has ID = QUALIFIED_ID, never a short form"; pub const SCHEMA_2_FIELDS : [3]str = ["REPO", "QUALIFIED_ID", "SCHEMA"]; pub const SCHEMA_2_RULE : str = "every card carries REPO, QUALIFIED_ID and SCHEMA = 2 in addition to its family's fields; a Trinity tri card also carries ALIASES, NAMESPACE, MODE, STABILITY, CATEGORY, JOB_TIMEOUT, SIDE_EFFECTS, CAPABILITIES, MCP_ENABLED, MCP_NAME, MCP_DISPLAY_NAME, EXAMPLES, EXIT_CODES, RESULT, COLLIDES_WITH, ROUTED, ROUTE_KIND, ROUTE_NOTE, WITNESS_SOURCE"; @@ -38,9 +38,9 @@ pub const RESOLVE_NEEDS_REPOSITORY : u32 = 1; pub const RESOLVE_UNKNOWN : u32 = 2; pub const RESOLUTION_RULE : str = "a legacy ID resolves through LEGACY_IDS -> LEGACY_TARGETS and nothing else: tri/ is always the gHashTag/t27 command, even when gHashTag/trinity has a command of the same name; a short ID that names only a Trinity command is refused with the message `use gHashTag/trinity:tri/`; a short ID in neither table is unknown"; pub const MIGRATION_MESSAGE : str = "legacy id tri/ names the gHashTag/t27 command; for the gHashTag/trinity command use gHashTag/trinity:tri/"; -pub const LEGACY_COUNT : u32 = 62; -pub const LEGACY_IDS : [62]str = ["tri/abandoned", "tri/cell", "tri/census", "tri/ci", "tri/competitors", "tri/discard", "tri/doctor", "tri/elab", "tri/emit", "tri/experience", "tri/fleet", "tri/fmt", "tri/fpga", "tri/gates", "tri/gen", "tri/harness", "tri/health", "tri/hooks", "tri/issues", "tri/jumps", "tri/kinds", "tri/lean", "tri/ledgers", "tri/loop", "tri/merging", "tri/misread", "tri/mods", "tri/mutate", "tri/now", "tri/one-away", "tri/orphaned", "tri/pr", "tri/prose", "tri/quantifiers", "tri/red", "tri/reseal", "tri/rtl", "tri/seals", "tri/serve", "tri/skill", "tri/status", "tri/sweep", "tri/synth", "tri/test", "tri/topic", "tri/types", "tri/unparsed", "tri/vectors", "tri/verdict", "tri/vsim", "tri/window", "tri/worktrees", "mcp/gitbutler", "mcp/needle", "mcp/neon", "mcp/notebooklm", "mcp/railway-mcp-server", "mcp/t27-traceability", "mcp/tri-mcp", "mcp/tri-ssot", "mcp/trinity", "mcp/zig-docs"]; -pub const LEGACY_TARGETS : [62]str = ["gHashTag/t27:tri/abandoned", "gHashTag/t27:tri/cell", "gHashTag/t27:tri/census", "gHashTag/t27:tri/ci", "gHashTag/t27:tri/competitors", "gHashTag/t27:tri/discard", "gHashTag/t27:tri/doctor", "gHashTag/t27:tri/elab", "gHashTag/t27:tri/emit", "gHashTag/t27:tri/experience", "gHashTag/t27:tri/fleet", "gHashTag/t27:tri/fmt", "gHashTag/t27:tri/fpga", "gHashTag/t27:tri/gates", "gHashTag/t27:tri/gen", "gHashTag/t27:tri/harness", "gHashTag/t27:tri/health", "gHashTag/t27:tri/hooks", "gHashTag/t27:tri/issues", "gHashTag/t27:tri/jumps", "gHashTag/t27:tri/kinds", "gHashTag/t27:tri/lean", "gHashTag/t27:tri/ledgers", "gHashTag/t27:tri/loop", "gHashTag/t27:tri/merging", "gHashTag/t27:tri/misread", "gHashTag/t27:tri/mods", "gHashTag/t27:tri/mutate", "gHashTag/t27:tri/now", "gHashTag/t27:tri/one-away", "gHashTag/t27:tri/orphaned", "gHashTag/t27:tri/pr", "gHashTag/t27:tri/prose", "gHashTag/t27:tri/quantifiers", "gHashTag/t27:tri/red", "gHashTag/t27:tri/reseal", "gHashTag/t27:tri/rtl", "gHashTag/t27:tri/seals", "gHashTag/t27:tri/serve", "gHashTag/t27:tri/skill", "gHashTag/t27:tri/status", "gHashTag/t27:tri/sweep", "gHashTag/t27:tri/synth", "gHashTag/t27:tri/test", "gHashTag/t27:tri/topic", "gHashTag/t27:tri/types", "gHashTag/t27:tri/unparsed", "gHashTag/t27:tri/vectors", "gHashTag/t27:tri/verdict", "gHashTag/t27:tri/vsim", "gHashTag/t27:tri/window", "gHashTag/t27:tri/worktrees", "gHashTag/t27:mcp/gitbutler", "gHashTag/trinity:mcp/needle", "gHashTag/trinity:mcp/neon", "gHashTag/t27:mcp/notebooklm", "gHashTag/trinity:mcp/railway-mcp-server", "gHashTag/t27:mcp/t27-traceability", "gHashTag/t27:mcp/tri-mcp", "gHashTag/t27:mcp/tri-ssot", "gHashTag/trinity:mcp/trinity", "gHashTag/trinity:mcp/zig-docs"]; +pub const LEGACY_COUNT : u32 = 63; +pub const LEGACY_IDS : [63]str = ["tri/abandoned", "tri/cell", "tri/census", "tri/ci", "tri/competitors", "tri/discard", "tri/doctor", "tri/elab", "tri/emit", "tri/experience", "tri/fleet", "tri/fmt", "tri/fpga", "tri/gates", "tri/gen", "tri/harness", "tri/health", "tri/hooks", "tri/issues", "tri/jumps", "tri/kinds", "tri/lean", "tri/ledgers", "tri/loop", "tri/merging", "tri/misread", "tri/mods", "tri/mutate", "tri/now", "tri/one-away", "tri/orphaned", "tri/pr", "tri/prose", "tri/quantifiers", "tri/red", "tri/reseal", "tri/rtl", "tri/seals", "tri/serve", "tri/skill", "tri/status", "tri/sweep", "tri/synth", "tri/test", "tri/topic", "tri/types", "tri/unparsed", "tri/vectors", "tri/verdict", "tri/vsim", "tri/window", "tri/worktrees", "mcp/gitbutler", "mcp/inngest-dev", "mcp/needle", "mcp/neon", "mcp/notebooklm", "mcp/railway-mcp-server", "mcp/t27-traceability", "mcp/tri-mcp", "mcp/tri-ssot", "mcp/trinity", "mcp/zig-docs"]; +pub const LEGACY_TARGETS : [63]str = ["gHashTag/t27:tri/abandoned", "gHashTag/t27:tri/cell", "gHashTag/t27:tri/census", "gHashTag/t27:tri/ci", "gHashTag/t27:tri/competitors", "gHashTag/t27:tri/discard", "gHashTag/t27:tri/doctor", "gHashTag/t27:tri/elab", "gHashTag/t27:tri/emit", "gHashTag/t27:tri/experience", "gHashTag/t27:tri/fleet", "gHashTag/t27:tri/fmt", "gHashTag/t27:tri/fpga", "gHashTag/t27:tri/gates", "gHashTag/t27:tri/gen", "gHashTag/t27:tri/harness", "gHashTag/t27:tri/health", "gHashTag/t27:tri/hooks", "gHashTag/t27:tri/issues", "gHashTag/t27:tri/jumps", "gHashTag/t27:tri/kinds", "gHashTag/t27:tri/lean", "gHashTag/t27:tri/ledgers", "gHashTag/t27:tri/loop", "gHashTag/t27:tri/merging", "gHashTag/t27:tri/misread", "gHashTag/t27:tri/mods", "gHashTag/t27:tri/mutate", "gHashTag/t27:tri/now", "gHashTag/t27:tri/one-away", "gHashTag/t27:tri/orphaned", "gHashTag/t27:tri/pr", "gHashTag/t27:tri/prose", "gHashTag/t27:tri/quantifiers", "gHashTag/t27:tri/red", "gHashTag/t27:tri/reseal", "gHashTag/t27:tri/rtl", "gHashTag/t27:tri/seals", "gHashTag/t27:tri/serve", "gHashTag/t27:tri/skill", "gHashTag/t27:tri/status", "gHashTag/t27:tri/sweep", "gHashTag/t27:tri/synth", "gHashTag/t27:tri/test", "gHashTag/t27:tri/topic", "gHashTag/t27:tri/types", "gHashTag/t27:tri/unparsed", "gHashTag/t27:tri/vectors", "gHashTag/t27:tri/verdict", "gHashTag/t27:tri/vsim", "gHashTag/t27:tri/window", "gHashTag/t27:tri/worktrees", "gHashTag/t27:mcp/gitbutler", "gHashTag/t27:mcp/inngest-dev", "gHashTag/trinity:mcp/needle", "gHashTag/trinity:mcp/neon", "gHashTag/t27:mcp/notebooklm", "gHashTag/trinity:mcp/railway-mcp-server", "gHashTag/t27:mcp/t27-traceability", "gHashTag/t27:mcp/tri-mcp", "gHashTag/t27:mcp/tri-ssot", "gHashTag/trinity:mcp/trinity", "gHashTag/trinity:mcp/zig-docs"]; ; Command names both repositories' tri dispatch (the name or an alias of a registry command that is also a t27 card). pub const COLLISION_COUNT : u32 = 2; pub const COLLISIONS : [2]str = ["fpga", "test"]; @@ -59,7 +59,7 @@ pub const STABILITIES : [3]str = ["stable", "experimental", "dangerous"]; pub const NAMESPACES : [6]str = ["core", "dev", "forge", "agent", "mcp", "system"]; ; --- What the consumer measures to (tools/trinity_tools_registry.py inventory at the pin) --------------- pub const T27_TRI_CARDS : u32 = 52; -pub const MCP_CARDS : u32 = 10; +pub const MCP_CARDS : u32 = 11; pub const TRINITY_TRI_CARDS : u32 = 29; pub const TRINITY_TABLE_COMMANDS : u32 = 187; pub const TRINITY_TABLE_MCP_ENABLED : u32 = 29; diff --git a/specs/tools/mcp/inngest-dev.t27 b/specs/tools/mcp/inngest-dev.t27 new file mode 100644 index 000000000..1e842bf71 --- /dev/null +++ b/specs/tools/mcp/inngest-dev.t27 @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/tools/mcp/inngest-dev.t27 -- tool mcp/inngest-dev, MCP server "inngest-dev" (self-hosted Inngest, Railway project 999) +; Source of truth for the tool card on t27.ai (#/tools?tool=mcp/inngest-dev). +; Tool names, descriptions (first line) and input keys are the server's own tools/list answer, +; recorded over Streamable HTTP on 2026-09-13 (initialize -> notifications/initialized -> tools/list, +; serverInfo name "inngest-dev", title "Inngest Dev Server MCP Tools", version 1.0.0, +; response header x-inngest-server-kind: cloud); nothing is typed by hand. +; This is the scheduler the Queen holds: every cron and every skill card of specs/crons and +; specs/skills is registered as an Inngest function by the app specs/automation/inngest-queen-scheduler.t27 +; describes, and these 20 tools are how a bee or an operator lists, invokes, reruns or cancels them. +; Layer 5 of the ladder Specs -> Skills -> Crons -> Agents -> Tools. ASCII only (L3). +; phi^2 + 1/phi^2 = 3 | TRINITY + +module tool_mcp_inngest_dev; + +pub const KIND : str = "tool"; +pub const FAMILY : str = "mcp"; +pub const ID : str = "mcp/inngest-dev"; +pub const SERVER : str = "inngest-dev"; +pub const SERVER_VERSION : str = "1.0.0"; +pub const TRANSPORT : str = "http"; +; The registration line as a client states it; the REST tools (get_apps, list_functions, ...) answer +; HTTP 401 until the client also sends Authorization: Bearer (measured 2026-09-13). +pub const LAUNCH : str = "claude mcp add --transport http inngest-dev https://inngestinngest-production-c468.up.railway.app/mcp"; +pub const ENV : [1]str = ["INNGEST_SIGNING_KEY"]; +; No .mcp.json in this repository registers it; the Queen's runtime (trios/agent-server) holds the address. +pub const CONFIG : str = ""; +pub const REPO : str = "gHashTag/t27"; +pub const QUALIFIED_ID : str = "gHashTag/t27:mcp/inngest-dev"; +pub const SCHEMA : u32 = 2; +pub const SOURCE : str = "tools/list of https://inngestinngest-production-c468.up.railway.app/mcp (2026-09-13)"; +pub const ABOUT : str = "MCP face of the self-hosted Inngest server (Railway project 999) that runs the Queen's crons and skills as functions of the app t27-queen; lists apps and functions, reads runs and traces, invokes, reruns and cancels."; +pub const ABOUT_SOURCE : str = "serverInfo.title of the initialize answer plus specs/automation/inngest-queen-scheduler.t27"; +; Tools as the server lists them (tools/list), their descriptions and inputSchema property keys. +pub const TOOLS : [20]str = ["cancel_run", "get_app", "get_apps", "get_event_runs", "get_function", "get_run", "get_run_status", "get_run_trace", "grep_docs", "health", "invoke_function", "invoke_function_sync", "list_docs", "list_function_runs", "list_functions", "list_runs", "poll_run_status", "read_doc", "rerun", "send_event"]; +pub const TOOLS_ABOUT : [20]str = ["Cancels an in-progress function run", "Fetches details for a single app, including sync metadata and function count", "Lists active apps in the authenticated environment. Set archived to true to list archived apps instead.", "Lists function runs triggered by a specific event", "Fetches function configuration and status details for a function within an app", "Fetches the canonical run summary for a single function run", "Deprecated compatibility tool retained for existing dev server integrations. Use get_run and get_run_trace for new integrations. Parameters:", "Fetches the trace tree for a single function run", "Search documentation using exact string matching (grep). Useful for finding specific API names, error codes, or identifiers. Parameters: pat", "Returns the health status of the API service", "Invokes a function, executing the function either asynchronously or synchronously based on the mode parameter in the request body", "Deprecated compatibility tool retained for existing dev server integrations. Use invoke_function for the shared asynchronous Cloud and dev s", "List all available documentation categories and their document counts. No parameters required.", "Lists runs for one function in the authenticated environment", "Lists function configuration and status details for an app", "Lists runs in the authenticated environment, optionally filtered by app and function IDs", "Deprecated compatibility tool retained for existing dev server integrations. Use get_run for new integrations. Poll multiple function runs u", "Read the full content of a specific documentation file. Parameters: path (required string - the doc file path relative to docs directory)", "Creates a new run using the original run's triggering event data", "Deprecated compatibility tool retained for existing dev server integrations. Send an event to the Inngest dev server and return the event ID"]; +pub const TOOLS_INPUTS : [20]str = ["runId", "appId", "archived,cursor,limit", "cursor,eventId,includeOutput,limit", "appId,functionId", "includeOutput,runId", "runId", "includeOutput,runId", "pattern,limit", "", "appId,data,functionId,idempotencyKey", "functionId,data,user,timeout", "", "appId,cursor,from,functionId,includeOutput,isDeferred,limit,order,status,timeField,until", "appId,cursor,limit", "appId,cursor,from,functionId,includeOutput,isDeferred,limit,order,status,timeField,until", "runIds,timeout,pollInterval", "path", "fromStep,runId", "name,data,user,eventIdSeed"]; +pub const RESOURCES : [0]str = []; +pub const RESOURCES_ABOUT : [0]str = []; +; 4 of the 20 carry the server's own word "Deprecated compatibility tool" (get_run_status, invoke_function_sync, poll_run_status, send_event); a bee prefers get_run, invoke_function and the REST-backed list tools. +pub const TOOLS_NOTE : str = "Recorded from the live tools/list, not from source: the server is the upstream inngest binary, its source is not in this repository. Measured 2026-09-13 without a key: health, get_apps and list_runs answer REST API v2 returned HTTP 401: Authentication failed; list_docs and grep_docs answer (173 documents). The REST-backed tools need Authorization: Bearer on the MCP request."; +; The server is the upstream inngest binary run by Railway, not code of this repository. +pub const EXTERNAL : bool = true; +pub const AGENTS : [1]str = ["T"]; +pub const AGENTS_NOTE : str = "specs/agents/t.t27 TOOLS names mcp/inngest-dev: the Queen (Tau) holds the scheduler; a bee reaches it through the Queen's brief, not by its own registration."; +; help-output is the nearest witness the catalog vocabulary has for 'diffed against the server's own tools/list on a named host'; no workflow runs it yet, so nothing here claims runtime. +pub const WITNESS : str = "help-output"; +pub const ENABLED : bool = true; From 8f15d96e7b712f3601f18d1265d16825dbfeb900 Mon Sep 17 00:00:00 2001 From: gHashTag Date: Sun, 13 Sep 2026 04:10:30 +0000 Subject: [PATCH 2/2] chore(seals): reseal tools/catalog.t27 after the 63rd legacy row (t27c seal --save) The four gen_hash_* of tools_ToolsCatalog.json described the 62-row catalog; coverage and spec-guards said so. Resealed with t27c v0.2.0; verify: all hashes MATCH; check_seal_currency: STALE 0; check_seal_coverage: OK. Closes #3594 --- .trinity/seals/tools_ToolsCatalog.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.trinity/seals/tools_ToolsCatalog.json b/.trinity/seals/tools_ToolsCatalog.json index 05b246b5e..1aa46a070 100644 --- a/.trinity/seals/tools_ToolsCatalog.json +++ b/.trinity/seals/tools_ToolsCatalog.json @@ -1,12 +1,12 @@ { - "gen_hash_c": "sha256:384910416b5d8272b4c4e5996275a22c4e80114239022a0175a3fb0ea37366c6", - "gen_hash_rust": "sha256:53f1d086bd48db70e287ff758507ab09c805a9856afd0ba43beee8f83f11055b", - "gen_hash_verilog": "sha256:b8e6f8c0267d8428d26348ce712dda23278355d6b78b33023442da569aef8026", - "gen_hash_zig": "sha256:571c3fbda53beff630328215d4a7128144dec103c4455d3f64c196a981cd9384", + "gen_hash_c": "sha256:a0007fe9e3313994b5afb5e3bc310241f4c9d83fd43cd6e4ad10aab48fc5f3b0", + "gen_hash_rust": "sha256:39fc1e4670ca8a6d3c28d631a926044240e6a5521cf7378096bf6f5f6dab7099", + "gen_hash_verilog": "sha256:191ac688fd734ba5ad0e9ef410dd12bcc671285692c36c591edb814289502186", + "gen_hash_zig": "sha256:4047f02d8d2d73f2f9d17a03251de5aa086ecfcc8b0813fcac99b8ff4873cacc", "module": "ToolsCatalog", "ring": 12, - "sealed_at": "2026-09-12T12:19:38Z", + "sealed_at": "2026-09-13T04:09:22Z", "sealed_by": "t27c-bootstrap@0.2.0", - "spec_hash": "sha256:697ee78508508e7b71573758a7336b359795faf20d4b2aeeb7ee6dc48a52d12e", + "spec_hash": "sha256:1ec86e7561e1830b7f478ffc835f028522b5297c375296b7674990b182956235", "spec_path": "specs/tools/catalog.t27" } \ No newline at end of file