Skip to content

Guarantee annotation preservation: centralize writer field-mapping + ship a round-trip conformance verifier #7

Description

@tercel

Problem

Adapters that subclass RegistryWriter override _to_function_module (for framework-specific target/func adaptation) and hand-copy the FunctionModule(...) field list. When an override omits a field, it is dropped silently — no error, no failing test, no warning.

Concretely, annotations were dropped this way in two adapters, so approval/ACL gating (which keys on requires_approval) never fired for their scanned routes. The canonical toolkit RegistryWriter is correct; the structural risk is that every override can re-introduce the gap, and nothing guards it.

Action items (Phase 1 — do now)

  1. Centralize the field-mapping. Refactor the base RegistryWriter._to_function_module to construct FunctionModule with all carried fields from ScannedModule (annotations, metadata, documentation, examples, display, tags, version, input/output schemas), and expose a narrow overridable hook for framework-specific work (e.g. _resolve_target(mod) / _adapt_func(func)). Adapters override only the hook → they can no longer drop fields.

  2. Round-trip conformance verifier. Provide a reusable test helper (pure apcore + apcore-toolkit, no framework dependency) that asserts: scan → register → get_definition(module_id).annotations preserves requires_approval / destructive (and metadata / examples). Adapters import and run it in their own suites, so the otherwise-invisible bug becomes a red light everywhere.

  3. Declare ScannedModule canonical. apcore_toolkit.types.ScannedModule is the single source of truth. At least one adapter forks a local ScannedModule that drifted (missing examples), which makes this repo's own RegistryWriter crash on those modules ('ScannedModule' object has no attribute 'examples'). Document it as canonical and provide typing/guidance so adapters stop forking. (Adapter-side removal of local forks tracked in the adapter repos.)

Scope / notes

  • Phase 1 of a two-phase plan. This unblocks the correctness fix across all adapters and prevents recurrence. The apcore-core design work (policy API, destructive↔approval semantics) is deliberately deferred to Phase 2 and tracked separately in aiperceivable/apcore.
  • Version coupling: adapters bump their apcore-toolkit floor to consume the verifier + refactor.
  • Related: adapter fixes in fastapi-apcore (done), django-apcore (pending).

Related issues

Activity

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions