docs: drop internal Part A/B/C/D/E labels from public docs

"Part A/B/C/D/E" is our internal decomposition (tracked in .claude/plan.md
and referenced in commit messages + GitHub issues). It leaked into
user-facing docs during v0.26.0 release prep. Users don't care about our
internal breakdown — they care about features and versions.

Cleanup:
- README.md: "New in v0.26.0" bullets now describe features by name only,
  (vX.Y.Z) version tags retained where present
- SECURITY.md: v0.26.0 hardening entries grouped by feature name, not Part
- CONTRIBUTING.md: module tree annotations use (v0.26.0) not (v0.26.0 Part X)

.claude/CLAUDE.md: added explicit rule under Release Checklist terminology
stating that Part X labels are internal-only and must NOT appear in public
docs. Prevents the same mistake next release.

.claude/plan.md + commit messages continue to use Part X — that's the
correct venue for internal dev decomposition.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alpamys 2026-04-20 22:05:47 +05:00
parent 899ad8edf7
commit 0034628b03
4 changed files with 14 additions and 13 deletions

View File

@ -440,6 +440,7 @@ soup version # Show version (--full for details)
- **"Phase"** = a single version release (e.g. v0.26.0). NOT individual sub-Parts (A/B/C/D/E).
- **"Part"** = a chunk of work within a phase (e.g. v0.26.0 Part A = Model Registry). Parts are an internal decomposition for TDD + review efficiency, not for separate releases.
- **One release per phase.** All Parts ship together under a single tag. Bumping version before all Parts land is fine; tagging is ONE time per phase.
- **"Part A/B/C/D/E" is internal-only terminology** — it belongs in `.claude/plan.md`, `.claude/CLAUDE.md`, commit messages, and GitHub issues. It **must NOT** appear in user-facing docs: `README.md`, `SECURITY.md`, `CONTRIBUTING.md`, `examples/README.md`, release notes. Users care about features and versions, not our internal breakdown. In public docs, describe each feature by its user-facing name only (e.g. "Local Model Registry"), with an optional `(vX.Y.Z)` tag to show when it shipped.
**Multi-part phases (A, B, C…):** implement part by part. Write tests FIRST (TDD), then implement to pass them. Run `ruff check soup_cli/ tests/` + `pytest tests/ -v --tb=short` after each part to catch issues early. Commits CAN be split per Part (for bisect clarity) but the release / tag / PyPI publish happens ONCE after all Parts pass the full checklist. Only proceed to the Release Checklist below after ALL parts pass lint + tests.

View File

@ -103,9 +103,9 @@ soup_cli/
migrate/ - Config migration (LLaMA-Factory, Axolotl, Unsloth)
recipes/ - Ready-made configs for popular models (43 recipes)
autopilot/ - Zero-config decision engine (v0.25.0)
registry/ - Model Registry (hashing, store, diff) (v0.26.0 Part A)
cans/ - Shareable .can artifact format (v0.26.0 Part E)
data/traces/ - Trace-to-Preference harvester (v0.26.0 Part C)
registry/ - Model Registry (hashing, store, diff) (v0.26.0)
cans/ - Shareable .can artifact format (v0.26.0)
data/traces/ - Trace-to-Preference harvester (v0.26.0)
utils/ - GPU, errors, MoE, GaLore, QAT, Unsloth, vLLM, SGLang, Liger, FlashAttn, FSDP, Ring Attention, long-context, quality, curriculum, freeze, dataset-registry, mlx, peft_builder, paths
ui/ - Web UI (FastAPI + HTML/JS SPA)

View File

@ -40,11 +40,11 @@ soup train
The flywheel: **Train -> Registry -> Deploy -> Observe -> Improve -> Train**.
- **Local Model Registry** (Part A) `soup registry push/list/show/diff/search/promote/delete`: track every fine-tune with lineage, config, and eval baseline. `soup history <name>` renders the full DAG. Backing store: `~/.soup/registry.db`.
- **Eval-Gated Training** (Part B) `training.eval_gate` (or `soup train --gate evals/gate.yaml`) runs a declarative suite at epoch boundaries and halts training on regression. `soup eval gate` for post-hoc verdicts. Baselines may be `registry://<id>`, a file, or omitted.
- **Trace-to-Preference** (Part C) `soup data from-traces` ingests LangChain / OpenAI / Soup-serve logs, builds DPO/KTO-ready preference pairs from thumbs, regenerations, or user edits. `soup data review` previews pairs before training.
- **Quant-Lobotomy Checker** (Part D) `soup eval quant-check --before X --after Y --tasks t.jsonl` renders an OK / MINOR / MAJOR verdict per task so you never ship a quantization regression unknowingly.
- **Soup Cans** (Part E) `.can` = tar.gz of manifest + config + data_ref. `soup can pack/inspect/verify/fork` makes recipes shareable + reproducible; safe tar extraction blocks symlink / path-traversal escape; 100 MB cap; format version locked to 1.
- **Local Model Registry**`soup registry push/list/show/diff/search/promote/delete`: track every fine-tune with lineage, config, and eval baseline. `soup history <name>` renders the full DAG. Backing store: `~/.soup/registry.db`.
- **Eval-Gated Training**`training.eval_gate` (or `soup train --gate evals/gate.yaml`) runs a declarative suite at epoch boundaries and halts training on regression. `soup eval gate` for post-hoc verdicts. Baselines may be `registry://<id>`, a file, or omitted.
- **Trace-to-Preference**`soup data from-traces` ingests LangChain / OpenAI / Soup-serve logs, builds DPO/KTO-ready preference pairs from thumbs, regenerations, or user edits. `soup data review` previews pairs before training.
- **Quant-Lobotomy Checker**`soup eval quant-check --before X --after Y --tasks t.jsonl` renders an OK / MINOR / MAJOR verdict per task so you never ship a quantization regression unknowingly.
- **Soup Cans**`.can` = tar.gz of manifest + config + data_ref. `soup can pack/inspect/verify/fork` makes recipes shareable + reproducible; safe tar extraction blocks symlink / path-traversal escape; 100 MB cap; format version locked to 1.
- **Security-hardened**: name/tag validation; SQL LIKE-wildcard escaping; Windows-safe path containment via shared `os.path.realpath + commonpath`; SSRF allowlist on judge URLs; HTTPS-only `DataRef`; dunder-key / null-byte rejection in can-fork; cycle detection in lineage walks; structured-error-as-regression policy in eval gate.
### New in v0.25.0 — "Beyond the Wrapper"

View File

@ -130,11 +130,11 @@ No known critical vulnerabilities in current releases.
- **v0.24.1**: AWQ/GPTQ output path traversal validation moved before import check (previously unreachable when autoawq/auto-gptq not installed), Windows Unicode fix for Rich console output (replaced non-ASCII symbols with ASCII equivalents)
- **v0.24.2**: Chat proxy SSRF protection (localhost-only HTTP, HTTPS for remote), chat proxy max_tokens capped at 16384 + temperature/top_p bounded, chat proxy Bearer token auth required, XSS prevention (HTML-escape before markdown render), runs compare max 5 runs, config from-form validates via load_config_from_string, SSE read endpoints no auth (GET)
- **v0.25.0**: Tool-calling JSON-only parsing (no eval), RLVR math_verify regex-extracted numerics (no eval), code_exec 5s timeout + 512MB RLIMIT on POSIX + ephemeral cwd + socket patch + `python -I -S` + 10KB output cap, verifiable_domain Literal constraint, LoRA PEFT mutual exclusion (DoRA/VeRA/OLoRA), data augment path containment + caps, forgetting_detection bounds, checkpoint_intelligence bounds + symlink refusal, autopilot path containment (realpath + commonpath) + goal Literal + GPU/time budget bounds, MLX trainers no trust_remote_code
- **v0.26.0 Part A — Registry**: name/tag validation (alphanumeric + `_-.` only, null-byte rejected, name ≤128 / tag ≤64 chars), artifact path containment (default `enforce_cwd=True` via `os.path.realpath + commonpath`, stored path is realpath), SQL LIKE wildcard escaping (`%` and `_` escaped with `ESCAPE '\\'` in `search()` and prefix `resolve()`), DB 600 perms on POSIX, lineage indirect-cycle detection (BFS ancestor walk before insert), CLI Rich markup escaped everywhere, `resolve()` raises `AmbiguousRefError` on ambiguous prefix (no silent None)
- **v0.26.0 Part B — Eval Gate**: suite path via shared `utils/paths.is_under_cwd` containment, `regression_threshold` [0.0, 1.0], `every_n_epochs` [1, 100], `on_regression` Literal ("stop"/"warn"/"continue"), `GateTask.tasks`/`prompts` null-byte rejection, `judge_model` URL scheme allowlist (`ollama://`, `https://`, `http://localhost`/`http://127.0.0.1`) — SSRF hardening, callback fails-safe: structured errors treated as regressions under `on_regression="stop"`
- **v0.26.0 Part C — Trace-to-Preference**: input/output path containment via shared `is_under_cwd`, trace line cap 100,000, `--format`/`--signal` Literal validation, PII warning panel before every run, JSON-only parsing (no eval), malformed JSON lines skipped silently
- **v0.26.0 Part D — Quant-Lobotomy**: `--before`/`--after`/`--tasks` all containment-checked, `registry://` refs support optional `kinds` filter to avoid picking the wrong artifact, format Literal validated
- **v0.26.0 Part E — Soup Cans**: Manifest format version pinned to 1; name alphanumeric+`_-.`; author max 128 chars, no null bytes/newlines; created_at must parse via `datetime.fromisoformat`; description max 4096; DataRef URL HTTPS-only; hf_dataset regex-validated; tar extraction uses `filter="data"` on Python 3.12+, fallback only on `TypeError`/`AttributeError` (not `TarError`); manual symlink/hardlink rejection + `commonpath` check; 100 MB size cap on pack + fork; dunder-key (`__*__`) and null-byte rejection in fork modifications to prevent prototype pollution; inspect/read_config refuse paths outside cwd
- **v0.26.0 — Registry**: name/tag validation (alphanumeric + `_-.` only, null-byte rejected, name ≤128 / tag ≤64 chars), artifact path containment (default `enforce_cwd=True` via `os.path.realpath + commonpath`, stored path is realpath), SQL LIKE wildcard escaping (`%` and `_` escaped with `ESCAPE '\\'` in `search()` and prefix `resolve()`), DB 600 perms on POSIX, lineage indirect-cycle detection (BFS ancestor walk before insert), CLI Rich markup escaped everywhere, `resolve()` raises `AmbiguousRefError` on ambiguous prefix (no silent None)
- **v0.26.0 — Eval Gate**: suite path via shared `utils/paths.is_under_cwd` containment, `regression_threshold` [0.0, 1.0], `every_n_epochs` [1, 100], `on_regression` Literal ("stop"/"warn"/"continue"), `GateTask.tasks`/`prompts` null-byte rejection, `judge_model` URL scheme allowlist (`ollama://`, `https://`, `http://localhost`/`http://127.0.0.1`) — SSRF hardening, callback fails-safe: structured errors treated as regressions under `on_regression="stop"`
- **v0.26.0 — Trace-to-Preference**: input/output path containment via shared `is_under_cwd`, trace line cap 100,000, `--format`/`--signal` Literal validation, PII warning panel before every run, JSON-only parsing (no eval), malformed JSON lines skipped silently
- **v0.26.0 — Quant-Lobotomy**: `--before`/`--after`/`--tasks` all containment-checked, `registry://` refs support optional `kinds` filter to avoid picking the wrong artifact, format Literal validated
- **v0.26.0 — Soup Cans**: Manifest format version pinned to 1; name alphanumeric+`_-.`; author max 128 chars, no null bytes/newlines; created_at must parse via `datetime.fromisoformat`; description max 4096; DataRef URL HTTPS-only; hf_dataset regex-validated; tar extraction uses `filter="data"` on Python 3.12+, fallback only on `TypeError`/`AttributeError` (not `TarError`); manual symlink/hardlink rejection + `commonpath` check; 100 MB size cap on pack + fork; dunder-key (`__*__`) and null-byte rejection in fork modifications to prevent prototype pollution; inspect/read_config refuse paths outside cwd
## Security Scanning