Registry reference resolution builds /agt/… instead of /agent/…, failing with HTTP 404 on compliant registries #131

Open
opened 2026-08-10 15:00:09 +00:00 by CoreRasurae · 0 comments
Member

Metadata

  • Commit Message: fix(registry): use full package type names in registry resolve URL
  • Branch: bugfix/m1-registry-resolve-full-type-names

Background and context

The Package Registry Standard (docs/actor-registry-standard.md §3.2) defines two distinct concepts per package type: the Type (agent, graph, skill, template, …) and the Prefix used only in Package IDs (pkg_agt_, pkg_grh_, pkg_skl_, pkg_tpl_, …). The §8.2.2 resolve endpoint is GET /{package_type}/{namespace}/{name} where {package_type} is the full type name — confirmed by the §8.2.2 response ("type": "actor") and the §8.4.2 discovery response (supported_types lists full names).

In src/cleveractors/registry/reference_resolver.py, _RegistryReferenceStrategy (resolve → line ~186, aresolve → line ~219) applies _TEMPLATE_TYPE_TO_PACKAGE_TYPE, a TemplateType→Package-ID-prefix table, to the type sent on the wire, rewriting agentagt, graphgrh, skillskl, etc., before RegistryClient.resolve_package() builds the request. A compliant registry therefore receives GET /agt/... — a path it does not route (full names only) — and answers 404.

This reaches every reference-resolver call site, because all of them correctly pass the full type name:

  • Bare agents.<name> agent references: agents/agent_resolution.py (package_type="agent", ADR-2037 D-2; docs/index.md §4.1.1)
  • Skill references: agents/skill_resolution.py (package_type="skill", ADR-2034)
  • Route references: route_resolution.py (package_type="graph", ADR-2037 D-7; docs/index.md §5.1.1)
  • Template-driven package references: templates/base.py InstantiationContext._resolve_package_reference (package_type=ref.ref_type, a full template type name)

The mapping itself is not the bug and MUST be preserved: it is required to convert a template/system type name into the Package-type prefix that appears in Package IDs (pkg_agt_...), cache keys (_compute_cache_key) and identity-map lookups. Only its application to the HTTP path segment is wrong.

Current behavior

Resolving a bare agent reference against a compliant registry fails with HTTP 404:

$ python test_app.py test --graph calculator-app-actor_sep2.yaml \
    --prompt "follow the instructions." --local-store ../packages --registry-key "..."
Base URL: https://opencode.ai/zen/v1
RegistryClient using HTTP with an API key — the key may be transmitted in cleartext. ...
Error: Execution failed: Agent 'calculator_builder': failed to resolve agent reference '192.168.1.53:luis-mendes/calculator-app-builder-b': HTTP 404

Network evidence against the Caddy-fronted registry at http://192.168.1.53 (the graph's calculator_builder: "192.168.1.53:luis-mendes/calculator-app-builder-b"):

GET /agent/luis-mendes/calculator-app-builder-b?version=latest   (Bearer key) → 200
GET /agt/luis-mendes/calculator-app-builder-b?version=latest     (Bearer key) → 308 → (followed) → 404

The server advertises full type names (supported_types: ["actor","template","graph","stream","agent","skill","mcp","lsp"]) and only routes those. The control binary client/registry-cli.py passes the type argument verbatim (resolve agent luis-mendes calculator-app-builder-bGET /agent/...200), proving the server is spec-compliant and the defect is in the library.

Note: even after fixing redirect-following (see related #130), this still fails — /agt/... redirects (308) to a trailing-slash variant that then 404s. The two are independent defects on the same repro host.

Expected behavior

RegistryClient.resolve_package() is called with the full package type name (agent, graph, skill, …), so the request URL is GET /{name}/{namespace}/{name} with a routable type segment. Resolution of 192.168.1.53:luis-mendes/calculator-app-builder-b succeeds (HTTP 200) and the agent is created. The _TEMPLATE_TYPE_TO_PACKAGE_TYPE mapping continues to be applied wherever prefixes are actually needed (Package IDs, cache keys, template→package type conversion) and is untouched for those uses.

Acceptance criteria

  • _RegistryReferenceStrategy.resolve / aresolve pass the full type name (e.g. agent) as {package_type}; no resolve URL ever carries a short prefix segment (agt, grh, skl, tpl, …).
  • The original repro resolves: a bare host:ns/name agent reference against a spec-compliant registry returns HTTP 200 and the agent is created.
  • Template-driven package references (InstantiationContext._resolve_package_reference) keep working, and _TEMPLATE_TYPE_TO_PACKAGE_TYPE is still applied for Package-ID / cache-key / prefix conversion (template→package mapping preserved).
  • Skill references request /skill/{ns}/{name} and route references request /graph/{ns}/{name}.
  • registry-cli.py resolve agent <ns> <name> behaviour is unchanged (/agent/...).
  • No regression in local: / ID: reference resolution.
  • Coverage stays >= 97% (nox -s coverage_report).

Supporting information

  • docs/actor-registry-standard.md §3.2 (Type vs Prefix), §8.2.2 (resolve endpoint), §8.4.2 (discovery supported_types)
  • docs/registry/client.mdresolve_package(package_type="actor" / "skill") usage with full type names
  • ADR-2037 D-2 (package_type="agent") / D-7 (package_type="graph"); ADR-2034 (package_type="skill")
  • docs/index.md §4.1.1, §5.1.1
  • Code: src/cleveractors/registry/reference_resolver.py (_TEMPLATE_TYPE_TO_PACKAGE_TYPE, _RegistryReferenceStrategy, _compute_cache_key); call sites in agents/agent_resolution.py, agents/skill_resolution.py, route_resolution.py, templates/base.py
  • Related: #121 (closed — introduced agent-package reference resolution), #130 (open — sibling 308-redirect defect against the same repro host; distinct root cause, verified independent)
  • Reproduction verified against a compliant Caddy-fronted registry at http://192.168.1.53

Subtasks

  • Fix _RegistryReferenceStrategy.resolve / aresolve so the value passed to RegistryClient.resolve_package is the full type name (drop only the transport-time application of _TEMPLATE_TYPE_TO_PACKAGE_TYPE; keep the mapping for _compute_cache_key and Package-ID/prefix conversion).
  • Tests (Behave): add regression scenario asserting the HTTP path uses full type names (/agent/..., /skill/..., /graph/...) and that template→prefix mapping still applies to Package IDs/cache keys.
  • Verify the original repro resolves successfully.
  • Verify coverage >= 97% via nox -s coverage_report.
  • Run nox (all default sessions), fix any errors.

Definition of Done

This issue is complete when:

  • All subtasks above are completed and checked off.
  • A Git commit is created where the first line matches the Commit Message in Metadata exactly, followed by a blank line, then additional lines providing relevant details.
  • The commit is pushed to the branch matching the Branch in Metadata exactly.
  • The commit is submitted as a pull request to master, reviewed, and merged.
  • The companion TDD issue is merged before this fix (this issue depends on the TDD issue, Forgejo dependency set at creation).
## Metadata - **Commit Message:** `fix(registry): use full package type names in registry resolve URL` - **Branch:** `bugfix/m1-registry-resolve-full-type-names` ## Background and context The Package Registry Standard (`docs/actor-registry-standard.md` §3.2) defines two distinct concepts per package type: the **Type** (`agent`, `graph`, `skill`, `template`, …) and the **Prefix** used only in Package IDs (`pkg_agt_`, `pkg_grh_`, `pkg_skl_`, `pkg_tpl_`, …). The §8.2.2 resolve endpoint is `GET /{package_type}/{namespace}/{name}` where `{package_type}` is the **full type name** — confirmed by the §8.2.2 response (`"type": "actor"`) and the §8.4.2 discovery response (`supported_types` lists full names). In `src/cleveractors/registry/reference_resolver.py`, `_RegistryReferenceStrategy` (`resolve` → line ~186, `aresolve` → line ~219) applies `_TEMPLATE_TYPE_TO_PACKAGE_TYPE`, a TemplateType→Package-ID-prefix table, to the type sent on the wire, rewriting `agent` → `agt`, `graph` → `grh`, `skill` → `skl`, etc., before `RegistryClient.resolve_package()` builds the request. A compliant registry therefore receives `GET /agt/...` — a path it does not route (full names only) — and answers `404`. This reaches every reference-resolver call site, because all of them correctly pass the full type name: - Bare `agents.<name>` agent references: `agents/agent_resolution.py` (`package_type="agent"`, ADR-2037 D-2; `docs/index.md` §4.1.1) - Skill references: `agents/skill_resolution.py` (`package_type="skill"`, ADR-2034) - Route references: `route_resolution.py` (`package_type="graph"`, ADR-2037 D-7; `docs/index.md` §5.1.1) - Template-driven package references: `templates/base.py` `InstantiationContext._resolve_package_reference` (`package_type=ref.ref_type`, a full template type name) The mapping itself is **not** the bug and MUST be preserved: it is required to convert a template/system type name into the Package-type prefix that appears in Package IDs (`pkg_agt_...`), cache keys (`_compute_cache_key`) and identity-map lookups. Only its application to the HTTP path segment is wrong. ## Current behavior Resolving a bare agent reference against a compliant registry fails with `HTTP 404`: ``` $ python test_app.py test --graph calculator-app-actor_sep2.yaml \ --prompt "follow the instructions." --local-store ../packages --registry-key "..." Base URL: https://opencode.ai/zen/v1 RegistryClient using HTTP with an API key — the key may be transmitted in cleartext. ... Error: Execution failed: Agent 'calculator_builder': failed to resolve agent reference '192.168.1.53:luis-mendes/calculator-app-builder-b': HTTP 404 ``` Network evidence against the Caddy-fronted registry at `http://192.168.1.53` (the graph's `calculator_builder: "192.168.1.53:luis-mendes/calculator-app-builder-b"`): ``` GET /agent/luis-mendes/calculator-app-builder-b?version=latest (Bearer key) → 200 GET /agt/luis-mendes/calculator-app-builder-b?version=latest (Bearer key) → 308 → (followed) → 404 ``` The server advertises full type names (`supported_types: ["actor","template","graph","stream","agent","skill","mcp","lsp"]`) and only routes those. The control binary `client/registry-cli.py` passes the type argument verbatim (`resolve agent luis-mendes calculator-app-builder-b` → `GET /agent/...` → `200`), proving the server is spec-compliant and the defect is in the library. Note: even after fixing redirect-following (see related #130), this still fails — `/agt/...` redirects (308) to a trailing-slash variant that then 404s. The two are independent defects on the same repro host. ## Expected behavior `RegistryClient.resolve_package()` is called with the **full package type name** (`agent`, `graph`, `skill`, …), so the request URL is `GET /{name}/{namespace}/{name}` with a routable type segment. Resolution of `192.168.1.53:luis-mendes/calculator-app-builder-b` succeeds (HTTP 200) and the agent is created. The `_TEMPLATE_TYPE_TO_PACKAGE_TYPE` mapping continues to be applied wherever prefixes are actually needed (Package IDs, cache keys, template→package type conversion) and is untouched for those uses. ## Acceptance criteria - [ ] `_RegistryReferenceStrategy.resolve` / `aresolve` pass the full type name (e.g. `agent`) as `{package_type}`; no resolve URL ever carries a short prefix segment (`agt`, `grh`, `skl`, `tpl`, …). - [ ] The original repro resolves: a bare `host:ns/name` agent reference against a spec-compliant registry returns HTTP 200 and the agent is created. - [ ] Template-driven package references (`InstantiationContext._resolve_package_reference`) keep working, and `_TEMPLATE_TYPE_TO_PACKAGE_TYPE` is still applied for Package-ID / cache-key / prefix conversion (template→package mapping preserved). - [ ] Skill references request `/skill/{ns}/{name}` and route references request `/graph/{ns}/{name}`. - [ ] `registry-cli.py resolve agent <ns> <name>` behaviour is unchanged (`/agent/...`). - [ ] No regression in `local:` / `ID:` reference resolution. - [ ] Coverage stays >= 97% (`nox -s coverage_report`). ## Supporting information - `docs/actor-registry-standard.md` §3.2 (Type vs Prefix), §8.2.2 (resolve endpoint), §8.4.2 (discovery `supported_types`) - `docs/registry/client.md` — `resolve_package(package_type="actor" / "skill")` usage with full type names - ADR-2037 D-2 (`package_type="agent"`) / D-7 (`package_type="graph"`); ADR-2034 (`package_type="skill"`) - `docs/index.md` §4.1.1, §5.1.1 - Code: `src/cleveractors/registry/reference_resolver.py` (`_TEMPLATE_TYPE_TO_PACKAGE_TYPE`, `_RegistryReferenceStrategy`, `_compute_cache_key`); call sites in `agents/agent_resolution.py`, `agents/skill_resolution.py`, `route_resolution.py`, `templates/base.py` - Related: #121 (closed — introduced agent-package reference resolution), #130 (open — sibling 308-redirect defect against the same repro host; distinct root cause, verified independent) - Reproduction verified against a compliant Caddy-fronted registry at `http://192.168.1.53` ## Subtasks - [ ] Fix `_RegistryReferenceStrategy.resolve` / `aresolve` so the value passed to `RegistryClient.resolve_package` is the full type name (drop only the transport-time application of `_TEMPLATE_TYPE_TO_PACKAGE_TYPE`; keep the mapping for `_compute_cache_key` and Package-ID/prefix conversion). - [ ] Tests (Behave): add regression scenario asserting the HTTP path uses full type names (`/agent/...`, `/skill/...`, `/graph/...`) and that template→prefix mapping still applies to Package IDs/cache keys. - [ ] Verify the original repro resolves successfully. - [ ] Verify coverage >= 97% via `nox -s coverage_report`. - [ ] Run `nox` (all default sessions), fix any errors. ## Definition of Done This issue is complete when: - All subtasks above are completed and checked off. - A Git commit is created where the first line matches the Commit Message in Metadata exactly, followed by a blank line, then additional lines providing relevant details. - The commit is pushed to the branch matching the Branch in Metadata exactly. - The commit is submitted as a pull request to `master`, reviewed, and merged. - The companion TDD issue is merged before this fix (this issue depends on the TDD issue, Forgejo dependency set at creation).
CoreRasurae added this to the v2.1.0 milestone 2026-08-10 15:00:09 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
cleveragents/cleveractors-core#131
No description provided.