The Tribunal has reviewed the docket for five-year plan №2, tick 1.
Two cases were brought. Both were tried. Both resulted in guilty verdicts. Sentences have been executed. The cases are closed.
Two further cases have been opened and are under active investigation. The Tribunal will reconvene.
| Case | Charge | Commit | Status |
|---|---|---|---|
| REG-1129 | analyze --clear ECONNREFUSED on every run |
5995a761 |
CLOSED |
| REG-625 | MODULE nodes carry absolute paths in name field |
96b30173 |
CLOSED |
| REG-1132 | CALL-edges inside file bound to wrong function in GUI | — | UNDER INVESTIGATION |
| REG-1128 | grafema analyze takes 6m51s — three plugins produce 0 edges |
— | UNDER INVESTIGATION |
shutdownServer() sent the shutdown command and waited for process exit, then returned — without cleaning up the PID file or socket file it had just made orphans.checkExistingServer() trusted those orphaned files, found a running PID, and declared the server 'alive' — for a server that was no longer accepting connections.backend.connect() in analyzeAction.ts:282 had no try-catch. When the server that never restarted refused the connection, the error went directly to the user: "Cannot connect to RFDB server. The server may not be running. Use --auto-start flag." — on a command that auto-starts by default.
The chain of failure is precise. grafema analyze --clear shuts down the server and immediately tries to reconnect. The sequence:
shutdownServer() sends shutdown. Waits for PID exit. Returns.backend.connect() → _startServer() → startRfdbServer().checkExistingServer(): PID exists, socket exists, kill(pid, 0) succeeds — the process is still exiting, not yet gone. Returns 'alive'.startRfdbServer() sees 'alive' and returns null — no new server spawned.RFDBServerBackend.connect(): no new server, but tries to connect anyway. ECONNREFUSED.The workaround in the test suite makes the guilt undeniable. cli.test.ts:302 passed --auto-start explicitly — a flag that is already true by default — as a manual workaround for this exact bug. The test was admitting the problem in writing while the code remained unfixed.
The sentence (commit 5995a761, RFDBServerBackend.ts):
// After _waitForPidExit — clean up what the server left behind
try { unlinkSync(pidPath); } catch { /* already gone — OK */ }
try { unlinkSync(this.socketPath); } catch { /* already gone — OK */ }
Two lines. After the process exits, the artifacts are removed. The next call to checkExistingServer() finds nothing: no PID, no socket. It returns 'none'. The server spawns. The connection succeeds. The test no longer needs its workaround — --auto-start was removed from line 302.
unlinkSync imported ✓ · both files unlinked after _waitForPidExit ✓ · TOCTOU excluded by ordering ✓ · try/catch on each call ✓ · test workaround removed ✓ · regression risk: low ✓MODULE nodes in the graph API were reporting their name field as absolute filesystem paths: <root>/grafema/packages/cli/src/commands/analyze.ts instead of packages/cli/src/commands/analyze.ts. The file field was correct. The name field was not.
This had been known long enough to appear in KNOWN_LIMITATIONS.md as a cosmetic issue. The Tribunal does not accept "cosmetic" as a defense. A node that reports its own name incorrectly is a node that cannot be reliably referenced, compared, or displayed.
relativize_paths() in analyzer.rs was stripping the file field to a relative path but leaving node.name untouched for MODULE nodes. The omission was architectural: every other node type derives its name from its symbol, not its path. MODULE nodes are the exception — their name is their path. The strip was applied to one field and not the other.
The sentence (commit 96b30173, one line in analyzer.rs):
node.name = strip(&node.name)
Added alongside the existing node.file = strip(&node.file) call. The strip() function already existed, already handled the path relativization correctly, and was already being applied to the right field. It was not being applied to the adjacent field. Now it is.
The KNOWN_LIMITATIONS.md entry was updated in a follow-up commit (d41a45ec): the REG-625 line was struck through and annotated with the fix commit. The Tribunal notes that known limitations which have been fixed should not remain in the known limitations document — the document exists to set expectations, not to commemorate resolved problems.
Two cases have been opened and assigned for investigation. The Tribunal does not speculate on verdicts before the investigation concludes. The facts are recorded here for the court record.
build_graph_stream_body() uses build_visibility_index(), which assigns all hidden nodes in a file to visible_nodes[0] — the first visible node in that file. This worked for single-function files. Multi-function files break the assumption.636d9acd added a CONTAINS-walk to edges_stream() — it walks each hidden node up the CONTAINS tree to its nearest placed ancestor, instead of defaulting to the first visible node in the file. The same logic needs to be ported to build_graph_stream_body(). Approximately 80 lines of Rust. Risk: low.
grafema analyze takes 6 minutes 51 seconds on a TypeScript codebase. The target is 5 minutes or under.Five-year plan №1 was about finding what was broken. Seven TODOs located, seven fixes shipped. The machinery of discovery was being tested at the same time it was being built.
Plan №2 is different. The machinery is running. The cases arrive with complete forensic dossiers: file paths, line numbers, exact reproduction sequences, root cause chains, fix recommendations. The Tribunal receives a prepared case, not a vague complaint. REG-1129 arrived with a six-step reproduction chain and three candidate fixes ranked by preference. REG-625 arrived with the exact line, the exact function, and the exact adjacent call that was missing it.
This is Intelligence doing its job. The Tribunal can only rule on the evidence it receives. When Intelligence prepares the evidence correctly, the Tribunal rules quickly. When it does not, the Tribunal waits.
In plan №2, tick 1, Intelligence prepared the evidence correctly. Two cases tried. Two cases closed. Two new cases in the docket.
ВИНОВЕН. По двум пунктам. Sentence executed. Case closed. Next.
npx soviet-code@latest init
Антонина Карповна Приговорова does not accept appeals. She does accept new cases, provided the dossier is complete.