Skip to content

fix(website): the Functions page could not draw the only broken function - #1124

Open
gHashTag wants to merge 1 commit into
mainfrom
fix/functions-catalog-blind-five
Open

gHashTag wants to merge 1 commit into
mainfrom
fix/functions-catalog-blind-five

Conversation

@gHashTag

Copy link
Copy Markdown
Owner

The site's Functions page drew 28 cards. The deployed app registers 33.

GET /api/inngest/functions/status on the bot answered on 2026-09-22 with 33
functions; apps/website/public/functions/spec-functions.json carried 28. The
set difference is five live-only rows and nothing catalog-only -- a strict
subset, so this change is purely additive.

Those five carry 448 of the week's runs and all five failed runs in the whole
project
. Every one of them belongs to crm-proactive-sweep, the only function
anywhere with failed > 0. Card membership was frozen at build time while the
run counters are polled live, so no amount of polling could make the broken card
appear: the page was structurally incapable of showing the one thing that was
wrong.

function domain cron runs 7d failed
crm-proactive-sweep crm */30 * * * * 337 5
ton-pending-watch money 0 * * * * 94 0
club-invoice-abandoned-watch analytics 20 * * * * 11 0
robokassa-unclaimed-watch money 20 7 * * * 4 0
client-telemetry-daily analytics 0 7 * * * 2 0

Five .t27 function specs and five Inngest cron cards are added, read from the
bot source at 05fd960. The code witness public/functions/manifest.json gains
the five matching rows, copied from the bot's own functions manifest and marked
read_at; deployedApp.mainRegisters moves 28 -> 33 and baseFunctions stays
24, because 24 is still what the 2026-09-09 probe pass measured. The catalogs
were regenerated by running the generator, not edited.

Two spec fields deliberately disagree with the witness and the cards say so:
SIDE_EFFECTS reads messages-owners because the outreach card goes to the
seller who owns the bot rather than the end client, and GUARD reads
safe-mode because all five stop a probe at the same isSafeMode early return.

{
  "version": 1,
  "head_sha": "d807d9619089697b5337bb2b83d28f291b6f8c04",
  "summary": "The site's Functions page drew 28 cards while the deployed app registers 33, and the five it could not draw carried every failed run in the project; five function specs, five Inngest cron cards and five code-witness rows close that gap.",
  "changes": [
    "Adds five .t27 function specs under apps/website/public/t27/files/specs/functions/ for crm-proactive-sweep, ton-pending-watch, robokassa-unclaimed-watch, club-invoice-abandoned-watch and client-telemetry-daily, each read from the bot source at commit 05fd960.",
    "Adds the five matching Inngest cron cards under apps/website/public/t27/files/specs/crons/, which is what joins a cron function to its schedule card; the catalog now reports cron cards joined 10/10.",
    "Extends the code witness apps/website/public/functions/manifest.json with the five rows copied from the bot's own src/inngest_app/functions.manifest.json, each carrying read_at 05fd960, and moves deployedApp.mainRegisters from 28 to 33.",
    "Records the five rows with deployed_2026_09_09 null rather than false or absent: their deployment is unread, because the 2026-09-09 probe pass predates their registration and the live status endpoint answered for all five on 2026-09-22.",
    "Regenerates the catalogs by running scripts/agents-from-specs.mjs through npm run prebuild; no generated file was hand-edited.",
    "Adds ten Russian entries to apps/website/i18n/agents.ru.json so that locale coverage stays complete at functions 33/33 and crons 38/38 instead of dropping to 28/33 and 33/38.",
    "Updates the committed-catalog test in apps/website/scripts/agents-from-specs.test.mjs from 28 specs to 33 and pins the new facts: the five are present, witnessed, joined to a cron card, and their deployment reads null rather than false."
  ],
  "tests": [
    {
      "command": "node apps/website/scripts/agents-from-specs.mjs",
      "result": "Generator ran clean and wrote 33 function specs where it previously wrote 28.",
      "status": "passed",
      "evidence": "agents-from-specs: functions 33 specs (typecheck ok 33/33; spec+code 33, spec-only 0, code-only 0; deployed 24, not deployed 4, unknown 5; with differences from the manifest 5; cron cards joined 10/10)"
    },
    {
      "command": "python3 -c \"import json;print(len(json.load(open('apps/website/public/functions/spec-functions.json'))['functions']))\"",
      "result": "The regenerated catalog carries exactly 33 function cards.",
      "status": "passed",
      "evidence": "33 -- the same command on the base commit e7a11be prints 28"
    },
    {
      "command": "grep -o '\"id\":\"crm-proactive-sweep\"' apps/website/public/functions/spec-functions.json",
      "result": "The one function with failed runs is now in the catalog.",
      "status": "passed",
      "evidence": "\"id\":\"crm-proactive-sweep\" -- its card reads health warn, witness spec+code, cronSpec inngest/999-multibots-telegraf/crm-proactive-sweep"
    },
    {
      "command": "npm run prebuild (apps/website)",
      "result": "The whole prebuild chain ran, including the spec index and the docs, onboarding and viewport generators.",
      "status": "passed",
      "evidence": "agents-from-specs: i18n ru ...: skills 26/27, crons 38/38, agents 27/27, functions 33/33, tools 92/92; onboarding-from-spec: spec tests 9, asserts 49, all hold"
    },
    {
      "command": "npm run test:agents-specs (apps/website)",
      "result": "All forty-six generator tests pass with the updated catalog pins.",
      "status": "passed",
      "evidence": "# tests 46 / # pass 46 / # fail 0"
    },
    {
      "command": "npm run check:crons-catalog (apps/website)",
      "result": "The crons catalog contract holds with the five new cards.",
      "status": "passed",
      "evidence": "Cron catalog: PASS (33 jobs, 8 source lines re-read, 4 kinds)"
    },
    {
      "command": "npm run check:spec-catalog (apps/website)",
      "result": "The central spec catalog contract still holds.",
      "status": "passed",
      "evidence": "Central spec catalog: PASS (1419 exact source links, identity, SHA pinning, fail-closed paths, embedded Explorer, compiler pinned at ?v=bb39b9a5ca412a26)"
    },
    {
      "command": "npm run check:queen-spec-mirrors (apps/website)",
      "result": "Spec mirror provenance is unchanged by this pass.",
      "status": "passed",
      "evidence": "Spec mirrors: PASS (1419 canonical specs, 1419 source placements and exact two-way provenance links)"
    },
    {
      "command": "npm run check:agents (apps/website)",
      "result": "Fails on three assertions about the Queen's module list, all of which fail identically on an untouched checkout of the base commit.",
      "status": "failed",
      "evidence": "module 'passport' is in none of the index's three groups (qa/agents-spec-contract.mjs:417). Reproduced on a pristine worktree of e7a11be after a clean prebuild; with 417 and 528 neutralised both trees stop at the same third assertion, line 531. Every assertion about functions, crons, the manifest and the secrecy scan (lines 1-410) passes on this branch."
    },
    {
      "command": "npm run typecheck (apps/website)",
      "result": "The error count is identical before and after this change.",
      "status": "failed",
      "evidence": "changed=179 base=179 errors, all in src/utils/cosmos.ts, src/utils/neuro.ts and other files this branch does not touch."
    },
    {
      "command": "npm run build (apps/website)",
      "result": "The site builds from the regenerated catalogs.",
      "status": "passed",
      "evidence": "vite v7 built in 1m 7s; dist/assets/QueenComb-Cu6WrTs4.js 1,161.81 kB"
    }
  ],
  "limitations": [
    "The five new specs are not yet in the vendored spec corpus: apps/website/public/t27/manifest.json is synced from gHashTag/t27@master by scripts/sync-t27-specs.mjs, so the ten new cards read inSpecCorpus false and the next sync could remove them. The follow-up is to land the same ten files in gHashTag/t27 and re-vendor.",
    "The five new cron cards read witness spec-only, because apps/website/public/crons/manifest.json is produced by scripts/sync-crons.mjs from on-disk checkouts including a private one, which cannot be run from here. The follow-up is to re-run that sync so the five jobs gain a code witness.",
    "apps/website/public/functions/manifest.json remains hand-maintained: no script produces it, as its own generatedFrom note has said since 2026-09-09. It is left correct and consistent with the contract at qa/agents-spec-contract.mjs:272-274 and 339-340, and the follow-up is a sync script that reads the bot's own src/inngest_app/functions.manifest.json the way sync-crons.mjs reads its sources.",
    "The 28 older manifest rows are still pinned at bot commit a9c08b4 and have drifted from 05fd960 in roughly forty fields, most of them on_failure log where the bot now says admin-telegram. Re-pinning them would touch about 28 existing specs and is deliberately a separate pass; generatedFrom.addendum records both pins.",
    "No probe was sent to the five new functions, so each carries SAFE_PROBE empty and PROBE_RESULT skipped rather than a probe result this branch did not measure.",
    "The live status endpoint's lastError carries only runId, endedAt and eventName; no spec field promises error text, because the upstream GraphQL query at src/inngest_app/status/inngestGraphql.ts:107 never asks for a message.",
    "These catalog assertions do not run on a pull request: check:agents is not in the required checks workflow and npx vite build bypasses npm's prebuild hook, so they run only in the nightly t27-world-scan workflow. Every command above was therefore run locally and its output is quoted here.",
    "No tracking issue exists for this work, so the commit carries no Closes reference rather than an invented one."
  ],
  "tags": [
    "inngest",
    "catalog",
    "observability",
    "specfirst",
    "trinity"
  ],
  "blog": {
    "title": "The page that could not show the one thing that was broken",
    "summary": "A catalog whose membership is frozen at build time while its numbers are polled live cannot ever display a card that was added after the build. Five Inngest functions, one of them the only failing function in the whole project, were invisible for exactly that reason.",
    "outline": [
      "The measurement first: the deployed app's status endpoint answered on 2026-09-22 with 33 registered functions, while the site's build-time catalog carried 28, and the difference was a strict subset with nothing on the site's side.",
      "Those five missing functions carried 448 of the week's runs and all five failed runs in the entire project, every one of them belonging to crm-proactive-sweep, the only function anywhere with a non-zero failure count.",
      "The shape of the defect matters more than its size: card membership was decided at build time while the run counters were polled live, so no amount of polling could ever make the broken card appear.",
      "Three of the five are payment-adjacent, watching for money that arrived at a provider or on a chain and was never credited to the person who sent it, which is the last work anyone would want invisible.",
      "The fix is spec-first and purely additive: five .t27 function specs, five Inngest cron cards to join the schedules, and five rows in the hand-maintained code witness the generator compares each spec against.",
      "Nothing generated was edited by hand; the catalogs were rebuilt by running the generator through prebuild, which is the only way a change to a generated artifact can be said to have a source.",
      "Deployment is recorded as unread rather than false, because the deployment reading in the witness comes from a probe pass that predates these five registrations, and a stale false would have printed as a live claim.",
      "Two fields deliberately disagree with the upstream witness and say so on the card: the outreach card goes to the seller who owns the bot rather than the end client, and all five stop a probe at the same safe-mode early return.",
      "The catalog vocabulary has no db-read, so rather than inventing a value or pretending the read does not happen, each card drops it from the effect list and states the read in its own note.",
      "The gates that would have caught this absence exist, but none of them runs on a pull request: the contract is not in the required workflow and the build command bypasses the prebuild hook that regenerates the catalogs."
    ]
  }
}

The live status endpoint of 999-multibots-telegraf answered on 2026-09-22
with 33 registered functions. The site's build-time catalog carried 28.
The difference is a strict subset -- five live-only rows, nothing catalog-
only -- and those five carry 448 of the week's runs and all five failed
runs in the entire project. crm-proactive-sweep is the only function
anywhere with failed > 0, and it was not in the catalog at all.

Card membership is decided at build time while the run counters are
polled live, so no amount of polling could make the broken card appear:
the page was structurally incapable of showing the one thing that was
wrong. That is what this changes.

Five function specs and five Inngest cron cards are added, read from the
bot at 05fd960 (crmProactiveSweep.ts:101, tonPendingWatch.ts:51,
robokassaUnclaimedWatch.ts:44, clubInvoiceAbandonedWatch.ts:22,
clientTelemetryDaily.ts:62). The code witness public/functions/manifest.json
gains the five matching rows, copied from the bot's own functions manifest
and marked read_at 05fd960; mainRegisters goes 28 -> 33.

Their deployment is recorded as unread (deployed_2026_09_09 null), not
false. The false three of them still carry upstream is the 2026-09-09
probe pass, which predates their registration -- and the live endpoint
answered for all five. baseFunctions stays 24 because 24 is still what
that pass measured.

Two spec fields deliberately disagree with the manifest and say so on the
card: the outreach card of crm-proactive-sweep goes to the seller who owns
the bot, not to the end client, so SIDE_EFFECTS reads messages-owners and
not messages-user; and all five stop a probe at the same isSafeMode early
return, so GUARD reads safe-mode where the manifest recorded none. The
manifest's db-read is dropped because the catalog vocabulary has no such
value; each card states the read in NOTE instead.

The catalogs are regenerated by scripts/agents-from-specs.mjs, not edited.
@github-actions github-actions Bot added the status:in-progress 🔵 Agent working label Sep 22, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status:in-progress 🔵 Agent working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant