Plan the public facade refactor and profile policy updates
This commit is contained in:
359
docs/roadmap/profile-policy.md
Normal file
359
docs/roadmap/profile-policy.md
Normal file
@@ -0,0 +1,359 @@
|
||||
# Built-In Profile Compatibility Policy
|
||||
|
||||
## Status
|
||||
|
||||
Provisional and under active discussion. Nothing in this roadmap is an
|
||||
accepted policy, an implementation commitment, a release decision, or a
|
||||
description of current Promptkit behavior. Current code, GoDoc, durable
|
||||
documentation, published module contracts, and release tags remain
|
||||
authoritative until this proposal is finalized and implemented.
|
||||
|
||||
## Prerequisite And Sequencing
|
||||
|
||||
Implementation of this roadmap must begin only after the
|
||||
[public facade refactor](public-facade.md) is complete and its compatibility
|
||||
and validation criteria have passed. The refactor preserves existing behavior;
|
||||
this subsequent work introduces the deliberate profile-policy changes.
|
||||
|
||||
Profile-source composition, maintained-profile construction, and catalog
|
||||
dependency assembly must use the internal owners established by that refactor.
|
||||
Both scopes may ship in `v0.10.0`, but they remain separately reviewable changes.
|
||||
This prerequisite does not prevent continued discussion or planning here.
|
||||
|
||||
## Purpose
|
||||
|
||||
Define a truthful compatibility and release boundary for Promptkit's
|
||||
maintained built-in profiles. The intended direction is to permit exceptionally
|
||||
rapid catalog updates without weakening Promptkit's stability commitments for
|
||||
its engine, public Go API, configuration semantics, backend registry, or other
|
||||
non-profile behavior.
|
||||
|
||||
Model catalogs change faster than the Promptkit runtime. Providers control
|
||||
their own model catalogs and service lifecycles. Promptkit cannot
|
||||
reasonably guarantee that a maintained profile's upstream model or endpoint
|
||||
will remain available, and retaining obsolete profiles can be actively
|
||||
misleading when their targets no longer provide the expected service.
|
||||
|
||||
The release model should treat external catalog profiles as volatile data,
|
||||
while providing a small set of Promptkit-owned aliases with stable IDs for
|
||||
applications that prefer a maintained general-purpose selection.
|
||||
|
||||
## Proposed Compatibility Boundary
|
||||
|
||||
The provisional policy would exclude external catalog profile data from
|
||||
Promptkit's cross-version compatibility surface. A catalog or Promptkit
|
||||
release could, without deprecation or advance notice:
|
||||
|
||||
- add or remove an external catalog profile;
|
||||
- rename a profile, represented as removing one ID and adding another;
|
||||
- change the upstream model selected by a profile;
|
||||
- change profile defaults such as reasoning effort, timeout, service tier,
|
||||
sampling controls, token limits, or extra parameters; and
|
||||
- correct or otherwise revise profile metadata in response to upstream
|
||||
behavior.
|
||||
|
||||
Promptkit would make no cross-version promise about the continued presence,
|
||||
identity, settings, suitability, or upstream availability of an external
|
||||
catalog profile. The separately defined Promptkit-owned alias IDs would have
|
||||
the continuity guarantee below. Promptkit would make no claim that an upstream
|
||||
provider will continue to serve a cataloged model or endpoint for the lifetime
|
||||
of a Promptkit or catalog release.
|
||||
|
||||
This volatility exception should apply only to external catalog profile
|
||||
data. It should not silently weaken the ordinary compatibility rules for:
|
||||
|
||||
- Promptkit's exported Go API and GoDoc contracts;
|
||||
- prompt, profile, and schema format semantics;
|
||||
- request preparation, execution, validation, repair, cancellation, error,
|
||||
credential, ownership, and concurrency behavior;
|
||||
- public built-in backend IDs and registry behavior;
|
||||
- the external catalog packages' exported Go API;
|
||||
- the catalog manifest and asset schema understood by Promptkit; or
|
||||
- consumer-defined profiles and backends.
|
||||
|
||||
Backend definitions, including endpoint, credential-environment, and capacity
|
||||
metadata, remain outside the profile-volatility exception and subject to the
|
||||
ordinary compatibility policy.
|
||||
|
||||
## Proposed Stable Promptkit Profiles
|
||||
|
||||
Promptkit would maintain a small, explicitly documented set of built-in
|
||||
profiles using existing profile definitions and inheritance:
|
||||
|
||||
| Stable profile ID | Initial definition | Initial purpose |
|
||||
| --- | --- | --- |
|
||||
| `promptkit-openrouter-standard` | Inherits from external catalog profile `gemini-flash-latest`. | A maintained selection for general-purpose text generation. |
|
||||
| `promptkit-openrouter-auto` | Selects backend `openrouter` and model `openrouter/auto`. | Delegates model selection to OpenRouter's automatic routing. |
|
||||
|
||||
These definitions and purposes describe the initial selections only and are
|
||||
not continuing model-selection promises.
|
||||
|
||||
The auto profile can initially be a direct profile definition; it does not
|
||||
require a second catalog alias or a new public API. It inherits connection and credential
|
||||
metadata from the OpenRouter backend and need not add generation overrides.
|
||||
Promptkit forwards `openrouter/auto` as the model identifier through its ordinary
|
||||
client. OpenRouter owns the routing decision, eligible models, and resulting
|
||||
provider behavior. Promptkit adds no model-selection algorithm or fallback
|
||||
loop. Its ordinary local validation does not check the upstream availability
|
||||
of `openrouter/auto`.
|
||||
|
||||
Both profiles receive the stable-ID guarantee below. References to aliases
|
||||
describe inherited definitions where applicable; the same namespace,
|
||||
precedence, and structural-validation requirements cover direct definitions.
|
||||
Only these two profiles are in scope. This roadmap imposes no additional
|
||||
approval process for future profiles.
|
||||
|
||||
The only profile-specific continuity promise is that the literal names
|
||||
`promptkit-openrouter-standard` and `promptkit-openrouter-auto` remain
|
||||
available, subject to the supported dependency and consumer-override scope
|
||||
below. Their actual models may change at any time, for any reason, without
|
||||
notice to anyone. No deprecation, approval, or change-announcement gate applies
|
||||
to model selection. The names do not promise a permanent model, provider,
|
||||
routing strategy, or set of defaults. Both initially use OpenRouter, but the
|
||||
profile names themselves are the only continuity guarantee.
|
||||
|
||||
In particular, `promptkit-openrouter-auto` is not required to retain
|
||||
`openrouter/auto` or automatic routing indefinitely. Neither profile guarantees
|
||||
unchanged output, cost, latency, capabilities, or upstream availability. While
|
||||
using upstream automatic routing, the selected model can vary between requests
|
||||
even with unchanged Promptkit and catalog versions.
|
||||
|
||||
Catalog dependency updates must preserve local resolution of the two maintained
|
||||
profile names. If a referenced catalog profile disappears or is renamed,
|
||||
adjust the affected alias together with the dependency update and ship both in
|
||||
the same Promptkit release. If the catalog retains the referenced ID but
|
||||
changes its model, inheritance picks up the change automatically; no separate
|
||||
model-selection approval is required. Ordinary code review and structural
|
||||
validation apply. Upstream deprecation, retirement, and mapping accuracy remain
|
||||
the catalog library's responsibility and do not create a Promptkit monitoring
|
||||
or upstream-verification obligation.
|
||||
|
||||
Release validation must prove that every maintained alias resolves against
|
||||
the selected catalog versions. This continuity guarantee applies to the
|
||||
versions selected and tested by Promptkit and assumes consumers have not
|
||||
overridden the alias or its base with their own definitions. Independently
|
||||
upgrading a transitive catalog can remove an alias's base without updating
|
||||
Promptkit; that untested combination is outside the guarantee.
|
||||
|
||||
Aliases would retain the ordinary profile precedence and inheritance
|
||||
semantics. They would introduce no new public API or automatic model failover.
|
||||
An already deployed application would retain its compiled alias and catalog
|
||||
data until upgraded; an upstream withdrawal would not change its selection
|
||||
automatically.
|
||||
|
||||
Adding these profiles does not change existing default-profile selection.
|
||||
Consumers opt into them through the existing profile-selection mechanisms.
|
||||
|
||||
### Ownership, Precedence, And Composition
|
||||
|
||||
The maintained alias definitions belong to a small Promptkit-owned profile
|
||||
source. Profile precedence is consumer sources in their existing order, then
|
||||
Promptkit-owned aliases, then external catalog profiles. Consumers may override
|
||||
an alias or its base using the ordinary profile mechanisms.
|
||||
|
||||
Reserve the `promptkit-` profile-ID prefix against definitions in external
|
||||
catalogs. Reject such catalog definitions even if they do not yet collide with
|
||||
an existing alias. This namespace rule does not prohibit consumer overrides.
|
||||
|
||||
Retain existing catalog-local inheritance and backend-ownership validation,
|
||||
and verify that the combined maintained profiles resolve without relying on
|
||||
consumer overrides. Do not assert a permanent model or routing selection based
|
||||
on a profile name. Runtime inheritance must continue to observe the complete
|
||||
source hierarchy, including consumer overrides of aliases and their bases.
|
||||
Reuse the existing resolver; exact private assembly and validation sequencing
|
||||
belongs in the implementation plan. Do not introduce a second inheritance
|
||||
implementation or freeze alias values in a way that bypasses consumer overrides.
|
||||
|
||||
## Local Validation And Existing Safeguards
|
||||
|
||||
Profile volatility does not remove existing structural validation or library
|
||||
safeguards. Preserve the following implemented responsibilities without making
|
||||
them additional profile-availability or permanent implementation promises:
|
||||
|
||||
- catalog assets are immutable build inputs rather than runtime downloads;
|
||||
- manifests and profiles satisfy the supported schemas;
|
||||
- IDs are unique and profiles select their owning backend;
|
||||
- external catalogs do not define IDs in the reserved `promptkit-` namespace;
|
||||
- secret-bearing fields and prohibited connection metadata are rejected;
|
||||
- profile values are normalized, copied, resolved, and overlaid through the
|
||||
existing Promptkit architecture;
|
||||
- the selected catalogs pass Promptkit's integration suite before a Promptkit
|
||||
release adopts them; and
|
||||
- the module graph and checksums provide a reproducible identity for the data
|
||||
that was tested.
|
||||
|
||||
These checks establish local integrity for selected data, together with the
|
||||
maintained-profile resolution requirement above. They do not establish external
|
||||
catalog profile continuity across versions or live upstream availability.
|
||||
|
||||
Promptkit's checks cover local syntax and structural semantics: supported
|
||||
fields, duplicate IDs, namespace conflicts, inheritance resolution, backend
|
||||
references, endpoint URL format, and existing security and value constraints.
|
||||
They expressly exclude attempts to verify that an endpoint exists, a model ID
|
||||
is recognized upstream, or a provider serves that model. Catalog libraries own
|
||||
the accuracy of upstream model and endpoint mappings. Promptkit must not add
|
||||
network probes, model-list lookups, or paid inference checks to catalog adoption
|
||||
or release validation. Ordinary execution continues to report upstream errors
|
||||
through the existing generation-error contract.
|
||||
|
||||
## Provisional Release Model
|
||||
|
||||
The first release adopting this policy should be a new Promptkit minor release
|
||||
because it changes a previously documented consumer expectation and may remove
|
||||
profile IDs on which deployed configuration depends. `v0.10.0` is the current
|
||||
candidate.
|
||||
|
||||
The OpenRouter catalog's published `v1.0.0` contract promised stable profile
|
||||
IDs and advance handling before removal. A later README cannot retroactively
|
||||
weaken that promise. The current recommendation is therefore to establish the
|
||||
new boundary in `promptkit-backend-openrouter` major version 2, using the dated
|
||||
release convention below, even if its exported Go declarations and manifest
|
||||
schema do not change.
|
||||
|
||||
After that boundary is established, maintained catalog releases could publish
|
||||
profile additions, deletions, and modifications rapidly under their documented
|
||||
volatile-data policy. Promptkit could select a reviewed catalog update without
|
||||
treating profile churn as a compatibility break in its otherwise stable core.
|
||||
Later catalog updates and corresponding alias adjustments may ship in a
|
||||
Promptkit patch release, such as `v0.10.1` after `v0.10.0`, provided unrelated
|
||||
compatibility contracts remain intact. Profile churn alone does not require
|
||||
`v0.11.0` or another minor release.
|
||||
|
||||
Promptkit's integration validation covers the catalog versions it selected
|
||||
and tested. It does not guarantee upstream correctness for those versions.
|
||||
Go module version selection may cause an advanced consumer's build
|
||||
to select a newer compatible catalog module than Promptkit's own requirement;
|
||||
the resolved module graph, rather than Promptkit's `go.mod` alone, determines
|
||||
the actual embedded data.
|
||||
|
||||
Release notes may identify selected catalog updates and summarize changes for
|
||||
convenience, but no notice of model-selection changes is required, in advance
|
||||
or afterward. Ordinary release records and validation still apply; they must
|
||||
not introduce a profile-change announcement gate.
|
||||
|
||||
### Proposed Date-Based Catalog Versions
|
||||
|
||||
The proposed catalog version convention is `vMAJOR.YYYYMMDD.N`. This is a
|
||||
calendar-based convention encoded in Go-compatible semantic-version syntax:
|
||||
|
||||
- `MAJOR` identifies the compatibility generation of the exported Go package
|
||||
and catalog asset format. Profile additions, deletions, renames, and setting
|
||||
changes do not require a major-version increase under the proposed policy.
|
||||
- `YYYYMMDD` is the release publication date in UTC. It occupies the numeric
|
||||
minor-version component and communicates snapshot freshness, not the scale
|
||||
or compatibility of a profile change.
|
||||
- `N` starts at zero for each UTC date and increments for every additional
|
||||
release that day, regardless of the kind of profile change. It occupies the
|
||||
numeric patch-version component and carries no profile-continuity promise.
|
||||
|
||||
For example, `v2.20260922.0` and `v2.20260922.1` would be successive releases
|
||||
on September 22, 2026, followed by `v2.20260923.0` on the next day. These are
|
||||
illustrative dates, not scheduled releases. Use the actual publication date;
|
||||
published versions remain immutable, and corrections receive new versions.
|
||||
Within a major generation, these versions sort chronologically under Go's
|
||||
ordinary module-version ordering.
|
||||
|
||||
Go requires a matching major-version suffix in module paths for version 2 and
|
||||
later. The OpenRouter transition would therefore use
|
||||
`gitea.maximumdirect.net/eric/promptkit-backend-openrouter/v2` in the catalog's
|
||||
module declaration and Promptkit's imports and dependency requirement. A first
|
||||
release on the example date would be `v2.20260922.0`; a preliminary `v2.0.0`
|
||||
release is not required. Promptkit consumers would continue importing
|
||||
Promptkit through its existing module path. See the
|
||||
[Go module version rules](https://go.dev/ref/mod#versions) and
|
||||
[major-version suffix rules](https://go.dev/ref/mod#major-version-suffixes).
|
||||
|
||||
Both maintained catalog libraries, OpenRouter and Rakestrawhome, would
|
||||
transition to this policy and dated major-version-2 convention as part of this
|
||||
work, with matching `/v2` module paths. Thereafter each would release
|
||||
independently; releases need not share dates or revision numbers.
|
||||
Promptkit itself would retain its existing version-number
|
||||
convention and explicitly select and test individual catalog versions.
|
||||
|
||||
This proposal replaces the earlier idea of classifying catalog refreshes as
|
||||
ordinary minor releases and metadata corrections as patches. The date records
|
||||
when a snapshot was published; release notes may summarize what changed.
|
||||
Neither establishes live upstream availability or cross-version profile
|
||||
continuity. The convention remains provisional along with this roadmap.
|
||||
|
||||
## Consumer Guidance
|
||||
|
||||
The eventual durable documentation should make the tradeoff explicit:
|
||||
|
||||
- external catalog profiles optimize for convenient access to a maintained
|
||||
current model catalog;
|
||||
- selecting or inheriting directly from an external catalog profile accepts
|
||||
its volatility;
|
||||
- selecting either `promptkit-openrouter-standard` or
|
||||
`promptkit-openrouter-auto` guarantees only continued availability of that
|
||||
literal profile name within the supported dependency scope; models and
|
||||
settings may change for any reason without notice;
|
||||
- `promptkit-openrouter-auto` initially delegates model selection to OpenRouter;
|
||||
its initial routing behavior is not a permanent contract, and upstream
|
||||
routing can change independently of a library upgrade;
|
||||
- pinning the complete resolved Go module graph preserves the exact catalog
|
||||
assets used by that build, but cannot preserve live upstream availability;
|
||||
- applications that require their own fixed model selection or settings should
|
||||
define a complete application-owned profile with an explicit backend, model,
|
||||
and defaults; and
|
||||
- an application-owned alias that inherits from an external catalog profile
|
||||
isolates application configuration from the catalog ID only while that base
|
||||
exists; it deliberately continues to inherit changes to the base profile.
|
||||
|
||||
Promptkit should not promise automatic migration or replacement aliases for
|
||||
every removed external catalog ID, deprecation windows for catalog profiles,
|
||||
or runtime fallback from a removed or unavailable model. Its small maintained
|
||||
alias set provides continuity through coordinated library releases.
|
||||
|
||||
## Expected Documentation And Repository Changes
|
||||
|
||||
If accepted, implementation would likely require coordinated changes in
|
||||
Promptkit and each maintained catalog repository:
|
||||
|
||||
- revise catalog compatibility and release documentation to distinguish the
|
||||
stable Go/schema boundary from volatile profile data and document the
|
||||
`vMAJOR.YYYYMMDD.N` convention;
|
||||
- update Promptkit's release policy with a narrowly scoped built-in-profile
|
||||
volatility exception for external catalogs and an explicit continuity
|
||||
guarantee for Promptkit-owned alias IDs, while retaining its other pre-`v1`
|
||||
compatibility rules;
|
||||
- add `promptkit-openrouter-standard` through existing profile inheritance and
|
||||
`promptkit-openrouter-auto` as a direct `openrouter/auto` profile; document
|
||||
their distinct purposes and opt-in selection;
|
||||
- require coordinated catalog and alias updates, with release checks proving
|
||||
every maintained alias resolves against the selected catalog versions;
|
||||
- update the architecture, format, source, development, and consumer
|
||||
documentation at their existing ownership boundaries;
|
||||
- keep exact external profile inventories in the catalog repositories, linking
|
||||
to the selected versions from Promptkit rather than duplicating their tables;
|
||||
keep Promptkit's small alias inventory and runtime semantics in its own
|
||||
canonical documentation;
|
||||
- revise tests and compatibility-fixture terminology so they protect local
|
||||
structural validity and maintained-profile resolution, without asserting
|
||||
cross-version stability of external profiles; retain an exact selected-version
|
||||
snapshot only where its review value justifies its maintenance cost;
|
||||
- publish both revised catalog contracts as dated major-version-2 releases
|
||||
with matching `/v2` module paths;
|
||||
- update Promptkit's catalog imports and requirement, current selected-profile
|
||||
documentation, and release guidance; and
|
||||
- publish the policy transition and its consumer impact in the eventual
|
||||
Promptkit minor release note and annotated tag.
|
||||
|
||||
No implementation should begin from this document until its provisional
|
||||
status has been updated through the repository's normal planning process and
|
||||
the public facade refactor prerequisite has been completed.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
This proposal does not introduce:
|
||||
|
||||
- runtime catalog downloads, discovery, or mutable global registration;
|
||||
- any upstream endpoint or model-existence verification by Promptkit, or
|
||||
guarantees based on current provider health;
|
||||
- automatic replacement aliases or migration tables for every removed catalog
|
||||
profile, or runtime fallback models;
|
||||
- weakened validation of catalog structure or content;
|
||||
- weaker compatibility for Promptkit's public engine or consumer-defined
|
||||
configuration; or
|
||||
- a general exception allowing arbitrary dependency updates to break stable
|
||||
Promptkit behavior.
|
||||
218
docs/roadmap/public-facade.md
Normal file
218
docs/roadmap/public-facade.md
Normal file
@@ -0,0 +1,218 @@
|
||||
# Public Facade Refactor
|
||||
|
||||
## Status
|
||||
|
||||
Accepted direction; implementation has not begun. This feature roadmap defines
|
||||
the intended end state and compatibility requirements. A separate staged
|
||||
implementation plan will define the work sequence. Current GoDoc and durable
|
||||
documentation remain authoritative until implementation lands.
|
||||
|
||||
## Purpose
|
||||
|
||||
Make Promptkit's root package a deliberately maintained consumer facade while
|
||||
placing engine implementation and assembly behind Go's `internal/` boundary.
|
||||
Consumers should depend only on intentional public contracts, and maintainers
|
||||
should be able to refactor internal behavior without changing those contracts.
|
||||
|
||||
The aim is a clearer ownership boundary, not the smallest possible root package
|
||||
or a reduction in consumer capabilities. Private root functions are already
|
||||
inaccessible to consumers; relocating them improves separation but does not by
|
||||
itself control the exported API. The refactor must also protect public type
|
||||
ownership, signatures, fields, and method sets against accidental exposure of
|
||||
implementation details.
|
||||
|
||||
## Current Position
|
||||
|
||||
Promptkit already places execution, repair, capacity management, rendering,
|
||||
source loading, transport, and validation in specialized internal packages.
|
||||
Its [architecture policy](../policy/architecture.md) already identifies the
|
||||
root package as the supported public facade.
|
||||
|
||||
The remaining root implementation includes engine construction and collaborator
|
||||
assembly, source selection, profile overlay construction, filesystem source
|
||||
setup, and an in-memory profile repository. These responsibilities can move
|
||||
inward while the root retains public declarations and explicit adapters.
|
||||
|
||||
ConfigKit's completed facade refactor is a design reference: root-owned public
|
||||
types wrap private engine state and expose explicitly selected methods. Its
|
||||
implementation should inform this work without introducing a dependency on
|
||||
ConfigKit or copying mechanisms that Promptkit does not need.
|
||||
|
||||
## Target End State
|
||||
|
||||
### Root-Owned Public Contract
|
||||
|
||||
The root `promptkit` package remains the consumer import path and owns:
|
||||
|
||||
- public named types, interfaces, constants, and error identities;
|
||||
- public configuration, request, result, inspection, and profile values;
|
||||
- constructors, options, and deliberate forwarding methods;
|
||||
- opaque public handles backed by private internal state;
|
||||
- public GoDoc and supported serialization and formatting behavior; and
|
||||
- explicit value conversion, injected-collaborator adaptation, and public
|
||||
error translation where they cross the facade boundary.
|
||||
|
||||
Public types must remain root-defined. Do not alias them to internal types,
|
||||
anonymously embed internal implementations to promote methods, expose internal
|
||||
types in public fields or signatures, or add public bridge methods for wiring.
|
||||
Private fields may refer to internal implementations.
|
||||
|
||||
Straightforward convenience constructors and boundary code may remain in the
|
||||
root. A forwarding layer or additional record type should have a concrete
|
||||
ownership or compatibility purpose; moving every helper is not an objective.
|
||||
|
||||
### Internal Engine Assembly
|
||||
|
||||
A cohesive internal assembly owner constructs an operational engine from
|
||||
internal configuration and supplied collaborators. `internal/engine` is the
|
||||
proposed home; exact private package and helper layout belongs in the
|
||||
implementation plan. Its responsibilities
|
||||
include source selection and defaults, maintained catalog loading, profile
|
||||
overlay assembly, backend registration assembly, capacity-manager construction,
|
||||
default client and validator selection, and runner/repairer wiring.
|
||||
|
||||
The public `Engine` delegates through private state to internal implementation.
|
||||
Root options express consumer choices and translate public values; internal
|
||||
construction owns how those choices assemble components. Preserve established
|
||||
contracts for option capture, application, validation, and source access.
|
||||
Incidental private ordering is not a new compatibility requirement.
|
||||
|
||||
Build on the existing specialized internal responsibilities. Internal assembly
|
||||
is the composition owner, not a replacement for the runner,
|
||||
catalog adapter, profile repositories, transport, or domain packages. It should
|
||||
not duplicate execution orchestration already owned by `internal/usecase`.
|
||||
|
||||
Move the in-memory profile repository behind the internal boundary;
|
||||
`internal/profile` is its natural home. Reuse existing definition validation and
|
||||
copying owners. Other root implementation
|
||||
helpers should move to their cohesive existing owner or to internal assembly
|
||||
as appropriate. Avoid generic registries, service locators, or a new extension
|
||||
framework for this relocation.
|
||||
|
||||
Dependency direction remains root facade to internal components. Internal
|
||||
production packages must not import the root package. The root can use internal
|
||||
domain values and narrow collaborator interfaces for explicit conversions;
|
||||
this proposal does not require all root imports to pass through a single
|
||||
internal package or require duplicate forwarding APIs to achieve that shape.
|
||||
|
||||
## Compatibility Requirements
|
||||
|
||||
This is a behavior-preserving refactor. Inventory the actual exported surface,
|
||||
including methods and fields, before relocation. An exported declaration is
|
||||
accessible even when it is absent from the consumer guide. Do not infer that
|
||||
an apparently low-level declaration is safe to remove: injected model clients
|
||||
and other intentional extension contracts may rely on it.
|
||||
|
||||
Preserve existing public names, signatures, named-type identity, method sets,
|
||||
interface satisfaction, exported struct fields, and supported value behavior.
|
||||
Any discovered API removal or redesign requires a separate explicit decision
|
||||
and consumer migration rationale; the minor release is not blanket permission
|
||||
to remove accessible declarations.
|
||||
|
||||
The refactor must preserve, in particular:
|
||||
|
||||
- established option order, replacement and accumulation rules, nil behavior,
|
||||
validation timing, and capture/copy contracts;
|
||||
- profile-source precedence, lazy consumer source reads, inheritance, and
|
||||
maintained-catalog validation;
|
||||
- public error identities and typed errors through `errors.Is` and `errors.As`,
|
||||
including cancellation propagation and sensitive-detail redaction;
|
||||
- public JSON representations, formatting, and defensive-copy guarantees;
|
||||
- injected client and artifact-reader contracts, including caller ownership
|
||||
of collaborator values;
|
||||
- preparation and inspection semantics, hash relationships, request overrides,
|
||||
appended messages, output validation, and bounded repair;
|
||||
- prepared-execution engine binding, shared lifecycle when handles are copied,
|
||||
single-use execution, discard behavior, and credential retention; and
|
||||
- engine-local concurrency, admission, cancellation, usage accounting, and
|
||||
transport behavior.
|
||||
|
||||
Preserve intentional contracts without elevating incidental private layout,
|
||||
helper names, operation ordering, diagnostic wording, or opaque hash encodings
|
||||
into new promises. The baseline inventory identifies accessible API; it is
|
||||
not authority to turn every observed implementation behavior into a contract.
|
||||
|
||||
## Verification And Test Ownership
|
||||
|
||||
Follow the [testing policy](../policy/testing.md). Existing external-package
|
||||
contract tests and maintained offline examples should continue to exercise the
|
||||
same consumer API. Tests coupled to private layout may be adapted or
|
||||
consolidated under the testing policy without changing their contract-level
|
||||
expectations.
|
||||
|
||||
Move implementation tests with their owning behavior when package relocation
|
||||
requires it. Keep focused source, profile, runner, capacity, and transport
|
||||
coverage at the existing internal owners. Root tests should focus on public
|
||||
compatibility, boundary conversion, error adaptation, and representative
|
||||
assembled workflows. Do not duplicate internal test matrices at the facade or
|
||||
add one test per trivial forwarding method.
|
||||
|
||||
Add a focused public-boundary check that detects internal types escaping
|
||||
through exported types, signatures, fields, or promoted methods, and rejects
|
||||
public aliases to internal implementations. Use Go's type information where
|
||||
needed to inspect the actual exported method sets. The check must permit
|
||||
private internal state and the established sealed option mechanism. Protect
|
||||
the no-internal-production-imports-of-root dependency rule without freezing an
|
||||
incidental file layout or exact internal package inventory.
|
||||
|
||||
Compare the exported surface before and after the refactor. Use existing
|
||||
behavioral coverage first, adding tests only for consequential gaps introduced
|
||||
by the new boundary. Pay particular attention to option timing, conversion
|
||||
ownership, typed errors, and prepared-execution lifecycle. Run the complete
|
||||
[maintainer validation workflow](../development.md#maintainer-validation),
|
||||
including race checks and both offline examples, before accepting the result.
|
||||
No live provider calls or sibling repository are required for validation.
|
||||
|
||||
## Relationship To The Profile Policy Work
|
||||
|
||||
This refactor and the [profile-policy proposal](profile-policy.md) are separate
|
||||
scopes that may ship together in the planned `v0.10.0` release. Establish the
|
||||
facade boundary with current behavior preserved before implementing the
|
||||
catalog-policy and standard-profile changes. Their assembly logic can then
|
||||
land in its intended internal owner.
|
||||
|
||||
This roadmap does not itself change catalog versions, introduce standard
|
||||
profiles, or adopt the provisional profile compatibility policy. Release
|
||||
guidance should distinguish the internal refactor from the deliberate consumer
|
||||
policy changes accompanying it. A completed facade refactor should require no
|
||||
consumer migration on its own.
|
||||
|
||||
## Documentation End State
|
||||
|
||||
Update the [architecture policy](../policy/architecture.md) to describe the
|
||||
implemented facade and assembly boundary, and the
|
||||
[component overview](../internal/overview.md) to identify the new owner and
|
||||
relocated responsibilities. Update affected internal source and runner
|
||||
documentation and links when implementation moves.
|
||||
|
||||
Go declarations and GoDoc remain the canonical public contract. Consumer and
|
||||
format documentation should not acquire new requirements from a private
|
||||
relocation. Record the durable facade decision in an ADR if needed to preserve
|
||||
its rationale; ConfigKit is a reference, not an ongoing normative dependency.
|
||||
Remove this temporary roadmap after completion and durable documentation
|
||||
updates according to the [documentation policy](../policy/documentation.md).
|
||||
|
||||
## Completion Criteria
|
||||
|
||||
- The root exposes deliberate, root-owned consumer contracts and explicit
|
||||
adapters without leaking internal types or promoted implementation methods.
|
||||
- Internal assembly and repositories own the relocated implementation, with
|
||||
one production path and no parallel legacy engine.
|
||||
- Specialized internal components retain clear ownership and do not import
|
||||
the public facade.
|
||||
- Public API comparison and behavioral tests establish compatibility,
|
||||
including ownership, errors, option timing, and prepared execution.
|
||||
- Boundary checks protect accidental API exposure without preventing ordinary
|
||||
internal refactoring or consumer extension.
|
||||
- Required validation passes, documentation matches the implemented state,
|
||||
and consumers require no migration for this refactor.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- Public API expansion, removal, or redesign.
|
||||
- Changes to provider behavior, formats, defaults, or execution semantics.
|
||||
- Replacing the existing specialized packages with one large engine package.
|
||||
- A dependency on ConfigKit or a reusable facade-generation framework.
|
||||
- A minimum root-package line count, exhaustive wrapper tests, or a blanket
|
||||
prohibition on private boundary logic in the root.
|
||||
- Implementing the separate profile-policy roadmap during this refactor.
|
||||
Reference in New Issue
Block a user