Reserve slash for namespace-qualified identifiers
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
# 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.
|
||||
Status: feature roadmap; not implemented. The reserved-slash naming convention
|
||||
and reference-resolution rules are accepted target behavior. The public scope
|
||||
API, discovery surface, and migration details remain open as identified below.
|
||||
|
||||
## Purpose
|
||||
|
||||
@@ -43,19 +43,25 @@ 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
|
||||
## Accepted 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.
|
||||
Reserve `/` exclusively as the namespace separator in PromptKit prompt, profile,
|
||||
and backend identifiers and references. A qualified identifier has exactly two
|
||||
nonempty components: `namespace/local-name`. Neither component can contain `/`.
|
||||
Dots remain available within local names. An unqualified identifier has no slash
|
||||
and remains valid under the existing nonblank-ID rule.
|
||||
|
||||
Reject resource identifiers or supplied references with multiple slashes or an
|
||||
empty qualified component, such as `a/b/c`, `/name`, and `namespace/`. These
|
||||
rules do not apply to provider model values, endpoints, resource paths, or prompt
|
||||
versions. Preserve exact spelling; do not silently trim or rewrite IDs.
|
||||
|
||||
| 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` |
|
||||
| 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
|
||||
@@ -64,14 +70,16 @@ 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
|
||||
not modify that value. Both example profiles may retain the configured model
|
||||
`google/gemma-4-31b-it`. 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.
|
||||
Retain unqualified and dotted IDs. Existing slash-containing IDs need review:
|
||||
those with one slash and nonempty components become qualified identities, while
|
||||
those outside the new grammar require migration. This intentional format break
|
||||
is accepted in favor of unambiguous resolution; the migration work is described
|
||||
below.
|
||||
|
||||
## Proposed Consumer Scope
|
||||
|
||||
@@ -89,13 +97,15 @@ 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:
|
||||
The accepted resolution rules, independent of the final scope API, are:
|
||||
|
||||
1. A supplied local name is qualified using the selected scope for its resource
|
||||
type, then looked up exactly.
|
||||
1. A supplied name without a slash is qualified using the selected scope for its
|
||||
resource type, then looked up exactly. Without that scope, it is looked up as
|
||||
an exact unqualified ID.
|
||||
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.
|
||||
3. A valid supplied name containing one slash is fully qualified and is looked
|
||||
up exactly, regardless of scope. Malformed resource references are rejected.
|
||||
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
|
||||
@@ -112,19 +122,21 @@ 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
|
||||
### Local And Qualified References In One Operation
|
||||
|
||||
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.
|
||||
Syntax alone distinguishes local and qualified references. Do not decide whether
|
||||
to qualify a name by checking which candidates 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.
|
||||
Within a `weatherreporter` prompt scope, `summarize.alerts` resolves only to
|
||||
`weatherreporter/summarize.alerts`, while `homewatch/summarize.alerts` explicitly
|
||||
selects that other library's prompt. A qualified profile override similarly
|
||||
bypasses the profile scope. Scoped operations accept both forms without a
|
||||
separate reference type or requiring a return to the original engine for
|
||||
cross-namespace access.
|
||||
|
||||
The original engine remains the way to select an exact unqualified ID without
|
||||
applying a scope. No escape syntax for unqualified IDs is introduced here.
|
||||
|
||||
### Separate Resource Scopes
|
||||
|
||||
@@ -136,8 +148,9 @@ 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.
|
||||
still open. Define which scopes apply to unqualified names in each request
|
||||
field; qualified references always bypass them. Include any directly supplied
|
||||
backend selection in this decision.
|
||||
|
||||
## Discovery And Collection Organization
|
||||
|
||||
@@ -151,10 +164,9 @@ 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.
|
||||
Derive namespace membership from the qualified identifier's namespace component:
|
||||
`weather` must not include `weatherreporter/...`. Nested slash-separated
|
||||
namespaces are outside the accepted grammar.
|
||||
|
||||
The initial proposal does not require a collection manifest. Titles,
|
||||
descriptions, and other collection metadata can be considered if consumers
|
||||
@@ -172,12 +184,30 @@ introduce implicit qualification of definition keys, mounting under caller-chose
|
||||
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.
|
||||
Existing unscoped exact lookup remains available for IDs valid under the new
|
||||
grammar. Compatibility with arbitrary slash-containing resource IDs is
|
||||
intentionally broken. The migration must:
|
||||
|
||||
- Audit maintained catalogs and representative consumer definitions for invalid
|
||||
IDs and for valid one-slash IDs whose namespace meaning needs review.
|
||||
- Choose explicit old-to-new mappings and check for collisions. Do not
|
||||
automatically replace slashes with dots: distinct existing IDs could collapse
|
||||
to the same new identity.
|
||||
- Update renamed keys and their references together, including inheritance,
|
||||
prompt default profiles, profile backend references, backend smoke-test
|
||||
defaults, and affected examples and consumer request IDs.
|
||||
- Keep provider model strings unchanged. Renaming a profile does not rename
|
||||
the upstream model.
|
||||
- Document consumer action and coordinate the PromptKit format change with
|
||||
catalog adoption under the [release policy](../policy/release.md). Its catalog
|
||||
profile-data exception does not cover this general format/API behavior change;
|
||||
account for its explicitly retained built-in profile names when selecting
|
||||
migrations.
|
||||
|
||||
Renaming a backend changes its identity; duplicating it under another ID can
|
||||
separate capacity accounting. Do not use blanket aliases or duplicate catalog
|
||||
entries as an automatic compatibility mechanism. Exact release versions and
|
||||
catalog mappings remain implementation-planning work.
|
||||
|
||||
The [architecture policy](../policy/architecture.md) continues to assign CLI
|
||||
syntax, flags, and application policy to consumers such as Scriptorium. PromptKit
|
||||
@@ -196,8 +226,9 @@ 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.
|
||||
1. Settle the open API decisions below and audit existing identifier usage
|
||||
against the accepted grammar. Record explicit mappings and coordinated
|
||||
migration 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.
|
||||
@@ -206,39 +237,47 @@ if a concrete consumer need emerges.
|
||||
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:
|
||||
Acceptance cases for the settled rules, with scope/discovery details 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.
|
||||
- Two provider profile scopes resolve the same local name, such as
|
||||
`google.gemma-4-31b-it`, to different profiles without changing the configured
|
||||
provider model value `google/gemma-4-31b-it`.
|
||||
- A qualified reference bypasses the selected scope without double qualification;
|
||||
adding another collection does not change local or qualified resolution.
|
||||
- Multiple slashes and empty qualified components are rejected in resource IDs
|
||||
and references, while provider model values retain their existing syntax.
|
||||
- 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.
|
||||
- Existing exact-ID calls using valid IDs, intentional overlays, and prompt
|
||||
versions retain their behavior. Migrated catalog references resolve to their
|
||||
intended resources without collisions.
|
||||
- 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
|
||||
1. **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
|
||||
2. **Scope validation:** how does the scope API represent no scope, report an
|
||||
invalid namespace selection, and handle a well-formed but currently absent
|
||||
namespace? Apply the accepted separator rules, distinguish syntax from
|
||||
existence, and preserve omitted-ID defaults. Do not add case folding or other
|
||||
character restrictions without a separate decision.
|
||||
3. **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?
|
||||
4. **Catalog migration:** what exact old-to-new mappings and coordinated release
|
||||
plan will implement the accepted breaking change, and which otherwise valid
|
||||
IDs should additionally adopt provider/application namespaces?
|
||||
|
||||
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.
|
||||
The delimiter, two-component qualified grammar, syntax-based resolution, and
|
||||
acceptance of the required breaking migration are settled. Resolve the remaining
|
||||
API and delivery choices around that foundation: consumers select a scope once
|
||||
and use local or explicitly qualified names predictably within an assembled
|
||||
library.
|
||||
|
||||
Reference in New Issue
Block a user