Skip to content

feat: harden public Hermes primitive publication - #3

Merged
srinitude merged 17 commits into
mainfrom
feat/refresh-public-primitives
Jul 11, 2026
Merged

feat: harden public Hermes primitive publication#3
srinitude merged 17 commits into
mainfrom
feat/refresh-public-primitives

Conversation

@srinitude

Copy link
Copy Markdown
Owner

Summary

  • replace sweeping publication with explicit local allowlists and fail-closed candidate policy
  • export skills, plugins, profiles, and the validator personality through transactional package and whole-batch boundaries
  • validate public safety, identity neutrality, native package completeness, real Hermes plugin/profile behavior, structure, docs, installer behavior, and deterministic inventories
  • publish the current validated inventory: 9 skills, 0 plugins, 0 profile distributions, and 1 reusable personality
  • make the publisher require a clean exact origin/main, repository-local identity, public GitHub visibility, local policy files, an exclusive lock, exact NUL-delimited staging, and the full validation packet

Candidate and retention decisions

  • eight skill candidates passed current-source classification and were exported
  • one previously public skill is retained byte-for-byte as last-known-good because its newer source candidate fails a support-file completeness gate
  • all current plugin and profile candidates failed at least one unconditional provenance, privacy, completeness, structural, or native-package gate, so none are manifest-listed
  • the legacy tutorial plugin/profile suite was removed rather than grandfathered because retaining it would violate the new unconditional completeness and CI gates; no weaker validator carve-out was introduced
  • private identifiers discovered by independent review were scrubbed from public copies and added to the local-only denylist

Safety and transaction behavior

  • candidate-source symlinks fail before staging
  • per-package replacement preserves last-known-good output on candidate failure
  • whole-batch rollback restores all selected destinations and inventories byte-for-byte on a later candidate or validator failure, removes newly created destinations and residue, and emits no change list
  • source fingerprints include tracked files plus newly exported files only under manifest-listed package roots; unrelated untracked content and runtime/cache paths are excluded
  • the validator personality installs without implicit activation

Validation

  • 143 unit tests passed with no skips or xfails
  • public-safety validation passed
  • identity-neutrality validation passed
  • package-completeness validation passed
  • intentionally-unpublished tutorial-suite validation passed
  • Python structure validation passed across scripts, tests, and plugins
  • installer and publisher shell syntax passed
  • disposable dry-run wrote nothing
  • disposable real install copied 9/9 skills byte-for-byte, Hermes discovered all 9, installed validator without activating it, and passed hermes config check
  • two consecutive hardened exporter passes produced empty change lists with stable source and tracked-tree hashes
  • every branch commit uses Kiren Srinivasan <kiren@fantasymetals.com> with no AI-authorship trailer
  • original 214-path failed export remains preserved and unchanged in the original checkout and timestamped backup

Publication state

The automated publisher remains paused. It will not be resumed until this PR is green and merged, remote main and inventories are verified exactly, the original checkout is reconciled from the preserved backup, and two post-merge publisher no-op runs succeed.

srinitude added 17 commits July 11, 2026 08:50
Move exporter and validator behavior into small reusable modules
(toolbox_common, sanitize_rules, candidate_policy, export_transaction,
safety_checks, package_checks, public_manifest) behind unchanged CLI
wrappers, and add a parser-based structure gate
(verify-python-structure.py) enforcing 200-line files, 30-line
constructs, and depth-3 control nesting.

Equivalence witnessed: old (db735d9) and new exporters produced
byte-identical skills/ and plugins/ trees from the same synthetic
sources; the inventory manifest now derives plugin entries from repo
contents instead of only the current sweep, matching the committed
23-plugin manifest.
RED: PYTHONDONTWRITEBYTECODE=1 python3 -m unittest tests.test_export_transaction -v
failed 7/7 before implementation: the previous exporter deleted each
destination before validation, so source-validation, sanitizer, interrupted-
copy, and manifest-mismatch failures corrupted last-known-good packages, and
unchanged packages were re-listed in the change list.

Each candidate now stages into a temporary sibling directory, is sanitized
deterministically, gets its manifest generated and cross-checked in staging,
passes privacy/required-file checks there, and only then atomically replaces
its own destination; byte-identical packages are skipped and omitted from the
NUL-delimited change list. Destinations are never removed before a staged
candidate validates, and a failed swap restores the previous package bytes.
Harden scripts/publish-public-candidates.sh and the publish mode of
scripts/scan-public-candidates.py behind tests/test_publisher_contract.py:
dirty worktree, checkout drift from origin/main, missing local
plugin/profile allowlists, missing source-profile gate, missing repo-local
git identity, validator failure, and failing repo tests all block commit
and push; only NUL-listed accepted paths plus the deterministic inventory
files are staged; no-candidate runs exit 0 with empty stdout; git add
sweeps, --autostash, and git pull are banned statically. Split the scan
main into gate functions to satisfy the 200/30/depth-3 structure limits.

RED witnessed before implementation:
PYTHONDONTWRITEBYTECODE=1 python3 -m unittest tests.test_publisher_contract -v
-> FAILED (failures=10 of 14) against the previous scripts.
GREEN: same command OK (14 tests); full suite 119 tests OK; structure,
shell syntax, public-safety, identity-neutrality, and tutorial
real-runtime validators all pass. Publisher cron remains paused.
Classify the current candidate inventory fail closed: publish eight current-source skills, retain the valid prompt-enhancer last-known-good package, and keep the validated validator personality. Remove 23 legacy tutorial plugins and the tutorial profile because the current public packages fail the no-test-double and 200/30 structural gates, while all 29 current plugin and 10 current profile candidates are rejected by the same public completeness policy. Candidate evidence remains local under .git/info.
Restart the skill slice after source drift, reclassify the candidate against the current fail-closed gates, and transactionally publish the accepted support-file update. No other candidate class changed.
Fail closed before staging when any candidate source path is a symlink, preventing an out-of-tree target from being copied into a public package. The regression test first demonstrated that the old exporter followed the link and then proves last-known-good preservation.
Record the symlink-hardening source and regression test in the deterministic public fingerprint inventory.
Extend the untracked identity denylist and rerun the transactional exporter so private business and family-profile identifiers are replaced in public copies. Include the newly accepted current-source plugin-builder reference discovered during the same drift-aware export.
Source fingerprints now cover exactly tracked files plus files beneath
manifest-listed skill/plugin/profile/personality package roots, with a
safe hidden-path-excluding walk fallback for non-git fixture repos, so
unrelated untracked files such as .serena can no longer be ingested.

The exporter wraps all selected exports, inventory writes, and the
safety/identity/completeness/tutorial validators in a whole-batch
transaction: any late candidate or validator failure restores every
selected destination and both inventories byte-for-byte, removes newly
created destinations, leaves no staging or backup residue, and emits no
change list.
Run the tutorial-suite gate even when the suite is intentionally absent, so a partial tutorial reintroduction fails inside the whole-batch rollback boundary. Refresh the accepted integration-audit skill after verified source drift and regenerate exact inventory hashes.
Reclassify and export current public-safe plan-update-executor and plugin-builder source drift, then regenerate exact manifests and fingerprints after the full validation packet passes.
Create the Hermes venv and source-tree layout expected by the real PluginManager and profile-install tests, place its CLI on PATH, and keep PyYAML available to the workflow interpreter. A disposable CI-home simulation passed all 30 real-runtime/profile tests before this commit.
@srinitude

Copy link
Copy Markdown
Owner Author

Independent adversarial review identified privacy-sanitization, fingerprint-scope, symlink, and whole-batch rollback issues. Each was fixed with regression coverage. The final local packet passed 143 tests plus all validators, a disposable CI-runtime simulation passed the 30 real Hermes runtime/profile tests, both GitHub Actions runs are green, the 461-file remote PR set exactly matches the reviewed local diff, and manifest-listed package roots exactly match the public tree. The publisher remains paused pending post-merge verification.

@srinitude
srinitude merged commit b3bbeff into main Jul 11, 2026
2 checks passed
@srinitude
srinitude deleted the feat/refresh-public-primitives branch July 11, 2026 12:59
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