Skip to content

feat(backends): EmbeddedBinding implements apply_activation (Granite Switch path); remove render_controls + set_request_adapter (Epic #929 Phase 2) - #1559

Open
planetf1 wants to merge 13 commits into
generative-computing:mainfrom
planetf1:issue-1142
Open

feat(backends): EmbeddedBinding implements apply_activation (Granite Switch path); remove render_controls + set_request_adapter (Epic #929 Phase 2)#1559
planetf1 wants to merge 13 commits into
generative-computing:mainfrom
planetf1:issue-1142

Conversation

@planetf1

@planetf1 planetf1 commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Pull Request

Issue

Fixes #1142.

Description

Embedded adapters are already present in a deployment's model weights and must be activated per request. That logic lived as an OpenAI-backend-specific type check, while EmbeddedBinding remained a stub, so another backend would have had to reproduce hidden request-rewriting details.

This PR gives EmbeddedBinding a real apply_activation() method and routes the OpenAI backend through it. It preserves the required request shape, including removing a conflicting model parameter, and deletes two unused activation methods from the old design.

Where this fits

This is Phase 2 work for Epic #929 and the embedded-adapter counterpart to the LocalFile/PEFT work in #1141 / PR #1454. It unblocks HF embedded-adapter support in #1018 and contributes to the shim-removal work in #1144. Output-contract resolution (#1516) and broader telemetry work (#1466) remain separate.

What changed

  • Implement EmbeddedBinding.apply_activation() for request-scoped adapter selection.
  • Replace the OpenAI inline activation branch with the binding method.
  • Export the request type needed by backend implementations and fail loudly if a shim carries the wrong binding.
  • Remove unused render_controls and set_request_adapter methods.
  • Update embedded-adapter docs and add unit and integration coverage.

Caveat

EmbeddedBinding deliberately has no prepare, activate, deactivate, or release lifecycle: no weights are loaded or toggled. Invocation-complete telemetry remains with #1560 because request activation alone cannot know the eventual generation outcome.

Testing

Focused adapter tests, the non-qualitative suite, Ruff, mypy, markdownlint, and the documentation quality gate pass. Required GitHub checks pass.

Testing

  • Tests added to the respective file if code was changed
  • New code has 100% coverage if code was added
  • Ensure existing tests and github automation passes (a maintainer will kick off the github automation when the rest of the PR is populated)

Attribution

  • AI coding assistants used

Adding a new component, requirement, sampling strategy, or tool?

If your PR adds or modifies one of the types below, check the matching box. A checklist of type-specific review items will be posted as a comment.

  • Component
  • Requirement
  • Sampling Strategy
  • Tool

NOTE: Please ensure you have an issue that has been acknowledged by a core contributor and routed you to open a pull request against this repository. Otherwise, please open an issue before continuing with this pull request.

@github-actions github-actions Bot added the enhancement New feature or request label Aug 18, 2026
planetf1 added a commit to planetf1/mellea that referenced this pull request Aug 20, 2026
…date build_prompt message

Continues the multi-party review follow-ups on this PR (issue generative-computing#1516):

- rag.py / guardian.py: drop the ten module-level Adapter constants.
  Their only purpose (feeding io_contract= to call_intrinsic) was removed
  by the earlier commits, nothing in production references them, and the
  generative-computing#1141/generative-computing#1142 weights work builds on the binding classes (PR generative-computing#1454 merged,
  PR generative-computing#1559 open) rather than on these constants — whose underscore
  capability axis would never match _find_adapter's name-keyed scan
  anyway. test_rag_contracts.py / test_guardian_io_contract.py now look
  contracts up via get_io_contract(), exercising the registry directly.
- _core.py NOTE(generative-computing#1516): re-pointed at the remaining placeholder
  constructions (the core.py _REQUIREMENT_CHECK_ADAPTER test stub and the
  shims' _ShimWeightsBinding).
- core.py: comment no longer assumes the rag/guardian sibling constants
  are kept.
- build_prompt NotImplementedError message consolidated into the
  _BUILD_PROMPT_NOT_IMPLEMENTED constant (was five copies).
- _util.py: call_intrinsic's Raises ValueError entry now covers
  well-formed JSON with a contract-rejected top-level shape.

Assisted-by: opencode
Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>
@planetf1
planetf1 marked this pull request as ready for review August 20, 2026 14:46
@planetf1
planetf1 requested a review from a team as a code owner August 20, 2026 14:46
planetf1 added a commit to planetf1/mellea that referenced this pull request Aug 21, 2026
…date build_prompt message

Continues the multi-party review follow-ups on this PR (issue generative-computing#1516):

- rag.py / guardian.py: drop the ten module-level Adapter constants.
  Their only purpose (feeding io_contract= to call_intrinsic) was removed
  by the earlier commits, nothing in production references them, and the
  generative-computing#1141/generative-computing#1142 weights work builds on the binding classes (PR generative-computing#1454 merged,
  PR generative-computing#1559 open) rather than on these constants — whose underscore
  capability axis would never match _find_adapter's name-keyed scan
  anyway. test_rag_contracts.py / test_guardian_io_contract.py now look
  contracts up via get_io_contract(), exercising the registry directly.
- _core.py NOTE(generative-computing#1516): re-pointed at the remaining placeholder
  constructions (the core.py _REQUIREMENT_CHECK_ADAPTER test stub and the
  shims' _ShimWeightsBinding).
- core.py: comment no longer assumes the rag/guardian sibling constants
  are kept.
- build_prompt NotImplementedError message consolidated into the
  _BUILD_PROMPT_NOT_IMPLEMENTED constant (was five copies).
- _util.py: call_intrinsic's Raises ValueError entry now covers
  well-formed JSON with a contract-rejected top-level shape.

Assisted-by: opencode
Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>
… construction onto separate lines

Prep step for Epic generative-computing#929 Phase 2: generative-computing#1516 and generative-computing#1142 both need to change one of
io_contract/weights on the same call and the same docstring paragraph. This
splits each into its own local variable/bullet, separated by blank lines,
so the two PRs no longer touch adjacent lines and can merge in either order.

No behavior change.

Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>
…ender_controls + set_request_adapter (Epic generative-computing#929 Phase 2)

EmbeddedBinding gets one method, apply_activation(request, identity), for
adapters embedded in the served base model (Granite Switch) — there is no
weights lifecycle to prepare/activate/deactivate/release, only a field on
the outgoing request. OpenAIBackend's inline
isinstance(adapter, EmbeddedIntrinsicAdapter) block that wrote
chat_template_kwargs.adapter_name and dropped the rewriter-set model param
is now owned by the binding, reached through EmbeddedIntrinsicAdapter.weights.

Removes the two dead activation methods the previous scope was built around
(AdapterMixin.render_controls, AdapterMixin.set_request_adapter) along with
OpenAIBackend's no-op render_controls override — neither had a working
implementation or caller.

adapter_scope() now rejects a non-WeightsBinding adapter with a clear
TypeError instead of an AttributeError, since EmbeddedBinding has no
activate()/deactivate() to scope.

Assisted-by: Claude Code
Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>
generative-computing#1142)

Adds an Embedded/Granite Switch construction example to
docs/docs/advanced/intrinsics.md (Adapter(weights=EmbeddedBinding.from_base_model(backend)))
alongside the existing LocalFileBinding one, plus a backend x reality
support matrix.

Adds a weights-binding shapes reference table to AGENTS.md Section 14,
comparing LocalFileBinding's activate()/deactivate() lifecycle against
EmbeddedBinding's single apply_activation(request, identity) request edit.

Assisted-by: Claude Code
Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>
…ation

Independent review (3 perspectives) found one BLOCKER and several
correctness/design issues in the initial generative-computing#1142 implementation, all
verified against the pinned source before fixing:

- BLOCKER: apply_activation fired its two telemetry hooks via
  _run_async_in_thread from inside an already-running coroutine
  (OpenAIBackend._generate_from_intrinsic), spawning a throwaway asyncio
  loop + daemon thread per call that was never reclaimed (10 calls with
  metrics enabled leaked 20 threads, confirmed independently). Fixed by
  making apply_activation async and awaiting invoke_hook directly.
- WARNING: apply_activation fired adapter_function_invocation_complete
  with outcome="success" hardcoded, before generation/parsing (which
  OpenAIBackend resolves lazily) could possibly have failed. Fixed by no
  longer firing invocation_complete from apply_activation -- only
  phase_complete (phase="activate"), which the method genuinely
  completes. Wiring a real invocation-complete signal in requires the
  caller to fire it once generation/parsing resolve; documented as a
  follow-up rather than solved here.
- WARNING: EmbeddedActivationRequest, required to call the public
  apply_activation, wasn't exported from mellea.backends.adapters.
  Exported it and switched openai.py to import both it and
  EmbeddedBinding from the public package.
- Hardened the openai.py activation branch with an explicit
  else: raise TypeError for a reassigned .weights (previously would
  have silently skipped activation), and wired base_model_name into
  EmbeddedBinding.source in OpenAIBackend.add_adapter (was always "").
- Added the missing adapter_scope TypeError regression test, fixed a
  _fire_phase_complete naming collision (same name, different first
  parameter, across two binding classes), corrected the docs'
  composable-construction example (built a backend it never bound, and
  implied backend support the code doesn't have), dropped a misapplied
  openai backend marker from a fully-mocked integration test, and
  removed a duplicate integration test.

Assisted-by: Claude Code
Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>
…ards

- Restate the composable-construction callout in intrinsics.md
  per backend: OpenAIBackend.add_adapter accepts only the deprecated
  EmbeddedIntrinsicAdapter shim, not a raw weights binding.
- Pair the LocalFileBinding example's identity with the LoRA adapter
  type that from_catalog actually loads (first catalog-listed type),
  and give the OpenAIBackend example an explicit api_key.
- Document the NotImplementedError cases in _generate_from_intrinsic's
  Raises section.
- Pin the registration-time source stamp and the reassigned-.weights
  fail-loud TypeError in the embedded integration test.

Assisted-by: opencode
Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>
The registration method mutates the caller's EmbeddedBinding (stamping
base_model_name into source) but its docstring did not say so; the
sibling LocalHFBackend.add_adapter documents its side effects explicitly.

Assisted-by: opencode
Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>
…acker refs

The IntrinsicAdapter/EmbeddedIntrinsicAdapter notes and the _Shim*
placeholders cited Phase-2 plans and issue numbers that had gone stale
(generative-computing#1137 is closed and out of scope; generative-computing#1141 shipped without replacing the
shims). Both shim notes now state current behaviour only and agree with
each other; the shim raise messages drop the phase/issue prefixes.
test_shims.py's message match follows the new wording. Shims themselves
are slated for removal, so no forward references are introduced.

Assisted-by: opencode
Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>
- test_embedded_binding.py: import from the public package (sibling style);
  pin the dispatched HookType in the phase-complete test (a payload-similar
  hook type would otherwise pass); pin the explicit chat_template_kwargs=None
  branch; use the module-level HookType import.
- EmbeddedBinding.source docstring: state what is actually recorded (the
  backend's base_model_name, stamped by OpenAIBackend.add_adapter) instead
  of a future span attribute.
- _ShimIOContract docstring: 'intrinsic adapter shims' — the class is used
  by both deprecated shims, not IntrinsicAdapter alone.
- adapter_scope docstring: docs/dev/adapter_observability.md no longer
  exists; point at the metric schema's actual home
  (AdapterFunctionMetricsPlugin in mellea/telemetry/metrics_plugins.py).

Assisted-by: opencode
Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>
planetf1 added a commit to planetf1/mellea that referenced this pull request Aug 21, 2026
…date build_prompt message

Continues the multi-party review follow-ups on this PR (issue generative-computing#1516):

- rag.py / guardian.py: drop the ten module-level Adapter constants.
  Their only purpose (feeding io_contract= to call_intrinsic) was removed
  by the earlier commits, nothing in production references them, and the
  generative-computing#1141/generative-computing#1142 weights work builds on the binding classes (PR generative-computing#1454 merged,
  PR generative-computing#1559 open) rather than on these constants — whose underscore
  capability axis would never match _find_adapter's name-keyed scan
  anyway. test_rag_contracts.py / test_guardian_io_contract.py now look
  contracts up via get_io_contract(), exercising the registry directly.
- _core.py NOTE(generative-computing#1516): re-pointed at the remaining placeholder
  constructions (the core.py _REQUIREMENT_CHECK_ADAPTER test stub and the
  shims' _ShimWeightsBinding).
- core.py: comment no longer assumes the rag/guardian sibling constants
  are kept.
- build_prompt NotImplementedError message consolidated into the
  _BUILD_PROMPT_NOT_IMPLEMENTED constant (was five copies).
- _util.py: call_intrinsic's Raises ValueError entry now covers
  well-formed JSON with a contract-rejected top-level shape.

Assisted-by: opencode
Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>
Comment thread mellea/backends/openai.py
Comment on lines +774 to +784
# rather than silently skip activation and send an unactivated request.
if isinstance(adapter.weights, EmbeddedBinding):
activation_request = EmbeddedActivationRequest(
extra_body=extra_body, api_params=api_params
)
await adapter.weights.apply_activation(activation_request, adapter.identity)
else:
raise TypeError(
f"EmbeddedIntrinsicAdapter.weights must be an EmbeddedBinding; "
f"got {type(adapter.weights).__name__}. Activation cannot proceed."
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: can we change this to be if not isinstance(...): raise TypeError and then unindent the code that's currently in the if branch?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 2d06437.

Assisted-by: Codex
Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>
Keep main's remove_adapter coverage while retaining generative-computing#1559's removal of obsolete request-control verbs.

Assisted-by: Codex
Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>
Assisted-by: Codex
Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>
planetf1 added a commit to planetf1/mellea that referenced this pull request Aug 25, 2026
…adapter, not a parallel argument (generative-computing#1556)

* chore(adapters): split EmbeddedIntrinsicAdapter's io_contract/weights construction onto separate lines

Prep step for Epic generative-computing#929 Phase 2: generative-computing#1516 and generative-computing#1142 both need to change one of
io_contract/weights on the same call and the same docstring paragraph. This
splits each into its own local variable/bullet, separated by blank lines,
so the two PRs no longer touch adjacent lines and can merge in either order.

No behavior change.

Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>

* test(adapters): add canonical per-adapter-function output-contract registry

Introduces mellea/backends/adapters/io_contracts.py: a capability-keyed
registry of IOContract instances, keyed by the same catalog name passed to
call_intrinsic() and resolve_adapter(). Moves _ListContract (from rag.py)
next to the existing _DictContract in _core.py, adds the guardian-specific
contracts, and adds _RequirementCheckContract to consolidate the score-range
validation core.requirement_check() previously hand-rolled after each call.

This is the single source of truth a later commit wires resolve_adapter()
and the intrinsic helpers to consume, instead of each declaring its own
IOContract instance that could silently drift from the other's.

Assisted-by: Claude Code
Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>

* refactor(intrinsics): resolve the output contract from the adapter, not a parallel argument

call_intrinsic() resolved the adapter and discarded it, taking the output
contract instead as a separate io_contract= argument that each caller
supplied from its own module-level Adapter constant. Nothing tied the two
together, so a caller could pass a contract that didn't match the adapter
resolve_adapter() actually returned.

call_intrinsic() now keeps the adapter resolve_adapter() returns and calls
its own io_contract.parse() on the raw output; the io_contract= parameter is
gone, so a mismatched pair is no longer expressible. IntrinsicAdapter and
EmbeddedIntrinsicAdapter (the shims resolve_adapter() constructs) now look
up their contract in the io_contracts registry instead of the
_ShimIOContract placeholder, which is now unreachable and removed. The ten
module-level Adapter constants in rag.py/guardian.py keep their identity and
weights as before, and read io_contract from that same registry rather than
declaring their own instance.

core.py's three helpers (check_certainty, requirement_check,
find_context_attributions) previously had no declared contract at all — the
first two skipped validation (raw json.loads), and requirement_check
hand-rolled its own score-range check after the call. All three now have a
declared contract in the registry; requirement_check's hand-rolled
validation is replaced by _RequirementCheckContract, and
find_context_attributions reads its now-list-wrapped result via ["items"].

Weights binding is untouched — this stays entirely on the io_contract axis
(the design discussion in generative-computing#1486 that split the two). The ten constants'
placeholder LocalFileBinding() and the backed-out Adapter.__post_init__
cross-check remain future work, as noted in _core.py.

Verified against real granite-4.1-3b weights: test/stdlib/components/
intrinsic/test_core.py, test_rag.py, and test_guardian.py (qualitative,
GPU-gated) all pass on this run — 3 passed + 2 pre-existing xfails
(non-deterministic attribution count, tracked separately) for core.py, 14/14
for rag.py, 6/6 for guardian.py. No test constructs a resolve_adapter()
result carrying the old placeholder contract; test_io_contracts.py's
registry-completeness test guards that going forward.

Fixes generative-computing#1516

Assisted-by: Claude Code
Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>

* refactor(intrinsics): address code review — export registry, drop dead constants, fix real duplicate

Three independent reviewers found the same gap from different angles: the
registry this PR introduces to close the parallel-declaration problem still
had one. mellea/stdlib/requirements/requirement.py's requirement_check_to_bool()
hand-rolled the exact score-range validation just consolidated into
_RequirementCheckContract, with a comment pointing at code this PR deleted
from core.py. It now delegates to get_io_contract("requirement-check").parse(),
which is a strict improvement on its undocumented AttributeError-on-non-dict
failure mode (now the documented ValueError the contract raises).

Also, per review:

- Export get_io_contract from mellea.backends.adapters.__init__ (and __all__),
  matching the sibling adapter-package imports. Unexported, it was invisible to
  the docs pipeline (io_contracts.mdx was pruned as "not imported by
  __init__.py") and to the AGENTS.md-mandated docstring quality gate, despite
  being the function the module's own docstring designates as the mandatory
  entry point.
- Delete _UNCERTAINTY_ADAPTER and _CONTEXT_ATTRIBUTION_ADAPTER from core.py:
  nothing referenced them — their only purpose (supplying io_contract= to
  call_intrinsic) was exactly what the prior commit removed. Keep
  _REQUIREMENT_CHECK_ADAPTER, which test_core_schema.py uses as a
  resolve_adapter() stub.
- Add a regression test per shim class (test_shims.py) asserting
  IntrinsicAdapter/EmbeddedIntrinsicAdapter carry the real registry contract,
  not a placeholder. Without it, reverting get_io_contract(intrinsic_name)
  back to a stub would have passed every existing test in the file. Verified
  by temporarily reintroducing a stub object in place of get_io_contract(): both
  new tests failed as expected, then passed again once reverted.
- Enforce the registry's exhaustiveness over known_intrinsic_names() at import
  time in io_contracts.py, mirroring the existing duplicate-effective_capability
  check in catalog.py, rather than relying solely on a test.
- Correct test_core_schema.py's module docstring, which claimed resolve_adapter
  itself runs; only its stubbed return value does.

Assisted-by: Claude Code
Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>

* refactor(intrinsics): apply remaining review suggestions and nits

Follow-up to the review response commit — the lower-severity items all three
reviewers raised, applied where they were cheap and genuinely useful:

- adapter.py: convert the remaining `.. deprecated::` RST directives on
  IntrinsicAdapter/EmbeddedIntrinsicAdapter to Google-style `Deprecated:`
  sections, matching the `Note:` conversion already done on the same
  docstrings. (CustomIntrinsicAdapter's directive is untouched by this diff
  and left alone.)
- _core.py / io_contracts.py: replace the stale "not used in Phase 1;
  implemented in Phase 2" build_prompt placeholder message — self-contradictory
  now that this module *is* the Phase 2 work — with an accurate description of
  the current state. Updated the one test asserting on the old wording.
- _core.py: module docstring now names _ListContract and explains the
  generic-vs-capability-specific split with io_contracts.py.
- io_contracts.py: get_io_contract's docstring now states its keys are
  catalog `name`s, not `effective_capability` tokens, and corrects "permissive"
  to mean permissive about which keys are present, not about the JSON shape.
  Added the matching inline comment on the fallback return.
- io_contracts.py: comment distinguishing the two AdapterSchemaMismatchError
  raise sites in _PolicyGuardrailsContract (neither key present vs. both).
  _RequirementCheckContract's docstring now names both production consumers
  it consolidates (core.py and requirement.py) with full paths.
- test_io_contracts.py: new non-GPU test feeding the recorded
  context-attribution model output (test/stdlib/components/intrinsic/testdata)
  through the real contract. The GPU-gated equivalent is xfail(strict=False)
  for unrelated non-determinism, so it gives no CI signal on schema drift;
  this closes that gap without a GPU.

Assisted-by: Claude Code
Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>

* test(intrinsics): add contract-wiring tests and fix docstring accuracy

Applies the multi-party review findings on this PR (issue generative-computing#1516):

- test_core_contracts.py: CI-runnable wiring tests for check_certainty
  and find_context_attributions — the two helpers that moved to
  registry-contract validation (plus the items unwrap) with only
  GPU-gated qualitative/xfail coverage before
- test_requirement.py: cover the newly-typed ValueError for non-object
  JSON in requirement_check_to_bool (was an undocumented AttributeError)
- test_io_contracts.py: guard the reverse direction of the registry
  exhaustiveness invariant (orphan keys)
- core.py: the new Raises: ValueError entries were narrower than the
  contracts' actual raise paths (wrong top-level shape is also ValueError)
- io_contracts.py: the string literal after the registry assignment was a
  dead expression — dicts have no docstring; make it a comment
- test_rag_contracts.py / test_guardian_io_contract.py: the contracts no
  longer live in rag.py/guardian.py (Phase 1 -> io_contracts.py, generative-computing#1516)
- rag.py / guardian.py / core.py: state consistently that the per-helper
  Adapter constants are weights scaffolding for generative-computing#1141/generative-computing#1142, not a second
  contract source

Assisted-by: opencode
Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>

* refactor(intrinsics): drop dead per-helper Adapter constants, consolidate build_prompt message

Continues the multi-party review follow-ups on this PR (issue generative-computing#1516):

- rag.py / guardian.py: drop the ten module-level Adapter constants.
  Their only purpose (feeding io_contract= to call_intrinsic) was removed
  by the earlier commits, nothing in production references them, and the
  generative-computing#1141/generative-computing#1142 weights work builds on the binding classes (PR generative-computing#1454 merged,
  PR generative-computing#1559 open) rather than on these constants — whose underscore
  capability axis would never match _find_adapter's name-keyed scan
  anyway. test_rag_contracts.py / test_guardian_io_contract.py now look
  contracts up via get_io_contract(), exercising the registry directly.
- _core.py NOTE(generative-computing#1516): re-pointed at the remaining placeholder
  constructions (the core.py _REQUIREMENT_CHECK_ADAPTER test stub and the
  shims' _ShimWeightsBinding).
- core.py: comment no longer assumes the rag/guardian sibling constants
  are kept.
- build_prompt NotImplementedError message consolidated into the
  _BUILD_PROMPT_NOT_IMPLEMENTED constant (was five copies).
- _util.py: call_intrinsic's Raises ValueError entry now covers
  well-formed JSON with a contract-rejected top-level shape.

Assisted-by: opencode
Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>

* docs(intrinsics): document registered-adapter contract precedence

call_intrinsic now parses via the resolved adapter's io_contract, so a
user-registered Adapter for a catalog name takes precedence over the
io_contracts registry for parsing. State that in the registry's module
docstring and in call_intrinsic, where the single-source-of-truth claim
otherwise overreaches for the registered-adapter path.

Assisted-by: opencode
Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>

* docs(intrinsics): fix increment review findings — stale docs, unguarded stub, missing negative test

Closes out the 3-party review of the follow-up increment (b88b17d..50ff6a5):

- io_contracts.py: the module docstring still described the constant
  carrying model the increment deleted (and contradicted the precedence
  paragraph three lines below); re-point at the shims and the core.py
  test stub as the construction-time readers
- _core.py: NOTE(generative-computing#1516) claimed the shims would make the backed-out
  type-agreement check fire; _ShimWeightsBinding has no adapter_type to
  compare and shim identities track the configured type — split the two
  cases
- test_core_schema.py: pin _REQUIREMENT_CHECK_ADAPTER to the registry
  instance (the is get_io_contract(...) guard test_shims.py established
  was not extended to the one non-shim construction that survived)
- test_io_contracts.py: negative test for the context-attribution
  contract's required item keys (every sibling contract has one;
  shrinking the frozenset used to pass the whole suite)
- rag.py / guardian.py: complete the Raises ValueError accuracy pass the
  increment started on core.py/_util.py — dict contracts are not a
  JSON object, list contracts are not a JSON array / non-object element
- _util.py: the new Raises clause now covers the array element case, and
  says 'same capability' (the field _find_adapter actually matches)
- small wording fixes: 'only other tests' (docs/examples e2e runs also
  exist), missing relative pronoun in two docstrings, and the issue
  reference form in the two rewritten test headers

Assisted-by: opencode
Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>

* fix(intrinsics): address remaining contract review feedback

Move the requirement-check adapter stub into its test, scope registry invariants to built-in catalogue entries, and distinguish policy-guardrails exclusivity errors.\n\nAssisted-by: Codex

Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>

---------

Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>
Assisted-by: Codex
Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(backends): EmbeddedBinding implements apply_activation (Granite Switch path); remove render_controls + set_request_adapter (Epic #929 Phase 2)

2 participants