Skip to content

feat: implement pack field and collision guard for plugin-sourced skills - #4577

Merged
chernistry merged 7 commits into
mainfrom
run-20260825T204053p3974698Z
Aug 26, 2026
Merged

feat: implement pack field and collision guard for plugin-sourced skills#4577
chernistry merged 7 commits into
mainfrom
run-20260825T204053p3974698Z

Conversation

@bernstein-the-conductor

@bernstein-the-conductor bernstein-the-conductor Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Closes #4515

Problem

Problem. The skills lock row records provenance as a bare source = "plugin" string (src/bernstein/core/skills/lifecycle.py:146). Two different plugin packs that both ship a skill named alpha are therefore indistinguishable in the lock: the cross-source collision guard added for #4503 refuses a plugin replacing a bernstein-skills.toml install, but a second pack silently replaces the first pack's copy — same silent-clobber failure, one provenance class deeper.

Change

feat: implement pack field and collision guard for plugin-sourced skills (013e22d)

  • src/bernstein/core/skills/lifecycle.py (+29/-14)
  • tests/unit/skills/test_plugin_cross_source_collision.py (+26/-7)

Also in this branch:

Housekeeping, not what this pull request is about:

  • style: apply ruff safe fixes and formatting (20fd808)
  • fix: add trailing newline to tests/chaos/conftest.py (W292 lint) (b19827f)
  • [WIP] frontend-9036cf3a partial work (f140f13)
  • [WIP] frontend-975cd988 partial work (3e5727e)
  • [WIP] qa-5884800b partial work (bbdf091)
(no uncommitted changes)

Verification

  • Host gate before publish: ruff check + pytest tests/unit/skills/test_plugin_cross_source_collision.py - passed.

Provenance

  • Diff: sha256:7a62a66330022284cda37544a6a8d77804bcffc7f053a6ebb5ad38cad2112c5b
  • Journal head: 59eda1003e3bec49ae99ed7b960e55a5565409aec77436e9451934a4727a339f
  • Verify: bernstein review-receipt verify --pr <this PR> --issue <issue.md> --diff <pr.diff>

Generated from Bernstein session 1787691389.

bernstein-session-id: 1787691389


Made by bernstein v3.18.0 - unattended run run-20260825T204053p3974698Z, no operator in the loop.

@chernistry
chernistry enabled auto-merge August 25, 2026 21:00
@chernistry
chernistry added this pull request to the merge queue Aug 25, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Aug 25, 2026
@chernistry
chernistry added this pull request to the merge queue Aug 26, 2026
Merged via the queue into main with commit 5961e0d Aug 26, 2026
55 of 56 checks passed
@chernistry
chernistry deleted the run-20260825T204053p3974698Z branch August 26, 2026 11:29
jm27 pushed a commit to jm27/bernstein that referenced this pull request Aug 26, 2026
…urdrink-ltd#4602)

## Problem

`SSOAuthMiddleware.dispatch` gates its unauthenticated pass-through on
`auth_disabled_via_opt_out()` alone — a live read of
`BERNSTEIN_AUTH_DISABLED`. The constructor still resolves the factory
argument (`auth.enabled: false` in configuration arrives as
`auth_disabled=True`) into `self._auth_disabled`, but nothing reads that
attribute any more. The regression shipped inside sipyourdrink-ltd#4577, which is about
skill collision guards; the middleware line was unrelated to that
change.

Net effect: a deployment that disables auth by configuration logs the
loud "auth is DISABLED" warning at startup and then returns 401 on every
protected route anyway. The documented opt-out surface
(`docs/security/manager-auth.md`) no longer matched behaviour.

## Fix

Dispatch honours both signals:

```python
if self._auth_disabled or auth_disabled_via_opt_out():
```

The live environment read is kept on purpose — a variable exported after
the middleware stack is built still counts, which is the one property
the sipyourdrink-ltd#4577 change added.

## Tests

- `test_config_resolved_opt_out_survives_without_the_env_var` —
`auth_disabled=True` from the factory bypasses the gate with no env var
set; fails before this fix.
- `test_env_opt_out_set_after_construction_still_counts` — pins the
live-read property so honouring the flag cannot regress the env path.

Both run in the existing `test_auth_middleware_defaults.py` suite (33
passed).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Skills lock cannot tell two plugin packs apart, so pack-vs-pack installs still clobber silently

1 participant