Skip to content

[Product Gap] Publish a complete versioned API/schema and naruon compatibility contract #315

Open

Description

@seonghobae

Buyer-visible outcome

Make Clearfolio consumable as a stable standalone service and modular CWL/naruon component without requiring clients to reverse-engineer controllers, PR bodies or prose. Every supported public operation, response, error, lifecycle state and integration boundary must be represented by a versioned machine-readable contract with compatibility tests and explicit deprecation/migration rules.

Current evidence and gap

The canonical documentation line already marks API/schema completeness as PARTIAL:

  • docs/API_CONTRACT.md describes current endpoint authority/version semantics and explicitly treats the existing buyer OpenAPI as partial rather than complete;
  • ARCHITECTURE.md and ADR-0001 require versioned host/MSA composition without direct cross-service database access;
  • protected-main controller/API records are authoritative runtime behavior, but the repository does not yet expose one complete generated/validated contract that an independent naruon or standalone client can consume as the sole public schema source.

This issue owns public contract completeness and compatibility. It must not duplicate #270 security logic, #268 lifecycle internals, #312 durable execution implementation or #314 identity-provider internals; it exposes those capabilities only after their public behavior reaches an integrated protected baseline.

Contract scope

Publish and validate a versioned contract for all supported public surfaces, including as applicable:

Use a repository-owned OpenAPI contract for HTTP APIs. If asynchronous broker/event contracts are later public integration surfaces, use a separately versioned machine-readable event schema rather than pretending OpenAPI describes broker semantics.

Versioning and compatibility rules

  • Define one canonical API version policy; path/media/schema version semantics must be unambiguous.
  • Addition of optional response fields may be backward compatible only when client contracts prove it.
  • Removing/renaming fields, changing type/cardinality/nullability, changing status/error semantics, altering authorization requirements, or adding a terminal lifecycle state is breaking unless a reviewed compatibility rule says otherwise.
  • Active-PR behavior cannot appear in the released schema as shipped until integrated.
  • Deprecation requires a documented replacement, consumer migration window/trigger, compatibility tests and removal criterion; do not invent calendar guarantees without release policy evidence.
  • Error bodies use stable controlled codes/shape and must not leak tenant existence, secrets, local paths, stack traces or document content.
  • Opaque identifiers remain non-numeric and client code must not infer internal persistence layout.

naruon / MSA contract

The naruon integration boundary must be an explicit consumer of the same public versioned contract, not a privileged hidden API.

  • no cross-service application-database writes;
  • host-owned identity/federation is translated into Clearfolio's verified public auth contract;
  • tenant and artifact authorization remain Clearfolio server authority;
  • model routing through contextual-orchestrator is optional and cannot become authority for deterministic conversion, authorization, fidelity or release acceptance;
  • contract tests must run with a standalone client fixture and a naruon-compatible adapter fixture without requiring naruon source-repository mutation from this writer loop;
  • schema/version negotiation and controlled unsupported-version failure must be explicit.

Machine-readable contract quality

  • generate or validate the OpenAPI artifact from reviewed source-of-truth definitions so code and schema cannot silently diverge;
  • fail CI when public routes/models/status codes or documented enum values drift from the contract;
  • validate examples against their schemas;
  • enforce unique stable operationId values;
  • constrain strings, arrays, uploads and response sizes where the runtime does;
  • represent authentication/authorization requirements truthfully without putting secrets in examples;
  • include artifact Range/header/security semantics where OpenAPI can express them and link normative prose for protocol details that cannot be fully modeled;
  • package the exact schema with release artifacts and bind it to source/artifact provenance.

Test-first acceptance

Before implementation, add RED contract tests that demonstrate current drift or incompleteness. Then require at least:

  • every shipped public route is represented exactly once;
  • every documented route resolves to a current controller/public operation;
  • request/response DTO names and required/nullability/type constraints match runtime serialization;
  • SUBMITTED, PROCESSING, SUCCEEDED, FAILED and any future versioned states match source exactly;
  • stable error/status matrix tests for auth, not-found concealment, malformed/oversized/unsupported input and artifact-token failures;
  • artifact full/single-range/416/header semantics;
  • examples validate against the schema;
  • breaking-change detector against the latest released schema;
  • naruon-compatible consumer contract test and standalone consumer contract test;
  • unsupported API version failure test;
  • migration/deprecation compatibility tests;
  • exact 100% owned production line/statement and branch coverage for new generator/validator code and complete beginner-readable public docs/docstrings;
  • exact-head CI, Security Scan, SAST, package/SBOM/provenance and independent review under repository policy.

Security and privacy

Machine-readable schemas are public contract evidence, not permission to expose internal objects. Do not publish raw tenant/subject identifiers beyond intended public fields, secrets, HMAC/token material, storage paths, internal exception types, provider credentials or unrestricted audit payloads.

Schema generation must be deterministic and must not execute untrusted uploaded documents, invoke models, fetch arbitrary remote URLs or require production credentials.

Documentation / release updates

Update canonical docs/PRD.md, docs/TRD.md, ARCHITECTURE.md, relevant ADRs, docs/UML.md, docs/DATA_MODEL.md where public entities change, docs/API_CONTRACT.md, docs/TEST_STRATEGY.md, docs/OPERABILITY.md, docs/MIGRATION_ROLLBACK.md, docs/TRACEABILITY.md, docs/ACQUISITION_DILIGENCE.md, docs/RELEASE_ACCEPTANCE.md, README/AGENTS/CLAUDE and CHANGELOG as applicable.

A release is not compatible merely because the server starts. The released OpenAPI/schema digest, generated client/consumer smoke evidence and source/artifact provenance must all bind to the same protected release identity.

Dependency order

Do not encode active #270/#268/#295/#312/#314 behavior as shipped. Implement the first contract-completeness slice from the stable protected baseline and evolve it as those public behaviors integrate, preserving compatibility evidence at each step.

Activity

  1. added
    area: apiAPI, protocol, event, or external contract
    area: authAuthentication, authorization, identity, or tenant isolation
    area: ci-cdCI, GitHub Actions, checks, release, or supply chain
    area: securitySecurity boundary, hardening, or vulnerability prevention
    status: triagedOpen issue has an organization taxonomy assignment
    type: featureNew or expanded product capability
    on Aug 22, 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

    area: apiAPI, protocol, event, or external contractarea: authAuthentication, authorization, identity, or tenant isolationarea: ci-cdCI, GitHub Actions, checks, release, or supply chainarea: securitySecurity boundary, hardening, or vulnerability preventionmaintenancepriority: mediumNormal-priority or P2 workscope: product-gapCustomer-visible product gapstatus: triagedOpen issue has an organization taxonomy assignmenttype: featureNew or expanded product capability

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions