Files
club-3090/.gitignore
noonghunna bc815b3272 feat(byo): apply-swap — download + serve a Route-C fine-tune (#628)
* feat(byo): apply-swap — download + serve a Route-C fine-tune

A curated-arch fine-tune (e.g. josefprusa/ThinkingCap-Qwen3.6-27B AutoRound
→ qwen3.6-27b) hard-stops at the pull gate's stratum-5 no-fit-model (correct
— nothing to price), so the c3 Bring [D] download failed with "download did
not complete". Route-C was pure guidance ("clone the compose, point --model
at your weights") with no code behind it — the deferred "swap_path apply".

Build it as a DISTINCT action that never touches the locked 6-stratum gate:

- scripts/lib/profiles/swap_apply.py (new): resolve the Route-C swap
  (arch→curated sibling + has_mtp_head from deriver), download the brought
  weights SHA-verified via downloader.download_model (a minimal EInput), and
  emit a serve-locally compose that CLONES the --profile-like sibling's REAL
  compose (keeping its curated chat-template / reasoning+tool parsers / MTP
  wiring — NOT the derived-vllm template, which drops all that) with --model
  re-pointed at a `<weights>:/brought-model:ro` mount, --served-model-name set
  to the brought basename, and --speculative-config kept iff the checkpoint
  carries an MTP head (else dropped). Written alongside the sibling compose as
  `_brought-<san>.yml` (gitignored) so its relative ../ mounts resolve.
- scripts/pull.sh: intercept `--apply-swap` in the wrapper (strictly additive,
  like --json) → run the apply-swap action; prints `[apply-swap] compose: …`.
  The gate path is byte-unchanged without the flag.
- c3: services.run_bring_download gains `apply_swap=` (appends --apply-swap +
  captures the emitted compose via last_swap_compose()); the [D] worker passes
  it on route==C and stashes the compose; ② Serve serves that swap compose
  directly (serve_generated) instead of a reproduction of the sibling's own
  catalog compose.
- pull.py: fix the stale NOTE — "the bf16 base won't fit and lacks the MTP
  head" → the base HAS the head; now just the size reason.

Tests: test-pull-swap.sh section 4 (emit: --model repointed, MTP kept/dropped
by head presence, curated flags + JSON args survive the YAML round-trip,
distinct container_name); test_services apply_swap flag + compose capture. The
locked-gate hard-stop tests stay green; --json fit-check byte-identical.
Validated live: pull.sh --json still no-fit-model+route-C, and apply_swap emits
a correct ThinkingCap swap compose (MTP kept).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm

* c3: reframe Route-C fit-check card as ✓ Servable + a clear [D] action

The fit-check card for a curated-arch fine-tune (Route-C swap) was
self-contradicting: a RED "not eligible" + a bare "no-fit-model" token at
the top, then a GREEN "② Serve is armed with <sibling>" at the bottom —
which read as a dead-end AND named the wrong model (the sibling, not the
brought fine-tune). The engine's "no-fit-model" is the *means* (generic
fit-math can't price a curated-hybrid arch), not the user's answer; the
outcome is servable via the sibling's recipe.

Reframe the Route-C case in _byo_result_text:
- green "✓ Servable — a fine-tune of <sibling>" instead of red "not eligible",
- one plain "How it serves" line (reuses the sibling's chat-template / tools /
  spec-dec with your weights) instead of the --quantization/impl bullets,
- MTP kept/dropped line from has_mtp_head,
- the next-step is an explicit "→ Press [D] to download + serve <BROUGHT model>"
  (the fine-tune, not the sibling) — which #628's --apply-swap now fulfils,
- raw verdict + backend note dimmed for debugging, not the headline.

Non-swap cases (eligible / Route A / B / plain no-fit) are byte-unchanged.
Regression test added; c3 fast suite green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm

---------

Co-authored-by: noonghunna <10742901+noonghunna@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 05:50:16 +05:00

73 lines
2.3 KiB
Plaintext

# Model weights — never commit. Default download dir is models-cache/ (set
# via MODEL_DIR env var if you want a different path).
models-cache/
*.safetensors
*.gguf
*.bin
# Genesis patches fetched by setup.sh (upstream, not ours to vendor).
# Lives at models/<model>/vllm/patches/genesis/ in the new layout.
# No trailing slash — also matches local symlinks pointing at out-of-tree clones.
models/*/vllm/patches/genesis
# v0.8.0 [E] Pull-Emit-Derived runtime capture artifacts (the §6 capture
# points + manifest; consumed by the later [F] Loop phase). Per-run output,
# never committed.
.pull-captures/
# serve-cockpit producer lane ② Serve — temp composes generated by
# generate-compose.sh (CockpitData.generate_compose). Written under the repo
# root so their relative ../ mounts resolve; cleaned up on serve/decline, but
# gitignored so a crash-leftover never lands in `git add -A`.
c3-genc-*.yml
# BYO Route-C apply-swap serve-locally composes (pull.sh --apply-swap): a clone
# of the sibling compose with --model → the brought weights, written IN the
# sibling's compose dir so its relative ../ mounts resolve. Generated artifact.
_brought-*.yml
# Python
__pycache__/
*.pyc
*.pyo
*.egg-info/
.venv/
venv/
# Editor
.vscode/
.idea/
*.swp
.DS_Store
# Docker compose state
**/compose/*.log
# Local env overrides
.env
*.env.local
# Local safety backups of compose files (e.g. docker-compose.yml.default)
**/compose/*.default
# Patched vLLM source clone (volume-mounted by dual-card composes)
vllm-src/
# Internal diagnostics / feasibility memos — kept local, not published.
# Per-model published diagnostics live at models/<name>/vllm/diagnostics/.
docs/diagnostics/
# Bench output. Most runs are intermediate investigations (cliff probes, soak
# validation matrices, residency instrumentation) — those live in issue threads
# and gitignored docs/diagnostics/. Bench evidence backing numbers in BENCHMARKS.md
# / STRUCTURED_COT.md / CHANGELOG is tracked via the negations below; future
# grammar-ab-* and grammar-full-* runs will auto-track when committed.
results/*
!results/grammar-ab-*/
!results/grammar-full-*/
!results/lucebox-*/
!results/v0.20-migration/
# #252: curated quality-baseline corpus (committed; the trusted n>=3 aggregates
# `quality-baseline.sh` diffs fresh runs against). Run output elsewhere stays ignored.
!results/baselines/