Document namespace and scoped lookup roadmap
This commit is contained in:
244
docs/roadmap/namespaces.md
Normal file
244
docs/roadmap/namespaces.md
Normal file
@@ -0,0 +1,244 @@
|
||||
# Namespaces And Scoped Resource Lookup
|
||||
|
||||
Status: proposed feature roadmap; not implemented. The consumer need is
|
||||
established, but the API shape and naming rules below remain proposals unless
|
||||
identified as existing behavior.
|
||||
|
||||
## Purpose
|
||||
|
||||
Let consumers select a namespace once and use convenient local names within
|
||||
that namespace across PromptKit operations. An assembled engine may contain
|
||||
multiple application prompt libraries and provider profile catalogs with
|
||||
overlapping local names. Resolution must remain unambiguous.
|
||||
|
||||
The motivating cases are:
|
||||
|
||||
- WeatherReporter and another application both define `summarize.alerts`.
|
||||
Each consumer selects its application namespace and uses the local name.
|
||||
- OpenRouter and RakestrawHome both provide the model identified in the
|
||||
discussion as `google/gemma-4-31b-it`. Consumers distinguish the execution
|
||||
profiles by provider namespace while retaining convenient local naming.
|
||||
|
||||
Model names here illustrate identity and resolution, not provider availability
|
||||
or a promise of maintained catalog entries.
|
||||
|
||||
The primary need is organization and convenient lookup within assembled
|
||||
libraries. Ansible collections are a conceptual reference for qualified names;
|
||||
package distribution and relocatable collection imports are not required for
|
||||
this feature.
|
||||
|
||||
## Existing Foundation
|
||||
|
||||
The [format reference](../formats.md) defines prompt, profile, and backend keys
|
||||
as exact literal IDs. Punctuation is already allowed, and references are not
|
||||
trimmed or re-keyed. Merely adopting prefixed IDs therefore does not provide
|
||||
the requested scoped lookup behavior.
|
||||
|
||||
Existing prompt and profile listings expose assembled identities. The
|
||||
[consumer guide](../consumers/pkg-promptkit.md) describes current operations;
|
||||
their Go declarations and GoDoc remain authoritative until this feature lands.
|
||||
|
||||
[ADR 0001](../adr/0001-configuration-boundary.md) assigns source loading,
|
||||
composition, and inheritance to ConfigKit. This proposal adds interpretation
|
||||
of consumer-supplied resource names against the final effective configuration,
|
||||
without a second source-composition pass.
|
||||
|
||||
## Proposed Identity Convention
|
||||
|
||||
Use `namespace/local-name` as the qualified identifier. The first slash is the
|
||||
namespace boundary; the rest of the local name is literal and may contain dots
|
||||
or additional slashes. This is the recommended convention, not a settled
|
||||
format change.
|
||||
|
||||
| Resource | Namespace | Local name | Qualified ID |
|
||||
| --- | --- | --- | --- |
|
||||
| Prompt | `weatherreporter` | `summarize.alerts` | `weatherreporter/summarize.alerts` |
|
||||
| Prompt | `homewatch` | `summarize.alerts` | `homewatch/summarize.alerts` |
|
||||
| Profile | `openrouter` | `google/gemma-4-31b-it` | `openrouter/google/gemma-4-31b-it` |
|
||||
| Profile | `rakestrawhome` | `google/gemma-4-31b-it` | `rakestrawhome/google/gemma-4-31b-it` |
|
||||
|
||||
Prompt, profile, and backend identities remain separate resource types. The
|
||||
same namespace can contain all three, and resources in it may come from
|
||||
multiple configuration sources. A namespace does not imply a directory,
|
||||
package, provider model identifier, or security boundary.
|
||||
|
||||
A profile ID identifies execution settings. Its configured model value is
|
||||
still the identifier passed to the provider; qualifying the profile ID does
|
||||
not modify that value. Different profiles may select the same model with
|
||||
different settings. Prompt versions also remain separate from namespaces and
|
||||
continue to use the existing selection rules.
|
||||
|
||||
Retain existing exact IDs, including unqualified and dotted names. Before
|
||||
formalizing namespace discovery, audit slash-containing IDs in maintained
|
||||
catalogs and representative consumer configurations: interpreting their first
|
||||
component as a namespace may affect grouping even when exact lookup is unchanged.
|
||||
|
||||
## Proposed Consumer Scope
|
||||
|
||||
Prefer a lightweight, immutable view over an existing engine. The following
|
||||
sketch illustrates the consumer experience only; it does not settle a method
|
||||
name, return type, error behavior, or final signature:
|
||||
|
||||
```go
|
||||
weather := engine.InNamespace("weatherreporter")
|
||||
// Operations through weather can select the local prompt "summarize.alerts".
|
||||
```
|
||||
|
||||
The view would share the engine's captured configuration, clients, and execution
|
||||
machinery. Selecting a namespace would not rebuild the engine or duplicate its
|
||||
backend capacity accounting. Consumers could use different views concurrently
|
||||
without changing a shared current-namespace setting.
|
||||
|
||||
The proposed resolution rules are:
|
||||
|
||||
1. A supplied local name is qualified using the selected scope for its resource
|
||||
type, then looked up exactly.
|
||||
2. A missing scoped resource does not trigger a search in other namespaces or
|
||||
among unqualified IDs. Loading another collection cannot redirect lookup.
|
||||
3. An operation without a selected scope retains existing exact-ID behavior.
|
||||
4. Scope applies to caller-supplied resource names. Stored references, including
|
||||
prompt default profiles, profile backends, inheritance references, and backend
|
||||
smoke-test default profiles, retain their existing exact meaning. They are
|
||||
not rebound to the invoking consumer's namespace.
|
||||
5. Omitted optional IDs retain their existing selection/default behavior; an
|
||||
omission is not converted into a namespace prefix or a lookup for an empty
|
||||
local name.
|
||||
6. Where outputs, inspection, errors, or diagnostic reports identify a selected
|
||||
resource, preserve its resolved full identity. Any exposed local name should
|
||||
be distinguishable from that identity.
|
||||
|
||||
Keep qualification consistent across execution, preparation, request validation,
|
||||
prompt/profile inspection, and applicable smoke-test selections. Namespace
|
||||
selection must not change request override precedence, prompt version selection,
|
||||
or provider model strings.
|
||||
|
||||
### Local Names Versus Exact IDs
|
||||
|
||||
The presence of a slash cannot distinguish local and qualified references:
|
||||
`google/gemma-4-31b-it` is a legitimate local profile name under `openrouter`.
|
||||
Do not decide whether to qualify a name by checking whether the unqualified
|
||||
candidate happens to exist; that would make resolution depend on loaded content.
|
||||
|
||||
The recommended initial approach is that a scoped resource field consistently
|
||||
accepts a local name, while the original engine remains available for exact IDs.
|
||||
Under that approach, even a string that looks qualified is treated as local
|
||||
when passed through the corresponding scope. An explicit per-reference exact-ID
|
||||
mechanism is an alternative if mixed local and qualified selections in one
|
||||
request justify it. Settle this before defining the public API.
|
||||
|
||||
### Separate Resource Scopes
|
||||
|
||||
A consumer may want prompt shorthand under `weatherreporter` and profile
|
||||
shorthand under `openrouter` in the same request. Evaluate independently
|
||||
selectable prompt, profile, and backend scopes instead of assuming one namespace
|
||||
must apply to every field. A prompt's configured default profile needs no caller
|
||||
profile scope because the stored reference is already exact.
|
||||
|
||||
Independent scopes are recommended where the consumer needs shorthand, but the
|
||||
scope options and the meaning of a convenience `InNamespace` operation are
|
||||
still open. Do not silently apply a prompt scope to an otherwise exact profile
|
||||
override. Include any directly supplied backend selection in this decision.
|
||||
|
||||
## Discovery And Collection Organization
|
||||
|
||||
Namespace-aware discovery is supporting work: consumers should be able to
|
||||
identify available namespaces and list their resources without each application
|
||||
inventing parsing and filtering rules. Keep this proportionate to the primary
|
||||
scoped-lookup feature.
|
||||
|
||||
Decide whether scoped listing returns full identities, local names alongside
|
||||
full identities, or another explicit shape. A caller must be able to tell how
|
||||
to pass a listed name back to a scoped operation without double qualification.
|
||||
Retain the existing unscoped listing contracts.
|
||||
|
||||
If namespace membership is derived from the recommended prefix convention,
|
||||
match the complete namespace boundary: `weather` must not include
|
||||
`weatherreporter/...`. Additional slashes within the local name do not imply
|
||||
recursive namespace traversal.
|
||||
|
||||
The initial proposal does not require a collection manifest. Titles,
|
||||
descriptions, and other collection metadata can be considered if consumers
|
||||
need more than identity and grouping.
|
||||
|
||||
## Composition And Compatibility
|
||||
|
||||
Qualified identities reduce accidental collisions between independently
|
||||
authored libraries. Definitions with the same exact qualified identity still
|
||||
follow the existing ConfigKit overlay and inheritance rules; namespaces do not
|
||||
create a separate collision policy.
|
||||
|
||||
Leave source composition and configuration inspection with ConfigKit. Do not
|
||||
introduce implicit qualification of definition keys, mounting under caller-chosen
|
||||
prefixes, or rewriting of stored references as part of consumer scope. Those
|
||||
would be separate configuration-design work.
|
||||
|
||||
Existing unscoped engine calls and catalog identifiers must continue to work.
|
||||
Adoption of the new convention by maintained catalogs needs an explicit
|
||||
migration decision. Renaming a profile or backend can affect configured
|
||||
references; duplicating a backend under another ID can also separate capacity
|
||||
accounting. Do not treat blanket aliases or duplicate catalog entries as a
|
||||
cost-free compatibility mechanism.
|
||||
|
||||
The [architecture policy](../policy/architecture.md) continues to assign CLI
|
||||
syntax, flags, and application policy to consumers such as Scriptorium. PromptKit
|
||||
would supply reusable scope and resolution semantics.
|
||||
|
||||
## Work Not Included In The Initial Proposal
|
||||
|
||||
- Package installation, collection registries, and dependency resolution.
|
||||
- Caller-selected collection mount points or import alias rewriting.
|
||||
- Implicit namespace search paths or fallback to whichever resource exists.
|
||||
- Namespace-based access control or filesystem isolation.
|
||||
- Changes to model names, inference behavior, or configuration precedence.
|
||||
|
||||
These boundaries limit the initial proposal; they do not prohibit future work
|
||||
if a concrete consumer need emerges.
|
||||
|
||||
## Delivery Outline
|
||||
|
||||
1. Settle the open naming and API decisions below and audit existing identifier
|
||||
usage. Record any catalog migration as explicit coordinated work.
|
||||
2. Implement the smallest public scope surface with shared name qualification
|
||||
and existing engine collaborators. Cover supported operations consistently.
|
||||
3. Add the selected discovery behavior and representative consumer examples.
|
||||
4. Verify compatibility and scoped resolution through focused offline tests,
|
||||
following the [testing policy](../policy/testing.md). Update GoDoc, the
|
||||
format reference, consumer guide, and relevant internal documentation as
|
||||
behavior lands; retire this roadmap when its work is complete.
|
||||
|
||||
Suggested acceptance cases, subject to the selected API contract:
|
||||
|
||||
- Two prompt scopes resolve the same local name to their respective prompts;
|
||||
a missing name never resolves from the other scope or an unqualified entry.
|
||||
- Two provider profile scopes preserve a slash-containing local name and select
|
||||
different profiles without changing the configured provider model value.
|
||||
- Prompt shorthand and a profile override use their intended scopes, while
|
||||
stored default references and omitted selections retain their meaning.
|
||||
- Scoped views coexist concurrently and share backend capacity with ordinary
|
||||
calls on the underlying engine.
|
||||
- Existing exact-ID calls, intentional overlays, and prompt versions retain
|
||||
their behavior.
|
||||
- Listings and reported identities support the chosen local/full-ID round trip.
|
||||
- Representative validation, inspection, execution, and smoke-test paths use
|
||||
the same qualification rules without duplicating every test at every layer.
|
||||
|
||||
## Open Decisions
|
||||
|
||||
1. **Naming convention:** adopt the first-slash boundary, or select another
|
||||
separator? What namespace syntax is needed without narrowing existing IDs?
|
||||
2. **Public scope shape:** immutable view, scope options, or another small
|
||||
surface? Which resource scopes can be selected independently, and what does
|
||||
a one-namespace convenience operation mean?
|
||||
3. **Exact access within scoped requests:** use the original engine for exact
|
||||
selections, or provide an explicit per-reference distinction?
|
||||
4. **Scope validation:** when should an empty, malformed, or currently absent
|
||||
namespace produce an error? Distinguish syntax from resource existence and
|
||||
do not accidentally change omitted-ID defaults.
|
||||
5. **Discovery:** which listing/filtering operations are needed, how are legacy
|
||||
IDs grouped, and how are local and full identities represented?
|
||||
6. **Catalog adoption:** which maintained IDs, if any, should change, and what
|
||||
compatibility and release plan would accompany those changes?
|
||||
|
||||
Resolve these choices before treating the proposed mechanics as implementation
|
||||
requirements. The central requirement is already clear: consumers select a
|
||||
scope once and use local names predictably within an assembled library.
|
||||
Reference in New Issue
Block a user