From 009a53f9ec9681dd8c83983751e021ebe007320e Mon Sep 17 00:00:00 2001 From: gHashTag Date: Wed, 9 Sep 2026 15:15:28 +0000 Subject: [PATCH] specs/functions: the 28 Inngest functions of 999-multibots-telegraf as first-class .t27 specs (layer 5) One specs/functions/.t27 per function registered at 999-multibots-telegraf main @a9c08b4, KIND "function", module fn_: canonical and legacy ids and events, TRIGGER (event|cron), STEPS in source order, RETRIES, ON_FAILURE, SIDE_EFFECTS, GUARD, the 2026-09-09 safe probe (SAFE_PROBE, PROBE_RESULT), CONTROL and NOTE. Same header / module / pub const style as specs/crons. Values are read from the functions manifest (the code witness the site vendors) and, where it has gaps, from the checkout itself; each such fill is named in NOTE. Kept visible, not resolved: payment-ai-server-process declares an onFailure handler (admin-telegram) where the manifest says log; eight functions declare no retries and carry the SDK default 4 with a NOTE; four functions are not on the production Railway build as of 2026-09-09 (PROBE_RESULT not-deployed, GUARD unknown). specs/i18n/agents-ru.t27 SCOPE gains specs/functions ([4]str); OWNERS.md gains the functions/ row; docs/now records the measurement. Measured: 28/28 typecheck ok under the vendored compiler wasm (4d9c0447b5ca2887...), nothing discarded, field schema satisfied, ASCII only. Not run here: cargo build (bootstrap/build.rs LANG-EN guard) -- no Rust toolchain in this environment; the Cyrillic scan was repeated by hand. Closes #3552 --- ...26-09-09-inngest-functions-as-t27-specs.md | 11 ++ specs/OWNERS.md | 1 + specs/functions/README.md | 112 ++++++++++++++++++ specs/functions/analytics-sales-advise.t27 | 42 +++++++ specs/functions/analytics-skills-detect.t27 | 42 +++++++ specs/functions/broadcast-message-send.t27 | 42 +++++++ .../content-detailed-script-generate.t27 | 42 +++++++ .../content-scenario-clips-generate.t27 | 42 +++++++ specs/functions/content-scripts-generate.t27 | 42 +++++++ .../functions/instagram-competitors-find.t27 | 42 +++++++ specs/functions/instagram-reels-analyze.t27 | 42 +++++++ .../instagram-top-content-extract.t27 | 42 +++++++ specs/functions/monitoring-error-report.t27 | 42 +++++++ specs/functions/monitoring-health-check.t27 | 42 +++++++ specs/functions/monitoring-logs-analyze.t27 | 42 +++++++ specs/functions/monitoring-logs-trigger.t27 | 42 +++++++ specs/functions/morph-images-generate.t27 | 42 +++++++ specs/functions/neuro-image-generate.t27 | 42 +++++++ specs/functions/payment-ai-server-process.t27 | 42 +++++++ specs/functions/reels-ai-callback.t27 | 42 +++++++ specs/functions/reels-ai-generate.t27 | 42 +++++++ specs/functions/reels-loop-generate.t27 | 42 +++++++ specs/functions/render-avatar-video-run.t27 | 42 +++++++ specs/functions/render-job-run.t27 | 42 +++++++ specs/functions/render-riddle-run.t27 | 42 +++++++ specs/functions/training-model-complete.t27 | 42 +++++++ specs/functions/training-model-start.t27 | 42 +++++++ specs/functions/training-model-v2-start.t27 | 42 +++++++ specs/functions/training-stuck-check.t27 | 42 +++++++ .../functions/webhook-generation-validate.t27 | 42 +++++++ specs/functions/welcome-avatar-generate.t27 | 42 +++++++ specs/i18n/agents-ru.t27 | 2 +- 32 files changed, 1301 insertions(+), 1 deletion(-) create mode 100644 docs/now/2026-09-09-inngest-functions-as-t27-specs.md create mode 100644 specs/functions/README.md create mode 100644 specs/functions/analytics-sales-advise.t27 create mode 100644 specs/functions/analytics-skills-detect.t27 create mode 100644 specs/functions/broadcast-message-send.t27 create mode 100644 specs/functions/content-detailed-script-generate.t27 create mode 100644 specs/functions/content-scenario-clips-generate.t27 create mode 100644 specs/functions/content-scripts-generate.t27 create mode 100644 specs/functions/instagram-competitors-find.t27 create mode 100644 specs/functions/instagram-reels-analyze.t27 create mode 100644 specs/functions/instagram-top-content-extract.t27 create mode 100644 specs/functions/monitoring-error-report.t27 create mode 100644 specs/functions/monitoring-health-check.t27 create mode 100644 specs/functions/monitoring-logs-analyze.t27 create mode 100644 specs/functions/monitoring-logs-trigger.t27 create mode 100644 specs/functions/morph-images-generate.t27 create mode 100644 specs/functions/neuro-image-generate.t27 create mode 100644 specs/functions/payment-ai-server-process.t27 create mode 100644 specs/functions/reels-ai-callback.t27 create mode 100644 specs/functions/reels-ai-generate.t27 create mode 100644 specs/functions/reels-loop-generate.t27 create mode 100644 specs/functions/render-avatar-video-run.t27 create mode 100644 specs/functions/render-job-run.t27 create mode 100644 specs/functions/render-riddle-run.t27 create mode 100644 specs/functions/training-model-complete.t27 create mode 100644 specs/functions/training-model-start.t27 create mode 100644 specs/functions/training-model-v2-start.t27 create mode 100644 specs/functions/training-stuck-check.t27 create mode 100644 specs/functions/webhook-generation-validate.t27 create mode 100644 specs/functions/welcome-avatar-generate.t27 diff --git a/docs/now/2026-09-09-inngest-functions-as-t27-specs.md b/docs/now/2026-09-09-inngest-functions-as-t27-specs.md new file mode 100644 index 000000000..ac3888eda --- /dev/null +++ b/docs/now/2026-09-09-inngest-functions-as-t27-specs.md @@ -0,0 +1,11 @@ +# NOW -- The 28 Inngest functions of 999-multibots-telegraf as first-class .t27 specs (2026-09-09) + +## Inngest functions as first-class .t27 specs + +- `specs/functions/` (28): one `.t27` module per Inngest function the bot `999-multibots-telegraf` registers at `main @a9c08b4` (`functions/.t27`, `KIND = "function"`, module `fn_`). Every constant is `pub const`; the schema is in `specs/functions/README.md`. Layer five of the ladder Specs -> Skills -> Crons -> Agents -> Functions: what one run does step by step (STEPS in source order), what starts it (TRIGGER, EVENT + LEGACY_EVENTS or CRON + TZ), how it fails (RETRIES, ON_FAILURE), what it touches outside (SIDE_EFFECTS), the first step that stops a bad payload (GUARD) and what the 2026-09-09 safe probe reached (SAFE_PROBE, PROBE_RESULT). +- Values were read from the source, not inferred: the functions manifest (28 entries, the code witness the site vendors) plus the checkout itself where the manifest has gaps -- three functions with no file/steps/retries in the manifest and eight with undeclared `retries` (the spec writes the Inngest JS SDK v3 default, 4, and says so in NOTE). One disagreement is kept visible rather than resolved: `payment-ai-server-process` declares an `onFailure` handler that messages the admin chat, the manifest says `log`. +- Not hidden: four functions (`training-model-complete`, `training-stuck-check`, `webhook-generation-validate`, `welcome-avatar-generate`) are not on the production Railway build as of 2026-09-09 (24 base functions deployed, 28 on `main`); their PROBE_RESULT is `not-deployed`, GUARD `unknown`. +- Measured: **28/28** typecheck ok under the vendored wasm (sha256 `4d9c0447b5ca2887...`), nothing discarded, field schema satisfied, all ASCII. The bootstrap compiler on `master` was not run against these files. +- Language: the specs are English-only (LANG-EN). `specs/i18n/agents-ru.t27` `SCOPE` gains `specs/functions` (`[4]str`); the RU bundle (`trinity:apps/website/i18n/agents.ru.json`) gains 28 entries keyed by `ID` in the companion trinity PR. +- Not claimed: no function was renamed in the code by this change; no run was triggered; no silicon, no first/only/best. +- `specs/OWNERS.md` gains the row `functions/` -> **T-Queen**. diff --git a/specs/OWNERS.md b/specs/OWNERS.md index a3e6ae826..caaa3e3b2 100644 --- a/specs/OWNERS.md +++ b/specs/OWNERS.md @@ -21,6 +21,7 @@ | `isa/` | **C-Compiler** | Register alphabet | | `skills/`, `crons/`, `i18n/` | **T-Queen** | Agent skills and scheduled jobs as `.t27` specs, plus the per-locale translation contracts (`i18n/agents-.t27`) that point at the site's text bundles; the site (gHashTag/trinity) generates its catalogs from a vendored copy | | `agents/` | **T-Queen** | The 27 agents of `docs/agents/AGENTS_ALPHABET.md` as `.t27` specs (`agents/.t27`, `KIND = "agent"`): letter, domain, archetype, register, invariants, the documents that bind it (`SOUL.md`, `AGENTS.md`, the alphabet) and the skills a source evidently binds; the site joins experience by LETTER | +| `functions/` | **T-Queen** | The 28 Inngest functions of `999-multibots-telegraf` as `.t27` specs (`functions/.t27`, `KIND = "function"`): canonical and legacy ids and events, trigger, steps, retries, failure handling, side effects, guard and the 2026-09-09 safe-probe result; the site joins them to a vendored copy of the functions manifest | Each subtree with substantial churn should keep a local **`OWNERS.md`** (see below). diff --git a/specs/functions/README.md b/specs/functions/README.md new file mode 100644 index 000000000..700916b6a --- /dev/null +++ b/specs/functions/README.md @@ -0,0 +1,112 @@ +# specs/functions — Inngest functions of 999-multibots-telegraf as first-class `.t27` specs + +> **Where this lives.** This directory in `gHashTag/t27` is the canonical home of these +> specs — edit them here. `gHashTag/trinity` keeps a vendored copy under +> `apps/website/public/t27/files/specs/functions/` and its build reads that copy through the +> vendored compiler wasm (`t27_compiler.wasm`). The wasm's `typecheck.ok` is necessary, +> not sufficient: it stays `true` for a wrong annotation such as `str = 5`, so the site's +> generator (`scripts/agents-from-specs.mjs`) also checks the field schema below. The +> bootstrap compiler on `master` was not run against these files in the commit that +> added them; all 28 were compiled with the vendored wasm (sha256 `4d9c0447b5ca2887...`), +> typecheck ok, nothing discarded. + +One file per Inngest function the bot `999-multibots-telegraf` registers (28 at `main +@a9c08b4`). The `.t27` file is the source of truth for the function card on t27.ai +(`#/functions?function=`); `public/functions/spec-functions.json` is generated from it by +the real compiler. The code witness is a vendored copy of the functions manifest +(`public/functions/manifest.json`, the same 28 entries), extracted from the source tree — a +card with a spec and a manifest entry is labelled `spec+code`, a spec without one `spec-only`, +a manifest entry without a spec `code-only`. + +File name: `.t27` (the canonical id, e.g. `neuro-image-generate.t27`); module name: +`fn_` (`fn_neuro_image_generate`). + +## The ladder + +``` +Specs -> Skills -> Crons -> Agents -> Functions +specs/** specs/skills specs/crons specs/agents specs/functions + what starts what one Inngest run does, step by + a run and when step, and what it touches outside +``` + +A cron-triggered function (`TRIGGER = "cron"`) is also a scheduled job, so five of them are +stated twice: as a cron card in `specs/crons` (`inngest/999-multibots-telegraf/`) +and as a function card here. The site joins the two by `REPO` + `LEGACY_ID` = the cron's +`NAME`; nothing is inferred from a domain or a file name. + +## Schema (every constant is `pub const`) + +| constant | type | meaning | +|-----------------|----------|------------------------------------------------------------------------------------------------------------| +| `KIND` | `str` | always `"function"` | +| `ID` | `str` | canonical id (`--`), equals the file name; must equal `id` in the manifest | +| `LEGACY_ID` | `str` | the id the deployed code still registers (`legacy_id` in the manifest) | +| `NAME` | `str` | display name | +| `REPO` | `str` | `999-multibots-telegraf` | +| `SERVICE` | `str` | `file:line` of `inngest.createFunction(` in that repo | +| `DOMAIN` | `str` | `neuro` \| `reels` \| `training` \| `morph` \| `render` \| `payment` \| `broadcast` \| `instagram` \| `content` \| `monitoring` \| `analytics` \| `webhook` \| `welcome` | +| `TRIGGER` | `str` | `event` \| `cron` | +| `EVENT` | `str` | canonical event name; `""` for a cron function | +| `LEGACY_EVENTS` | `[N]str` | event names the code still listens to (multi-trigger); `[0]str = []` for a cron function | +| `CRON` | `str` | five-field cron expression; `""` for an event function | +| `TZ` | `str` | time zone of `CRON` (`UTC`); carried for event functions too | +| `SUMMARY_EN` | `str` | what one run does (English) | +| `STEPS` | `[N]str` | `step.run` names in source order; `${...}` in a name is a template the code expands per item | +| `RETRIES` | `u8` | `retries` declared on the function; when none is declared, `4` (Inngest JS SDK v3 default) and `NOTE` says so | +| `ON_FAILURE` | `str` | `admin-telegram` (an `onFailure` handler messages the admin chat) \| `log` (no handler) \| `refund+notify` | +| `SIDE_EFFECTS` | `[N]str` | from `charges-balance`, `paid-api`, `messages-user`, `messages-owners`, `messages-admin`, `db-write`, `external-webhook`, `none` | +| `GUARD` | `str` | first step that stops a bad payload (`zod-schema`, `check-user`, `validate-input`, `amount-match`, …); `none` when the first step already acts; `unknown` when the function could not be probed | +| `SAFE_PROBE` | `str` | JSON payload sent in the 2026-09-09 safe probe; `""` when none was sent | +| `PROBE_RESULT` | `str` | `COMPLETED` \| `FAILED-at-guard` \| `skipped` (no probe sent) \| `not-deployed` (function absent from the probed build) | +| `CONTROL` | `str` | `spec+code` \| `spec-only` \| `code-only` — what the author expects the site to find | +| `NOTE` | `str` | anything a reader must know that the fields above cannot say | + +The generator fails the build when: the compiler verdict is not clean; a constant is +missing, not `pub`, or has the wrong annotation / array length / integer range; `KIND` is not +`"function"`; `ID` does not equal the file name; the module name is not `fn_`; `TRIGGER`, +`ON_FAILURE`, `PROBE_RESULT` or `CONTROL` is outside its vocabulary; a `SIDE_EFFECTS` value is +outside the list; an event function has `CRON` or no `EVENT`; a cron function has `EVENT`, +`LEGACY_EVENTS` or no `CRON`; or `SAFE_PROBE` is neither `""` nor JSON. A spec whose +`TRIGGER`, `EVENT`, `CRON`, `RETRIES`, `ON_FAILURE`, `STEPS` or `SIDE_EFFECTS` differ from the +manifest entry with the same `ID` is not a build failure: the difference is written on the +card as a message, and the card's health drops to `warn`. + +## What was read from where (honesty) + +* Source: `999-multibots-telegraf` `main @a9c08b4`. The manifest was extracted from that tree; + where it carries no `file`, no `steps` or `retries: null` (three functions: `training-model-v2-start`, + `payment-ai-server-process`, `broadcast-message-send`, and eight functions with undeclared + `retries`), the spec reads the same checkout directly and says so in `NOTE`. +* `payment-ai-server-process`: the code declares `onFailure: createInngestFailureHandler(...)`, + which logs and messages the admin chat; the manifest says `log`. The spec says + `admin-telegram` and keeps the disagreement in `NOTE`; the site shows it as a message. +* `RETRIES = 4` for undeclared retries is the SDK default, not a declaration. The 2026-09-09 + probe saw such functions reach attempt 5, which is consistent with four retries. +* Four functions are **not on the production Railway build** as of 2026-09-09 + (`training-model-complete`, `training-stuck-check`, `webhook-generation-validate`, + `welcome-avatar-generate`): the deployed app registers 24 base functions, `main` registers + 28. Their `PROBE_RESULT` is `not-deployed`, `GUARD` is `unknown`, and `NOTE` says so. The + site reads the `deployed_2026_09_09` flag from the manifest and shows it on the card. +* Unregistered code in the tree (`test-simple`, `test-simple-message`, `test-advanced-loop`, + `kie-ai-webhook-manual-check`, `voice-training-*`, `webhook-health-check`, + `periodic-webhook-health-check`, the duplicate `morphImages.ts`) has no spec: nothing is + registered silently. +* Live run counts are not in the spec and not in the manifest. The site polls a read-only + status endpoint of the bot; when it is unreachable the card says "status source offline", + and an unknown state is labelled unknown. + +## Language + +Specs are English-only (t27 LANG-EN; `bootstrap/build.rs` fails the build on Cyrillic) and +ASCII-only. Russian `NAME` / `SUMMARY` travel through the contract +`specs/i18n/agents-ru.t27`, whose `SCOPE` names `specs/functions`; the bundle lives in +`gHashTag/trinity` at `apps/website/i18n/agents.ru.json`, keyed by `ID`. + +## Editing + +Edit in `gHashTag/t27` (`specs/functions/.t27`), re-vendor the byte-identical copy into +`gHashTag/trinity` `apps/website/public/t27/files/specs/functions/`, then run +`node scripts/agents-from-specs.mjs` and `npm run check:agents` in `apps/website`. When the +code changes (a rename, a new step, a different `retries`), update the manifest copy and the +spec in the same change; the card shows any distance between the two. diff --git a/specs/functions/analytics-sales-advise.t27 b/specs/functions/analytics-sales-advise.t27 new file mode 100644 index 000000000..03e008d7b --- /dev/null +++ b/specs/functions/analytics-sales-advise.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/analytics-sales-advise.t27 -- function analytics-sales-advise (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=analytics-sales-advise). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/analytics/dailySalesAdvisor.ts#L54 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_analytics_sales_advise; + +pub const KIND : str = "function"; +pub const ID : str = "analytics-sales-advise"; +pub const LEGACY_ID : str = "daily-sales-advisor"; +pub const NAME : str = "Daily sales advisor"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/analytics/dailySalesAdvisor.ts:54"; +pub const DOMAIN : str = "analytics"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "cron"; +pub const EVENT : str = ""; +pub const LEGACY_EVENTS : [0]str = []; +pub const CRON : str = "0 9 * * *"; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Every day at 09:00 UTC loads the bot owners and their payments over the last seven, two and one days and sends each owner a sales report, with a copy to the admin chat."; +; step.run names in source order +pub const STEPS : [5]str = ["load-owners", "load-payments-7d", "load-payments-1d", "load-payments-2d", "report-${ownerId}"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 1; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "log"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [2]str = ["messages-owners", "messages-admin"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "none"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = "{}"; +pub const PROBE_RESULT : str = "COMPLETED"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "The same schedule is stated as a cron card, specs/crons ID inngest/999-multibots-telegraf/daily-sales-advisor. The step name report-${ownerId} is a template expanded once per owner. A manual invoke on 2026-09-09 messaged 13 owners; the hardening list asks this function to honour safe mode."; diff --git a/specs/functions/analytics-skills-detect.t27 b/specs/functions/analytics-skills-detect.t27 new file mode 100644 index 000000000..ba554c9c6 --- /dev/null +++ b/specs/functions/analytics-skills-detect.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/analytics-skills-detect.t27 -- function analytics-skills-detect (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=analytics-skills-detect). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/analytics/skillDetector.ts#L30 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_analytics_skills_detect; + +pub const KIND : str = "function"; +pub const ID : str = "analytics-skills-detect"; +pub const LEGACY_ID : str = "skill-detector"; +pub const NAME : str = "Skill detector"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/analytics/skillDetector.ts:30"; +pub const DOMAIN : str = "analytics"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "cron"; +pub const EVENT : str = ""; +pub const LEGACY_EVENTS : [0]str = []; +pub const CRON : str = "0 10 * * *"; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Every day at 10:00 UTC loads the known skills, detects new service types from recent usage, one detection step per service type, and notifies the admin chat."; +; step.run names in source order +pub const STEPS : [3]str = ["load-existing-skills", "detect-${serviceType}", "notify-admin"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 1; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "log"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [2]str = ["messages-owners", "messages-admin"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "none"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = "{}"; +pub const PROBE_RESULT : str = "COMPLETED"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "The same schedule is stated as a cron card, specs/crons ID inngest/999-multibots-telegraf/skill-detector. The step name detect-${serviceType} is a template expanded once per service type."; diff --git a/specs/functions/broadcast-message-send.t27 b/specs/functions/broadcast-message-send.t27 new file mode 100644 index 000000000..90abdd615 --- /dev/null +++ b/specs/functions/broadcast-message-send.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/broadcast-message-send.t27 -- function broadcast-message-send (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=broadcast-message-send). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/broadcast/broadcastMessage.ts#L22 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_broadcast_message_send; + +pub const KIND : str = "function"; +pub const ID : str = "broadcast-message-send"; +pub const LEGACY_ID : str = "broadcast-message"; +pub const NAME : str = "Broadcast message"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/broadcast/broadcastMessage.ts:22"; +pub const DOMAIN : str = "broadcast"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "event"; +pub const EVENT : str = "broadcast/message.send"; +pub const LEGACY_EVENTS : [1]str = ["broadcast/send-message"]; +pub const CRON : str = ""; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Sends a broadcast to a bot audience: validates the request, checks the sender permissions, fetches the recipients, sends the messages and summarises the delivery results."; +; step.run names in source order +pub const STEPS : [5]str = ["validate-input", "check-permissions", "fetch-users", "send-messages", "analyze-results"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 3; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "log"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [1]str = ["messages-user"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "validate-input"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = "{}"; +pub const PROBE_RESULT : str = "FAILED-at-guard"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "The manifest carries no file, steps or retries for this function (its extractor did not resolve them); SERVICE, STEPS and RETRIES here were read from the same checkout (retries 3). Guard is validate-input. A test_telegram_id in the payload narrows the audience to one recipient."; diff --git a/specs/functions/content-detailed-script-generate.t27 b/specs/functions/content-detailed-script-generate.t27 new file mode 100644 index 000000000..6bf7486be --- /dev/null +++ b/specs/functions/content-detailed-script-generate.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/content-detailed-script-generate.t27 -- function content-detailed-script-generate (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=content-detailed-script-generate). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/content/generateDetailedScript.ts#L191 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_content_detailed_script_generate; + +pub const KIND : str = "function"; +pub const ID : str = "content-detailed-script-generate"; +pub const LEGACY_ID : str = "generate-detailed-script"; +pub const NAME : str = "Generate detailed script"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/content/generateDetailedScript.ts:191"; +pub const DOMAIN : str = "content"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "event"; +pub const EVENT : str = "content/detailed-script.generate"; +pub const LEGACY_EVENTS : [1]str = ["content/generate-detailed-script"]; +pub const CRON : str = ""; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Expands a script into detailed scenes: creates the script record, generates the scene-by-scene text with a language model and stores the detailed script."; +; step.run names in source order +pub const STEPS : [3]str = ["create-script-record", "generate-detailed-scenes", "save-detailed-script"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 4; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "log"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [2]str = ["paid-api", "db-write"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "zod-schema"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = "{}"; +pub const PROBE_RESULT : str = "FAILED-at-guard"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "RETRIES is not declared in the code, so the Inngest JS SDK v3 default of 4 applies. Guard is zod-schema."; diff --git a/specs/functions/content-scenario-clips-generate.t27 b/specs/functions/content-scenario-clips-generate.t27 new file mode 100644 index 000000000..b6f031a56 --- /dev/null +++ b/specs/functions/content-scenario-clips-generate.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/content-scenario-clips-generate.t27 -- function content-scenario-clips-generate (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=content-scenario-clips-generate). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/content/generateScenarioClips.ts#L221 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_content_scenario_clips_generate; + +pub const KIND : str = "function"; +pub const ID : str = "content-scenario-clips-generate"; +pub const LEGACY_ID : str = "generate-scenario-clips"; +pub const NAME : str = "Generate scenario clips"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/content/generateScenarioClips.ts:221"; +pub const DOMAIN : str = "content"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "event"; +pub const EVENT : str = "content/scenario-clips.generate"; +pub const LEGACY_EVENTS : [1]str = ["content/generate-scenario-clips"]; +pub const CRON : str = ""; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Builds a scenario from a script: creates the scenario record, generates the detailed scenes, packs the text reports into an archive and updates the record."; +; step.run names in source order +pub const STEPS : [4]str = ["create-scenario-record", "generate-detailed-scenes", "create-text-reports-archive", "update-scenario-record"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 4; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "log"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [2]str = ["paid-api", "db-write"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "zod-schema"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = "{}"; +pub const PROBE_RESULT : str = "FAILED-at-guard"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "RETRIES is not declared in the code, so the Inngest JS SDK v3 default of 4 applies. Guard is zod-schema."; diff --git a/specs/functions/content-scripts-generate.t27 b/specs/functions/content-scripts-generate.t27 new file mode 100644 index 000000000..66c3064ff --- /dev/null +++ b/specs/functions/content-scripts-generate.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/content-scripts-generate.t27 -- function content-scripts-generate (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=content-scripts-generate). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/content/generateContentScripts.ts#L44 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_content_scripts_generate; + +pub const KIND : str = "function"; +pub const ID : str = "content-scripts-generate"; +pub const LEGACY_ID : str = "generate-content-scripts"; +pub const NAME : str = "Generate content scripts"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/content/generateContentScripts.ts:44"; +pub const DOMAIN : str = "content"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "event"; +pub const EVENT : str = "content/scripts.generate"; +pub const LEGACY_EVENTS : [1]str = ["instagram/generate-scripts"]; +pub const CRON : str = ""; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Writes content scripts from a stored reel: loads the reel, extracts and transcribes the audio, generates the scripts with a language model and stores them."; +; step.run names in source order +pub const STEPS : [5]str = ["get-reel-data", "extract-audio", "transcribe-audio", "generate-scripts", "save-scripts"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 4; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "log"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [2]str = ["paid-api", "db-write"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "zod-schema"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = "{}"; +pub const PROBE_RESULT : str = "FAILED-at-guard"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "RETRIES is not declared in the code, so the Inngest JS SDK v3 default of 4 applies. Guard is zod-schema. The legacy event name keeps the instagram/ prefix the function was first registered under."; diff --git a/specs/functions/instagram-competitors-find.t27 b/specs/functions/instagram-competitors-find.t27 new file mode 100644 index 000000000..258ad96fc --- /dev/null +++ b/specs/functions/instagram-competitors-find.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/instagram-competitors-find.t27 -- function instagram-competitors-find (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=instagram-competitors-find). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/content/findCompetitors.ts#L134 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_instagram_competitors_find; + +pub const KIND : str = "function"; +pub const ID : str = "instagram-competitors-find"; +pub const LEGACY_ID : str = "find-competitors"; +pub const NAME : str = "Find competitors"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/content/findCompetitors.ts:134"; +pub const DOMAIN : str = "instagram"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "event"; +pub const EVENT : str = "instagram/competitors.find"; +pub const LEGACY_EVENTS : [1]str = ["instagram/find-competitors"]; +pub const CRON : str = ""; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Finds Instagram competitors for a project: validates the request and the project, calls the Instagram API, filters by follower count, stores the competitors and notifies the requester in Telegram."; +; step.run names in source order +pub const STEPS : [6]str = ["validate-input", "validate-project", "call-instagram-api", "filter-by-followers", "save-to-competitors-table", "send-telegram-notification"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 4; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "log"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [2]str = ["paid-api", "db-write"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "validate-input"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = "{}"; +pub const PROBE_RESULT : str = "FAILED-at-guard"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "RETRIES is not declared in the code, so the Inngest JS SDK v3 default of 4 applies. Guard is validate-input."; diff --git a/specs/functions/instagram-reels-analyze.t27 b/specs/functions/instagram-reels-analyze.t27 new file mode 100644 index 000000000..6af8dd5e6 --- /dev/null +++ b/specs/functions/instagram-reels-analyze.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/instagram-reels-analyze.t27 -- function instagram-reels-analyze (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=instagram-reels-analyze). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/content/analyzeCompetitorReels.ts#L211 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_instagram_reels_analyze; + +pub const KIND : str = "function"; +pub const ID : str = "instagram-reels-analyze"; +pub const LEGACY_ID : str = "analyze-competitor-reels"; +pub const NAME : str = "Analyze competitor reels"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/content/analyzeCompetitorReels.ts:211"; +pub const DOMAIN : str = "instagram"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "event"; +pub const EVENT : str = "instagram/reels.analyze"; +pub const LEGACY_EVENTS : [1]str = ["instagram/analyze-reels"]; +pub const CRON : str = ""; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Analyzes the recent reels of an Instagram competitor for a project: validates the request and the project, calls the reels API, filters by date, computes the metrics, stores the analysis and notifies the requester in Telegram."; +; step.run names in source order +pub const STEPS : [7]str = ["validate-input", "validate-project", "call-instagram-reels-api", "filter-reels-by-date", "calculate-metrics", "save-to-reels-analysis-table", "send-telegram-notification"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 4; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "log"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [2]str = ["paid-api", "db-write"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "validate-input"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = "{}"; +pub const PROBE_RESULT : str = "FAILED-at-guard"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "RETRIES is not declared in the code, so the Inngest JS SDK v3 default of 4 applies. Guard is validate-input."; diff --git a/specs/functions/instagram-top-content-extract.t27 b/specs/functions/instagram-top-content-extract.t27 new file mode 100644 index 000000000..2cf6e1ce3 --- /dev/null +++ b/specs/functions/instagram-top-content-extract.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/instagram-top-content-extract.t27 -- function instagram-top-content-extract (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=instagram-top-content-extract). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/content/extractTopContent.ts#L33 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_instagram_top_content_extract; + +pub const KIND : str = "function"; +pub const ID : str = "instagram-top-content-extract"; +pub const LEGACY_ID : str = "extract-top-content"; +pub const NAME : str = "Extract top content"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/content/extractTopContent.ts:33"; +pub const DOMAIN : str = "instagram"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "event"; +pub const EVENT : str = "instagram/top-content.extract"; +pub const LEGACY_EVENTS : [1]str = ["instagram/extract-top"]; +pub const CRON : str = ""; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Extracts the top-performing reels already stored for a project: queries the stored reels, processes them and formats the report."; +; step.run names in source order +pub const STEPS : [3]str = ["query-top-reels", "process-reels", "format-report"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 4; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "log"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [2]str = ["paid-api", "db-write"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "zod-schema"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = "{}"; +pub const PROBE_RESULT : str = "FAILED-at-guard"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "RETRIES is not declared in the code, so the Inngest JS SDK v3 default of 4 applies. Guard is zod-schema."; diff --git a/specs/functions/monitoring-error-report.t27 b/specs/functions/monitoring-error-report.t27 new file mode 100644 index 000000000..37eeeb700 --- /dev/null +++ b/specs/functions/monitoring-error-report.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/monitoring-error-report.t27 -- function monitoring-error-report (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=monitoring-error-report). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/monitoring/criticalErrorMonitor.ts#L175 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_monitoring_error_report; + +pub const KIND : str = "function"; +pub const ID : str = "monitoring-error-report"; +pub const LEGACY_ID : str = "critical-error-monitor"; +pub const NAME : str = "Critical error report"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/monitoring/criticalErrorMonitor.ts:175"; +pub const DOMAIN : str = "monitoring"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "event"; +pub const EVENT : str = "monitoring/error.report"; +pub const LEGACY_EVENTS : [1]str = ["app/error.critical"]; +pub const CRON : str = ""; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Reports a critical application error to the admin chat: analyzes the error, formats the message, sends the notification and logs the incident for later analysis."; +; step.run names in source order +pub const STEPS : [4]str = ["analyze-error", "format-message", "send-notification", "log-for-analysis"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 1; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "log"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [1]str = ["messages-admin"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "none"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = "{}"; +pub const PROBE_RESULT : str = "COMPLETED"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "No guard: the event is emitted by the application itself. The hardening list asks the formatter to render string, Error and {message} payloads and never print [object Object]."; diff --git a/specs/functions/monitoring-health-check.t27 b/specs/functions/monitoring-health-check.t27 new file mode 100644 index 000000000..b8e808be9 --- /dev/null +++ b/specs/functions/monitoring-health-check.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/monitoring-health-check.t27 -- function monitoring-health-check (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=monitoring-health-check). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/monitoring/criticalErrorMonitor.ts#L235 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_monitoring_health_check; + +pub const KIND : str = "function"; +pub const ID : str = "monitoring-health-check"; +pub const LEGACY_ID : str = "health-check"; +pub const NAME : str = "Health check"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/monitoring/criticalErrorMonitor.ts:235"; +pub const DOMAIN : str = "monitoring"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "cron"; +pub const EVENT : str = ""; +pub const LEGACY_EVENTS : [0]str = []; +pub const CRON : str = "*/30 * * * *"; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Every 30 minutes checks the API server and the Inngest service and messages the admin chat when either is unhealthy."; +; step.run names in source order +pub const STEPS : [3]str = ["check-api-health", "check-inngest-health", "notify-unhealthy"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 2; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "log"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [1]str = ["messages-admin"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "none"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = "{}"; +pub const PROBE_RESULT : str = "COMPLETED"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "The same schedule is stated as a cron card, specs/crons ID inngest/999-multibots-telegraf/health-check. Lives in the same file as monitoring-error-report."; diff --git a/specs/functions/monitoring-logs-analyze.t27 b/specs/functions/monitoring-logs-analyze.t27 new file mode 100644 index 000000000..9eded6423 --- /dev/null +++ b/specs/functions/monitoring-logs-analyze.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/monitoring-logs-analyze.t27 -- function monitoring-logs-analyze (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=monitoring-logs-analyze). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/monitoring/logMonitor.ts#L352 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_monitoring_logs_analyze; + +pub const KIND : str = "function"; +pub const ID : str = "monitoring-logs-analyze"; +pub const LEGACY_ID : str = "log-monitor"; +pub const NAME : str = "Daily log analysis"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/monitoring/logMonitor.ts:352"; +pub const DOMAIN : str = "monitoring"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "cron"; +pub const EVENT : str = ""; +pub const LEGACY_EVENTS : [0]str = []; +pub const CRON : str = "0 10 * * *"; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Every day at 10:00 UTC reads the application logs, analyzes them for errors and warnings, generates a summary and sends it to the admin chat."; +; step.run names in source order +pub const STEPS : [4]str = ["read-logs", "analyze-logs", "generate-message", "send-notification"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 2; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "log"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [1]str = ["messages-admin"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "none"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = "{}"; +pub const PROBE_RESULT : str = "COMPLETED"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "The same schedule is stated as a cron card, specs/crons ID inngest/999-multibots-telegraf/log-monitor. When LOG_DIR is absent on the host the analysis has nothing to read; the hardening list asks for a fallback to the Inngest run summary."; diff --git a/specs/functions/monitoring-logs-trigger.t27 b/specs/functions/monitoring-logs-trigger.t27 new file mode 100644 index 000000000..b7e650308 --- /dev/null +++ b/specs/functions/monitoring-logs-trigger.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/monitoring-logs-trigger.t27 -- function monitoring-logs-trigger (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=monitoring-logs-trigger). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/monitoring/logMonitor.ts#L408 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_monitoring_logs_trigger; + +pub const KIND : str = "function"; +pub const ID : str = "monitoring-logs-trigger"; +pub const LEGACY_ID : str = "trigger-log-monitor"; +pub const NAME : str = "Log analysis on demand"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/monitoring/logMonitor.ts:408"; +pub const DOMAIN : str = "monitoring"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "event"; +pub const EVENT : str = "monitoring/logs.trigger"; +pub const LEGACY_EVENTS : [1]str = ["logs/monitor.trigger"]; +pub const CRON : str = ""; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Runs the same log analysis as the daily job when asked by an event: reads the logs, analyzes them, generates the summary and sends it to the admin chat."; +; step.run names in source order +pub const STEPS : [4]str = ["read-logs", "analyze-logs", "generate-message", "send-notification"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 1; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "log"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [1]str = ["messages-admin"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "none"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = "{}"; +pub const PROBE_RESULT : str = "COMPLETED"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "Shares its file and its four steps with monitoring-logs-analyze; only the trigger differs."; diff --git a/specs/functions/morph-images-generate.t27 b/specs/functions/morph-images-generate.t27 new file mode 100644 index 000000000..3d3e76cc0 --- /dev/null +++ b/specs/functions/morph-images-generate.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/morph-images-generate.t27 -- function morph-images-generate (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=morph-images-generate). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/training/morphImages.ts#L30 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_morph_images_generate; + +pub const KIND : str = "function"; +pub const ID : str = "morph-images-generate"; +pub const LEGACY_ID : str = "morph-images"; +pub const NAME : str = "Morph images"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/training/morphImages.ts:30"; +pub const DOMAIN : str = "morph"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "event"; +pub const EVENT : str = "morph/images.generate"; +pub const LEGACY_EVENTS : [1]str = ["morph/images.requested"]; +pub const CRON : str = ""; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Morphs a sequence of user images into one video: checks the user and the balance, notifies the start, processes each image pair into a clip, concatenates the clips, cleans up and delivers the result."; +; step.run names in source order +pub const STEPS : [8]str = ["check-user-exists", "check-balance", "notify-start", "process-all-pairs", "process-loop-pair", "concatenate-all-videos", "cleanup-temp-files", "deliver-result"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 3; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "log"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [3]str = ["charges-balance", "paid-api", "messages-user"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "check-user-exists"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = "{\"telegram_id\": \"0\", \"bot_name\": \"e2e_nonexistent_bot\", \"is_ru\": true, \"job_id\": \"e2e-probe\", \"image_files\": [], \"extraction_path\": \"/nonexistent/e2e\", \"morphing_type\": \"seamless\", \"model\": \"kling-v1.6-pro\"}"; +pub const PROBE_RESULT : str = "FAILED-at-guard"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "Guard is check-user-exists. A second, unregistered copy of this function exists in the tree (src/inngest_app/functions/morphImages.ts); the registered one is the file named in SERVICE."; diff --git a/specs/functions/neuro-image-generate.t27 b/specs/functions/neuro-image-generate.t27 new file mode 100644 index 000000000..62abd9e17 --- /dev/null +++ b/specs/functions/neuro-image-generate.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/neuro-image-generate.t27 -- function neuro-image-generate (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=neuro-image-generate). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/neuroImageGeneration.ts#L56 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_neuro_image_generate; + +pub const KIND : str = "function"; +pub const ID : str = "neuro-image-generate"; +pub const LEGACY_ID : str = "neuro-image-generation"; +pub const NAME : str = "Neuro image generation"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/neuroImageGeneration.ts:56"; +pub const DOMAIN : str = "neuro"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "event"; +pub const EVENT : str = "neuro/image.generate"; +pub const LEGACY_EVENTS : [1]str = ["neuro/photo.generate"]; +pub const CRON : str = ""; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Generates one or more images for a Telegram user from a prompt and a model URL: loads the bot and the user, computes the total cost, charges the balance, then generates and sends each image and settles the balance at the end."; +; step.run names in source order +pub const STEPS : [11]str = ["get-bot", "check-user", "get-user-gender", "update-level", "calculate-total-cost", "process-payment", "get-aspect-ratio", "generate-image-${i}", "notify-image-${i}", "deduct-balance-final", "final-notification"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 3; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "admin-telegram"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [4]str = ["charges-balance", "paid-api", "messages-user", "db-write"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "check-user"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = "{\"telegram_id\": \"0\", \"bot_name\": \"e2e_nonexistent_bot\", \"prompt\": \"safe-mode probe\", \"is_ru\": true, \"num_images\": 1, \"model_url\": \"e2e/none\"}"; +pub const PROBE_RESULT : str = "FAILED-at-guard"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "Guard is check-user: an unknown telegram_id stops the run before any payment or paid API call. The step names generate-image-${i} and notify-image-${i} are templates the code expands once per requested image."; diff --git a/specs/functions/payment-ai-server-process.t27 b/specs/functions/payment-ai-server-process.t27 new file mode 100644 index 000000000..4d370143c --- /dev/null +++ b/specs/functions/payment-ai-server-process.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/payment-ai-server-process.t27 -- function payment-ai-server-process (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=payment-ai-server-process). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/payments/paymentProcessing.ts#L64 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_payment_ai_server_process; + +pub const KIND : str = "function"; +pub const ID : str = "payment-ai-server-process"; +pub const LEGACY_ID : str = "payment-processing-ai-server"; +pub const NAME : str = "AI-server payment processing"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/payments/paymentProcessing.ts:64"; +pub const DOMAIN : str = "payment"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "event"; +pub const EVENT : str = "payment/ai-server.process"; +pub const LEGACY_EVENTS : [1]str = ["payment/process-ai-server"]; +pub const CRON : str = ""; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Processes a payment reported by the AI server: matches the amount to a subscription plan or a payment option, loads the user and the bot configuration, updates the user balance and sends the payment notification."; +; step.run names in source order +pub const STEPS : [6]str = ["check-subscription-plan", "check-payment-option", "get-user-info", "get-bot-config", "update-user-balance", "send-notification"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 3; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "admin-telegram"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [2]str = ["db-write", "messages-user"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "amount-match"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = "{\"IncSum\": \"0.01\", \"inv_id\": \"e2e-safe-mode-probe\"}"; +pub const PROBE_RESULT : str = "COMPLETED"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "The manifest carries no file, steps or retries for this function (its extractor did not resolve them); SERVICE, STEPS and RETRIES here were read from the same checkout, where retries is declared as 3 and onFailure is createInngestFailureHandler, which logs and messages the admin chat -- the manifest says on_failure log. Guard is amount-match: an amount matching no plan or option stops the run, which is why the 2026-09-09 probe with IncSum 0.01 COMPLETED without a balance change."; diff --git a/specs/functions/reels-ai-callback.t27 b/specs/functions/reels-ai-callback.t27 new file mode 100644 index 000000000..dbfdcc77c --- /dev/null +++ b/specs/functions/reels-ai-callback.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/reels-ai-callback.t27 -- function reels-ai-callback (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=reels-ai-callback). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/ai-reels-callback.ts#L158 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_reels_ai_callback; + +pub const KIND : str = "function"; +pub const ID : str = "reels-ai-callback"; +pub const LEGACY_ID : str = "ai-reels-callback"; +pub const NAME : str = "AI reels callback"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/ai-reels-callback.ts:158"; +pub const DOMAIN : str = "reels"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "event"; +pub const EVENT : str = "reels/ai.callback"; +pub const LEGACY_EVENTS : [1]str = ["ai-reels-callback"]; +pub const CRON : str = ""; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Handles the provider callback for an AI reel job: extracts the job id, then sends the completed video, a failure message or a processing update to the user who ordered it."; +; step.run names in source order +pub const STEPS : [3]str = ["send-completed-video", "send-failed-message", "send-processing-update"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 3; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "admin-telegram"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [2]str = ["paid-api", "messages-user"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "extract-job-id"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = "{}"; +pub const PROBE_RESULT : str = "FAILED-at-guard"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "Guard is extract-job-id: a payload without a job id fails before anything is sent."; diff --git a/specs/functions/reels-ai-generate.t27 b/specs/functions/reels-ai-generate.t27 new file mode 100644 index 000000000..661e695b1 --- /dev/null +++ b/specs/functions/reels-ai-generate.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/reels-ai-generate.t27 -- function reels-ai-generate (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=reels-ai-generate). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/existing/generateAIReelsFunction.ts#L44 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_reels_ai_generate; + +pub const KIND : str = "function"; +pub const ID : str = "reels-ai-generate"; +pub const LEGACY_ID : str = "ai-reels-generation"; +pub const NAME : str = "AI reels generation"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/existing/generateAIReelsFunction.ts:44"; +pub const DOMAIN : str = "reels"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "event"; +pub const EVENT : str = "reels/ai.generate"; +pub const LEGACY_EVENTS : [1]str = ["ai-reels/generate"]; +pub const CRON : str = ""; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Builds a short AI reel: a lip-sync video from an image and a text or audio track, a second generated clip, the two merged, and the result sent to the user in Telegram."; +; step.run names in source order +pub const STEPS : [4]str = ["generate-lipsync-video", "generate-wan25-video", "merge-videos", "notify-telegram"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 2; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "log"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [2]str = ["paid-api", "messages-user"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "none"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = ""; +pub const PROBE_RESULT : str = "skipped"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "No guard: the first step already calls a paid API, so the 2026-09-09 probe skipped this function (PROBE_RESULT skipped). The hardening list asks for a validate-input step before that call."; diff --git a/specs/functions/reels-loop-generate.t27 b/specs/functions/reels-loop-generate.t27 new file mode 100644 index 000000000..65018282a --- /dev/null +++ b/specs/functions/reels-loop-generate.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/reels-loop-generate.t27 -- function reels-loop-generate (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=reels-loop-generate). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/existing/generateAdvancedLoopingVideoFunction.ts#L77 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_reels_loop_generate; + +pub const KIND : str = "function"; +pub const ID : str = "reels-loop-generate"; +pub const LEGACY_ID : str = "generate-advanced-looping-video"; +pub const NAME : str = "Advanced looping video"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/existing/generateAdvancedLoopingVideoFunction.ts:77"; +pub const DOMAIN : str = "reels"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "event"; +pub const EVENT : str = "reels/loop.generate"; +pub const LEGACY_EVENTS : [1]str = ["reels/generate-advanced-loop"]; +pub const CRON : str = ""; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Turns a set of user images into a looping video: morphing clips between the images, download and concatenation, background music, delivery to the user in Telegram and to the pulse channel, then cleanup."; +; step.run names in source order +pub const STEPS : [7]str = ["generate-morphing-clips", "download-video-clips", "combine-video-clips", "add-music", "send-to-telegram", "send-to-pulse", "cleanup"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 2; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "log"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [2]str = ["paid-api", "messages-user"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "min-images"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = "{\"telegram_id\": \"0\", \"image_urls\": [], \"bot_token\": \"\", \"prompt\": \"safe-mode probe\"}"; +pub const PROBE_RESULT : str = "FAILED-at-guard"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "Guard is min-images: fewer images than the minimum stops the run before any clip is generated."; diff --git a/specs/functions/render-avatar-video-run.t27 b/specs/functions/render-avatar-video-run.t27 new file mode 100644 index 000000000..3df80b738 --- /dev/null +++ b/specs/functions/render-avatar-video-run.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/render-avatar-video-run.t27 -- function render-avatar-video-run (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=render-avatar-video-run). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/render/renderAvatarVideo.ts#L174 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_render_avatar_video_run; + +pub const KIND : str = "function"; +pub const ID : str = "render-avatar-video-run"; +pub const LEGACY_ID : str = "render-avatar-video"; +pub const NAME : str = "Render avatar video"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/render/renderAvatarVideo.ts:174"; +pub const DOMAIN : str = "render"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "event"; +pub const EVENT : str = "render/avatar-video.run"; +pub const LEGACY_EVENTS : [1]str = ["render/avatar-video"]; +pub const CRON : str = ""; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Produces an avatar video: generates the speech audio, runs the avatar generation (Hedra, then HeyGen), transcribes, writes B-roll prompts and generates the B-rolls in parallel, then writes the job settings to S3 and triggers the render."; +; step.run names in source order +pub const STEPS : [13]str = ["create-job", "generate-speech-audio", "start-hedra-generation", "wait-hedra-completion", "start-heygen-generation", "wait-heygen-completion", "generate-transcription", "generate-broll-prompts", "generate-brolls-parallel", "wait-brolls-completion", "create-job-settings", "upload-settings-to-s3", "trigger-render"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 3; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "admin-telegram"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [3]str = ["paid-api", "external-webhook", "db-write"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "zod-schema"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = "{}"; +pub const PROBE_RESULT : str = "FAILED-at-guard"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "Guard is zod-schema. Each wait-* step polls a provider job until it completes."; diff --git a/specs/functions/render-job-run.t27 b/specs/functions/render-job-run.t27 new file mode 100644 index 000000000..e0276ae38 --- /dev/null +++ b/specs/functions/render-job-run.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/render-job-run.t27 -- function render-job-run (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=render-job-run). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/render/render.ts#L38 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_render_job_run; + +pub const KIND : str = "function"; +pub const ID : str = "render-job-run"; +pub const LEGACY_ID : str = "render"; +pub const NAME : str = "Render job"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/render/render.ts:38"; +pub const DOMAIN : str = "render"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "event"; +pub const EVENT : str = "render/job.run"; +pub const LEGACY_EVENTS : [1]str = ["render"]; +pub const CRON : str = ""; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Renders a video job on the render server: creates the job folder, downloads the inputs, renders, uploads the output to S3 and calls the job callback."; +; step.run names in source order +pub const STEPS : [5]str = ["create-job-folder", "download-files", "render", "upload-to-s3", "callback"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 3; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "admin-telegram"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [3]str = ["paid-api", "external-webhook", "db-write"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "zod-schema"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = "{}"; +pub const PROBE_RESULT : str = "FAILED-at-guard"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "Guard is zod-schema: the payload is parsed before any file is downloaded."; diff --git a/specs/functions/render-riddle-run.t27 b/specs/functions/render-riddle-run.t27 new file mode 100644 index 000000000..7ff243e89 --- /dev/null +++ b/specs/functions/render-riddle-run.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/render-riddle-run.t27 -- function render-riddle-run (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=render-riddle-run). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/render/renderRiddle.ts#L59 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_render_riddle_run; + +pub const KIND : str = "function"; +pub const ID : str = "render-riddle-run"; +pub const LEGACY_ID : str = "render-riddle"; +pub const NAME : str = "Render riddle video"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/render/renderRiddle.ts:59"; +pub const DOMAIN : str = "render"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "event"; +pub const EVENT : str = "render/riddle.run"; +pub const LEGACY_EVENTS : [1]str = ["render-riddle"]; +pub const CRON : str = ""; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Produces a riddle video from a template: checks render capacity, loads the template, generates the speech audio and the avatar clips, transcribes, generates one B-roll per scene, prepares the template JSON and triggers the render."; +; step.run names in source order +pub const STEPS : [15]str = ["preflight-render-capacity", "load-template-json", "create-job", "generate-speech-audio", "start-avatar-generation", "wait-avatar-completion", "start-avatar-generation", "wait-avatar-completion", "extract-avatar-speech-url", "generate-transcription", "generate-broll-prompts", "generate-broll-${index}", "wait-broll-${index}", "prepare-template-json", "trigger-render"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 3; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "log"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [3]str = ["paid-api", "external-webhook", "db-write"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "zod-schema"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = "{}"; +pub const PROBE_RESULT : str = "FAILED-at-guard"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "Guard is zod-schema. The step names generate-broll-${index} and wait-broll-${index} are templates expanded once per scene; start-avatar-generation and wait-avatar-completion appear twice in the code and are listed twice here."; diff --git a/specs/functions/training-model-complete.t27 b/specs/functions/training-model-complete.t27 new file mode 100644 index 000000000..2f6e1a47e --- /dev/null +++ b/specs/functions/training-model-complete.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/training-model-complete.t27 -- function training-model-complete (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=training-model-complete). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/existing/handleModelTrainingCompleted.ts#L38 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_training_model_complete; + +pub const KIND : str = "function"; +pub const ID : str = "training-model-complete"; +pub const LEGACY_ID : str = "handle-model-training-completed"; +pub const NAME : str = "Model training completed"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/existing/handleModelTrainingCompleted.ts:38"; +pub const DOMAIN : str = "training"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "event"; +pub const EVENT : str = "training/model.complete"; +pub const LEGACY_EVENTS : [1]str = ["model/training.completed"]; +pub const CRON : str = ""; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Handles the training-completed event from the provider: finds the training record, updates its status and the model list, and sends the user a Telegram notification about the finished or failed training."; +; step.run names in source order +pub const STEPS : [3]str = ["find-training-record", "update-training-status", "send-telegram-notification"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 2; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "admin-telegram"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [4]str = ["charges-balance", "paid-api", "messages-user", "db-write"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "unknown"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = ""; +pub const PROBE_RESULT : str = "not-deployed"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "Not on the production Railway build as of 2026-09-09 (deployed_2026_09_09 false in the manifest): the deployed app registers 24 base functions and this one is not among them. Guard is unknown because the function could not be probed there."; diff --git a/specs/functions/training-model-start.t27 b/specs/functions/training-model-start.t27 new file mode 100644 index 000000000..056fdbd78 --- /dev/null +++ b/specs/functions/training-model-start.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/training-model-start.t27 -- function training-model-start (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=training-model-start). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/existing/generateModelTrainingFunction.ts#L38 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_training_model_start; + +pub const KIND : str = "function"; +pub const ID : str = "training-model-start"; +pub const LEGACY_ID : str = "generate-model-training"; +pub const NAME : str = "Model training start (v1)"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/existing/generateModelTrainingFunction.ts:38"; +pub const DOMAIN : str = "training"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "event"; +pub const EVENT : str = "training/model.start"; +pub const LEGACY_EVENTS : [1]str = ["model/training.start"]; +pub const CRON : str = ""; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Starts a Replicate fine-tune for a user: validates credentials, refuses duplicates, checks the training archive URL, creates the Replicate model and training, records it, and tells the user the training has started."; +; step.run names in source order +pub const STEPS : [8]str = ["validate-credentials", "check-duplicates", "validate-zip-url", "create-replicate-model", "save-pending-record", "create-replicate-training", "update-training-record", "notify-user-started"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 0; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "log"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [4]str = ["charges-balance", "paid-api", "messages-user", "db-write"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "validate-steps"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = "{\"telegram_id\": \"0\", \"bot_name\": \"e2e_nonexistent_bot\", \"steps\": -1, \"zipUrl\": \"\", \"triggerWord\": \"e2e\", \"modelName\": \"e2e\", \"is_ru\": true}"; +pub const PROBE_RESULT : str = "FAILED-at-guard"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "RETRIES is 0 by declaration: a failed start is not retried, because a retry would create a second Replicate training. Guard is validate-steps."; diff --git a/specs/functions/training-model-v2-start.t27 b/specs/functions/training-model-v2-start.t27 new file mode 100644 index 000000000..1611415af --- /dev/null +++ b/specs/functions/training-model-v2-start.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/training-model-v2-start.t27 -- function training-model-v2-start (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=training-model-v2-start). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/training/modelTrainingV2.ts#L45 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_training_model_v2_start; + +pub const KIND : str = "function"; +pub const ID : str = "training-model-v2-start"; +pub const LEGACY_ID : str = "model-training-v2"; +pub const NAME : str = "Model training start (v2)"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/training/modelTrainingV2.ts:45"; +pub const DOMAIN : str = "training"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "event"; +pub const EVENT : str = "training/model-v2.start"; +pub const LEGACY_EVENTS : [1]str = ["model/training.v2.requested"]; +pub const CRON : str = ""; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Starts a v2 fine-tune for a user: checks the user and the balance, encodes the training archive, creates the training on the provider, records it, deducts the balance and notifies the user; on a later failure the balance is refunded."; +; step.run names in source order +pub const STEPS : [11]str = ["check-user-exists", "update-user-level", "get-bot", "check-balance", "encode-zip", "create-training", "save-training-to-db", "notify-user", "deduct-balance", "refund-balance", "handle-error"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 4; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "log"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [4]str = ["charges-balance", "paid-api", "messages-user", "db-write"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "check-user-exists"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = "{\"telegram_id\": \"0\", \"bot_name\": \"e2e_nonexistent_bot\", \"zipUrl\": \"\", \"triggerWord\": \"e2e\", \"modelName\": \"e2e\", \"steps\": 1, \"is_ru\": true, \"gender\": \"male\"}"; +pub const PROBE_RESULT : str = "FAILED-at-guard"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "The manifest carries no file, steps or retries for this function (its extractor did not resolve them); SERVICE, STEPS and RETRIES here were read from the same checkout. RETRIES is not declared in the code, so the Inngest JS SDK v3 default of 4 applies. Guard is check-user-exists."; diff --git a/specs/functions/training-stuck-check.t27 b/specs/functions/training-stuck-check.t27 new file mode 100644 index 000000000..9f403df62 --- /dev/null +++ b/specs/functions/training-stuck-check.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/training-stuck-check.t27 -- function training-stuck-check (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=training-stuck-check). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/training/checkStuckTrainings.ts#L47 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_training_stuck_check; + +pub const KIND : str = "function"; +pub const ID : str = "training-stuck-check"; +pub const LEGACY_ID : str = "check-stuck-trainings"; +pub const NAME : str = "Stuck trainings check"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/training/checkStuckTrainings.ts:47"; +pub const DOMAIN : str = "training"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "cron"; +pub const EVENT : str = ""; +pub const LEGACY_EVENTS : [0]str = []; +pub const CRON : str = "*/30 * * * *"; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Every 30 minutes finds model trainings still marked pending or processing past the stuck threshold, asks Replicate for their real status and emits the completion events that reconcile them."; +; step.run names in source order +pub const STEPS : [3]str = ["find-stuck-trainings", "check-replicate-status", "send-completion-events"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 4; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "admin-telegram"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [4]str = ["charges-balance", "paid-api", "messages-user", "db-write"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "none"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = ""; +pub const PROBE_RESULT : str = "not-deployed"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "Not on the production Railway build as of 2026-09-09 (deployed_2026_09_09 false in the manifest). RETRIES is not declared in the code, so the Inngest JS SDK v3 default of 4 applies. The same schedule is stated as a cron card, specs/crons ID inngest/999-multibots-telegraf/check-stuck-trainings."; diff --git a/specs/functions/webhook-generation-validate.t27 b/specs/functions/webhook-generation-validate.t27 new file mode 100644 index 000000000..b9ebd4204 --- /dev/null +++ b/specs/functions/webhook-generation-validate.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/webhook-generation-validate.t27 -- function webhook-generation-validate (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=webhook-generation-validate). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/webhookHealthGuard.ts#L147 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_webhook_generation_validate; + +pub const KIND : str = "function"; +pub const ID : str = "webhook-generation-validate"; +pub const LEGACY_ID : str = "validate-webhook-before-generation"; +pub const NAME : str = "Webhook validation before generation"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/webhookHealthGuard.ts:147"; +pub const DOMAIN : str = "webhook"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "event"; +pub const EVENT : str = "webhook/generation.validate"; +pub const LEGACY_EVENTS : [1]str = ["video/generation-validate-webhook"]; +pub const CRON : str = ""; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Checks that the video-generation webhook endpoint is reachable before a generation is started and records the result."; +; step.run names in source order +pub const STEPS : [1]str = ["check-webhook-availability"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 1; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "admin-telegram"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [1]str = ["db-write"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "unknown"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = ""; +pub const PROBE_RESULT : str = "not-deployed"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "Not on the production Railway build as of 2026-09-09 (deployed_2026_09_09 false in the manifest). Guard is unknown because the function could not be probed there. Two other functions in the same file (webhook-health-check, periodic-webhook-health-check) are not registered and have no spec."; diff --git a/specs/functions/welcome-avatar-generate.t27 b/specs/functions/welcome-avatar-generate.t27 new file mode 100644 index 000000000..9ead4818d --- /dev/null +++ b/specs/functions/welcome-avatar-generate.t27 @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/functions/welcome-avatar-generate.t27 -- function welcome-avatar-generate (Inngest, 999-multibots-telegraf) +; Source of truth for the function card on t27.ai (#/functions?function=welcome-avatar-generate). +; The registration was read from 999-multibots-telegraf:src/inngest_app/functions/welcomeAvatarGeneration.ts#L108 (main @a9c08b4). +; ID is the canonical id of the spec-first rename; LEGACY_ID and LEGACY_EVENTS are what the +; deployed code still answers to. STEPS lists step.run names in source order; a ${...} in a +; name is a template the code expands per item. Values here are read from the source, not +; inferred from a name; what could not be read says so in NOTE. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module fn_welcome_avatar_generate; + +pub const KIND : str = "function"; +pub const ID : str = "welcome-avatar-generate"; +pub const LEGACY_ID : str = "welcome-avatar-generation"; +pub const NAME : str = "Welcome avatar generation"; +pub const REPO : str = "999-multibots-telegraf"; +; file:line of inngest.createFunction( in the repo named in REPO +pub const SERVICE : str = "src/inngest_app/functions/welcomeAvatarGeneration.ts:108"; +pub const DOMAIN : str = "welcome"; +; "event" or "cron"; an event function has EVENT (+ LEGACY_EVENTS), a cron function has CRON +pub const TRIGGER : str = "event"; +pub const EVENT : str = "welcome/avatar.generate"; +pub const LEGACY_EVENTS : [1]str = ["user/welcome.avatar.generate"]; +pub const CRON : str = ""; +pub const TZ : str = "UTC"; +pub const SUMMARY_EN : str = "Generates a welcome avatar for a new user: validates the bot, selects a hero, reserves a gift slot, generates the image and sends the welcome message."; +; step.run names in source order +pub const STEPS : [5]str = ["validate-bot", "select-hero", "reserve-gift-slot", "generate-image", "send-welcome"]; +; retries declared on the function; when the code declares none, the Inngest JS SDK v3 default (4) is written and NOTE says so +pub const RETRIES : u8 = 2; +; "admin-telegram" (onFailure handler messages the admin chat), "log" (no handler) or "refund+notify" +pub const ON_FAILURE : str = "admin-telegram"; +; what a run touches outside the function, from a fixed vocabulary (see README) +pub const SIDE_EFFECTS : [2]str = ["paid-api", "messages-user"]; +; the first step that stops a bad payload; "none" when the first step already acts, "unknown" when not probed +pub const GUARD : str = "unknown"; +; JSON payload of the 2026-09-09 safe probe and what it reached ("" / "skipped" when none was sent; "not-deployed" when the function is not on the probed build) +pub const SAFE_PROBE : str = ""; +pub const PROBE_RESULT : str = "not-deployed"; +pub const CONTROL : str = "spec+code"; +pub const NOTE : str = "Not on the production Railway build as of 2026-09-09 (deployed_2026_09_09 false in the manifest). Guard is unknown because the function could not be probed there."; diff --git a/specs/i18n/agents-ru.t27 b/specs/i18n/agents-ru.t27 index 8970558e6..1d41dd200 100644 --- a/specs/i18n/agents-ru.t27 +++ b/specs/i18n/agents-ru.t27 @@ -16,7 +16,7 @@ pub const LOCALE : str = "ru"; pub const SOURCE_LOCALE : str = "en"; ; Spec directories whose modules this bundle may translate; an entry ID must ; resolve to a spec in one of them. -pub const SCOPE : [3]str = ["specs/skills", "specs/crons", "specs/agents"]; +pub const SCOPE : [4]str = ["specs/skills", "specs/crons", "specs/agents", "specs/functions"]; ; Spec fields a bundle entry may carry. SUMMARY maps to SUMMARY_EN, NAME to NAME. pub const FIELDS : [2]str = ["SUMMARY", "NAME"]; pub const BUNDLE_REPO : str = "trinity";