station-v0.98 adds railcall_session_brief, described as "START HERE, once per
session: one compact snapshot of the whole station — version, frozen?, pending
approvals, schedules health…". Version is the first thing it advertises, and it
is never populated.
vp = os.path.join(os.path.dirname(WS), "workbench", "STATION_VERSION.json")
out["version"] = (json.load(open(vp)) or {}).get("version")
Two independent defects, either of which alone yields None:
- STATION_VERSION.json has no "version" key. Its keys are release_tag,
built_at, mcp_transport, registry_version, engine_commit, core_commit. The
value the brief wants is release_tag.
- The path is derived from the workspace rather than from the module. WS is
`os.environ.get("RAILCALL_WS") or os.path.join(_ENGINE_ROOT,
".railcall_workspace")`, so os.path.dirname(WS) is the station root only when
RAILCALL_WS is unset. The MCP server is normally launched with RAILCALL_WS
pointing at the operator's workspace, and then dirname(WS) is that
workspace's parent — an unrelated directory. The open() raises, the except
sets version to None.
Because both the read and the key are wrong, no configuration makes this field
work. mcp_server already computes the station root correctly elsewhere
(_station_root()), so the module has the right value available.
Reproduction steps:
- Launch with a workspace set, as the MCP server normally runs:
RAILCALL_WS=/tmp/scratch_ws
- Call the brief handler: mcp_server.h_brief(None, {}).
- Inspect the version field, the path the code builds, and the actual keys in
workbench/STATION_VERSION.json.
Expected:
The station's version — station-v0.98 — since it is the first field the tool's
own description promises.
Actual:
version field -> None
brief keys: ['ok','version','frozen','pending_approvals','schedules',
'recent_receipts','savings']
path it reads: /tmp/workbench/STATION_VERSION.json exists: False
real file keys: ['release_tag','built_at','mcp_transport',
'registry_version','engine_commit','core_commit']
The field is present in the response and always null, so a caller told to
"START HERE" for a station snapshot is shown an unknown version rather than an
absent one.
Root cause:
mcp_server.py h_brief() — reads a "version" key that STATION_VERSION.json does
not define, from a path derived as os.path.dirname(WS) rather than from the
module location.
Suggested fix:
vp = os.path.join(_station_root(), "workbench", "STATION_VERSION.json")
doc = json.load(open(vp)) or {}
out["version"] = doc.get("release_tag")
using the existing _station_root() helper, and reading release_tag. If a null
version should be distinguishable from a station that genuinely cannot be read,
omit the key rather than emitting null — the same rule the new listing rows
already apply when they drop null-valued fields.
Honest scope:
Minor and non-security: a display field in a read-only tool is always null. It
executes nothing, exposes nothing, and gates nothing. It is worth reporting
because the tool is new, the field is the first item in its own description, and
the fix is two lines against a helper the module already has. Severity is left
to the maintainer; I would rate it minor.
Counter-evidence checked:
- Confirmed both causes independently: printed the actual keys of the shipped
STATION_VERSION.json (no "version"), and printed the path h_brief builds under
a set RAILCALL_WS (does not exist).
- Confirmed the value is reachable — the file does carry release_tag, and
mcp_server has _station_root() for the path — so this is a wiring error rather
than missing data.
- Ran the real handler from a clean tarball extraction rather than reasoning
from the source alone.
Distinctness:
railcall_session_brief is new in station-v0.98. This is the same class as the
reported CLI setting that is stored and echoed but never read — a value the
product presents as live and never populates — but a different surface, module
and mechanism. I did not find a community thread about railcall_session_brief.