Skip to content

#870 stage A: catalog-backed H3 adapter partition check #888

Closed

Description

@dkackman

Stage A of #870 (the whole feature). Plan: plan v2, "Stage A: catalog-backed adapter check". The plan comment is authoritative; this restates it.

Reshaped for plan v2 (Don's ruling (a) on this stage's stop). What changed since the v1 body:

  • Only a proven entry can refuse. A conflicting trial/rejected entry only warns, naming the entry and its status.
  • There is one shared catalog with no per-workspace layering, and the index is cached per catalog listing.
  • Acceptance intent 7 is now "shipped trial entries only warn, and give the same result in every workspace". It replaces v1's workspace layering.

Builds

Plan v2 Design items 1-6:

  1. dw/adapter_compatibility.py takes an optional catalog index (model_name, weight_name) -> (entry name, workflows, status), built from entries that declare a workflow. Revision is ignored (Q2). With no index, behavior is exactly today's.

  2. An entry decides the partition: all of {t2va, fl2va} -> transformer; ref2va -> transformer_ref; a mix decides nothing.

  3. Order, gated by the entry's status:

    • proven entry that decides: a conflict with the step's partition is an error naming the entry ("catalog entry minimax-h3/realism-people (proven) lists it for t2va, which denoises against transformer"). Agreement clears the step with no "names neither" warning.
    • trial or rejected entry that decides: a conflict is a warning naming the entry and its status, never an error. Agreement clears "names neither", but a filename-token error still stands.
    • Uncovered file, or null or mixed workflow: the filename rule runs unchanged.
    • A proven entry that disagrees with a filename token gives a warning naming both, never an error (Q1). A filename-token error is kept only when no proven entry decides the other way.
  4. The catalog is one library shared by every workspace (server_lora_library(state), dw/server/deps.py:386, which takes no workspace). Only server callers pass the index:

    • /api/validate (MCP validate_workflow);
    • submit and rerun admission;
    • save and enhance-admit in routes/library.py.

    Build it from the same catalog_entries(state) that list_loras reads, and cache it per catalog listing the way ceiling_index is (deps.py:165). The CLI dw.validate, the worker's sub-workflow re-validation and warn_adapters pass none, so the server is stricter than the worker, never looser.

  5. The index is built once per catalog listing (cached), looked up per step, and never rebuilt per step or per for_each member.

  6. Data and docs:

    • loras/minimax-h3/realism-people.json: workflow -> ["t2va","fl2va"], plus an evidence note for the h3-quality matrix (R3, 4/5 faces on FL2VA/I2VA; the ref2va run inert). use_when says "not reference-to-video". It stays proven.
    • plugins/dw/skills/minimax-h3/references/checkpoints-and-loras.md:28-33: change only "validate warns the name fits neither partition" to "validate refuses it on ref2va".
    • Catalog-first rule in the module docstring, docs/ARCHITECTURE.md:105, docs/SERVER.md:368-375 and docs/LORAS.md. The server's validate enforces a proven entry's workflow; a trial entry's only warns; promoting an entry to proven is what makes it refuse.

Don's answers: Q1 warn on a catalog/filename disagreement; Q2 ignore the revision; Q3 not needed (a future save_lora pre-fill would use base_model only). The status rule is his ruling (a).

Owes

  • tests/test_h3_adapters.py:
    • a proven catalogued no-token file is an error on ref2va and clean on fl2va/t2va;
    • the same file under a trial (and a rejected) entry is a warning naming the entry on ref2va, not an error, and clean on fl2va;
    • no index gives today's "names neither" warning;
    • a null or mixed workflow falls back to the filename rule;
    • a proven entry that disagrees with the filename token gives a warning, not an error;
    • a trial entry never lifts a filename-token error;
    • the arguments.<name> path is kept for a variable-supplied value;
    • one index build per catalog listing, including a for_each step.
  • The existing sweep of every workflows/**/*.json also runs with the packaged catalog and stays error-free.
  • The docs in item 6.

Deploy

Server (engine plus loras/ data); restart on lem and mini-ai.

Passes when

The plan's acceptance intent 1-8 holds over MCP:

  • Realism People is refused on ref2va, and no job is created.
  • Realism People is clean on t2va/fl2va, with no "names neither" warning.
  • Uncatalogued files keep today's rule.
  • A variable-supplied value keeps the arguments.<name> path.
  • list_loras shows the new entry.
  • The shipped trial entries wushu-action-reference (on t2va) and better-human-motion (on ref2va) are valid with a warning naming the entry, and the result is the same in two workspaces.
  • Every catalog template validates clean.

It also passes every pending: #<this issue> case the tester writes.

No blockers.

Filed by the lead, claude-opus-5-5 / anthropic, decomposing plan v1; body reshaped for plan v2 by the lead, claude-opus-5-5 / anthropic.

Activity

  1. added
    featureWork bigger than a fix: designed with Don, built in stages (harnest R11)
    owner:leadFeature lead's turn (harnest R11)
    stageA child issue: one stage of a feature
    on Oct 14, 2026
  2. dkackman commented on Oct 14, 2026

    @dkackman
    OwnerAuthor

    Build stopped: plan v1 assumption fails against the code. (lead, claude-opus-5-5 / anthropic)

    Plan v1 design item 4 and acceptance intent 7 assume the LoRA catalog is layered per workspace ("scoped to the caller's selected workspace"; "with another workspace selected, the same validate only warns"). It isn't:

    • server_lora_library(state) (dw/server/deps.py:386) is "shared by every workspace": the server's loras/ (writable), then the examples' loras/. It takes no workspace.
    • catalog_entries(state) and the save_lora route (PUT /api/loras/{name}) take no workspace either, and docs/LORAS.md:141 documents the catalog as "writable, shared by every workspace".

    So a save_lora trial entry in a "qa-* workspace" lands in the one shared catalog and would refuse the file in every workspace. Intent 7 can't pass as written. The plan's first risk mitigation ("the workspace layering confines the effect" of a careless agent-written entry) doesn't hold either: one wrong entry would block valid runs server-wide.

    Everything else checks out: workflow lists are already in the catalog schema and data, and validation already has a per-request catalog-index precedent (ceiling_index, cached per listing in deps.py:165) to copy.

    Options for plan v2 (Don's call):

    • (a) Recommended: keep the shared catalog and drop intent 7. Mitigate the agent-writable risk another way: only a proven entry refuses, and a trial entry that decides against the step only warns, naming the entry. No new surface.
    • (b) Make the LoRA catalog workspace-layered (a workspace loras/ in front of the shared one, plus save_lora/list_loras workspace scoping). That is new MCP/REST behavior and a larger stage.

    Nothing is built and nothing is pushed for this stage.

  3. added
    owner:donParked for human decision
    status:needs-approvalParked pending a written proposal + human approval
    and removed
    owner:leadFeature lead's turn (harnest R11)
    on Oct 14, 2026
  4. dkackman commented on Oct 14, 2026

    @dkackman
    OwnerAuthor

    Parked by the loop driver: 2 sessions in a row ended without changing this issue's state or labels (NO_PROGRESS_PARK_AFTER=2), so the next cycle would run the same session again. Read the latest session comments, then hand it back with owner:lead and without status:needs-approval, or decide it here.

  5. dkackman commented on Oct 14, 2026

    @dkackman
    OwnerAuthor

    Don ruled (a) on #870 (2026-10-14). Back to the lead for plan v2 and re-spec.

  6. added
    owner:leadFeature lead's turn (harnest R11)
    and removed
    owner:donParked for human decision
    status:needs-approvalParked pending a written proposal + human approval
    on Oct 14, 2026
  7. dkackman commented on Oct 14, 2026

    @dkackman
    OwnerAuthor

    Body reshaped for #870 plan v2 (Don's ruling (a)): only a proven catalog entry refuses, and a trial/rejected one only warns, naming the entry. There is one shared catalog cached per listing, with no workspace layering. Acceptance intent 7 is replaced. Scope is narrower than v1. lead, claude-opus-5-5 / anthropic

  8. added a commit that references this issue on Oct 14, 2026
  9. dkackman commented on Oct 14, 2026

    @dkackman
    OwnerAuthor

    Stage A handed to the tester. (lead, claude-opus-5-5 / anthropic)

    What shipped: feat/870-A-catalog-adapter-check (2767429, 687e288), merged to develop as 9a21058. An earlier session built and merged it but ended before handing off. This session reviewed the diff against plan v2. lem is already on develop @ f73088a, which contains 9a21058, so I didn't redeploy. mini-ai isn't deployed from the agents' loop; the plan's "restart on mini-ai" is Don's.

    Plan v2 coverage:

    1. Lookup: adapter_compatibility.catalog_index(entries) returns (model_name, weight_name) -> (entry, workflows, status). Revision is ignored. With no index, the result is today's rule (test_no_index_is_todays_rule).

    2. Partition: _catalog_partition maps all of {t2va,fl2va} to transformer and ref2va to transformer_ref. A mix decides nothing (test_a_null_or_mixed_workflow_falls_back_to_the_name).

    3. Status order:

      • A proven conflict is an error naming the entry ("catalog entry 'minimax-h3/realism-people' (proven) lists it for 't2va, fl2va', which denoises against 'transformer'…").
      • A trial/rejected conflict is a warning naming the entry and its status.
      • An agreeing trial entry clears "names neither", but never lifts a file-name error.
      • A proven entry that disagrees with a file-name token is a warning naming both.
      • Tests: the test_a_proven_* / test_a_weaker_* cases in tests/test_h3_adapters.py. The arguments.<name> path is pinned by test_the_caller_is_told_where_they_wrote_it.
    4. Callers: deps.lora_index(state) is built from the shared catalog_entries(state), which moved from routes/loras.py to deps.py so list_loras and validation read the same function. It is passed by:

      • admit_for, which covers /api/validate, submit, rerun and enhance-admit;
      • the save path in routes/library.py.

      The CLI, the worker and warn_adapters pass none.

    5. Cost: the index is cached on state.lora_indexes, keyed on the listing's (name, path, mtime). test_one_build_per_listing_for_every_member (server, for_each) and test_a_trial_entry_warns_and_promoting_it_refuses exercise the real server path.

    6. Data and docs:

      • realism-people.json: workflow is now ["t2va","fl2va"], use_when says "not reference-to-video", and there's a new evidence note (issue 870). It stays proven.
      • The skill line now reads "validate refuses it on ref2va".
      • The catalog-first rule is in the module docstring, ARCHITECTURE.md, SERVER.md and LORAS.md.
      • The workflows/**/*.json sweep also runs with the packaged catalog (test_no_stored_workflow_mispairs_an_adapter).

    Deviations:

    • If two entries cover the same file, the index keeps the stronger status (proven > trial > rejected; test_a_stronger_entry_wins_a_shared_file). The plan doesn't address this case.
    • A trial conflict on a no-token file gives the entry's warning in place of "names neither", not both.

    Checks:

    • ruff is clean.
    • pytest: 14481 passed, 17 failed. All 17 are Kandinsky-6 tests (ModuleNotFoundError: diffusers.pipelines.kandinsky6 in this checkout's diffusers) and none touch this stage's files.

    There's no MCP shape change, so this isn't breaking-change.

  10. added and removed
    owner:leadFeature lead's turn (harnest R11)
    on Oct 14, 2026
  11. dkackman commented on Oct 14, 2026

    @dkackman
    OwnerAuthor

    Verified over MCP against lem develop @ f73088a (includes 9a21058), workspace regression-model-specific. Tester: claude-opus-5-5 via anthropic.

    The carrier for every case was a one-step ModularPipeline on MiniMaxAI/MiniMax-H3, varying workflow and loras. Every case marked pending: #888 passes, except M-F146, which was excluded as explained below:

    • M-F142. (a) and (b): Realism-People on ref2va is refused at validate_workflow. (c): run_workflow on templates/minimax/reference-to-video with Realism's lora_model_name/lora_weight_name and acknowledged_cost=true is refused at arguments.lora_weight_name, naming "catalog entry 'minimax-h3/realism-people' (proven)". No job id was returned, and list_jobs still shows 5828e643e28d as the newest job, so nothing was queued.
    • M-F143. The same adapter on t2va and fl2va, and on the video-with-audio and image-to-video templates, is valid with no "names neither" warning.
    • M-F144. Results per sub-case:
      • (a) The fl2v turbo on ref2va is refused, naming minimax-h3/turbo-keyframe (proven).
      • (b) The ref2v turbo on fl2va is refused, but the message is the proven catalog message (minimax-h3/turbo-reference (proven)), not the filename-rule message. Plan v2 lets a proven entry decide, so I count it as a pass.
      • (c) An uncatalogued repo (qa-nonexistent) on t2va, fl2va and ref2va is valid, with "names neither".
      • (d) TaoMate on ref2va and t2va is valid, with "names neither".
      • (e) Realism's file under another repo on ref2va is valid, with "names neither", and the realism entry is not named.
      • (f) Realism with revision:"main" on ref2va is still refused by the catalog.
    • M-F145. list_loras(model=H3, workflow=…, status="proven") lists minimax-h3/realism-people for both t2va and fl2va (workflow ["t2va","fl2va"], adapter check: read the LoRA's safetensors metadata, not just its filename (Realism People LoRA passes on ref2va) #870 evidence, "not reference-to-video" use_when). It is absent for ref2va.
    • M-F147. Every H3 template in shape=shot and shape=sequence validates valid: true, with no adapter error or adapter warning. That is the 17 templates/minimax/* shot templates (video-with-audio, image-to-video and reference-to-video were validated under M-F143 and M-F152(d)) plus dialogue-short and music-video.
    • M-F152. (a) and (b): trial entries on the wrong partition (wushu-action-reference on t2va/fl2va, better-human-motion on ref2va) are valid, with a warning naming the entry, "(trial)" and "promoting it to proven would make it refuse". (c): the right-partition pairs are clean. (d): the template-argument form warns at arguments.lora_weight_name. (e): C(t2va, wushu) and C(ref2va, better-motion) give identical warnings and fingerprints in three cases: with workspace="qa-c870-other", with workspace="regression-model-specific", and after use_workspace("qa-c870-other") with no argument. The scratch workspace is deleted.
    • M-F153. (a) The proven refusal names "(proven)". (b) The ref2v 4-step turbo on t2va, and wushu's fl2va file on ref2va, are each valid: false with the filename-rule error, so a trial entry doesn't lift it. (c) 360-orbit on ref2va is valid, with a "(trial)" warning.

    Not counted: M-F146 is wrong against plan v2, because it assumes per-workspace catalog layering. It was not run, and its pending: #888 line stays until the retire request dkackman/harnest#122 is ruled on. The pending: #888 lines on M-F142–M-F145, M-F147, M-F152 and M-F153 are now removed.

    Not checked: mini-ai (MPS). This verify covers lem only.

  12. added
    status:verifiedTester confirmed the fix via a real MCP call
    and removed on Oct 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureWork bigger than a fix: designed with Don, built in stages (harnest R11)owner:testerTester's turn to actstageA child issue: one stage of a featurestatus:verifiedTester confirmed the fix via a real MCP calltarget:lem

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions