SFPCKUSR32 CHANGELOG
====================

v0.4.0-beta1
-------------
- Promoted the validated v0.4.0 closed-beta build to public Beta 1.
- Changed release-label and help/report wording only; the writer logic is unchanged.
- Rebuilt reproducibly and reran the complete fixture suite.
- Documented successful production /DEL and /OLD=365 runs and an outside-sysop /DEL run.
- Cleaned the website ZIP: essential sysop files at root, details under docs, source and tests under source.

v0.4.0-closed-beta
--------------------
- Promoted the proven full-rule writer from recoverable-lab status to a
  manual-offline closed beta.
- Removed the /WRITE /LAB ceremony. /DRYRUN is read-only; any normal invocation
  without /DRYRUN is a real verified pack.
- Added legacy-compatible plain invocation: SFPCKUSR.EXE packs only records
  already marked Deleted=TRUE.
- Real write commands are now /DEL, /SEC=x, /OLD=x, combined OR, and explicit
  /AND, with optional /BACKUP=<root>.
- /WRITE and /LAB are rejected with migration guidance so an old test command
  cannot create ambiguity about the selected mode.
- Added prominent manual-offline warnings to help and write reports. The
  closed beta requires every Spitfire node process to be closed; SFWHOSON.DAT
  detects active callers but cannot prove idle nodes are closed.
- Retained mandatory verified backups, shared SFTOSS.BSY locking, staged
  DAT/PTR/LMR rebuilds, repeated pre-commit safety, post-write verification,
  automatic rollback, user #1 protection, and no /NOBACKUP escape hatch.
- Re-ran the full fixture suite using the release command model, including
  plain deleted-only writes, all rule modes, custom backups, no-op writes, and
  forced rollback.
- Re-ran /OLD=365 against a disposable copy of the supplied 200-user database
  without /WRITE /LAB: 161 removed, 39 retained, all nine 39,996-byte LMR
  files exactly matched the expected retained-slot shift and zero-fill result.
- Scheduled-event and built-in Sysop Menu use remain unapproved.

v0.3.0-lab
-----------
- Enabled the complete rule set for controlled laboratory writes:
    /DEL /WRITE /LAB
    /SEC=x /WRITE /LAB
    /OLD=x /WRITE /LAB
    /SEC=x /OLD=x /WRITE /LAB              (legacy-compatible OR)
    /SEC=x /OLD=x /AND /WRITE /LAB         (explicit AND)
- Write mode now requires an explicit /DEL, /SEC, or /OLD selection.
- /SEC and /OLD continue to require AllowPurge=TRUE; already-deleted records
  remain independently eligible; user record #1 remains protected.
- All rule modes share the same mandatory verified backup, staged DAT/PTR/LMR
  rebuild, repeated safety gate, commit, post-write verification, and rollback
  engine proven by the v0.2.0 /DEL writer.
- Added automated write fixtures for /OLD, /SEC, combined OR, and combined AND,
  including exact retained-user order and LMR slot-compaction verification.
- Re-tested the supplied 200-user X-Bit copy with /OLD=365 /WRITE /LAB: 161
  users removed, 39 retained, all nine 39,996-byte LMR files matched the exact
  expected retained-slot shift and zero-fill result, zero errors.
- Removed the VM-snapshot requirement from the fast lab instructions when the
  complete C:\SF lab tree is independently recoverable.

v0.2.0-lab
-----------
- Renamed the distributed executable to SFPCKUSR.EXE, preserving the
  SFPCKUSR32 product name while using a DOS-safe eight-character basename.
- Added the first write-capable laboratory path:
    SFPCKUSR.EXE /DEL /WRITE /LAB
- Write mode remains limited to users already marked Deleted=TRUE. /SEC,
  /OLD, and /AND remain dry-run-only.
- Added mandatory verified timestamped backups. There is no /NOBACKUP switch.
- Added /BACKUP=<root>; relative paths resolve beneath the Spitfire HOME,
  while absolute paths may target another drive or a path containing spaces.
- Default backup root is HOME\SFPCKUSR-BACKUPS.
- Backup tree includes SFUSERS.DAT/PTR, all LMR files, SFWHOSON.DAT snapshot,
  existing SFPURGED.USR, MANIFEST.TXT, and RESTORE_WARNING.TXT.
- Added staged DAT compaction, PTR rebuild from retained DAT names, DAT/PTR
  name cross-validation, fixed-capacity LMR shift-left/zero-fill rebuilding,
  and SFPURGED.USR audit append.
- Added repeated pre-commit safety and unchanged-file checks.
- Added post-write hash verification and automatic verified rollback on
  detected commit or verification failure.
- Added free-space checks for WORK, MESSAGE, and the selected backup root.
- Added warning when legacy SFPCKUSR.COM is present, including the DOS
  .COM-before-.EXE command-resolution risk.
- Help and documentation state that scheduled-event and built-in Sysop Menu
  use are not approved because SFTOSS.BSY does not itself prevent another
  Spitfire node from accepting a new caller.
- Added fixture coverage for successful writes, default/custom backups,
  no-op writes, existing purge history, LMR movement, and forced rollback.
- Automated POSIX fixture suite passes. Win32 PE32/i386 build completed with
  Windows 5.01 headers and no imported arithmetic helper.

v0.1.9-dryrun
---------------
- Added atomic shared MESSAGE\SFTOSS.BSY acquisition for every scan command.
- An existing SFTOSS.BSY now aborts before SFUSERS.DAT, SFUSERS.PTR, or LMR
  validation begins; SFPCKUSR32 never changes or removes a pre-existing lock.
- A lock owned by SFPCKUSR32 is held through scan and snapshot verification,
  then released on success, validation failure, active-caller refusal, and
  normal error exits.
- Added Windows Ctrl+C cleanup for an owned lock.
- /HELP and /? now wrap to 78 columns and pause after 22 console lines.
- Redirected/captured help does not pause; /VERSION never creates the lock.
- Added regression tests for acquisition/release, existing-lock refusal,
  lock ownership, help width, redirected help, and informational switches.
- Revalidated the supplied 200-user database with /DEL /DRYRUN: 12 selected,
  188 retained, 0 warnings, 0 errors, and no stale lock.
- No database write/packing code exists in this build.

v0.1.8-dryrun
---------------
- Added /DEL as an explicit deleted-record-only selector.
- /DEL /DRYRUN previews only users already marked Deleted=TRUE.
- /DEL cannot be combined with /SEC, /OLD, or /AND; ambiguous combinations
  and duplicate /DEL switches are rejected as command-line errors.
- /HELP and /? now document /DEL.
- Reports identify "Selection mode: /DEL (deleted records only)" and confirm
  that /SEC, /OLD, and /AND evaluation is disabled.
- Added regression tests for /DEL selection, invalid combinations, duplicate
  /DEL, help text, and byte-for-byte read-only verification.
- Validated the supplied 200-user database with /DEL /DRYRUN: 12 purge
  candidates, 188 retained, 0 warnings, 0 errors, and unchanged file hashes.
- Revalidated /SEC=10 /OLD=365 /AND /DRYRUN: 161 purge candidates and 39
  retained, with no behavior regression.
- No database write code exists in this build.

v0.1.7-dryrun
---------------
- Added /AND as an explicit, optional combination modifier.
- /AND requires both /SEC=x and /OLD=x.
- With /AND, additional non-deleted users must match security, age, and
  AllowPurge requirements together. Users already marked Deleted remain
  selected as part of the normal packing operation.
- Without /AND, /SEC and /OLD retain the original utility's OR behavior.
- Reports now state "Combination rule: AND", "OR (legacy-compatible)", or N/A.
- /AND candidate reasons show both matched rules and the [AND] marker.
- Added regression tests for AND selection, incomplete /AND commands,
  duplicate /AND, help text, and byte-for-byte read-only verification.
- Validated the supplied 200-user database with /SEC=10 /OLD=365 /AND:
  161 purge candidates, 39 retained, 0 warnings, and 0 errors.
- No database write code exists in this build.

v0.1.6-dryrun
---------------
- Corrected LMR validation using live Spitfire evidence and deeper static
  analysis of the original SFPCKUSR.COM.
- Real SFMSGxx.LMR files contain 9,999 four-byte slots (39,996 bytes), even
  when the current user database contains far fewer callers. This is normal.
- The original packer compacts the LMR values corresponding to purged user
  numbers, shifts later values left, then appends zero records so the LMR keeps
  its original fixed capacity.
- SFPCKUSR32 now requires each LMR to be four-byte aligned and to contain at
  least as many slots as current SFUSERS.DAT records; extra capacity is valid.
- Added /VERSION. Confirmed /HELP and /? as documented, tested public aliases.
- Added 9,999-slot, undersized-LMR, and misaligned-LMR regression fixtures.
- No database write code exists in this build.

v0.1.5-dryrun
---------------
- Fixed the first real user-database validation failure in v0.1.4.
- The internal replacement for MSVC's __aulldiv helper used the wrong x86
  runtime-helper calling convention. After the first 64-bit record-count
  division, the stack was corrupted, producing impossible file sizes and
  counters and preventing LMR discovery.
- Removed the __aulldiv replacement entirely. Record counts now use ordinary
  validated 32-bit arithmetic, which is more than sufficient for Spitfire's
  maintenance files and does not depend on undocumented compiler-helper ABIs.
- Added a Win32 object audit confirming no __aulldiv/__alldiv arithmetic helper
  reference remains.
- Revalidated the supplied 200-user database offline: plain /DRYRUN selects 12
  already-deleted users; /SEC=10 /DRYRUN selects 191 users; DAT/PTR counts are
  200/200 and nine matching LMR fixtures validate.
- No database write code exists in this build.

v0.1.4-dryrun
---------------
- Fixed SFWHOSON.DAT active-node detection after the first successful live run.
- Real Spitfire initializes unused node slots with UserNo=-1. The previous build
  treated every nonzero value as active and therefore falsely reported all 255
  unused slots as active.
- Only positive UserNo values are now considered active. Zero and negative
  values are treated as clear/unused sentinels.
- Updated fixtures to use the real -1 clear-slot convention and added regression
  tests for both -1 and 0 clear values plus positive active user numbers.
- No user-record selection, date handling, path discovery, or write behavior
  changed.

v0.1.3-dryrun
---------------
- Fixed the second Win32 startup failure reported during live testing.
- v0.1.2 no longer imported _aulldiv, but Clang still emitted an imported
  _chkstk stack-probe helper that was absent from the system MSVCRT.DLL.
- Added an internal 32-bit Windows stack-probe/allocation helper.
- Removed _chkstk from the MSVCRT import definition and confirmed the final
  PE import table contains no _chkstk, _aulldiv, or other arithmetic helper.
- No purge-selection, date-handling, path, or database-scanning behavior
  changed.

v0.1.2-dryrun
---------------
- Fixed the first Win32 startup failure: the previous executable imported
  the undocumented MSVCRT.DLL helper _aulldiv.
- Added an internal unsigned 64-bit division helper and removed _aulldiv
  from the import table.
- No purge-selection or database-scanning behavior changed.

v0.1.1-dryrun
---------------
- Corrected SFUSERS.DAT and SFUSERS.PTR discovery: both are read from the
  WORK directory configured in SFNODE.DAT, matching Spitfire and the
  original SFPCKUSR behavior.
- Updated fixtures, tests, and documentation for the corrected paths.

v0.1.0-dryrun - Phase 0
------------------------
- First native Win32 x86 build.
- Added read-only /DRYRUN.
- Added original-compatible /SEC=x and /OLD=x selection previews.
- Added SFWHOSON active-node refusal.
- Added SFUSERS.DAT/PTR and SFMSGxx.LMR count/alignment validation.
- Added candidate-level reasons and summary report.
- Added user-record #1 protection.
- Added stable two-digit-year interpretation:
    00-79 = 2000-2079
    80-99 = 1980-1999
  Future and invalid dates are excluded from /OLD.
- Added before/after hash checks to detect concurrent file changes.
- No packing or Spitfire database write code exists in this version.
