Skip to content

HW-16: ship and manage the dashboard plugin payload#152

Merged
skylarbpayne merged 6 commits into
mainfrom
remediation/hw-16
Jul 15, 2026
Merged

HW-16: ship and manage the dashboard plugin payload#152
skylarbpayne merged 6 commits into
mainfrom
remediation/hw-16

Conversation

@skylarbpayne

Copy link
Copy Markdown
Owner

HW-16 contract

Ships the issue-owned, wheel-canonical dashboard plugin payload source and a profile-scoped lifecycle manager. This PR does not edit package metadata, CLI registration, tracked top-level plugin sources, runtime core, or live Hermes profiles.

  • Base: 7ba36f01abf98bb60a43f4df07e4b9230e46c0d7
  • Head: 351d28e76cd00e05bfb5bfbb1a2fc40187a2e063
  • Branch: remediation/hw-16

Exact paths

  1. src/hermes_workflows/plugin_install.py
  2. src/hermes_workflows/plugin_payload/hermes-workflows-approvals/plugin.yaml
  3. src/hermes_workflows/plugin_payload/hermes-workflows-approvals/__init__.py
  4. src/hermes_workflows/plugin_payload/hermes-workflows-approvals/dashboard/manifest.json
  5. src/hermes_workflows/plugin_payload/hermes-workflows-approvals/dashboard/plugin_api.py
  6. src/hermes_workflows/plugin_payload/hermes-workflows-approvals/dashboard/dist/index.js
  7. src/hermes_workflows/plugin_payload/hermes-workflows-approvals/dashboard/dist/style.css
  8. tests/test_plugin_install.py
  9. tests/probes/fresh_profile_plugin.py
  10. tests/fixtures/plugin_manifest_v1.json

git diff --name-only 7ba36f01...HEAD equals this closed ten-path allowlist. pyproject.toml, src/hermes_workflows/cli.py, plugins/**, runtime core, docs, and .hermes/showcase-artifacts/** are unchanged.

Behavior

  • Exact six-file payload validation with package/plugin/dashboard version parity (0.0.1rc1)
  • Profile-home-scoped install and enablement; no live-profile discovery or fallback
  • Same-filesystem stage + atomic directory swap
  • One verified package-owned rollback retained across upgrade
  • Ownership-keyed receipts with per-file SHA-256 and size checks
  • Ownership-scoped rollback and uninstall
  • Recovery for interrupted stage, rollback swap, and uninstall moves
  • Refusal on traversal, symlinks, malformed/stale receipts, changed owned files, unsupported config shapes, and user-owned files
  • Fresh-profile manifest/API/JS/CSS route discovery
  • Honest reload report: dashboard rescan refreshes manifest/assets; dashboard restart is required to mount plugin_api.py

The payload __init__.py, API, JS, and CSS are byte-identical to the current tracked top-level sources. Issue-owned payload manifests carry the package version; top-level canonicalization remains deferred to its named adapter.

TDD and verification

Red observed before implementation:

  • uv run pytest -q tests/test_plugin_install.py
  • Collection failed with ImportError: cannot import name 'plugin_install' from 'hermes_workflows'

Green receipts:

  • Python 3.12 targeted: 16 passed in 0.73s
  • Oldest-supported Python 3.9 targeted: 16 passed in 0.42s
  • Full suite: 691 passed, 2 skipped in 41.59s
  • Fresh-profile probe: install old payload → upgrade to 0.0.1rc1 → discover manifest/API/JS/CSS routes → rollback to 0.0.1rc0 → uninstall; profile_removed=true, live_profile_mutated=false
  • python -m py_compile: pass
  • git diff --check 7ba36f01...HEAD: pass
  • Exact allowlist/protected-path audit: pass
  • Source-copy cmp checks for __init__.py, plugin_api.py, dist/index.js, and dist/style.css: pass

Focused tests cover atomic promotion failure restoring the previous install, interrupted rollback/uninstall recovery, ownership-scoped uninstall, retained rollback, config enablement, restart/rescan reporting, version parity, manifest/API/JS/CSS discovery, traversal/symlink refusal, stale/corrupt receipts, modified/user-owned file refusal, and fresh-profile lifecycle discovery.

Deferred adapter gates — intentionally not claimed here

A read-only wheel probe on this head proves the current package adapter is not complete:

  • Wheel currently contains only 4/6 payload files; ignored dashboard/dist/index.js and dashboard/dist/style.css are absent without the shared package adapter.
  • plugin_payload_manifest.v1.json remains the FND-PKG empty manifest (files: []).
  • INT-PKG-META owns wheel metadata/resource-manifest inclusion.
  • INT-PKG-ASSETS owns top-level-source canonicalization and generated asset packaging.
  • INT-PKG-CLI owns CLI registration.

Accordingly, this PR does not claim built-wheel installation or fresh-wheel discovery. It supplies the issue-owned module/payload contract those adapters consume.

Safety receipt

All lifecycle tests and the probe used temporary profile roots. No Palmer/default profile, plugin registry, workflow DB, service, cron, credential, dashboard process, or live installation was read for mutation, changed, restarted, or reconfigured.

Do not merge before the controller-owned fresh specification review and separate quality/security review.

@skylarbpayne

Copy link
Copy Markdown
Owner Author

HW-16 macOS real-temp-root successor pushed.

  • Head: 26b3a140a9119826a51117307c1798a6abb50570b1591906e829c5feb8b18475c68d0a2b0f8cbceb (exactly one successor commit)
  • Successor paths only: tests/probes/fresh_profile_plugin.py, tests/test_plugin_install.py
  • Red reproduced on Python 3.9 and 3.12: ordinary direct probe failed at symlink component /var; focused suite was exactly 1 failed, 88 passed; the new inherited-symlink-TMPDIR regression also failed before the probe change.
  • Green: direct probe passed on 3.9/3.12 from /private/tmp; exact regression passed on both; focused suites 90 passed on both; full suites 3.9 766 passed, 1 skipped, 3.12 765 passed, 2 skipped.
  • Cumulative PR diff remains the exact ten HW-16 paths; showcase diff empty; required ancestor present; excluded PR feat: support custom select values in review queue #131 absent.
  • Production installer is byte-for-byte unchanged. No live profile/plugin/registry/DB/service/cron mutation, install, restart, deploy, or merge.
  • GitHub checks: build, Python 3.9, Python 3.11, and release-candidate passed; deploy skipped. PR is OPEN/CLEAN/MERGEABLE.

@skylarbpayne
skylarbpayne merged commit 33176cb into main Jul 15, 2026
5 checks passed
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