Remove public prompt version metadata

This commit is contained in:
2026-11-02 04:04:35 +00:00
parent 500b0aa1c8
commit e01b23259a
9 changed files with 43 additions and 93 deletions

View File

@@ -72,7 +72,6 @@ func fromDomainPreparedRun(prepared *domain.PreparedRun) *PreparedRun {
} }
return &PreparedRun{ return &PreparedRun{
PromptID: prepared.PromptID, PromptID: prepared.PromptID,
PromptVersion: copyStringPtr(prepared.PromptVersion),
PromptHash: prepared.PromptHash, PromptHash: prepared.PromptHash,
SelectedProfileID: prepared.SelectedProfileID, SelectedProfileID: prepared.SelectedProfileID,
SelectedBackendID: prepared.SelectedBackendID, SelectedBackendID: prepared.SelectedBackendID,
@@ -99,7 +98,6 @@ func fromDomainRunResult(result *domain.RunResult) *RunResult {
RawOutput: result.RawOutput, RawOutput: result.RawOutput,
Validation: fromDomainValidationResult(result.Validation), Validation: fromDomainValidationResult(result.Validation),
PromptID: result.PromptID, PromptID: result.PromptID,
PromptVersion: copyStringPtr(result.PromptVersion),
PromptHash: result.PromptHash, PromptHash: result.PromptHash,
SessionID: result.SessionID, SessionID: result.SessionID,
RenderedPromptHash: result.RenderedPromptHash, RenderedPromptHash: result.RenderedPromptHash,
@@ -257,7 +255,6 @@ func fromDomainPromptInspection(inspection *domain.PromptInspection) *PromptInsp
} }
return &PromptInspection{ return &PromptInspection{
PromptID: inspection.PromptID, PromptID: inspection.PromptID,
PromptVersion: copyStringPtr(inspection.PromptVersion),
PromptHash: inspection.PromptHash, PromptHash: inspection.PromptHash,
DefaultProfileID: inspection.DefaultProfileID, DefaultProfileID: inspection.DefaultProfileID,
Inputs: inputs, Inputs: inputs,

View File

@@ -438,6 +438,13 @@ Validation: compile the facade when remaining fixtures permit and run JSON
contract tests. Search production code for stale prompt labels, separating contract tests. Search production code for stale prompt labels, separating
unrelated version fields from the removed feature. unrelated version fields from the removed feature.
Completion: public prompt identities and execution, inspection, requirement,
observation, and diagnostic values no longer expose prompt-version metadata.
Updated the conversions and GoDoc, and retained JSON round-trip checks while
asserting the removed field is absent from representative values. The isolated
JSON contract suite passed on Go 1.27.0, as did formatting and `git diff --check`.
Remaining callers and the maintained example are assigned to later work.
## Stage 11: Verify Identified Composition And Inheritance ## Stage 11: Verify Identified Composition And Inheritance
Scope: `internal/configuration/load_test.go`, `targets_test.go`, and focused Scope: `internal/configuration/load_test.go`, `targets_test.go`, and focused

View File

@@ -251,7 +251,7 @@ func NewEngine(cfg Config, opts ...Option) (*Engine, error) {
// InspectPrompt requires a nonblank promptID and performs an exact, // InspectPrompt requires a nonblank promptID and performs an exact,
// case-sensitive lookup in the captured configuration snapshot. A // case-sensitive lookup in the captured configuration snapshot. A
// namespace-scoped view qualifies slashless caller IDs before lookup; already // namespace-scoped view qualifies slashless caller IDs before lookup; already
// qualified IDs pass through. Prompt version labels do not select definitions. // qualified IDs pass through.
// //
// A successful result proves that the selected definition and any referenced // A successful result proves that the selected definition and any referenced
// message content files were structurally loaded. Inputs are returned in // message content files were structurally loaded. Inputs are returned in

View File

@@ -46,41 +46,28 @@ func TestGenerateResponseUsagePresenceJSON(t *testing.T) {
} }
} }
func TestPromptVersionJSONDistinguishesAbsenceAndDeclaredEmpty(t *testing.T) { func TestRemovedPromptVersionIsAbsentFromJSON(t *testing.T) {
tests := []struct { values := map[string]any{
name string "prepared": promptkit.PreparedRun{PromptID: "prompt"},
value *string "result": promptkit.RunResult{PromptID: "prompt"},
wantPresent bool "observation": promptkit.ExecutionEvent{PromptID: "prompt"},
wantValue string "diagnostic target": promptkit.SmokeTestTarget{PromptID: "prompt"},
}{ "inspection": promptkit.PromptInspection{PromptID: "prompt"},
{name: "absent"}, "requirements": promptkit.RequirementInspection{PromptID: "prompt"},
{name: "declared empty", value: stringPointerForTest(""), wantPresent: true}, "identity": promptkit.PromptIdentity{ID: "prompt"},
{name: "declared text", value: stringPointerForTest("release/v1"), wantPresent: true, wantValue: "release/v1"},
} }
for _, test := range tests { for name, value := range values {
t.Run(test.name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
check := func(label string, marshal func() ([]byte, error)) { payload, err := json.Marshal(value)
t.Helper() if err != nil {
payload, err := marshal() t.Fatal(err)
if err != nil { }
t.Fatal(err) object := decodeJSONObject(t, payload)
} for _, key := range []string{"prompt_version", "PromptVersion", "Version"} {
object := decodeJSONObject(t, payload) if _, ok := object[key]; ok {
value, present := object["prompt_version"] t.Fatalf("removed field %q serialized: %s", key, payload)
if present != test.wantPresent {
t.Errorf("%s prompt_version present=%t, want %t: %s", label, present, test.wantPresent, payload)
}
var decoded string
if test.wantPresent && (json.Unmarshal(value, &decoded) != nil || decoded != test.wantValue) {
t.Errorf("%s prompt_version=%#v, want %q", label, value, test.wantValue)
} }
} }
check("prepared", func() ([]byte, error) {
return json.Marshal(promptkit.PreparedRun{PromptVersion: test.value})
})
check("result", func() ([]byte, error) {
return json.Marshal(promptkit.RunResult{PromptVersion: test.value})
})
}) })
} }
} }
@@ -95,7 +82,6 @@ func TestPreparedRunJSONContractRoundTripsAllFields(t *testing.T) {
object := decodeJSONObject(t, payload) object := decodeJSONObject(t, payload)
assertJSONFields(t, object, assertJSONFields(t, object,
"prompt_id", "prompt_id",
"prompt_version",
"prompt_hash", "prompt_hash",
"selected_profile_id", "selected_profile_id",
"selected_backend_id", "selected_backend_id",
@@ -169,7 +155,6 @@ func TestRunResultJSONContractRoundTripsAllFields(t *testing.T) {
"raw_output", "raw_output",
"validation", "validation",
"prompt_id", "prompt_id",
"prompt_version",
"prompt_hash", "prompt_hash",
"session_id", "session_id",
"rendered_prompt_hash", "rendered_prompt_hash",
@@ -259,7 +244,6 @@ func fullyPopulatedPreparedRun() promptkit.PreparedRun {
start := time.Date(2026, time.August, 11, 12, 13, 14, 150_000_000, time.UTC) start := time.Date(2026, time.August, 11, 12, 13, 14, 150_000_000, time.UTC)
return promptkit.PreparedRun{ return promptkit.PreparedRun{
PromptID: "prompt.prepared", PromptID: "prompt.prepared",
PromptVersion: stringPointerForTest("2.1.0"),
PromptHash: "prompt-hash", PromptHash: "prompt-hash",
SelectedProfileID: "profile-prepared", SelectedProfileID: "profile-prepared",
SelectedBackendID: "backend-prepared", SelectedBackendID: "backend-prepared",
@@ -326,7 +310,6 @@ func fullyPopulatedRunResult() promptkit.RunResult {
IsValid: false, IsValid: false,
}, },
PromptID: "prompt.result", PromptID: "prompt.result",
PromptVersion: stringPointerForTest("3.2.1"),
PromptHash: "result-prompt-hash", PromptHash: "result-prompt-hash",
SessionID: "session-result", SessionID: "session-result",
RenderedPromptHash: "result-rendered-hash", RenderedPromptHash: "result-rendered-hash",

View File

@@ -50,14 +50,10 @@ type CollectionInfo struct {
ReleaseVersion *string ReleaseVersion *string
} }
// PromptIdentity identifies one prompt ID and its optional descriptive version // PromptIdentity identifies one prompt in the effective configuration captured
// label in the effective configuration captured when an Engine is constructed. // when an Engine is constructed. It has no stable JSON representation.
// Version is metadata only and never participates in prompt selection. A nil
// Version means no label was declared; a non-nil empty string is an explicit
// label. It has no stable JSON representation.
type PromptIdentity struct { type PromptIdentity struct {
ID string ID string
Version *string
} }
// ListProfiles returns profile IDs in the effective configuration captured // ListProfiles returns profile IDs in the effective configuration captured
@@ -92,8 +88,7 @@ func (e *Engine) ListProfiles(ctx context.Context, filters ...NamespaceFilter) (
} }
// ListPrompts returns prompt IDs in the effective configuration captured when // ListPrompts returns prompt IDs in the effective configuration captured when
// the engine was constructed, sorted lexically by ID. Each identity may include // the engine was constructed, sorted lexically by ID. Its optional filter follows the same
// its descriptive version label. Its optional filter follows the same
// NamespaceDefault, NamespaceNamed, NamespaceUnqualified, and NamespaceAll // NamespaceDefault, NamespaceNamed, NamespaceUnqualified, and NamespaceAll
// behavior as [Engine.ListProfiles], using the prompt namespace by default. // behavior as [Engine.ListProfiles], using the prompt namespace by default.
// At most one filter is accepted. // At most one filter is accepted.
@@ -119,7 +114,7 @@ func (e *Engine) ListPrompts(ctx context.Context, filters ...NamespaceFilter) ([
} }
public := make([]PromptIdentity, len(identities)) public := make([]PromptIdentity, len(identities))
for i, identity := range identities { for i, identity := range identities {
public[i] = PromptIdentity{ID: identity.ID, Version: copyStringPtr(identity.Version)} public[i] = PromptIdentity{ID: identity.ID}
} }
if err := ctx.Err(); err != nil { if err := ctx.Err(); err != nil {
return nil, mapPublicError(err) return nil, mapPublicError(err)

View File

@@ -100,14 +100,10 @@ type ObservedTokenUsage struct {
// its output. Failure is classified metadata; RetriesExhausted is a separate // its output. Failure is classified metadata; RetriesExhausted is a separate
// flag and does not replace the underlying failure kind. // flag and does not replace the underlying failure kind.
type ExecutionEvent struct { type ExecutionEvent struct {
Kind ExecutionEventKind Kind ExecutionEventKind
RunID string RunID string
Time time.Time Time time.Time
PromptID string PromptID string
// PromptVersion is the selected definition's optional descriptive label and
// never participates in prompt selection. Each event owns its pointer; nil
// means absent while a non-nil empty string is explicit.
PromptVersion *string
ProfileID string ProfileID string
BackendID string BackendID string
Model string Model string
@@ -134,7 +130,7 @@ func fromDomainExecutionEvent(value domain.ExecutionEvent) ExecutionEvent {
} }
return ExecutionEvent{ return ExecutionEvent{
Kind: ExecutionEventKind(value.Kind), RunID: value.RunID, Time: value.Time, Kind: ExecutionEventKind(value.Kind), RunID: value.RunID, Time: value.Time,
PromptID: value.PromptID, PromptVersion: copyStringPtr(value.PromptVersion), ProfileID: value.ProfileID, PromptID: value.PromptID, ProfileID: value.ProfileID,
BackendID: value.BackendID, Model: value.Model, Generation: value.Generation, BackendID: value.BackendID, Model: value.Model, Generation: value.Generation,
Attempt: value.Attempt, Dispatched: value.Dispatched, CapacityWait: value.CapacityWait, Attempt: value.Attempt, Dispatched: value.Dispatched, CapacityWait: value.CapacityWait,
GenerationDuration: value.GenerationDuration, RetryDelay: value.RetryDelay, Duration: value.Duration, GenerationDuration: value.GenerationDuration, RetryDelay: value.RetryDelay, Duration: value.Duration,

View File

@@ -119,9 +119,7 @@ type RequirementIssue struct {
// prompt context. Input and variable entries are sorted by exact name. Issues // prompt context. Input and variable entries are sorted by exact name. Issues
// are deduplicated by code and associated names, then sorted by that tuple. // are deduplicated by code and associated names, then sorted by that tuple.
// Their descriptions and entry explanations are safe summaries, not // Their descriptions and entry explanations are safe summaries, not
// machine-readable details. PromptVersion is caller-owned descriptive metadata, // machine-readable details.
// not a selection key: nil means no label was declared; a non-nil empty string
// is explicit.
// //
// Complete describes the supported analysis's discovery coverage, not whether // Complete describes the supported analysis's discovery coverage, not whether
// requirements are supplied, templates will render, artifacts or schemas are // requirements are supplied, templates will render, artifacts or schemas are
@@ -133,10 +131,6 @@ type RequirementIssue struct {
type RequirementInspection struct { type RequirementInspection struct {
// PromptID is the selected exact prompt ID. // PromptID is the selected exact prompt ID.
PromptID string PromptID string
// PromptVersion is the selected definition's descriptive version label and
// never participates in prompt selection. Nil means no label was declared; a
// non-nil empty string is an explicit label.
PromptVersion *string
// ProfileID is the selected profile identity; it does not indicate // ProfileID is the selected profile identity; it does not indicate
// execution readiness. // execution readiness.
ProfileID string ProfileID string
@@ -208,7 +202,7 @@ func fromDomainRequirementInspection(inspection *domain.RequirementInspection) *
return nil return nil
} }
result := &RequirementInspection{ result := &RequirementInspection{
PromptID: inspection.PromptID, PromptVersion: copyRequirementString(inspection.PromptVersion), PromptID: inspection.PromptID,
ProfileID: inspection.ProfileID, Complete: inspection.Complete, ProfileID: inspection.ProfileID, Complete: inspection.Complete,
Inputs: make([]InputRequirement, len(inspection.Inputs)), Inputs: make([]InputRequirement, len(inspection.Inputs)),
Variables: make([]VariableRequirement, len(inspection.Variables)), Variables: make([]VariableRequirement, len(inspection.Variables)),

View File

@@ -117,12 +117,8 @@ type SmokeTestTarget struct {
BackendID string BackendID string
// ProfileID is the selected profile, if any. // ProfileID is the selected profile, if any.
ProfileID string ProfileID string
// PromptID identifies the selected prompt; PromptVersion carries optional // PromptID identifies the selected prompt.
// descriptive metadata and never participates in selection. Nil means absent PromptID string
// while a non-nil empty string is explicit. The pointer belongs to this
// returned target.
PromptID string
PromptVersion *string
// DefaultSourceBackendID identifies the backend whose configured default // DefaultSourceBackendID identifies the backend whose configured default
// selected the profile, when that selection path was used. // selected the profile, when that selection path was used.
DefaultSourceBackendID string DefaultSourceBackendID string
@@ -311,7 +307,6 @@ func fromDomainSmokeTestReport(report domain.SmokeTestReport) (*SmokeTestReport,
BackendID: report.Target.BackendID, BackendID: report.Target.BackendID,
ProfileID: report.Target.ProfileID, ProfileID: report.Target.ProfileID,
PromptID: report.Target.PromptID, PromptID: report.Target.PromptID,
PromptVersion: copyStringPtr(report.Target.PromptVersion),
DefaultSourceBackendID: report.Target.DefaultSourceBackendID, DefaultSourceBackendID: report.Target.DefaultSourceBackendID,
SelectionSource: report.Target.SelectionSource, SelectionSource: report.Target.SelectionSource,
Endpoint: report.Target.Endpoint, Endpoint: report.Target.Endpoint,

View File

@@ -87,8 +87,7 @@ const (
type RunRequest struct { type RunRequest struct {
// PromptID is the required prompt identifier. A namespace-scoped engine view // PromptID is the required prompt identifier. A namespace-scoped engine view
// qualifies a slashless caller value; otherwise it selects the exact // qualifies a slashless caller value; otherwise it selects the exact
// configured ID. Descriptive prompt-version labels do not participate in // configured ID.
// selection.
PromptID string PromptID string
// ProfileID selects an execution profile. A namespace-scoped engine view // ProfileID selects an execution profile. A namespace-scoped engine view
// qualifies a slashless caller value. When empty, the prompt's default // qualifies a slashless caller value. When empty, the prompt's default
@@ -163,11 +162,6 @@ type RunRequest struct {
type PreparedRun struct { type PreparedRun struct {
// PromptID is the selected prompt identifier. // PromptID is the selected prompt identifier.
PromptID string `json:"prompt_id"` PromptID string `json:"prompt_id"`
// PromptVersion is the selected definition's descriptive version label and
// never participates in prompt selection. Nil means no label was declared; a
// non-nil empty string is explicit. JSON omits nil and preserves a declared
// empty string.
PromptVersion *string `json:"prompt_version,omitempty"`
// PromptHash is an opaque equality value for the selected definition. // PromptHash is an opaque equality value for the selected definition.
PromptHash string `json:"prompt_hash,omitempty"` PromptHash string `json:"prompt_hash,omitempty"`
// SelectedProfileID is the explicit request profile or prompt default that // SelectedProfileID is the explicit request profile or prompt default that
@@ -224,11 +218,6 @@ type RunResult struct {
Validation ValidationResult `json:"validation"` Validation ValidationResult `json:"validation"`
// PromptID is the selected prompt identifier. // PromptID is the selected prompt identifier.
PromptID string `json:"prompt_id"` PromptID string `json:"prompt_id"`
// PromptVersion is the selected definition's descriptive version label and
// never participates in prompt selection. Nil means no label was declared; a
// non-nil empty string is explicit. JSON omits nil and preserves a declared
// empty string.
PromptVersion *string `json:"prompt_version,omitempty"`
// PromptHash is the same opaque definition equality value exposed by // PromptHash is the same opaque definition equality value exposed by
// PreparedRun. // PreparedRun.
PromptHash string `json:"prompt_hash,omitempty"` PromptHash string `json:"prompt_hash,omitempty"`
@@ -404,19 +393,13 @@ type PromptInputDefinition struct {
// PromptInspection is the caller-owned result of [Engine.InspectPrompt]. // PromptInspection is the caller-owned result of [Engine.InspectPrompt].
// It has no stable JSON representation. // It has no stable JSON representation.
// //
// PromptVersion is caller-owned metadata: nil means no label was declared and // Inputs contains copied declared input metadata in definition order.
// a non-nil empty string is explicit. Inputs contains copied declared input
// metadata in definition order.
// OutputContract is the normalized contract declared by the prompt definition, // OutputContract is the normalized contract declared by the prompt definition,
// rather than a request-level effective override. PromptHash is opaque. // rather than a request-level effective override. PromptHash is opaque.
type PromptInspection struct { type PromptInspection struct {
// PromptID is the exact selected prompt ID after any namespace-view // PromptID is the exact selected prompt ID after any namespace-view
// qualification. // qualification.
PromptID string PromptID string
// PromptVersion is the selected definition's descriptive version label and
// never participates in definition selection. Nil means no label was
// declared; a non-nil empty string is an explicit label.
PromptVersion *string
// PromptHash is the opaque equality value for the selected definition. // PromptHash is the opaque equality value for the selected definition.
PromptHash string PromptHash string
// DefaultProfileID is declared metadata and is not resolved by inspection. // DefaultProfileID is declared metadata and is not resolved by inspection.