📝 Nexus_manual.mdv4.6.0 · 2026-10-19

nexus - manual

Module: nexus (NexusCore.php, nexus_link.php, nexus_pair.php, nexus_tool.php, nexus_tidy.php) Version: 2.2.2 Date: 2026-10-26 Another collaboration between Andrew.human and Claude.ai

Audience: people, and machines or AIs that read the forum. Facts are stated flatly.

1. What it is

A nexus links posts into a project: a locked old post, the newer post that replaces it, posts that contribute to it, posts it depends on. The link goes between posts (messages), not topics.

Five kinds of link, written "A kind B". Direction matters: it is how nexus knows which post is the master and who sits under whom. Use related only for plain grouping with no hierarchy.

Kind Reads as Example
contributes A belongs under B (B is the master side) an uninstall step, under the master post that describes the whole job. The default.
related A and B belong together no direction, no hierarchy
supersedes A replaces B the new topic's first post supersedes the locked old one
depends A depends on B A cannot be used without B
uses project A uses project B joins two separate projects without merging them (section 1a)

A project is every post reachable from any other through links of any kind except uses. Add a link and the two projects it joins become one. Pairs can be added one at a time, as you go; groupings may become large and tangled, and that is fine: every post of a project shows the whole project.

1a. Two projects that depend on each other (uses)

Sometimes a whole project depends on another whole project: the listatt project (its master is the post that describes listatt) is used by many later projects for their user interface. Linking a post of one to a post of the other with any other kind would merge them into one. A uses link does not:

php Sources/CollabCore/nexus_pair.php topic=8075 topic=7599 --kind=uses     # the project of 8075 uses the project of 7599

Two posts already in one project cannot be joined by uses (the command says so).

1b. Several masters: branch masters

A project has one master: its top post. But any post can also be flagged master of its own branch, meaning "this post heads the posts indented under it". You can flag as many posts as you like, whether or not anything is under them yet. Example, with Nexus at the top, then Listatt, then Collaborative:

Nexus (8075)               MASTER of the project
└─ Listatt (7599) BRANCH MASTER (Collaborative is under it)
└─ Collaborative (7735) BRANCH MASTER (nothing under it yet)
php Sources/CollabCore/nexus_pair.php topic=7599 topic=8075       # Listatt belongs under Nexus
php Sources/CollabCore/nexus_pair.php topic=7735 topic=7599 # Collaborative belongs under Listatt
php Sources/CollabCore/nexus_tool.php branch topic=7599 # flag Listatt as a branch master
php Sources/CollabCore/nexus_tool.php branch topic=7735 # flag Collaborative too
php Sources/CollabCore/nexus_tool.php branch --list # every flagged post
php Sources/CollabCore/nexus_tool.php branch topic=7599 --clear # remove a flag

A branch flag changes only the labelling: NEXUS.md marks the post BRANCH MASTER in the hierarchy and says "master of its branch (N under it)" in the chronology; listatt shows a BRANCH MASTER badge. It does not move the post, and it does not touch the project's own master (master, section 6). It needs the table nexus_branches, which the package creates when installed or reinstalled.

Putting a post into a project

php Sources/CollabCore/nexus_tool.php assign <post> <any post of the project> [--under=POST]

The post is linked under the project's master (or under --under, a post of that project). A post that is already in a project of its own is refused, because that would merge two projects; use unlink first, or join the projects with uses.

2. What you see

  1. NEXUS.md - a small real attachment on every post of a project. It is the same overview on each post (only the "this post" marker and the line naming the post differ): the master post, how many posts, when the project began, its latest post and its span in days, how many topics are locked, which posts are superseded or current; then the hierarchy (an outline, each post indented under the post it belongs to), the chronology (a table with a step number for every post, 1 = oldest, with date, locked or open, current or superseded, the post it sits under, and its role) and a plain list of the relations. Links only: the file holds no forum text. It is rebuilt automatically; edits are overwritten. Every post is listed with its topic number as well as its post number.
  2. The listatt box (listatt 6.29 or later) starts with the same picture as an outline: a summary line (post count, master, first and last date, span), then every post indented under the post it belongs to, each with its step number and date, a MASTER badge on the master, the current post starred, superseded posts struck through. It is drawn live for each viewer.
  3. Other projects. When a project uses, or is used by, another project (section 1a), NEXUS.md ends with an Other projects section naming each one (title, post number, size), and the listatt box draws each as its own card (listatt 7.1.0 or later).
  4. Search engines and AIs that index attachments (for example the forum's own markdown search) can read NEXUS.md, so finding one post leads to the whole project.

How the master, the hierarchy and the order are decided

3. Who can see which titles

4. The admin page

<forum>/Sources/nexus_link.php (administrators only, with a one-time form token).

A link between the same two posts, of the same kind, in either order, is a repeat. A link that repeats an existing one (either way round), links a post to itself, or touches a missing or protected post is refused with a reason.

5. The pair command (for people and AIs)

One line, in the spirit of attachme: it links two posts, and writes NEXUS.md on every post of the resulting project.

php Sources/CollabCore/nexus_pair.php <A> <B>              # A belongs under B (B = the master side)
php Sources/CollabCore/nexus_pair.php <A> <B> --kind=K # K = contributes (default) | depends | supersedes | related | uses
php Sources/CollabCore/nexus_pair.php <A> <B> --remove # remove the link(s) between A and B
php Sources/CollabCore/nexus_pair.php <A> --show # print the whole project post A belongs to

A and B are post (message) numbers, or pasted post addresses containing msg=1234 or msg1234, or a topic (topic=7735), which means that topic's first post. If both a post and a topic appear, the post wins. When a topic is used, the command prints a NOTE: line saying which post it was taken to be. --dry-run says what would happen and changes nothing. Run it from the forum root; it finds Settings.php by itself (--settings=PATH to override).

It prints the version, then one result line, and sets an exit code, so a script or an AI can act on it:

Result line starts Exit code Meaning
LINKED: 0 done; the line says which way it points (for example #1234 belongs under #1000) and lists every post now in the project
REMOVED: / WOULD REMOVE: / WOULD LINK: 0 done, or what a dry run would do
REFUSED: 1 not done; the line says why (post missing, same post twice, protected board, already linked, unknown kind)
(error on stderr) 2 could not start (no Settings.php, database down, table missing)

Tip for AIs: run --show on a post first to see which project it already belongs to, then add the pair. The attachment gets the post's own member as owner, and when the command runs as root the file takes the owner and group of the attachment folder (as attachme does with chown), so the web server can manage it.

6. The toolkit (nexus_tool.php)

For everything that is not "link two posts": one command, many sub-commands. Run it from the forum root.

php Sources/CollabCore/nexus_tool.php <command> [posts] [options]      # php nexus_tool.php --help lists them

Posts are numbers, pasted addresses (msg=1234) or topic=N (the topic's first post). Anything that deletes, or can touch more than one project, is a dry run unless you add --apply. Only master, branch and assign act at once. Changes wait for the nightly job: if nexus_tidy.php is running, the command stops with exit code 3.

Command What it does Default
master <post> Make that post the master of its project by hand acts at once
assign <post> <post of the project> [--under=POST] Put a post into a project (under its master, or under --under) acts at once
branch <post> Flag a post as the master of its own branch (any number of posts; it needs no posts under it) acts at once
branch <post> --clear / branch --list Remove the flag / list flagged posts acts at once / read-only
master <post> --clear Remove the hand-set master; it is worked out from the links again acts at once
master --list Projects that have a hand-set master read-only
projects One line per project: master, size, first and last date, locked count, posts read-only
show <post> The whole project that post belongs to (the NEXUS.md text) read-only
check Health report: links to gone posts, links into protected boards, loops, two masters in one project, flags on loose posts, NEXUS.md with no file, orphan or duplicate NEXUS.md, missing or out-of-date NEXUS.md. Exit 1 if anything is wrong read-only
export [--public] [--format=json|csv] [--file=PATH] Everything as text: for a backup, or for another program such as ISE. JSON has every link, every project with step numbers, dates, parent, master and address. --public writes only titles that guests may see (all others read "Post N"). CSV can be read back by import read-only
move <old> <new> Move every link, and a hand-set master flag, from one post to another (a topic was reposted or recreated). Links that would duplicate or loop onto themselves are dropped dry run
unlink <post> Remove every link of one post; it leaves its project (the project may split) dry run
dissolve <post> Remove every link in the post's project, and its hand-set master, and delete its NEXUS.md files dry run
rebuild <post> or rebuild --all Rewrite NEXUS.md even when it looks up to date (after a title format change, or to be sure) dry run
purge Delete every NEXUS.md attachment and file. Links and master flags are kept; nexus_tidy.php --apply or rebuild --all --apply makes the files again. Use before uninstalling if you want the attachments gone dry run
import --file=PATH Load links from a text file. One per line: A,B (A belongs under B), A,B,kind, A,kind,B, or master,POST. # starts a comment. Each line is checked like a normal link. The dry run also catches a line repeated in the file, but not links that only become invalid because of other lines. NEXUS.md is written once at the end dry run

Recipes

7. The nightly job

php Sources/CollabCore/nexus_tidy.php [options]    (run from the forum root)
Option Meaning
(none) Dry run. Prints what it would do, changes nothing.
--apply Make the changes.
--settings=PATH Settings.php to use. Default: searched upward from the script.
--pause=MS Pause between posts (default 50) so the live forum is not starved.
--stop Ordered stop: the running job finishes its current post, then exits. Nothing is killed.
--help Option list.

What it does, in order:

  1. Drops links whose post has gone or now sits in a protected board, and master flags that point at a gone post, a protected board, or a post in no project.
  2. For every post that has a link or a NEXUS.md: creates a missing NEXUS.md, rebuilds one that is out of date (a title changed, a topic was locked, a post moved, a neighbour deleted), and deletes any NEXUS.md that has no remaining link or no post (orphans).
  3. Deletes any NEXUS.md attached to no post at all.

Only attachments named exactly NEXUS.md are ever created, rewritten or deleted. Running it twice in a row changes nothing the second time. Only one copy can run (lock file nexus_tidy.lock). The version prints once when it starts. When to schedule it is the operator's decision; an example line for cron, the system's timer, is:

cd /var/www/html && nice -n 19 php Sources/CollabCore/nexus_tidy.php --apply

Exit code 0 = finished, 1 = finished with errors (listed), 2 = could not start, 3 = already running.

8. Data

Table {db_prefix}nexus_branches (v2.2.0): id_msg (a post flagged master of its own branch), id_member, added; any number of rows. Table {db_prefix}nexus_masters: id_msg (the post chosen by hand as master), id_member, added. Table {db_prefix}nexus_links: id_link, id_from, id_to, kind, id_member (who added it), added (time). One row per link; a link is unique per (from, to, kind). The NEXUS.md files are derived from this table and can always be remade by the nightly job.

A NEXUS.md is stored like any attachment: a row in {db_prefix}attachments (name NEXUS.md, type text/markdown, approved) and a file in the current attachment directory, written by a temporary file then renamed.

9. Limits and safety notes

10. Version history

Version Date Change
2.2.2 2026-10-26 Fix: options after the post numbers were ignored. nexus_pair.php A B --remove tried to add a link, --dry-run after the posts did not make a dry run, and nexus_tool.php master P --clear / dissolve P --apply ignored the option (PHP's getopt() stops at the first plain argument). Options are now read anywhere on the line (--kind=uses or --kind uses), and an unknown option is an error. Affects nexus_pair.php and nexus_tool.php.
2.2.1 2026-10-26 Topic numbers everywhere: every display prints the topic number beside the post number ("#49331 (topic 7599)") - the NEXUS.md master line, hierarchy, chronology (new "Topic no." column; the old locked/open column is now "Topic status"), relations and other projects; the result lines of nexus_pair.php and nexus_tool.php; the projects list; the JSON export; and the admin page.
2.2.0 2026-10-26 Branch masters: nexus_tool.php branch <post> flags any number of posts as the master of their own branch (new table nexus_branches); NEXUS.md marks them BRANCH MASTER and counts the posts under each; import/export carry branch,POST lines; move carries the flag; the nightly job drops flags on gone or protected posts. Fixes: the projects list and check no longer join projects through uses links, and a post that only has a uses link is no longer reported as an orphan. Pairs with listatt 7.2.0.
2.1.0 2026-10-26 New link kind uses: joins two separate projects without merging them (each keeps its own master and outline); NEXUS.md gets an "Other projects" section; a single post can use a project. New command nexus_tool.php assign <post> <post of the project> [--under=POST]. nexus_link.php offers "uses". Pairs with listatt 7.1.0.
2.0.0 2026-10-26 Master by hand (new table nexus_masters; admin page form; nexus_tool.php master) and the maintenance toolkit nexus_tool.php: projects, show, check, export (JSON or CSV, --public), move, unlink, dissolve, rebuild, purge, import; deleting commands are dry runs unless --apply, and wait for the nightly job. Admin page lists projects. The nightly job drops stray master flags. Pairs with listatt 6.30.
1.2.0 2026-10-26 NEXUS.md names the master post, shows the hierarchy as an outline and the chronology (step numbers, first and latest date, span). The default pair is now "A belongs under B" (kind contributes); related stays for flat grouping. A link that would make a loop is refused. Pairs with listatt 6.29.
1.1.2 2026-10-26 FIX: post titles in NEXUS.md and on the admin page showed &quot;, &amp; and similar as text. SMF stores subjects already escaped; they are now decoded once. Angle brackets in a title become round brackets in NEXUS.md. Existing files are corrected by the nightly job (or by the next link on any post of the project).
1.1.1 2026-10-26 A post can be given as a topic (topic=N = that topic's first post) in nexus_pair.php and on the admin page; the result says which post was used.
1.1.0 2026-10-24 New link kind related (plain grouping, now the default); new command nexus_pair.php (link, --remove, --show, --dry-run); NEXUS.md attachments are owned by the post's member and, when made as root, by the folder's owner; the "current ones" lines appear only when a project has a supersedes link; admin page offers "related to".
1.0.0 2026-10-24 First release: link table, admin page, NEXUS.md showing the whole project, nightly tidy job, protected boards. Pairs with listatt 6.27.