Skip to content

refactor(models): isolate saved-routing read authority #389

Description

@decode2

Outcome

Extract one shared production read authority for saved model routing. This issue owns shared routing types and normalization, synchronous and asynchronous authority reads, and minimal compatibility wrappers used by existing production callers. The wrappers must preserve every current caller behavior, including project-invalid collapse where the current caller expects that result. Direct export migration and export contract tests move to #395. Apply, UI, status, canonical, and durable-write work remain in later slices.

Chain context

Dependency diagram:

main
  └─ 📍 #389 shared types/normalization, sync/async authority, compatibility wrappers
       └─ #396 fail-closed apply and profile safety
            └─ #395 direct export contract/tests plus UI/lifecycle consumers
                 └─ #391 canonical names and target authority
                      └─ durable write
                           └─ materialization

Scope and acceptance criteria

  • Extract the existing routing types and model-entry/config normalization, including normalizeModelId, normalizeRoutingEntry, and normalizeModelConfig, into one shared production module.
  • Provide shared synchronous and asynchronous file-read wrappers that distinguish missing, valid, and invalid results and carry the invalid source path.
  • Route existing production callers through minimal compatibility wrappers around the shared authority. Preserve all current wrapper behavior, including project-invalid collapse where the current caller expects it. Do not directly migrate export, apply, UI, or status behavior in this issue.
  • Keep the shared authority production-reachable through compatibility wrappers used by existing callers. Production reachability must not depend on __testing or a test-only caller.
  • Keep synchronous and asynchronous production reads in agreement for missing, valid, and invalid sources, including invalid-global no-fallback behavior as currently observed by the wrappers.
  • Add authority-level behavior tests for shared types, normalization, sync and async status parity, source-path preservation, and compatibility-wrapper behavior. Keep these tests focused on authority extraction. Direct export and real-export tests belong to refactor(models): migrate routing UI and lifecycle consumers #395.
  • Explicitly create every test fixture directory before writing fixtures, including any root/agents directory used by discovery-adjacent authority tests.
  • Preserve the current metadata name parser and grammar, target paths, writes, JSON null behavior, literal string inherit behavior, omission semantics, apply behavior, startup behavior, and profile materialization.

Candidate allocation

The frozen 455 A+D candidate is being resliced without opening a new issue. Module work of 112 lines, the authority extraction and compatibility-wrapper hunks, and the authority test setup and tests from lines 1-118 belong to #389. The direct export hunk and export or real-caller tests from lines 120-196 move to #395. No safety test is deleted. The later slice may reuse established scaffolding without duplicating the safety proof.

Intentionally out of scope

Strict TDD and verification

Strict TDD is required. The RED phase must be an executable assertion-level failure after dependency hydration, not a missing-module or environment error. The current governance snapshot records assertion-level RED and focused GREEN 4/4 for the combined candidate only. It is not issue completion evidence for this extraction slice. The implementation PR must report its own observed evidence before claiming completion.

Environment prerequisite: use an authorized implementation environment with dependencies hydrated by the repository package manager, pnpm@11.1.1, including @earendil-works/pi-tui.

Run the focused and package-supported commands after the behavior tests exist:

node --experimental-strip-types --test tests/model-routing-authority.test.ts
node --experimental-strip-types --test tests/gentle-ai.test.ts
pnpm test
  • RED: add the smallest assertions for shared normalization, missing, valid, and invalid sync and async authority results, invalid source-path preservation, invalid-global no-fallback through the compatibility wrappers, and project-invalid collapse where current callers require it. Record the observed assertion-level failures after dependencies are available.
  • GREEN: extract the shared types, normalizer, and sync/async authority, then route existing production callers through minimal compatibility wrappers without changing their observable behavior. Record the focused test result.
  • TRIANGULATE: cover missing, valid, and invalid global/project sources, sync and async parity, wrapper behavior, invalid source paths, literal inherit, JSON null, omissions, existing target and path semantics, and explicit fixture-directory creation. Do not add direct export, apply, profile-safety, UI, or status migration proof here.
  • REFACTOR: remove superseded duplicate authority helpers without changing behavior, then rerun the focused commands and check-only syntax validation.

Review workload forecast and hard stop

Forecast only, measured against the clean immediate main base: 245 lower / 285 realistic / 335 upper A+D. The hard stop is above 400 A+D. No size:exception is permitted. If the clean diff exceeds 400, stop before publication and return to design for another causal split. Do not line-golf the diff or remove the authority tests.

Activity

  1. added
    enhancementNew feature or request
    status:approvedIssue approved by maintainer; PR may be opened
    and removed
    status:approvedIssue approved by maintainer; PR may be opened
    on Aug 21, 2026
  2. decode2 commented on Aug 21, 2026

    @decode2
    MemberAuthor

    The frozen #389 candidate is stopped at exactly 519 A+D, 354 additions and 165 deletions, above the hard cap of 400. There is no behavioral RED: the focused command failed before test execution because dependencies, including @earendil-works/pi-tui, are absent.

    Proposed stacked-to-main reslice: keep #389 as the shared read-authority and fail-closed unit, then create a separate Unit 2 issue for strict canonical config names and explicit target/profile alias authority. The candidate remains frozen and uncommitted. This hold grants no code, implementation, merge, or publication authority; #389 requires exact body review and human authorization before status:approved is restored, while Unit 2 starts at status:needs-review.

  3. changed the title [-]refactor(models): isolate and validate saved routing authority[/-] [+]refactor(models): isolate saved-routing read authority[/+] on Aug 21, 2026
  4. decode2 commented on Aug 22, 2026

    @decode2
    MemberAuthor

    The current #389 candidate is 449 A+D, 49 lines over the 400-line cap. The hard stop was honored. Evidence is assertion-level RED + focused GREEN 3/3 only, with no broader verification. No commit, push, or PR was made.

    A causal split is being applied: #389 retains the shared routing authority and fail-closed apply/export behavior, followed by a dependent UI/lifecycle consumer child, then #391.

  5. added
    status:approvedIssue approved by maintainer; PR may be opened
    and removed
    status:approvedIssue approved by maintainer; PR may be opened
    on Aug 22, 2026
  6. decode2 commented on Aug 22, 2026

    @decode2
    MemberAuthor

    The frozen candidate reached 462 A+D, which is 62 over the 400-line cap. The exact focused RED command produced 6 assertion-level failures. No GREEN result or broader verification was run.

    The hard stop is honored. No commit, push, or PR was made. We are applying a new causal split: #389 keeps shared types and normalization, sync/async authority, and the real export path; a new dependent child owns fail-closed apply behavior and the profile byte, mtime, and no-write proof; #395 and #391 remain later dependent slices.

  7. added
    status:approvedIssue approved by maintainer; PR may be opened
    and removed
    status:approvedIssue approved by maintainer; PR may be opened
    on Aug 22, 2026
  8. decode2 commented on Aug 22, 2026

    @decode2
    MemberAuthor

    The frozen candidate is 455 A+D, which is 55 lines over the 400-line hard stop. The exact recorded evidence is assertion-level RED followed by focused GREEN 4/4 only. No broader verification is claimed.

    The hard stop is in force. No commit, push, or PR was made.

    We are not opening a new issue. The candidate is being redistributed across the existing chain:

    This exact extraction versus export and UI redistribution is intended to recover reviewability without a size exception or a new issue. Hold and approval changes require separate exact human review.

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

    enhancementNew feature or requeststatus:approvedIssue approved by maintainer; PR may be opened

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions