Skip to content

FTN Transport with barons-ftn

barons-ftn is the boundary between Immortal Barons and an FTN mail system. The game reads and writes its own private packet directories. The helper wraps those packets for transport, chooses the next hop, and unwraps them after a mailer session. Neither side has to pretend that a BBS inbound or a BinkP outbox is an ordinary game directory.

This guide covers the operational details. For league concepts, roster HOST lines, and packet authentication, begin with Inter-BBS Leagues. The exact ZIP manifest and game-packet fields are in the developer packet-format reference.

The layers and their directories

There are three independent formats:

  1. A game packet is one signed JSON .brp document. Its contents name its author, final destination, sequence, league, and operations.
  2. A transport bundle is a ZIP file containing one or more unchanged game packets and transport-only routing metadata. Its temporary FTN name has the form NNNNCCCC.BRP.
  3. A stored-message envelope is an optional .msg file telling a tosser to send one transport bundle as a file attach. Obox and direct BSO links do not create this envelope.

The same .BRP extension on the first two is intentional, but every file the new helper publishes onto FTN is a ZIP transport bundle, never a raw game packet. Its 8.3 physical name is only an alias. Packet ZIP members use the canonical IB filename derived from their contents, and -in derives that name again rather than trusting any external filename. As a receive-only migration aid, -in can still recognize a raw JSON packet produced by an older helper.

Keep each owner in its own directory:

Directory Owner Healthy contents
bbs.cfg Inbound Immortal Barons Unwrapped JSON packets waiting for -planetary
bbs.cfg Outbound Immortal Barons Complete JSON packets waiting for -out
data/ftn-spool barons-ftn Usually empty; journals appear while a handoff is incomplete
ftn.cfg AttachDir (default data/att) connector/tosser NNNNCCCC.BRP bundles waiting to be sent
ftn.cfg NetmailDir connector/tosser Outgoing game-owned .msg envelopes
ftn.cfg InboundDir mailer/connector Newly received bundles waiting for -in
an obox connector/mailer Bundles queued for the peer owning that outbox
a BSO directory tosser/mailer/connector .?lo, .?ut, .bsy, and point subdirectories

Do not point bbs.cfg Inbound or Outbound directly at a BBS inbound, filebox, obox, or BSO directory. The separation is what prevents the game, helper, and mailer from reading or deleting the same file concurrently.

Commands and safe event order

The helper has two modes:

barons-ftn -in  -data /srv/ib/data
barons-ftn -out -data /srv/ib/data

With neither mode, -out is used for compatibility with old scheduled commands. Supplying both is an error. -data defaults to ./data, relative to the process's working directory. It can be omitted only when the BBS scheduler starts the command in the Immortal Barons installation directory.

The complete exchange order is:

  1. Let the mailer finish its inbound session.
  2. Run barons-ftn -in to validate and unwrap received bundles.
  3. Run immortal-barons -planetary to apply local game packets and create new replies, scores, and broadcasts.
  4. Run barons-ftn -out to claim and bundle that fixed outbound snapshot.
  5. Run the tosser when using .msg attach links, then let the mailer send its obox or BSO queues.

For an hourly Unix event:

/opt/ib/barons-ftn -in  -data /srv/ib/data
/opt/ib/immortal-barons -planetary -data /srv/ib/data
/opt/ib/barons-ftn -out -data /srv/ib/data
/opt/bbs/bin/sbbsecho
/opt/bbs/bin/binkp-poll

There is no FTN-wide inbound semaphore. Run -in from a mailer post-session event or after the receive command returns. The helper validates a complete ZIP and all member digests before publishing anything, but that validation cannot prove that an unrelated mailer is no longer writing the source file.

Scheduling it safely

The sequence above is the whole of it, but a scheduled run wants two things around it. This shape comes from a Synchronet board running the transport in a league:

#!/bin/bash
set -euo pipefail

# One run at a time. A second invocation while this one is working exits
# rather than queueing, since there is no FTN-wide inbound semaphore.
exec 9>/sbbs/xtrn/imb/data/planetary-run.lock
flock -n 9 || exit 0

# Keep the output. Stall reports are written for a run nobody watched.
exec >>/sbbs/xtrn/imb/data/planetary.log 2>&1
echo "=== $(date --iso-8601=seconds) ==="

cd /sbbs/xtrn/imb
./barons-ftn -in
./immortal-barons -planetary
./barons-ftn -out
/sbbs/exec/sbbsecho /sbbs/ctrl/sbbsecho.ini
/sbbs/exec/jsexec -c/sbbs/ctrl /sbbs/exec/binkit.js

flock -n keeps an overlapping run from starting. A scheduler that fires hourly will one day fire while a slow run is still going, and the lock turns that collision into a clean exit rather than two processes competing for the same spools.

The log matters more than it looks. -out names the peers a snapshot is still waiting on and how long they have been behind, and a scheduled run has nowhere to print that unless the output is kept, so the report is written for nobody. Redirecting to a file is what makes it worth having.

cd into the installation directory. -data can then be left off, since it defaults to ./data.

set -e has a consequence worth choosing on purpose. A non-zero exit from -in stops the script, so -out and the mailer never run, and outbound mail stops with them. That may well be right: an outbound snapshot built on a failed inbound is worth skipping. It is still a decision rather than a default to inherit unread. Recoverable problems are reported as warnings and exit 0, so only a real failure trips it.

ftn.cfg reference

ftn.cfg lives in the directory selected by -data. Keywords ignore case. Unknown keywords are ignored for forward compatibility. Relative filesystem paths are resolved beneath the data directory.

Inbound settings

InboundDir     /var/spool/binkp/inbound
OboxMeshFanout Yes
  • InboundDir is required by -in and names received attachments and raw obox/BSO bundles. Give it once per directory the mailer delivers into. Several mailers use more than one: a session that authenticates with a password and one that does not are filed apart, and the directory you leave out is read by nothing. ENiGMA½ is the clear case — secInbound for an authenticated session, inbound for the rest:
InboundDir /enigma/mail/ftn_secin
InboundDir /enigma/mail/ftn_in

Mystic files an unauthenticated session into an unsecure child of its inbound. That child needs its own line too: -in reads each named directory and does not descend into it. -status names any packet left unread in a directory it can see, including such a child, so the report tells you a line is missing. - InboundNetmailDir names received .msg envelopes. Left unset it means every InboundDir, so the order of those lines cannot decide whether an envelope is seen. Set it only to look somewhere else entirely. - OboxMeshFanout defaults to Yes. It controls only an unaddressed broadcast received without an attach envelope. See Mesh warning.

Stored-message attach settings

NetmailDir /sbbs/fido/netmail
AttachDir  /sbbs/fido/ib-attach
Binkley    Yes
SubjectPath Absolute
  • NetmailDir is where outgoing .msg envelopes are created. It is required when any peer uses Attach, including the compatibility default.
  • AttachDir holds outgoing bundles for Attach and BSO links. If omitted, the helper uses data/att (#231: deliberately not nested under the transport's other spool directories, since this is the one path a mailer's Subject field has to spell out under a hard byte limit — see Keeping attach subjects short).
  • Binkley Yes prefixes an attach subject with ^; No writes FLAGS KFS. Both request deletion of the attachment after a successful send.
  • SubjectPath Absolute writes the full attachment path. Basename writes only NNNNCCCC.BRP. Any other value is used as a literal path prefix. The stored-message Subject has 71 usable bytes, or 70 with the ^ prefix.

On the receiving side, the tosser normally leaves both the bundle and its stored-message envelope in the configured inbound. barons-ftn -in verifies that the message has the file-attach attribute, identifies Immortal Barons, names exactly one attachment inside InboundDir, comes from a roster address, and is addressed to this board. Only after all packets are delivered or forwarded does it delete both files. Other netmail is never removed.

Keeping attach subjects short

The IB installation and data directories may be arbitrarily deep if AttachDir is a short absolute path. For example:

AttachDir /var/spool/ib-attach
SubjectPath Absolute

This writes a Subject such as /var/spool/ib-attach/7PRK0001.BRP; the installation path is not included. A relative AttachDir is resolved beneath the data directory and therefore does not provide this workaround. Create the attachment directory with ownership and permissions that allow both barons-ftn and the mailer to use it.

Do not use /tmp or another automatically cleaned directory for this purpose. An attachment may remain queued across a reboot or cleanup interval, and removing it leaves the mailer with a dangling .msg envelope. Use a short, persistent spool directory instead.

SubjectPath Basename shortens the Subject further, to only 7PRK0001.BRP, but it is correct only when the mailer is independently configured to search the same directory named by AttachDir. barons-ftn cannot infer or configure that mailer search path, and not every mailer has one to configure — SBBSecho does not: it takes the directory straight from the Subject with no attachment search path at all, so a bare filename is looked for in its ctrl directory and reported not found. Basename is not a usable option on SBBSecho for this reason; use AttachDir (or an absolute SubjectPath prefix naming the same directory) instead. BSO flow files and oboxes do not use a Type-2 Subject, so the 71-byte limit applies only to Attach links.

Each Link identifies a directly connected IBBS roster node:

Link 2 Attach
Link 3 Obox /var/spool/binkp/outbox/node3
Link 4 BSO /var/spool/ftn/outbound.309 Hold

The modes are:

  • Attach creates a game-owned .msg in NetmailDir addressed to that next hop. It takes no per-link directory. It is the compatibility default, and it is the weakest of the three: a tosser stands between the helper and the mailer, and the Subject limit above is its alone. Prefer BSO where the mailer keeps a Binkley-style outbound.
  • Obox atomically publishes the bundle in the named peer-specific directory. The mailer must treat a final-name appearance as a complete file.
  • BSO takes the destination's .bsy, then either merges into a compatible Barons bundle already named by that flavour's flow file or publishes a new bundle in AttachDir and adds a delete-after-send flow entry. The directory must be the exact root for that address's zone; barons-ftn does not guess domain-to-zone mappings.

A link mode has to be one the peer can receive. It describes a handoff between two boards, so the mode you send with is only half of it:

  • Attach requires the receiving board's mail system to leave the .msg envelope as a file where barons-ftn -in can read it — its InboundNetmailDir, which unset means every InboundDir. Synchronet with SBBSecho does that. Mystic does not: it tosses netmail into its own message bases and leaves no .msg file behind, so a Mystic board can never claim an attach. Reach a Mystic peer with Obox or BSO.
  • Obox and BSO need nothing of the receiver but its mailer, since the bundle arrives as an ordinary file in the inbound.

A board sent an attach it cannot claim does not refuse it. The bundle stays in its inbound and is skipped on every run, with no warning on either side, while the sender's own logs report a clean handoff. Since a peer with no Link line of its own uses Attach, an ftn.cfg carrying no links at all cannot reach a Mystic board — which is how this was found on a three-board test rig, after 30 bundles had collected.

BSO flavours are Immediate, Continuous (also accepted as Crash), Direct, Normal, and Hold; Normal is the default. A point address uses the standard <net><node>.pnt/<point>.?lo layout automatically.

If a destination has no Link, it uses Attach. Thus an old ftn.cfg with no transport links continues to send every next hop through the existing .msg chain. This fallback applies to addressed routing. Once any Link is present, unaddressed mesh fanout uses only the explicitly listed peers; otherwise the helper would invent graph edges and defeat a ring or partial mesh. List every direct fanout neighbour, including one that uses Attach. A hub may freely mix all three modes.

Paths in a Link line must not contain spaces. NetmailDir, AttachDir, and the inbound directory settings consume the rest of their line and may contain spaces when the operating system permits them.

Plain packets for boards that cannot read a bundle

A board runs raw by default, and that is deliberate for this release. A peer that cannot unwrap a bundle does not merely fail to read it — its inbound run stops on the first one it meets and applies nothing at all until someone removes the file by hand. So a sysop who upgrades and configures nothing keeps sending what every board already understands, and has to ask for the faster shape rather than arrive at it.

The test is whether the peer runs barons-ftn -in, not what release it is on. barons-ftn is the only thing that makes or unwraps a bundle; the game never touches one. A board that reads .brp files straight out of its mailer's directory — the file-drop arrangement described under Optional FTN handoff — cannot unwrap a bundle however new its game is, and needs an ftn.cfg and a scheduled -in before anyone sends it one. A board on a release older than the bundled transport cannot either.

Turn bundling on for the whole board once every peer can unwrap one:

Bundled Yes

Or per peer, when a league is part way through upgrading. Add Raw or Bundled to the end of any link line; it overrides the board-wide setting for that peer only:

Bundled Yes
Link 3 Obox /home/bbs/filebox/peer Raw

Raw is a modifier rather than a mode of its own, because the envelope is what an old board cannot parse, not the way the file travels: it composes with attach, obox and BSO alike, and on a BSO link it is never merged into a bundle already advertised in the flow file.

Raw costs one attachment alias per packet, gives up coalescing, and carries no routing manifest — a receiver rebuilds the route from the packet's own origin and learns nothing about which peers a broadcast already reached, bounded by the hop limit and by replay detection instead. That is exactly how the transport behaved before bundles existed, and it is the price of reaching a board that cannot read one.

On a routed league only the Coordinator has to do anything. Every member sends it plain packets already, and its -in reads those whatever they are. It is the Coordinator's own sends that need Raw, and it can drop the setting for one member at a time as each upgrades, or switch the whole board to Bundled Yes once the last one is done.

Configuration examples

Two boards using direct oboxes

On node 1:

InboundDir /mystic/echomail/in
Link 2 Obox /mystic/filebox/ib_z99n1n2

On node 2, reverse the peer and directory:

InboundDir /mystic/echomail/in
Link 1 Obox /mystic/filebox/ib_z99n1n1

The game itself uses private paths:

Inbound  inbound
Outbound outbound

The roster makes node 1 the hub:

1 HOST 2 3 4
Hub BBS
777:10/1
...

The hub can use a different local handoff for every child:

InboundDir /srv/ftn/inbound
NetmailDir /sbbs/fido/netmail
AttachDir /srv/ib/attach
Binkley Yes

Link 2 Attach
Link 3 Obox /srv/binkd/obox/node3
Link 4 BSO /srv/binkd/outbound Normal

A packet from node 2 to node 4 arrives inside node 2's attach. Hub -in unwraps it, leaves its signed JSON bytes untouched, and publishes a new transport bundle through node 4's BSO flow. It does not wait for the hub's next planetary run.

Synchronet

BinkIT keeps a Binkley-style outbound, so a Synchronet board should hand the bundle to that outbound directly:

InboundDir /sbbs/fido/inbound
Link 1 BSO /sbbs/fido/outbound Normal

The outbound chain is:

barons-ftn -out -> NNNNCCCC.BRP + .flo entry -> BinkIT

SBBSecho is not in that path. The Subject byte limit does not apply either, because a flow file holds the whole pathname, so AttachDir can stay at its default.

Name the outbound directory for the destination's zone. Synchronet writes the system's own zone into the base directory and every other zone into outbound.<zone in hex>. See Direct BSO/FLO handoff for what the helper writes there.

Direct BSO/FLO handoff

InboundDir /var/spool/binkd/in
AttachDir /var/spool/ib/attach
Link 3 BSO /var/spool/binkd/outbound Normal

For peer 1:229/300, the helper uses 00e5012c.bsy and 00e5012c.flo in the configured BSO directory. The flow line begins with ^ and contains the full attachment pathname, asking the mailer to delete it after success.

While it owns 00e5012c.bsy, a later run may add its new snapshot to an existing compatible Barons bundle referenced by that flow file. It atomically replaces the ZIP wrapper at the same pathname; every signed packet member is copied byte-for-byte. Exact-member deduplication makes a replay after a crash idempotent. Entries without ^, files outside AttachDir, non-Barons files, other leagues or transmitters, and full bundles are not modified.

For point 1:229/300.4, the paths are:

00e5012c.pnt/00000004.bsy
00e5012c.pnt/00000004.flo

If .bsy already exists, that peer is normally reported busy and its durable spool transaction remains pending. The invocation does not poll or sleep: other peers continue, and the next scheduled -in or -out resumes pending transactions before claiming new work. The narrowly scoped exception is an old semaphore carrying barons-ftn's own PID marker; recovery is described below.

Bundling, names, and recovery

Every -out run takes one fixed snapshot under the same game.lock used by Immortal Barons. Packets written after that claim wait for the next run. All packets in the snapshot which share a next hop go into one ZIP bundle.

The FTN alias is NNNNCCCC.BRP:

  • NNNN is a four-character base-36 namespace derived from this league and the transmitting hop's node number. The encoding reserves a distinct namespace for legacy league-0 packets so one such packet cannot wedge a transport batch; that compatibility namespace is not a substitute for the Coordinator-assigned league number.
  • CCCC is a persistent four-character base-36 counter.
  • The counter advances for every physical handoff, including each broadcast copy, and does not reset with a new game season.

The counter is reserved before publication, so a crash may skip a value but cannot reuse it. Wrap is reported loudly. An existing alias is never overwritten; the allocator advances until it finds a free one.

Attach and obox bundles are immutable after publication. Obox reuse may be possible with a particular mailer's documented claim/rename protocol, but no common obox lock is assumed here; it remains disabled pending interoperability and race testing.

BSO is the exception. FTS-5005 gives the destination one .bsy covering its outbound files. After acquiring that semaphore, barons-ftn may safely rebuild a compatible bundle already advertised in the selected flow file. It releases .bsy only after the replacement is durable.

FTS-5005 permits a .bsy to contain one line of PID information. A semaphore created here contains barons-ftn pid=<number>, and the process also locks its first-byte range on Windows, or takes a whole-file flock on Unix, for the complete BSO update. A later helper removes that semaphore as stale only when all three checks agree: the marker is exactly ours, the ownership lock can be acquired non-blockingly, and the file is at least five minutes old. It then retries the standard exclusive .bsy creation. Thus a live helper remains protected even if its semaphore's timestamp is old, while a crash becomes recoverable without guessing from age alone.

An empty, malformed, young, locked, or foreign-marked .bsy is simply busy. barons-ftn never applies its five-minute policy to a mailer or tosser's semaphore; the mailer's own FTS-5005 age/restart mechanism remains responsible for those. A legacy empty semaphore left by an older barons-ftn is likewise indistinguishable and follows the mailer's policy. Never manually clear .bsy files merely because a peer is slow or offline.

Progress journals live under data/ftn-spool; the claimed bundle itself is written to AttachDir (default data/att) or to the peer's obox. A target is marked complete only after its bundle and .msg, obox placement, or BSO flow entry are durable. A restart uses the same alias and bytes, recognizes an already-created attach message, and completes only unfinished targets.

Inbound rejection is per packet member, not per bundle. A wrong-league packet, unknown destination, or routing cycle is recorded in the receipt while valid members are still delivered or forwarded. After those valid members finish, the complete original transport wrapper moves to ftn-spool/bad so the rejected routing context remains available for diagnosis; it is not retried on every later -in run. A local canonical-name collision is different: the receipt and source stay pending because the operator must decide which bytes are valid.

All barons-ftn processes—both directions—hold barons-ftn.lock. Movement between the connector spool and the private game directories also holds game.lock. The lock order is always connector first, game second. Atomic renames and exclusive file creation remain additional protections.

On local delivery, an existing canonical filename with identical bytes is logged as a duplicate, not rewritten, and not counted as a new delivery. If that canonical name already belongs to different bytes, the helper reports a collision and retains its receipt and source rather than overwriting either file or inventing a noncanonical name.

Routing and broadcasts

The JSON packet names its final destination. A transport bundle is addressed only to the next FTN hop. At a hub, -in reads enough JSON to choose the next hop but copies the original JSON bytes into the new bundle without changing or re-signing them. The actual node route and broadcast coverage live in the ZIP manifest and are discarded before local game delivery. The final route node is the transmitting hop, and the route length supplies the hop count, so neither fact is stored twice.

A routed league with HOST lines is the normal and recommended arrangement. The game creates addressed broadcast copies before signing, and the connector routes each copy normally.

Mesh warning

An old-style unaddressed broadcast has no final node. When it arrives over Obox or BSO and OboxMeshFanout Yes, -in delivers it locally and sends it to every configured peer in neither its route nor its covered list. Before a sender publishes sibling copies, it puts every durably scheduled recipient in the common covered list. This prevents those recipients from reflexively cross-sending the same broadcast.

These lists limit amplification; they do not make distributed fanout exactly once. In particular, a simple cycle of four or more nodes can have independently scheduled branches meet after both are already in flight, producing duplicates. The hop limit prevents an infinite loop, and canonical-name plus exact-byte duplicate detection lets the inbound converge safely.

If the topology is a true mesh and the source already reaches every board, set:

OboxMeshFanout No

Then -in delivers an unaddressed broadcast locally and stops. The source transport is responsible for putting one copy on every required direct link. Do not use this switch to disguise a physical star whose roster claims to be a mesh; describe that star with HOST lines instead.

Troubleshooting by file location

This table is about the transport. When the question is the game's — a packet that arrived and was refused, held, or quarantined, or a board that has gone quiet — see Inter-BBS Troubleshooting.

Where files accumulate Meaning Action
game Outbound -out did not run or cannot take game.lock Run barons-ftn -out; read its error
ftn-spool/out At least one target is busy or failed Read the warning; inspect that peer's .bsy, path, or netmail directory
AttachDir (default data/att), envelope still in NetmailDir Normal. The attachment waits for the tosser to pack the .msg that names it Nothing. Run/check the tosser
AttachDir (default data/att) with no .msg/flow Attach or BSO queue publication failed Check subject length, NetmailDir, BSO directory, and permissions
NetmailDir .msg The tosser has not packed outgoing netmail Run/check the tosser and allow file attaches
BSO .?lo The mailer has not successfully sent the referenced bundle Check peer address, password, route, and .bsy
peer obox The mailer has not sent or acknowledged the file Check the peer session and outbox mapping
transport InboundDir -in did not run, ran before receive completion, or rejected the wrapper Run it after the session and read warnings
transport InboundDir, listed by -status as unclaimed Attach bundles whose .msg envelope never arrives here — see Per-peer links unzip -p FILE manifest.json to confirm "delivery": "attach"; have the sender switch that link to Obox or BSO
a subdirectory of InboundDir, named by -status The mailer filed an unauthenticated session's files apart from the rest; -in reads each InboundDir and nothing below it Give that subdirectory its own InboundDir line, or fix the session password for that peer and move the waiting files up
ftn-spool/in Local publication or transit handoff is incomplete Correct the named target; the next -in resumes it
game Inbound -planetary has not applied the unwrapped packets Run immortal-barons -planetary
ftn-spool/bad An outbound packet was malformed/unroutable, or an inbound bundle contained a rejected member Preserve it for diagnosis; correct the producing board, route, league, or roster

One bad packet or busy peer does not stop unrelated destinations. Do not delete spool journals to make a warning disappear: they are the record that prevents partial work from being forgotten or blindly repeated.

The same goes for the files in AttachDir, which look more disposable than they are. On a hub most of them are not this board's own mail at all: they are packets that arrived addressed to somebody else and were re-published toward their next hop. The board that sent one has already seen it handed over successfully, so it will never send it again — deleting the attachment loses that mail for good, and the recipient's only symptom is a board that went quiet.

Before removing anything from AttachDir, decide which of the two rows above applies, because they look identical in a file listing:

  • Run barons-ftn -status. A receipt held in transit for another board names that board and that peer's last error. Anything it still lists is owed to somebody.
  • Find the envelope. Each Queued <packet> for <next hop> as <message> line from the run that created the attachment names the .msg that carries it, so the mapping is in the log. An envelope still sitting in NetmailDir means the tosser has not packed it yet and the pair is fine. An envelope that has gone while its attachment stayed is the fault worth chasing.

What a healthy spool looks like

A file count is the wrong measure here, and reading one as a backlog is the mistake to avoid. ftn-spool/out holds one child per claimed snapshot of the game's outbound, and a snapshot is kept whole until every target in it has been published — so one unreachable peer retains that snapshot's packets and the bundles of the peers that already went out. A peer that stays unavailable therefore produces a growing series of snapshot directories while healthy peers keep flowing, which is working as intended and not a queue of that many unsent packets.

What to read instead:

  • barons-ftn -out says so on every run. A run that publishes nothing because its peers are busy prints how many snapshots remain and which peers they wait on, rather than No outbound packets. — so a scheduled event's log distinguishes an empty system from a stalled one. The same peer named run after run is the signal worth acting on.
  • ftn-spool/in should drain. A receipt kept across runs means a canonical-name collision whose bytes differ, a transit handoff that has not completed, or a source or envelope that could not be removed. Its receipt.json names which.
  • The journals date themselves. A snapshot records when it was claimed and when a target in it last published, and a target that failed keeps the reason. A run that queues nothing therefore reports how long the oldest snapshot has gone without progress and why each peer is behind, rather than only how many are waiting. All three fields are optional: a journal written before they existed still loads, and its file date stands in for the age.
  • barons-ftn -status answers all of this and changes nothing. It reports each peer's unfinished snapshots longest wait first, with the recorded reason, the pending inbound receipts and which of the three ways each is stuck, any journal that will not parse, and how many packets are set aside. Reach for it before reading directories by hand.
  • It also reports packets nobody has claimed, which are in neither spool. A file the transport never took is a file no journal knows about, so the counts above cannot show it. -status lists any .BRP that has sat in the mailer's InboundDir, or in a subdirectory of it, for over an hour, and -in warns about the same files as it runs. The troubleshooting guide has the two causes and what to do about each.
  • immortal-barons -league-check reports the same backlog alongside the rest of the league setup, for the sysop who has gone looking there first. A waiting peer is shown but not marked a fault — a peer can be legitimately offline for days — while a journal that cannot be read is a FAIL, because nothing else will ever mention it. A packet nobody has claimed is a FAIL for the same reason: it sits in neither spool, so no other line here counts it.
  • ftn-spool/bad only grows. Nothing is retried from it and nothing removes it; it is yours to read and clear once the producing board, route, league or roster is corrected.
  • AttachDir (default data/att) should also drain: a bundle sitting there with no matching .msg/flow entry means the Attach or BSO queue publication step failed after the bundle was written — check the same causes as the troubleshooting table above (subject length, NetmailDir, BSO directory, permissions). This directory is deliberately not under ftn-spool/ and not shown by -status's spool report — it is the one transport path a mailer's Subject field has to spell out under a byte limit, so it lives where the sysop can point AttachDir at a short location if the default does not fit.

A published alias belongs to the mailer, not to the game. Once a target is published and marked done, its snapshot can disappear and barons-ftn no longer holds a journal saying that file is outstanding — the evidence moves to the transport:

Mode What holds the alias Cleared when
Attach the matching .msg names it the tosser and mailer chain sends it
BSO a ^ entry in the flow file the mailer sends it and deletes it
Obox the queued file is the mailer's own state the peer session takes it

So an alias sitting in a directory is not evidence of an abandoned file. A peer offline for a week is still a valid queue, and age alone cannot tell the two apart. Report growth, and delete only with mode-specific proof from the list above that the owning mailer is finished with it.

Upgrade order

ZIP bundles require barons-ftn -in on the receiving board. Without it the ZIP reaches the game, which cannot parse it as a JSON packet. Upgrade receivers first:

  1. Install the new helper on every board.
  2. Configure InboundDir and schedule barons-ftn -in after receive sessions.
  3. Verify that legacy raw .brp traffic is still delivered to the game.
  4. Configure the per-peer Link modes.
  5. Enable the new bundled -out path on senders.

Because -in accepts legacy raw JSON packets, steps 1–3 can be completed without coordinating an exact cutover minute.

This is the rolling case, and a protocol change is not. The order above covers the transport container, which the game's Protocol number does not describe. When a release moves that number, the league closes the game, lets every board finish sending what it has queued, and switches together. Its release notes will say so.

Before step 5, an Attach link with no AttachDir set gets one that lives under the data directory (see Stored-message attach settings) — a board whose data directory is already deep, as a Synchronet door is under the usual <sbbs>/xtrn/<door>/data layout, can lose all its Subject margin to that alone and publish nothing on the first -out, with no config change of its own. If -out fails immediately with an attachment subject ... is N bytes error, set AttachDir to a short, persistent directory outside the data tree per Keeping attach subjects short — check this before enabling step 5 on any board that used Attach links prior to this helper's bundled-transport rewrite, not after the first failure.

A Synchronet board should move that link to BSO at step 4 instead. See Synchronet.