Skip to content

docs(api): daily audit 2026-09-30 — alert detail_url into the rendered on-call spec, RUM issue-detail team_id semantics - #778

Open
flashduty[bot] wants to merge 1 commit into
mainfrom
api-review/20260930T160733Z
Open

flashduty[bot] wants to merge 1 commit into
mainfrom
api-review/20260930T160733Z

Conversation

@flashduty

@flashduty flashduty Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

api-review daily audit — 2026-09-30

--mode generate --scope all --auto.

Registry baseline: fc-pgy @ origin/main 1ab03856; the public row set was compared against the previous round's baseline (api_test.go @ 4f3e98cb, 2026-09-29T08:18Z): 348 Auth == "all" non-/event/push/ rows on both sides — 0 added, 0 removed, 0 auth reclassifications. The registry churn in the window (a02a42ae, 7bf0896d, 7952c342, 4d97318d, …) is entirely /event/push/* integration registration, which is out of public scope.

Operations changed

Module Added Updated Removed
on-call 0 2 schemas (AlertItem, AlertInfo) 0
rum 0 1 operation (usage note) 0
monitors / platform / safari 0 0 0

No path was added or removed, so docs.json and {en,zh}/openapi/api-catalog.mdx are deliberately untouched (the reconcile step only applies when the operation set changes). As a cross-check, the catalog's per-module and total counts still match the specs exactly: On-call 193, Monitors 23, RUM 41, AI SRE 53, Platform 28, total 338.

1. on-call — AlertItem and AlertInfo gain detail_url (2 files × 2 languages)

Source: fc-event structs/alert.go:74-78 —

Images []Image `json:"images"`

// DetailUrl is the console page for this alert. Empty when the deployment
// has no console base configured. It is filled at read time, not stored.
DetailUrl string `json:"detail_url,omitempty"`

POST /alert/info returns this struct. The consolidated specs received the property on 2026-09-29 (4b9015a4), but the per-module split files — the ones Mintlify actually renders — did not, so the docs site documented no detail_url for that endpoint. The property is inserted after images, matching the Go struct order the split files preserve, with the description text copied verbatim from the consolidated file (EN and ZH).

2. rum — POST /rum/issue/info reports the application's current team

fc-rum @ origin/main, cmd/server/controller/issue/info.go:221 (merged 2026-09-29 in PR #230, a190844):

if application != nil {
    item.ApplicationName = application.ApplicationName
    // The issue row keeps the team the application had when the issue was first seen;
    // the detail reports the application's current team, which is who owns it now.
    item.TeamID = application.TeamID
}

Everywhere else the value comes from the issue row (logic/transfer.go:55 IssueTableToItem → row.TeamID), so POST /rum/issue/list and POST /rum/issue/export still report the creation-time team. The shared RumIssueItem.team_id description (“copied from the owning application's team_id at issue creation”) remains accurate for those two operations, so it is left untouched; the divergence is stated as a one-bullet ## Usage / ## 使用说明 section on the detail operation only.

Committed internal drift found while reconciling (one acted on, two reported)

Comparing every schema and operation of each split file against the consolidated file at HEAD turned up three disagreements. Only the first is remediated here.

  1. AlertItem / AlertInfo detail_url — fixed above (split aligned up to the code, since the field exists in fc-event main).
  2. DutyError.reason — present in openapi.{en,zh}.json and monitors.openapi.{en,zh}.json (added 2026-09-06 by d1c68d0e, PR docs(monit): define datasource diagnostic tools and host-only Agent APIs #353, documenting the released POST /monit/datasource/tools/invoke error contract), absent from the on-call / platform / rum / safari splits. Not touched. go-pkg srv/error.go:177 defines exactly code + message in origin/main, and the skill's canonical envelope says “document exactly code and message — nothing else”, so adding it to the other splits would document an undocumented field on four modules; removing it would delete a contract that PR docs(monit): define datasource diagnostic tools and host-only Agent APIs #353 deliberately documented against monit-webapi, which is not on GitHub and therefore unverifiable here. It needs a human decision: either add the field to the envelope contract for every module, or drop it from the two files that carry it.
  3. AI SRE assignee fields on the work-item contract (WorkItemItem.assignees / agent_session_id / agent_session_venue, create/reset assignees, list assignee_type, plus WorkItemAssignee and the 7 work-item examples) — present in the consolidated files only (added 2026-09-23 by a6db6044), absent from the on-call split. Not touched in either direction. The backing commit 7eff20f30 (feat(work-item): let AI SRE be an assignee) is not in fc-event main — git branch -r --contains lists only origin/dev and origin/feat/work-item-ai-sre — and assignee_type never existed in any commit of main. Applying the split-wins rule here would delete documentation for a feature that is still in development; the consolidated copy stays until the backend lands on main (or the docs author reverts it deliberately). No rendered-docs impact either way.

Ruled out this round (window = 2026-09-29T08:18Z → now)

  • fc-event — 3 commits touched handler/struct dirs. 98155f413 fix(change): scope change_key uniqueness to the integration changes the Mongo index and the repeat-event filter in the engine (logic/change/change_event.go, model/change/change_event.go) — no /change/* request or response field, no binding: tag, no enum. 8354dba21 is a Markdown-only change. No public-contract change.
  • fc-event d811d8f4f (PR #2626, merged 2026-09-29 16:28+05:00) — 36 files, of which only logic/change/change.go, structs/change.go, structs/severity.go (+ their tests) are outside the change-source engines and .claude/skills/*. It does move the public change-status vocabulary: structs.ChangeEvent.ChangeStatus goes from binding:"oneof=Planned Ready Processing Canceled Done" to ... Done Failed and structs.ChangeStatusFailed = "Failed" is added (commit 762ec7043, carried into main by this merge), and IsChangeStatusTerminal now treats Failed as ending a change (end_time set) — the stale-event guard from 8318d3e9f is behaviour-only. Already documented — no drift: ChangeItem.change_status and ChangeEventItem.change_status in both the on-call split and the consolidated files already carry ["Planned","Ready","Processing","Canceled","Done","Failed"] (same order as the oneof) with the EN/ZH value tables, added 2026-09-28 in c76e84be. The ChangeEvent ingest struct itself is reached only from the /event/push/* integration handlers; the only public /change operation is POST /change/list, whose response enums are the ones verified above.
  • fc-pgy — every file changed in the window is wallet/billing (platform/wallet is hidden: true), on-prem license mail, structs/i18n.go (email strings), the registry, and new knowledge.*IfVersion permission factors that belong to jwt/button routes (deploy/permission.sql, logic/permission/permission_test.go). No auth == "all" row moved. No public-contract change.
  • fc-rum — ad698c2 (PR docs(comparison): sharpen status page, AI SRE billing, and stakeholder pricing points #234) only prevents a panicking JSON column decode (ApplicationRepositories.JSONColumn / ParseApplicationRepositories); the schema is unchanged. The repositories field itself (PR fix(api-reference): sync merged spec with timezone and grouping window fixes #220) was already documented in main on 2026-09-14 (7e3a424b), and the emitted RumApplicationItem / create / update properties match the Go types — no drift.
  • fc-datasource — 48cc588 swaps the required Slack scope list for data_source.SlackAISREBotScopes() inside VerifyWarRoomPermission; no schema change (scopes do not appear in any spec). The remaining commits register alert-source plugins (/event/push/*, out of scope).
  • fc-oncall, fc-statuspage, go-pkg — 0 commits in the window.

One open question left by that window

structs.SupportChangeStatus — the only exported enumeration of change statuses in fc-event — was deleted in the same window (structs/severity.go). The public read schema structs.ChangeItem.ChangeStatus is a plain string with no binding: tag, so the enum now documented on ChangeItem.change_status / ChangeEventItem.change_status is not tag-derived; its Go source of truth is the ChangeStatus* constants (still present) plus IsChangeStatusTerminal. Nothing in the specs is wrong today, but if the generator ever keys an enum off SupportChangeStatus, the next full regeneration would drop it. Not actionable here — flagging it because this round is the first to regenerate nothing and therefore could not have caught it.

unresolved

  1. POST /channel/incident/daily-counts (channel:read:incidentDailyCounts) — Auth == "all", mapped to on-call/channel, but no handler exists anywhere in fc-event main, and no spec documents it. Left undocumented rather than guessed. Same finding as the previous round (PR docs(api): daily audit 2026-09-29 — RUM remote-config error-session switches, channel filter UTF-8 note #581); it is not in docs.json and is not rendered.
  2. The 9 POST /integration/* rows — public, but no non-hidden module in the skill's mapping.yaml claims the /integration prefix. Still covered by the open PR docs(api): daily audit 2026-09-25 — document the new /integration API family #472; not duplicated here.
  3. Example gaps (report only): three non-GET operations have no requestBody example because they are file uploads — /enrichment/mapping/data/upload, /safari/skill/upload, and /monit/datasource/tools/invoke; the last one also has no JSON 200 example. Every other “missing 200 example” is a CSV/binary export (text/csv, application/octet-stream, application/x-ndjson). The monitors ones cannot be reconciled here: monit-webapi is not on GitHub.

Not duplicated from open PRs

#581 (2026-09-29) already carries the RUM RemoteConfigValues error-session switches and the /channel/* UTF-8 validation note; #472 carries the /integration family; #461 carries the monitors/on-call/safari spec sync. None of them touches AlertItem.detail_url, AlertInfo.detail_url or /rum/issue/info, so this change is additive to all three.

Verification

  • Every output file re-parses under python3 -c "import json; json.load(open(path))".
  • Whole-tree deep compare against HEAD (baseline read from git show HEAD:<path>, never the working tree) over all 12 non-legacy spec files: exactly 12 changed leaf paths, all intended — on-call.{en,zh} /components/schemas/{AlertItem,AlertInfo}/properties/detail_url/{description,type} plus ~, and {rum.openapi,openapi}.{en,zh} /paths//rum/issue/info/post/x-mint/content plus ~. monitors, platform, safari and openapi.legacy.zh.json are byte-identical.
  • Key-order discipline: the comparison is an ordered dump on both sides, so any reordering would surface as extra leaf differences; total diff is 20 insertions / 4 deletions across 6 files. Nothing was resorted.
  • EN/ZH parity: identical path sets (on-call 193, rum 41) and identical schema-property key order in every touched schema; operation counts unchanged (consolidated 338 paths / 728 schemas).
  • The inserted detail_url object is byte-identical (after key sort) between the on-call split and the consolidated file.

Examples

No operation was added and no 200 example was re-captured: the app-key environment variable is not readable from this environment, so dev-API capture was not possible. Nothing in this diff is a machine-fabricated example value — the added detail_url text is copied from the consolidated spec (which itself mirrors the Go doc comment), and the only newly authored prose is the single team_id usage bullet in EN and ZH.

How this diff was produced — please read

The documented pipeline (scripts/generate_openapi.py) still could not be run: it consumes per-module data files at .api-review/modules/*.json, which are gitignored and absent from the repo, and the team knowledge pack's restore procedure (runbooks/api-review-daily.md) together with its baseline-fidelity patch script (runbooks/api-review-apply-patches.py) are both missing — this is the 10th consecutive round blocked this way. Running the generator without those inputs drops committed paths and aborts on guard_no_path_drop(), so it was not run rather than run unsafely.

The edits were therefore applied as a verified minimal diff: before writing, json.dumps(obj, indent=2, ensure_ascii=False) was confirmed to reproduce each target file byte-for-byte (per-file trailing-newline handling included), so no byte outside the two intended changes could move. Script: /opt/scripts/api-review-20260930-patch.py (dry-run by default, --apply to write); the deep compare is /opt/scripts/api-deep-compare-20260930.py. A reviewer who wants this re-derived by the generator should expect the same two properties and the same usage bullet from the same Go sources.

…d on-call spec, RUM issue-detail team_id semantics

Two changes, both derived from the source repos at origin/main.

B. on-call AlertItem / AlertInfo gain `detail_url`.
   fc-event structs/alert.go:74-78 — `DetailUrl string `json:"detail_url,omitempty"``,
   filled at read time, empty when the deployment has no console base. The
   consolidated specs got the field on 2026-09-29 (4b9015a) but the per-module
   split files — the ones Mintlify renders — never did, so POST /alert/info
   documented no detail_url on the docs site.

A. POST /rum/issue/info documents that `team_id` is the application's current team.
   fc-rum cmd/server/controller/issue/info.go:221 `item.TeamID = application.TeamID`
   (PR #230, merge a190844, 2026-09-29). Issue rows keep the team recorded at
   creation (logic/transfer.go:55), which is what list and export still report.

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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants