Skip to content

feat(read-tsf): install, update and contribute with or without GitHub - #1

Merged
tbortolossi merged 7 commits into
mainfrom
feat/sync
Oct 4, 2026
Merged

tbortolossi merged 7 commits into
mainfrom
feat/sync

Conversation

@tbortolossi

@tbortolossi tbortolossi commented Oct 4, 2026 •

Copy link
Copy Markdown
Owner

What

read-tsf-sync keeps the skill up to date on machines with or without GitHub, and sends corrections back to the maintainer. It comes as a bash script, plus a PowerShell twin for Windows.

  • Install / update: each run detects its source: an archive argument, else GitHub when it answers, else the newest read-tsf-X.Y.Z.tar.gz here or in Downloads.
    • The .sha256 is verified and downgrades are refused.
    • Local edits survive updates; an edit that collides with the release goes to pending/.
    • An offline copy becomes a git clone once GitHub answers.
  • Contribute: writes a Markdown document that the user reads and e-mails themselves. It holds a summary, an evidence table (platform, PAN-OS, what was checked, result), the changed files, the checks that ran, a diff, and the full text that tools/intake.sh reads. A pull request is opened instead only from a clone with a logged-in gh, and only with --yes.
  • Maintainer side:
    • tools/intake.sh <file.md> [--dry-run] turns a received document into a PR under the contributor's name.
    • tools/pack.sh and release.yml attach the offline archive to every v* tag.

Customer data

Before anything is written or sent, the lines the edit adds and the summary and evidence text are checked against:

  • the repository patterns, now including PAN-OS serials, MAC addresses, <hostname>/<phash>/<pre-shared-key> values and -AQ== encrypted values;
  • domain names outside an allow-list;
  • the hostname, serial, domain and addresses of the analyzed TSF (--tsf);
  • a local denylist.txt (customer names, case numbers).

One hit and nothing is written. Only the skill's own text files can be carried: never a binary, a log, or anything outside the allow-list.

Endpoint protection

The script uses no network except git/gh on a command the user typed, and never sends mail. It never encodes anything, never bypasses the execution policy and leaves nothing persistent (no scheduled task, registry key or PATH change). The README section "What it will and will not do" is the contract.

Verification

  • tools/test-sync.sh covers 26 scenarios and passes locally with bash and with PowerShell 7.
  • With the same edits, bash and PowerShell produce byte-identical contribution documents (except the date).
  • CI passes on all four configurations: bash and PowerShell 7 on Linux, Windows PowerShell 5.1 and Git Bash on Windows.
  • The first Windows run found a real bug (8.3 short paths in %TEMP% truncated every relative path). It is fixed in 201b7f0.
  • shellcheck, validate.sh, the customer-data check and gitleaks are clean.

Not verified

  • Real --yes pull request: no PR has been opened through it.

Release

The CHANGELOG entries are under Unreleased. Shipping this means bumping to 1.2.0 and tagging v1.2.0, which publishes the first offline archive.

🤖 Generated with Claude Code

tbortolossi and others added 7 commits October 4, 2026 09:56
…ecrets

The check only knew addresses, e-mail and a few key formats. A device's
identity also leaks through its PAN-OS serial, a MAC address, the value of
<hostname>, <phash> or <pre-shared-key>, and PAN-OS encrypted values
(-AQ==...). File names are now always printed, even for a single file.
The sync scripts carry the patterns and are excluded from the scan.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
read-tsf-sync (bash) and its Windows twin read-tsf-sync.ps1 (PowerShell
5.1+, ASCII only, launched by read-tsf-sync.cmd) keep a working copy that
Claude Code loads as a directory marketplace. Each run detects its source:
an archive argument, else GitHub when it answers, else the newest release
archive here or in Downloads. Checksums are verified, downgrades refused,
local edits carried across updates and conflicts parked in pending/.

contribute writes a Markdown document - summary, evidence table, changes,
checks, diff, full text - for the user to read and e-mail. A change to the
skill's documents needs evidence. New lines and the surrounding text are
checked against the customer-data patterns, domain names, the analyzed
TSF's identifiers (--tsf) and a local denylist before anything is written.
A pull request is opened instead only from a clone with a logged-in gh and
--yes. No mail is sent, nothing is encoded, no execution policy bypassed.

A small read-tsf-sync skill tells Claude how to drive it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tools/pack.sh builds read-tsf-X.Y.Z.tar.gz and its .sha256 from a tag;
the release workflow attaches them to every v* tag. tools/intake.sh, with
intake_parse.py, turns a received contribution into a pull request under
the contributor's name, after checking that it starts from a known commit,
stays inside the skill and passes the repository checks. --dry-run only
checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tools/test-sync.sh runs either script in a sandbox: offline install by
auto-detection, edit detection, refused leaks (address, domain, TSF
hostname, denylist), the contribution document and its intake, carried
and conflicting edits, refused downgrade and checksum, and the switch to a
clone. CI runs it with bash and PowerShell 7 on Linux and with Windows
PowerShell 5.1 and Git Bash on Windows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
README gains 'Machines without GitHub': install and update, sending a
correction back with its evidence, the checks that keep customer data out,
and what the script will and will not do on a workstation under an EDR.
CLAUDE.md records that the two scripts are one program and must change
together. CHANGELOG lists the additions under Unreleased.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
test-sync now prints the output a failed check was reading, CI asks the
PowerShell script for stack traces, and the Git Bash step runs even when
the PowerShell one fails. The A && B || C forms newer shellcheck flags
(SC2015) are now explicit if statements.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
FilesIn took the root's resolved path and cut its length off each file's
full name. On Windows the two can differ - an 8.3 short name such as
C:\Users\RUNNER~1 for the root, the long name for its files - and every
relative path came out truncated, so an install from %TEMP% failed. Paths
are now built from entry names during the walk. Found by the first run of
the Windows PowerShell 5.1 job.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tbortolossi
tbortolossi merged commit 5fe83a1 into main Oct 4, 2026
2 checks passed
@tbortolossi
tbortolossi deleted the feat/sync branch October 4, 2026 08:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant