• .claude/skills/jsexec/SKILL.md

    From Rob Swindell (on Windows 11)@VERT to Git commit to main/sbbs/master on Fri May 29 00:55:34 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/3302985c18d7e05422f1249d
    Modified Files:
    .claude/skills/jsexec/SKILL.md
    Log Message:
    .claude/skills/jsexec: per-user ARS check pattern + stdout buffering gotcha

    Two findings from chat-index work and regression-suite debugging:

    1. Checking access against a specific user under jsexec.
    The natural-looking accessors (sub.can_read, dir.can_download)
    evaluate against the implicit session user -- which under jsexec
    doesn't exist, so they return true for everything. Document the
    reliable pattern: instantiate User(N) and walk the ownership
    chain calling u.compare_ars() on each ARS string conjunctively.
    Also note that the global "user" lowercase = useron in C++ -- it
    is undefined under jsexec, distinct from the User constructor.

    2. stdout / stderr / stdin are global File instances. They have a
    .flush() method that fflushes the underlying FILE*. The gotcha:
    print() goes through C stdio, which block-buffers (~4KB) when
    stdout is redirected to a file or pipe. A long-running script
    looks stalled under tail -f even though it's progressing. Route
    output through stdout.writeln() + stdout.flush() to make it
    line-buffered against the redirected FD.

    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Mon Jul 27 20:26:18 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/ad12bd0878c9c79494e92217
    Modified Files:
    .claude/skills/jsexec/SKILL.md
    Log Message:
    jsexec skill: document how the exit status is actually set

    The skill had one line on the subject - that exit(N) sets the process
    exit status - which left the two things people actually get wrong
    undocumented: that a script's return value is ignored entirely, and that
    an uncaught exception yields status 1.

    That gap has real cost. A hatchit.js bug reported this week was
    diagnosed on IRC as "the result of hatch_file() will be the return
    value, which is true (1) upon success" - a reasonable-sounding theory
    that is not how jsexec works, and that would have sent anyone acting on
    it to the wrong line of code. The actual cause was an uncaught
    TypeError thrown after the work had already succeeded.

    Adds an Exit status section covering both real sources, a measured table showing modules that return true / 7 still exit 0, and the behavior
    around them: exit(N) unwinds from anywhere in the call stack, on_exit
    handlers run on both the exit() and exception paths, and the exception
    message goes to stderr. Closes with the consequences worth internalizing
    - chiefly that status 1 does not mean the work didn't happen, since a
    crash after the side effects leaves them in place, and that a module
    must call exit(N) to report failure at all.

    Every claim verified against a live jsexec rather than read off the
    source.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net