Skip to content

Restore bundled provider/model capabilities when installed runtime config predates them #108

Closed

Description

@NOirBRight

Context

Issue #105's real GLM qualification reached ollama_cloud through CodexHub with HTTP 200, but the first requested core tool was never called and the adapter had nothing to transform.

The retained telemetry shows that the request eagerly expanded 205 App/MCP namespace tools. A bounded A/B isolates the new blocker:

  • Minimal real GLM request with the actual freeform apply_patch schema plus five existing explicit lifecycle/search tools: returns one adapted custom_tool_call in about three seconds.
  • The same request plus 200 synthetic namespace tools: no apply_patch call before the eight-second bound.
  • Therefore Adapt GLM-5.2 apply_patch function calls to the Codex freeform tool contract #105's response adapter is live; eager namespace-tool expansion is the current worker-qualification blocker.

Outcome

Add a generic provider/model capability for a deferred core tool surface so selected external models retain native non-namespace core tools while large App/MCP namespaces are not flattened eagerly. The policy must be configurable and reusable for future third-party models; do not hard-code GLM behavior into routing.

Scope

  • Add a provider/model capability that selects the external tool-surface strategy; preserve the current strategy as the default.
  • Configure Ollama Cloud GLM-5.2 to use the deferred-core strategy.
  • Under that strategy:
    • retain caller-advertised non-namespace core tools such as shell_command and apply_patch;
    • retain the bounded explicit tool_search and collaboration lifecycle tools already required by the compatibility path;
    • do not eagerly flatten App/MCP namespace declarations into hundreds of function tools.
  • Preserve deterministic ordering and fail closed on malformed capability values.
  • Emit sanitized telemetry with strategy, namespace declaration count, eager tool count, retained core count, and deferred count.
  • Do not change official-model behavior, provider routing, retry/fallback, permissions, or Codex's advertised apply_patch contract.
  • Do not claim complete deferred discovery; native/full tool_search lifecycle remains 0.1.8 Beta3: Complete the generic client tool_search lifecycle #63.

Acceptance criteria

  • A committed fast A/B harness reproduces the current failure: minimal surface green; 200-tool namespace surface red before the fix and green after the strategy is applied.
  • GLM receives the configured deferred-core surface without the observed 205-tool eager expansion.
  • Existing/default providers retain current eager namespace behavior.
  • Minimal freeform apply_patch still reaches Adapt GLM-5.2 apply_patch function calls to the Codex freeform tool contract #105's adapter and produces the paired custom/freeform call.
  • The exact Codex CLI qualification completes shell_command -> apply_patch -> shell_command, changes the file exactly once, and retains model=glm-5.2, upstream=ollama_cloud, route_mode=codexhub with no Luna/Terra fallback.
  • Focused protocol/routing tests, full Python suite, report-only quality gate, and two-axis review pass.

Dependencies

Evidence boundary

The failed broad harness also exposed a separate shutdown/reporting weakness, but no orphan process remains. Process cleanup is not part of this Issue unless it prevents the committed bounded A/B harness.

Reopened runtime-configuration inheritance regression (2026-07-15)

The closed delivery above remains historical evidence. This section supersedes its completed acceptance for the regression below.

Problem and facts

  • Restore bundled provider/model capabilities when installed runtime config predates them #108 / PR fix: budget external GLM tool surface #110 introduced the closed tool_surface_strategy capability and bundled Ollama Cloud glm-5.2 configuration for deferred_core; the focused strategy tests pass.
  • A deterministic local comparison shows the bundled configuration resolves ollama-cloud/glm-5.2 to deferred_core, while an installed runtime configuration resolves it to eager when the runtime predates the capability field.
  • In a fresh isolated GLM-5.2 request, the runtime-eager surface expanded 15 namespace declarations into 212 eager namespace tools (217 injected tools total), retained 13 core tools, skipped the requested first shell call, emitted a malformed apply_patch call, and failed closed.

Outcome

Restore generic missing-capability inheritance from bundled provider/model defaults when an installed runtime configuration predates a capability. Resolve the effective capability at the Python Gateway and the Rust/UI configuration persistence/export boundary. An explicit runtime model value wins. No routing behavior may depend on a GLM-specific branch.

Scope

  • Inherit a bundled provider/model capability only when the corresponding runtime entry omits it, using the repository's existing provider/model resolution rules.
  • Preserve explicit runtime model values, including an explicit eager override, and preserve explicit runtime provider values under the existing precedence rules.
  • Carry the resolved, validated value through the Python Gateway and any Rust/UI configuration load, save, merge, or export boundary changed by the implementation.
  • Add deterministic regressions for old runtime configuration, bundled-default resolution, and the resulting prepared external tool surface.

Non-goals

  • No GLM-specific routing branch or caller/request override.
  • No change to provider routing, retry/fallback, tool schema, apply_patch validation, permissions, official-model behavior, or full deferred-discovery work.
  • Do not relax fail-closed validation of malformed capability values.

Acceptance criteria

  • An installed runtime configuration missing the capability inherits the bundled provider/model default; qualified and unqualified Ollama Cloud GLM routes resolve to deferred_core.
  • An explicit runtime model eager value wins over the bundled model default; existing valid defaults and other provider/model behavior stay compatible.
  • Invalid configured capability values still fail closed before external I/O, and official requests remain unchanged.
  • Deterministic tests prove the inherited strategy produces the deferred-core prepared surface rather than eager namespace expansion.
  • Any changed persistence/merge boundary preserves explicit capability values without silently overwriting them.
  • A fresh isolated GLM-5.2 acceptance completes shell_command → apply_patch → shell_command, changes the target exactly once, and retains model=glm-5.2, upstream=ollama_cloud, and route_mode=codexhub with no official-model fallback.

Dependencies

Related: #105 owns the distinct apply_patch compatibility adapter. No dependency is added by this intake.

Expected hotset and parallel ownership

  • src-python/providers_config.py and dedicated provider-capability load/persistence tests, including tests/test_providers_config.py.
  • If needed for the configuration persistence/export boundary: src-tauri/src/config.rs, src-tauri/src/models.rs, and only the affected frontend configuration persistence files/tests.
  • Prohibited/read-only for this Worker: src-python/codex_proxy.py, src-python/config_overlay.py, and tests/test_routing.py. The existing deferred-core transformer is already proven; its error-mapping hotset is reserved for the distinct non-retryable adapter-error Issue.

Execution contract

Execution-Contract: v2

Verification-Class: strict

Verification-Commands: python -m pytest -q tests/test_providers_config.py; python -m pytest -q; python scripts/report_quality_gates.py (report-only; non-blocking). If the candidate changes the Rust configuration boundary: cargo test --manifest-path src-tauri/Cargo.toml. If it changes the frontend configuration boundary: cd frontend; npm run build; npm run test:ui-contract.

Manual-Evidence: One fresh isolated GLM-5.2 shell_command → apply_patch → shell_command acceptance with the exact route identity and no official-model fallback.

Architecture-Decision: resolved

Review-Owner: orchestrator

PR target: dev

Activity

  1. added
    bugSomething isn't working
    ready-for-agentFully specified, ready for an AFK agent
    on Jul 12, 2026
  2. NOirBRight commented on Jul 12, 2026

    @NOirBRight
    OwnerAuthor

    ARCHITECTURE DECISION — approved with bounded refinements

    1. Capability seam: add the closed tool_surface_strategy = eager | deferred_core capability at provider and optional model override; model wins, absence resolves to eager. This is configuration capability, never a model-alias routing branch and never a caller/request override.
    2. Resolve and validate once when provider/model entries are built, then carry only the resolved value in the upstream mapping. Wire both build_external_model_index and build_ollama_cloud_model_index: ollama-cloud is intentionally excluded from the generic index, so GLM would otherwise never receive the override. choose_upstream only copies the resolved capability; compatible_request_body defensively rejects an invalid internal value before upstream I/O. Official routing returns before this resolution.
    3. Surface rule is structural, not a semantic allowlist: preserve caller-advertised non-namespace tool entries unchanged, including shell_command and the freeform apply_patch schema. Strip raw namespace declarations in both modes. eager retains the exact current flattening behavior; deferred_core omits only nested functions that the current namespace flattener would add. Existing explicit functions remain.
    4. Keep the special collaboration lifecycle path separate. Existing lifecycle-gated aliases remain authoritative; do not flatten or defer-count them as ordinary core tools when they came from the special multi_agent_v1 path. Preserve the Adapt GLM-5.2 apply_patch function calls to the Codex freeform tool contract #105-base tool_search exposure if present, but do not newly enable discovery behavior or claim 0.1.8 Beta3: Complete the generic client tool_search lifecycle #63.
    5. Telemetry: emit one sanitized external_tool_surface_prepared event after preparation. Define namespace_declaration_count as raw eligible namespace declarations seen, eager_tool_count as nested functions actually flattened, retained_core_count as surviving caller-advertised non-namespace entries (a structural count, not an allowlist), and deferred_tool_count as nested functions intentionally omitted. Counts only; no names, schemas, IDs, inputs, patch content, or credentials.
    6. Persistence support is required but UI controls are not. Add optional closed-enum fields to Python, Rust, and TypeScript provider/model types, preserve them through TOML load/save, and specifically preserve model overrides through frontend discovery/merge (mergeDiscoveredModels currently rebuilds from the discovered model and can drop prior-only fields). Configure only Ollama Cloud glm-5.2 at model level; leave its provider and all other models on implicit eager.
    7. Invalid configured values fail closed before external I/O with sanitized error/event; official requests and valid legacy/default external payloads remain unchanged. Add exact default/eager payload-equivalence tests plus provider-default/model-override, qualified and unqualified Ollama GLM routes, invalid-value, deterministic-ordering/deduplication, no-raw-namespace, and persistence regressions.
    8. Build the deterministic red harness first. After focused tests are green, run the bounded isolated real CLI shell_command -> apply_patch -> shell_command qualification with exact child/process ownership; no shared Desktop/Gateway configuration mutation and no broad process termination. Open the integration draft PR only after that real qualification passes.

    This Issue comment is the authoritative decision record for this bounded seam. No separate UI feature or full deferred-discovery architecture is authorized in #108.

  3. NOirBRight commented on Jul 13, 2026

    @NOirBRight
    OwnerAuthor

    ARCHITECTURE DECISION ADDENDUM — resolve eager compatibility and fail-closed ordering

    This addendum resolves the conflict between clauses 3 and 7 of the prior decision. The Issue outcome (“preserve the current strategy as the default”) and exact legacy/default payload compatibility take precedence over the universal wording “strip raw namespace declarations in both modes.”

    1. eager is the compatibility adapter and must reproduce the Adapt GLM-5.2 apply_patch function calls to the Codex freeform tool contract #105 baseline (cb1724de) for valid legacy/default external payloads. In particular:
    2. deferred_core is the explicit opt-in normalization. It may promote the legacy additional_tools carrier, remove raw namespace declarations from the outgoing normalized tool surface, retain explicit non-namespace/core tools, and omit nested functions that eager would flatten. Only flatten-eligible declarations contribute to namespace/deferred telemetry counts; opaque namespaces are not reclassified as supported discovery.
    3. Scope the “no raw namespace” regressions to the selected deferred_core normalized surface and to declarations eager actually flattens. Do not use that assertion to change unrelated default/eager payloads.
    4. Include the defensive invalid-strategy ordering repair now. For non-official external routing, resolve/validate the carried strategy before JSON decode so malformed bytes and non-object JSON cannot bypass fail-closed rejection. Keep official passthrough byte-for-byte unchanged and add explicit malformed/non-object official regressions.
    5. No second real GLM qualification is required if the repair does not alter the valid deferred_core outgoing request/response path proven by d3f5293b. Prove that with focused payload/replay equivalence and invalid-path tests, then rerun the relevant full gates and the narrowed Spec/Standards delta review. If the valid deferred request shape changes, stop and require a new bounded live qualification.

    Rationale: the tool_surface_strategy seam earns its depth by containing variation behind one resolved capability. A new opt-in adapter must not silently rewrite the default adapter’s established external interface.

  4. self-assigned this
    on Jul 13, 2026
  5. added a commit that references this issue on Jul 13, 2026
  6. NOirBRight commented on Jul 13, 2026

    @NOirBRight
    OwnerAuthor

    Recovery plan for PR #110:

    • Expected writes are limited to scripts/qualify-issue-108-glm-tool-surface.ps1 (bounded retained-handle tree termination/cleanup and nested replay stdio isolation) and tests/test_smoke_scripts.py (a deterministic cleanup-bound regression).
    • No collision: the feature branch is clean at checkpoint 8b8d6265, tracks the matching remote tip, and no other registered worktree has this branch checked out.
    • I will run the two replay tests plus the regression, the full Python suite, the report-only quality gate, and git diff --check; then push one focused commit and monitor all PR checks. No live GLM qualification or elevated sandbox run is planned.
  7. NOirBRight commented on Jul 13, 2026

    @NOirBRight
    OwnerAuthor

    SCOPE CONFIRMATION — finish the Responses path

    The accepted shortest path remains Ollama Cloud Responses. #108 continues to own only the provider/model deferred_core surface and its bounded qualification harness; #105 owns the exact apply_patch response/history compatibility contract.

    PR #110 must finish its CI repair and then satisfy the existing clean shell_command -> apply_patch -> shell_command Responses qualification. Do not add a generic Chat/custom-tool bridge, change provider routing, or broaden discovery behavior in this Issue. CC Switch is architecture evidence for the conditional #66 fallback, not a reason to rewrite this PR.

  8. NOirBRight commented on Jul 13, 2026

    @NOirBRight
    OwnerAuthor

    Remediation plan for the remaining #105/#108 evidence gaps in PR #110:

    • Expected writes: scripts/qualify-issue-108-glm-tool-surface.ps1, tests/test_smoke_scripts.py, and one narrow sanitized fixture under tests/fixtures/ for deterministic A/B and qualification-evidence replay/validation. No production source, routing/config, or type files will be edited.
    • Add semantic replay coverage proving minimal green, 200-tool eager red, and the same 200-tool deferred-core green; add a fail-closed sanitizer/validator for the committed GLM route/tool-chain evidence.
    • Replace evidence-facing Gateway terminology only; externally fixed protocol field names remain unchanged.
    • Verify focused replay/routing/protocol/smoke tests, full Python, frontend build/UI contract, report-only quality gate, git diff --check, and a Spec/Standards delta review before pushing and monitoring all PR checks.

    Collision check: this branch is clean, tracks its remote at aec5cb09, is checked out only in this worktree, and the current upstream-only dev diff has no paths.

  9. NOirBRight commented on Jul 13, 2026

    @NOirBRight
    OwnerAuthor

    Resumed remediation plan:

    • Expected repository writes remain the qualification script, smoke coverage, and narrow sanitized replay/evidence fixtures; no production paths.
    • First make the semantic three-case A/B replay and fail-closed evidence schema/validator green, including Gateway terminology.
    • Then run the one externally authorized disposable full-access Responses qualification only with retained child handles; only a fully passing capture will write and commit a qualification fixture.
    • Verify focused tests first. If the live capture fails, record only a sanitized classification and send a new BLOCKED signal without retry.

    Collision check: the assigned branch is the sole worktree, its published head is current, and the upstream-only dev path set is empty.

  10. NOirBRight commented on Jul 13, 2026

    @NOirBRight
    OwnerAuthor

    Harness-correction plan:

    • Expected writes remain the qualification script, smoke coverage, and narrow sanitized evidence only; no production paths.
    • Repair the embedded Gateway capture's missing digest dependency, add a fast execution regression for the exact capture/digest seam, and classify local harness HTTP 500s separately from upstream transport.
    • Remove the stale transport failure fixture or replace it only with a truthful, explicitly superseded harness-error regression.
    • Re-run the deterministic replay and validator coverage before the one newly authorized corrected readiness-plus-acceptance sequence. No prompt change or retry follows a corrected-run failure.

    Collision check: the feature branch is clean, its remote matches HEAD, and the upstream-only dev path set is empty.

  11. NOirBRight commented on Jul 13, 2026

    @NOirBRight
    OwnerAuthor

    Readiness-harness correction plan:

    • Expected writes are limited to the qualification script, smoke/replay coverage, and at most a narrow sanitized readiness fixture; no production, routing, configuration, or prompt changes.
    • Preserve the completed-tool sequence as an array, then add deterministic readiness evidence replay for the singleton shell_command case: route identity, sentinel, turn completion, zero Gateway errors, and zero capture-harness errors.
    • Emit predicate-specific sanitized readiness summary/failure codes so a future preflight failure is not collapsed to a generic classification.
    • Run focused replay/validator coverage before the one newly authorized corrected readiness-plus-acceptance sequence. The prior false failure artifact remains uncommitted.

    Collision check: the branch is clean and synchronized at 0f1738a; the upstream-only dev path set is empty.

  12. NOirBRight commented on Jul 13, 2026

    @NOirBRight
    OwnerAuthor

    Follow-up evidence-review plan (current branch is clean; no write collision):

    1. Make the deterministic three-case replay derive its green/red result from the prepared tool surface, so the 200-tool eager failure is semantic rather than a fixture-only assertion.
    2. Bind the accepted sanitized qualification artifact to a replayable canonical tool-shape witness and digest/equivalence check, without storing prompts, patch contents, identifiers, paths, or credentials.
    3. Add negative regressions, rerun focused/full verification, then publish one focused evidence-remediation commit.
  13. NOirBRight commented on Jul 13, 2026

    @NOirBRight
    OwnerAuthor

    Final evidence-correction plan (branch is clean and synchronized; no collision):

    1. Pin the accepted qualification capture to exactly four Gateway request starts/completions and four matching surface records.
    2. Add a fail-closed regression that removes an entire request group and asserts the dedicated sanitized count code.
    3. Rerun focused/full checks and a bounded two-axis review, then push one focused commit and monitor the four PR checks.

    No live qualification, production/config/routing, or prompt changes are planned.

  14. NOirBRight commented on Jul 13, 2026

    @NOirBRight
    OwnerAuthor

    Completed by PR #110, merged into dev at 2916190. The provider/model deferred_core capability, eager compatibility, GLM configuration, deterministic minimal/eager-200/deferred-200 A/B, exact four-request qualification evidence, full local gates, two-axis review, and all four GitHub checks passed.

  15. changed the title [-]Budget external-model tool surfaces before GLM core execution[/-] [+]Restore bundled provider/model capabilities when installed runtime config predates them[/+] on Jul 15, 2026
  16. NOirBRight commented on Jul 15, 2026

    @NOirBRight
    OwnerAuthor

    Execution-Contract: v2

    Verification-Class: strict
    Verification-Commands:

    • python -m pytest -q tests/test_providers_config.py
    • python -m pytest -q (one local candidate full Python suite)
    • python scripts/report_quality_gates.py (report-only)
    • cargo test --manifest-path src-tauri/Cargo.toml only if Rust configuration persistence changes
    • frontend build and UI contract only if frontend persistence changes

    Manual-Evidence: one fresh isolated GLM-5.2 shell_command → apply_patch → shell_command acceptance with model=glm-5.2, upstream=ollama_cloud, route_mode=codexhub, and no Official fallback; Orchestrator/human-owned after compatible integration.
    Architecture-Decision: resolved
    Review-Owner: orchestrator
    Profile/Binding: debug — gpt-5.6-terra / max; effective binding and unrestricted filesystem/network with approval=never verified in preflight.
    Base: dev@d03f97bd00f5f0c44815d94e444c8ac10050f299
    Branch: codex/issue-108-provider-capability-inheritance
    Owned hotset: src-python/providers_config.py; tests/test_providers_config.py; only proven necessary Rust/frontend configuration-persistence boundaries.
    Prohibited hotset: src-python/codex_proxy.py; src-python/config_overlay.py; tests/test_routing.py.
    Blockers: none. #134 may proceed in its disjoint hotset.
    PR target: dev; use Closes #108 only for the complete reopened regression.

  17. NOirBRight commented on Jul 15, 2026

    @NOirBRight
    OwnerAuthor

    Completed by PR #136 and verified after compatible integration at dev@6cf5a53617b26cd3fe2e32867f128351ab233ae4.

    Final fresh isolated Responses acceptance passed:

    • route identity: model=glm-5.2, upstream=ollama_cloud, route_mode=codexhub
    • completed tool sequence: shell_command -> apply_patch -> shell_command
    • all four acceptance Gateway requests completed with HTTP 200
    • deferred_core remained active; apply_patch and apply_patch-history adapters both reported adapted
    • zero upstream retries, zero protocol fallback, and no Official-model fallback
    • exactly one target file changed, one hunk, one line replaced
    • sanitized evidence schema codexhub.issue108.qualification-evidence.v2, SHA-256 8683827A445958815D99C2C320E7CF9BC580ACE9C522061EB7E351A348566D84

    The merged Debug portable resources for providers_config.py and codex_proxy.py also matched the integrated source byte-for-byte. Acceptance is complete.

  18. removed their assignment
    on Jul 15, 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

    bugSomething isn't working

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions