Documentation
¶
Overview ¶
Package nodeusagepost posts COMPUTE-NODE-USAGE status — the latest fleet/node readiness, the active worker count, and inbound load — to a Slack "node-usage" channel. It is the OUTBOUND status half of fak's node-usage surface, the twin of internal/scoreboard / internal/benchpost / internal/dispatchpost: a local agent or a CI cadence calls it to publish the current node-usage picture so a human watching #node-usage sees which compute nodes are live and how loaded the fleet is without reading a roster.
The headline signal is the FLEET SNAPSHOT — the exact JSON `fak lab status --json` emits (a fleet.Snapshot). FromSnapshot folds that into one card, so "what is the latest state of compute node usage?" is one command. The ad-hoc --kpi path (in the CLI) carries the other node-usage signals — the active worker count and the open-issue inbound-load proxy — the same way `fak scoreboard post --kpi` does.
This is deliberately NOT the lab control bridge. There is no remote shell, no !send, no transcript readback — just chat.postMessage with a formatted block. It targets the SAME Slack workspace as #scoreboard/#capacity/#product (team T0BDEJF1HGB), so the bot token is shared; only the channel differs. A node-usage post must NEVER fall back to #scoreboard — node-usage status in the number feed would be a cross-channel mistake — so ResolveChannel returns "" when unset and the caller requires an explicit --channel.
Resolution order (token, channel) mirrors the scoreboard/bench/dispatch/bridge .env.slack.local idiom so one gitignored file configures every workspace:
FAK_NODE_USAGE_TOKEN then a FAK_NODE_USAGE_TOKEN= line in .env.slack.local,
then FALLBACK to the scoreboard token (FAK_SCOREBOARD_TOKEN)
so one bot token serves both channels in a shared workspace.
FAK_NODE_USAGE_CHANNEL then a FAK_NODE_USAGE_CHANNEL= line in .env.slack.local.
The channel id is NEVER hard-coded in tracked source (a real id is a gitignored value, per the scrubbing convention) — ResolveChannel returns "" when unset so the caller errors rather than posting to a wrong default.
Transport is reused verbatim from internal/scoreboard (a plain chat.postMessage client, no third-party deps). Only token/channel resolution and the snapshot fold are new here.
Index ¶
Constants ¶
const ChannelDefault = "C0BEFFPCSAU"
ChannelDefault is #node-usage in the scoreboard Slack workspace — the public built-in the node-usage feeder (.github/workflows/node-usage-feed.yml) already documents as its default. Mirrors dojopost/blockerpost/steeringChannelDefault's posture: the channel id is public (it grants nothing without the bot token), only the token is secret. Wiring it here stops the surface resolving to NO channel and silently dry-running (was INCOMPLETE in `fak slack health`, #1428).
Variables ¶
This section is empty.
Functions ¶
func FromSnapshot ¶
func FromSnapshot(snap fleet.Snapshot, source string) scoreboard.Update
FromSnapshot folds a fleet.Snapshot (the node-usage signal) into a scoreboard.Update — the one card shape every Slack feeder posts. It carries the readiness score, the per-state and per-class node counts, and a reporting/visibility line, so #node-usage scans the current compute-node usage at a glance.
HONESTY CONTRACT (why this is not the original conflated card):
- A fleet where every box is SILENT (no report) is a VISIBILITY GAP, not an outage: it reads a neutral card (no grade, no verdict → the :bar_chart: glyph) with the "populate liveness" guidance the human `fak lab status` footer prints — never a red F/ACTION.
- A REAL, OBSERVED problem (a box that reported `down`, or version skew / staleness among reporting boxes) reads ACTION with a clamped grade so it renders red. The grade is clamped because the card renderer picks its glyph from the grade prefix BEFORE the verdict, so an A/B grade would otherwise paint a real down green.
- `unknown` (silent) is never counted as `down` and never escalates on its own.
func ParseSnapshot ¶
ParseSnapshot decodes the JSON `fak lab status --json` emits into a fleet.Snapshot. It is the inverse of the render path: the CLI reads a snapshot file/stdin and folds it into a node-usage card, so the same pure fleet.Snapshot shape is the contract between `fak lab status` and `fak nodeusage post`.
func ResolveChannel ¶
func ResolveChannel() string
ResolveChannel returns the node-usage channel id from FAK_NODE_USAGE_CHANNEL, then a FAK_NODE_USAGE_CHANNEL= line in .env.slack.local. Returns "" if none found so a caller can require an explicit --channel (the real id is never a tracked default) rather than silently posting to #scoreboard.
func ResolveToken ¶
func ResolveToken() string
ResolveToken applies the documented order: FAK_NODE_USAGE_TOKEN env, then a FAK_NODE_USAGE_TOKEN= line in .env.slack.local, then a FALLBACK to the scoreboard token (FAK_SCOREBOARD_TOKEN / its .env.slack.local line). Returns "" if none found.
The fallback is deliberate and matches benchpost/dispatchpost: the node-usage channel lives in the same Slack workspace as #scoreboard, so one bot token serves both. It falls back ONLY to the scoreboard token, never to the lab SLACK_BOT_TOKEN (scoreboard.ResolveToken already refuses that fall-through).
Types ¶
This section is empty.