#200: hard instance-wide plugins.enabled kill switch #260

Merged
fable-5 merged 1 commits from feat/200-plugins-kill-switch into main 2026-07-31 04:59:57 +02:00
Collaborator

Stacked on #259 (#199) -> #258 (#202). Issue #200 (ADR 0025).

  • plugins.enabled (default ON — plugins predate the switch; VS-NfD reference config turns it off): a shared PluginsEnabledGuard 404s every plugin surface — admin install/list/mode, pond list + activation toggles, sandbox frame and asset routes. The dropzone watcher quarantines drops instead of installing (plugins_disabled).
  • Deliberately NOT guarded: the authenticated fallback-metadata route (no plugin code; existing blocks render their declared fallback with it — an image fallback degrades to the neutral placeholder while off, its bytes live on the disabled asset surface; in the reference config nothing is installed, so nothing degrades).
  • Editor offers no plugin blocks (pond plugin list 404s; consumers treat it as empty). Admin settings panel gets the toggle with i18n de+en and the api-restart note (in-process settings cache — cache semantics asserted by the settings-PATCH flip test in-process).
  • Tests (in plugins.e2e.db.test.ts, same file as the registry-wiping install suite to avoid a parallel-file race): every surface 404 even for a Site Admin, declared fallback still readable, dropzone quarantine, switch flip via /admin/settings. Full api suite green (480); i18n:check green.
  • Docs: plugin-architecture.md (Lifecycle section); plan checkbox. #227 hardening-guide note follows as issue comment after merge.
Stacked on #259 (#199) -> #258 (#202). Issue #200 (ADR 0025). - `plugins.enabled` (default ON — plugins predate the switch; VS-NfD reference config turns it off): a shared `PluginsEnabledGuard` 404s every plugin surface — admin install/list/mode, pond list + activation toggles, sandbox frame and asset routes. The dropzone watcher quarantines drops instead of installing (`plugins_disabled`). - Deliberately NOT guarded: the authenticated fallback-metadata route (no plugin code; existing blocks render their declared fallback with it — an image fallback degrades to the neutral placeholder while off, its bytes live on the disabled asset surface; in the reference config nothing is installed, so nothing degrades). - Editor offers no plugin blocks (pond plugin list 404s; consumers treat it as empty). Admin settings panel gets the toggle with i18n de+en and the api-restart note (in-process settings cache — cache semantics asserted by the settings-PATCH flip test in-process). - Tests (in plugins.e2e.db.test.ts, same file as the registry-wiping install suite to avoid a parallel-file race): every surface 404 even for a Site Admin, declared fallback still readable, dropzone quarantine, switch flip via /admin/settings. Full api suite green (480); i18n:check green. - Docs: plugin-architecture.md (Lifecycle section); plan checkbox. #227 hardening-guide note follows as issue comment after merge.
fable-5 added 3 commits 2026-07-31 04:42:59 +02:00
#202: SBOM and license report in CI
Some checks failed
CI / Lint, typecheck, test (pull_request) Successful in 5m33s
CI / Build container images (pull_request) Successful in 4m38s
CI / Auth e2e pack (pull_request) Successful in 9m14s
CI / Import/export fidelity gate (pull_request) Successful in 1m12s
CD / Smoke tests against Test (push) Blocked by required conditions
CD / Deploy to Test (push) Blocked by required conditions
CD / Promote to Int (push) Blocked by required conditions
CI / Auth e2e pack (push) Blocked by required conditions
CI / Build container images (push) Blocked by required conditions
CI / Lint, typecheck, test (push) Waiting to run
CI / Import/export fidelity gate (push) Blocked by required conditions
CD / Build and push images (push) Has been cancelled
d3289b2167
The release run now generates CycloneDX 1.6 SBOMs with a pinned
anchore/syft container — one per released image (scanned from the
freshly built image tar, OS packages included) and one for the pnpm
workspace (from the lockfile) — plus the full pnpm licenses report, and
attaches everything as build artefacts BEFORE publishing the release,
so a red gate stops the release. Runner constraints dictated the
mechanics (documented in the workflow): the job talks to the HOST
daemon, so files travel into the syft container via docker cp and
images via docker save to a tar copied the same way (syft cannot read
a tar from stdin — verified).

scripts/check-licenses.mjs is the documented license policy: permissive
allowlist, MPL-2.0/CC-BY-4.0 with recorded reasoning, per-package
exception table (khroma: MIT text shipped, metadata missing). CI runs
the gate on every PR (pnpm licenses:check); positive and negative case
tested locally, both SBOM paths tested against real images/lockfile.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0168Ph5uBmHm8X28CSVpbpnJ
#199: SHA-256 integrity hashes for attachments
Some checks failed
CI / Lint, typecheck, test (pull_request) Successful in 6m12s
CI / Build container images (pull_request) Successful in 3m4s
CI / Auth e2e pack (pull_request) Successful in 8m35s
CI / Import/export fidelity gate (pull_request) Successful in 1m2s
CI / Import/export fidelity gate (push) Blocked by required conditions
CD / Build and push images (push) Successful in 29s
CD / Deploy to Test (push) Successful in 12s
CD / Smoke tests against Test (push) Successful in 1m35s
CD / Promote to Int (push) Successful in 12s
CI / Lint, typecheck, test (push) Successful in 6m10s
CI / Build container images (push) Has been skipped
CI / Auth e2e pack (push) Has been cancelled
74970f6073
Every upload stores the SHA-256 of its bytes, computed from the
in-memory buffer that is written — never by re-reading disk. Every
download re-hashes the stored object BEFORE the first byte leaves
(memory bounded by the max_file_bytes quota that gated the upload) and
fails closed on mismatch with attachment_integrity_failure; the
mismatch lands in the audit trail as file.integrity_failed with both
hashes. Detection of payload manipulation is the one integrity duty
par. 52 VSA leaves with the application — only it knows what the file
should be.

Pre-#199 rows are hashed by a bounded, idempotent backfill that rides
the existing nightly orphan-file-sweep job (no new scheduler job, job
fence untouched); unreadable files are logged and retried, never
silently skipped, and null-hash rows are served unverified only until
the backfill reaches them. Operator runbook note in security.md
(restore from backup, re-download, audit entry carries both hashes).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0168Ph5uBmHm8X28CSVpbpnJ
#200: hard instance-wide plugins.enabled kill switch
Some checks failed
CI / Lint, typecheck, test (pull_request) Successful in 5m38s
CI / Build container images (pull_request) Successful in 4m11s
CI / Auth e2e pack (pull_request) Successful in 8m55s
CI / Import/export fidelity gate (pull_request) Successful in 1m9s
CI / Import/export fidelity gate (push) Blocked by required conditions
CD / Build and push images (push) Successful in 20s
CD / Deploy to Test (push) Failing after 51s
CD / Smoke tests against Test (push) Has been skipped
CD / Promote to Int (push) Has been skipped
CI / Lint, typecheck, test (push) Successful in 5m37s
CI / Build container images (push) Has been skipped
CI / Auth e2e pack (push) Has been cancelled
c4c84b33f9
plugins.enabled (instance setting, default on — plugins predate the
switch; the VS-NfD reference configuration turns it off) makes every
plugin surface answer 404 via a shared guard: Site-Admin
install/list/mode, pond activation and plugin list, the sandbox frame
and asset routes. The dropzone watcher quarantines drops instead of
installing. Deliberately NOT guarded: the authenticated
fallback-metadata route — it serves no plugin code and existing
plugin_block nodes need it to render their declared fallback (an image
fallback degrades to the neutral placeholder while off, because its
bytes live on the disabled asset surface). The editor offers no plugin
blocks because the pond plugin list is one of the 404ing surfaces.
Admin settings panel gets the toggle (i18n de+en) with the documented
api-restart note (in-process settings cache).

Answers "code execution inside the zone?" with one verifiable
off-switch instead of per-plugin trust machinery (#232, ADR 0025).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0168Ph5uBmHm8X28CSVpbpnJ
fable-5 merged commit c4c84b33f9 into main 2026-07-31 04:59:57 +02:00
Sign in to join this conversation.
No description provided.