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
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# NOW -- One card for the unified agent-operations system (2026-09-13)

## One card for the unified agent-operations system (Closes #3607)

- `specs/system/unified-agent-operations.t27` (module `system::unified_agent_operations`, `KIND = "system"`, `VERSION = 1`) names the four layers the repositories form -- `contracts` (t27), `control` (Queen, Bees, the `t27-queen` Inngest app), `edge` (999 bot, Mini App, Hive, CRM, media library, vibee-render), `evidence` (GoldenFloat registry, AX7203, Golden Sieve, papers) -- with `AUTHORITY_FLOWS_DOWN = true`: a lower layer never edits a higher one. 14 `SUBSYSTEMS`, 5 `SATELLITES`.
- Contract rules as fields: `CARD_REQUIRED` (six fields or the card is refused, `ON_BAD_CARD = "refuse-card-serve-rest"`), `STATUS_TAGS`, `FORBIDDEN_CLAIMS = ["first", "only", "best"]`, `DRIFT_CHECK = "regenerate-and-diff"` as a required status, `SOURCE_LANGUAGE = "en"` with generated `ru`, a one-card `FAST_PATH`, the change folder and the `[P]` parallel mark.
- Scheduler as an interface over an engine: `SCHEDULER_ENGINE = "inngest"`, `SCHEDULER_ALTERNATES = ["temporal"]`; every cron card must carry `SCHEDULE, TZ, JITTER_S, OVERLAP, CATCHUP` because a five-field expression alone is ambiguous on DST days; external `postgres`/`redis` state, 30/14-day run/trace retention, engine image pinned (measured 2026-09-13: fork image `ghcr.io/ghashtag/inngest:mcp-auth` until upstream PR inngest/inngest#4860 ships).
- Approvals: `HITL_MODEL = "wait-for-event"`, 72 h timeout into `question`, seven `NEEDS_APPROVAL` tools (merge, Railway variables and services, refund, external messages, secret rotation, data delete); a Bee patch is accepted by `["task-contract", "t27c"]`, the Queen owns the merge decision, the Bee sees the full trace. Budgets are card fields: `BEE_MAX_ITER = 8`, `BEE_MAX_TOKENS = 400000`, `RUN_MAX_MINUTES = 90`.
- Media, measured 2026-09-13 on the Railway CPU services: Qwen3-VL-2B Q8 at 17-30 tok/s prompt, about 1.5-3 tok/s generation; a four-frame clip scaled 448 px by width only reached 1514 prompt tokens and missed the 300 s timeout twice, so the card fixes `VISION_FRAME_LONGEST_SIDE = 448`, `VISION_VIDEO_MAX_TOKENS = 200` and lists the owner fallbacks in order. STT minimum `RTFX 2`, hallucination filter on, unread files reported as unread.
- Evidence fields are read from the registry (2026-09-12): `FORMATS = 83`, `SW_BITEXACT = 75`, Tier-E decode 14 / compute 19, `SILICON_CLAIMED = false`. Eight owner-only items are counted, not performed.
- Not checked: the card was not run through `t27c` on the authoring host (no checkout there); it is ASCII-only and follows the shape of `specs/automation/inngest-queen-scheduler.t27`. Not claimed: no host reads this card yet; no CONTROL field changes. The Russian plan that comments on it is gHashTag/999-multibots-telegraf PR #2387.
177 changes: 177 additions & 0 deletions specs/system/unified-agent-operations.t27
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
// SPDX-License-Identifier: Apache-2.0
// specs/system/unified-agent-operations.t27 -- the one system that the Trinity repositories form
// together: canonical contracts (t27), the Queen and her Bees, the Inngest scheduler, the 999
// application edge (bot, Mini App, Hive, CRM, media library), the self-hosted inference services
// (whisper = Speaches, vision = llama.cpp + Qwen3-VL) and the evidence tracks (GoldenFloat, AX7203,
// Golden Sieve, publications). This card names the parts, the contracts between them, the gates
// every change must pass and the budgets every run must keep. It claims nothing that a witness has
// not shown: every numeric field below is either a limit we choose or a value measured on
// 2026-09-13 and marked so. Hosts read this card with the compiler (t27_analyze -> ConstDecl);
// the Russian development plan (999-multibots-telegraf/docs/, the Russian "unified plan" file) is generated
// commentary on this card, never the other way round.
// phi^2 + 1/phi^2 = 3 | TRINITY

module system::unified_agent_operations {

pub const KIND : str = "system";
pub const ID : str = "unified-agent-operations";
pub const VERSION : u8 = 1;
pub const OWNER : str = "gHashTag";
pub const AUTHORED : str = "2026-09-13";

// ---------------------------------------------------------------- layers
// Four layers, one direction of authority: a lower layer never edits a higher one.
// 1 contracts -- gHashTag/t27 specs/**; the only place logic and English text originate.
// 2 control -- Queen (trios agent-server), Bees, the t27-queen Inngest app, this card.
// 3 edge -- 999-multibots-telegraf: bot, Mini App, Hive, CRM, vibee-render, 999 Inngest app.
// 4 evidence -- GoldenFloat registry, AX7203 transcripts, Golden Sieve verdicts, papers.
pub const LAYERS : [4]str = ["contracts", "control", "edge", "evidence"];
pub const AUTHORITY_FLOWS_DOWN : bool = true;

// Subsystems as the inventory of 2026-09-13 lists them (the Russian unified plan, section 1).
pub const SUBSYSTEMS : [14]str = [
"t27-toolchain", "trinity-reconstruction", "queen-hive-bees", "t27-queen-scheduler",
"999-bot-miniapp", "999-inngest", "999-crm-media", "whisper-speaches", "vision-llamacpp",
"goldenfloat-registry", "ax7203-fpga", "golden-sieve", "tri-net", "publications"
];
// Related but separately governed: leela, turbobaby, woody-weed, igla, browseros-trios.
pub const SATELLITES : [5]str = ["leela", "turbobaby", "woody-weed", "igla-training", "browseros-trios"];

// ------------------------------------------------------------- contracts
// Every card carries these fields or is refused (fail-closed, never fail-open).
pub const CARD_REQUIRED : [6]str = ["KIND", "ID", "VERSION", "OWNER", "REPO", "ENABLED"];
// A card that does not typecheck is listed as refused and skipped; the rest are served.
pub const ON_BAD_CARD : str = "refuse-card-serve-rest";
// Status vocabulary for prose derived from cards. Nothing else is allowed in generated text.
pub const STATUS_TAGS : [4]str = ["measured", "decision", "question", "known"];
// Words no generated text may contain (Trinity honesty rule).
pub const FORBIDDEN_CLAIMS : [3]str = ["first", "only", "best"];
// Text the host generates from a card must be regenerated, never hand-edited; a CI check
// compares regenerated output with the committed one and fails on drift (Spec Kit lesson:
// "the spec does not update itself").
pub const DRIFT_CHECK : str = "regenerate-and-diff";
pub const DRIFT_CHECK_REQUIRED_STATUS : str = "t27-drift";
// Localization is generated from the English card; a Russian file never carries new logic.
pub const SOURCE_LANGUAGE : str = "en";
pub const GENERATED_LANGUAGES : [1]str = ["ru"];
// Small change fast path: one card, one host file, no new field -> skip proposal/design,
// keep compile + drift + tests. Anything larger takes the full change folder.
pub const FAST_PATH_MAX_CARDS : u8 = 1;
pub const CHANGE_FOLDER : [4]str = ["proposal.md", "specs/", "design.md", "tasks.md"];
// Tasks safe to run in parallel are marked [P]; the Queen hands each [P] group to one Bee.
pub const PARALLEL_MARK : str = "[P]";

// -------------------------------------------------------------- scheduler
// The scheduler is an interface; Inngest is its current engine (self-hosted, Railway).
// Swapping the engine must not touch specs/crons or specs/skills.
pub const SCHEDULER_INTERFACE : str = "specs/automation/inngest-queen-scheduler.t27";
pub const SCHEDULER_ENGINE : str = "inngest";
pub const SCHEDULER_ALTERNATES : [1]str = ["temporal"];
// Every cron card must declare these, because a five-field cron alone is ambiguous on
// DST days ("may run zero, one, or two times") and says nothing about overlap or backfill.
pub const CRON_REQUIRED : [5]str = ["SCHEDULE", "TZ", "JITTER_S", "OVERLAP", "CATCHUP"];
pub const CRON_TZ_DEFAULT : str = "UTC";
pub const CRON_OVERLAP_VALUES : [3]str = ["skip", "buffer-one", "allow"];
pub const CRON_CATCHUP_VALUES : [2]str = ["none", "last-missed"];
// Self-hosted engine: one box plus external state, or state is lost with the box.
pub const ENGINE_STATE_EXTERNAL : bool = true;
pub const ENGINE_STATE_STORES : [2]str = ["postgres", "redis"];
// Runs and traces are deleted by policy, not by accident; the engine does not do it alone.
pub const RUN_RETENTION_DAYS : u16 = 30;
pub const TRACE_RETENTION_DAYS : u16 = 14;
// Engine version is pinned by digest and moved by PR. Measured 2026-09-13: fork image
// ghcr.io/ghashtag/inngest:mcp-auth (v1.44.0 + PR inngest/inngest#4860); return to the
// official image is an owner step after the upstream release (cron watcher 01f8b516).
pub const ENGINE_PINNED : bool = true;

// ------------------------------------------------------------ approvals
// Human-in-the-loop is an event, never a blocking call: the run parks on wait-for-event
// and resumes on approve/reject or times out into "question".
pub const HITL_MODEL : str = "wait-for-event";
pub const HITL_TIMEOUT_H : u16 = 72;
pub const HITL_ON_TIMEOUT : str = "question";
// Approval is declared per tool, not per agent. These tools always need it.
pub const NEEDS_APPROVAL : [7]str = [
"git.merge", "railway.variable.set", "railway.service.create", "payment.refund",
"telegram.send.external", "secret.rotate", "data.delete"
];
// The owner's one-word merge command and the PR footer that negates it are Russian literals
// kept in the edge repository (this file stays English); the host reads them from there.
pub const MERGE_WORD_SOURCE : str = "999-multibots-telegraf/docs/OWNER-DECISIONS.md";
pub const PR_FOOTER_REQUIRED : bool = true;
// A Bee patch is accepted only after the task contract and the compiler both pass on the
// host side; a second agent's opinion is not a verifier (MAST: missing task verification).
pub const BEE_ACCEPT : [2]str = ["task-contract", "t27c"];
pub const QUEEN_OWNS_MERGE_DECISION : bool = true;
pub const BEE_SEES_FULL_TRACE : bool = true;

// --------------------------------------------------------------- budgets
// Multi-agent runs cost about 15x a chat turn; budgets are card fields, not runtime knobs.
pub const BEE_MAX_ITER : u8 = 8;
pub const BEE_MAX_TOKENS : u32 = 400000;
pub const QUEEN_MAX_BEES_PER_TASK : u8 = 4;
pub const RUN_MAX_MINUTES : u16 = 90;
pub const ON_BUDGET_EXCEEDED : str = "stop-report-question";

// -------------------------------------------------------------- secrets
// Secrets live in the process environment or the owner-restored .env; scripts and skills
// never read them from a cloud CLI or API, never print a value (name, length, prefix only).
pub const SECRET_SOURCES : [2]str = ["process-env", "owner-dotenv"];
pub const SECRET_PRINT : str = "name-length-prefix";
// Public surfaces that carry no auth of their own must sit behind a private network or a
// proxy with a key: Speaches /docs and /openapi.json, llama.cpp GET /props, Inngest UI.
pub const PRIVATE_ONLY_SURFACES : [3]str = ["whisper:/docs", "vision:/props", "inngest:/"];

// --------------------------------------------------------------- media
// Speech to text: the self-hosted Speaches service; quality is a rate, RTFx, not a feeling.
pub const STT_SERVICE : str = "whisper";
pub const STT_RTFX_MIN : u8 = 2;
// Roughly one transcript in a hundred contains invented phrases; a hallucination filter is
// part of the pipeline, and an unread file is reported as unread, never as empty.
pub const STT_HALLUCINATION_FILTER : bool = true;
// The marker text itself is a localized string of the edge repository (media-library.md).
pub const UNREAD_MARKER_SOURCE : str = "999-multibots-telegraf/docs/crm/media-library.md";
// Vision: llama.cpp server with Qwen3-VL-2B on CPU. Measured 2026-09-13 on Railway:
// prompt processing 17-30 tok/s, generation about 1.5-3 tok/s; a four-frame clip at
// 448 px width-only scaling produced 1514 prompt tokens and did not finish in 300 s.
pub const VISION_SERVICE : str = "vision";
pub const VISION_MODEL : str = "ggml-org/Qwen3-VL-2B-Instruct-GGUF:Q8_0";
pub const VISION_FRAMES : u8 = 4;
pub const VISION_FRAME_LONGEST_SIDE : u16 = 448;
pub const VISION_VIDEO_MAX_TOKENS : u16 = 200;
pub const VISION_TIMEOUT_S : u16 = 300;
// Fallbacks, in order, when a clip still misses the timeout (owner decision, not automatic):
pub const VISION_FALLBACKS : [3]str = ["frames=2", "quant=Q4_K_M", "timeout=600"];
// Inference images are pinned; a daily-moving build broke prompt speed upstream (b10780).
pub const INFERENCE_IMAGES_PINNED : bool = true;

// ------------------------------------------------------------ reliability
// Reliability is measured by repeated runs: pass^k over K runs with fault injection, on the
// served cron/skill catalog, before a card's CONTROL may say "inngest".
pub const RELIABILITY_K : u8 = 5;
pub const RELIABILITY_FAULT_RATE_PCT : u8 = 20;
pub const RELIABILITY_METRIC : str = "pass^k";
// Config is a blueprint (this card); state is a row in the state store. State never enters
// a card, and a card never carries a run id.
pub const CONFIG_STATE_SEPARATED : bool = true;

// -------------------------------------------------------------- evidence
// Numbers about formats and hardware are read from the registry and board transcripts.
// Measured or registry-read 2026-09-12: 83 formats; 75 strict SW-bitexact; Tier-E snapshot
// 33/83 (decode 14, compute 19). The HW union above that is a question, not a claim.
pub const FORMATS : u8 = 83;
pub const SW_BITEXACT : u8 = 75;
pub const HW_TIER_E_DECODE : u8 = 14;
pub const HW_TIER_E_COMPUTE : u8 = 19;
pub const SILICON_CLAIMED : bool = false;
// Golden Sieve: every published number passes the cascade; a QUESTION verdict stays visible.
pub const CLAIM_AUDIT : str = "golden-sieve";

// ------------------------------------------------------------ boundaries
// Owner-only steps this card cannot perform and does not pretend to (2026-09-13):
// GitHub Actions billing (CI blocked); Inngest Cloud key rotation; 34 Dependabot alerts
// (2 high); inngest image back to official after #4860; render OPENAI_API_KEY answers 401;
// Ludmila 1210 Stars refund; rotation of leaked keys (12 categories); dead GramJS session.
pub const OWNER_ITEMS : u8 = 8;
pub const ENABLED : bool = true;
}
Loading