From e01b23259a7ded1f4e87856711ef8a0766d725f9 Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Mon, 2 Nov 2026 04:04:35 +0000 Subject: [PATCH] Remove public prompt version metadata --- convert.go | 3 -- docs/roadmap/implementation.md | 7 +++++ engine.go | 2 +- json_contract_test.go | 55 ++++++++++++---------------------- listing.go | 15 ++++------ observations.go | 14 ++++----- requirements.go | 10 ++----- smoke_diagnostics.go | 9 ++---- types.go | 21 ++----------- 9 files changed, 43 insertions(+), 93 deletions(-) diff --git a/convert.go b/convert.go index 779f74e..ce560c6 100644 --- a/convert.go +++ b/convert.go @@ -72,7 +72,6 @@ func fromDomainPreparedRun(prepared *domain.PreparedRun) *PreparedRun { } return &PreparedRun{ PromptID: prepared.PromptID, - PromptVersion: copyStringPtr(prepared.PromptVersion), PromptHash: prepared.PromptHash, SelectedProfileID: prepared.SelectedProfileID, SelectedBackendID: prepared.SelectedBackendID, @@ -99,7 +98,6 @@ func fromDomainRunResult(result *domain.RunResult) *RunResult { RawOutput: result.RawOutput, Validation: fromDomainValidationResult(result.Validation), PromptID: result.PromptID, - PromptVersion: copyStringPtr(result.PromptVersion), PromptHash: result.PromptHash, SessionID: result.SessionID, RenderedPromptHash: result.RenderedPromptHash, @@ -257,7 +255,6 @@ func fromDomainPromptInspection(inspection *domain.PromptInspection) *PromptInsp } return &PromptInspection{ PromptID: inspection.PromptID, - PromptVersion: copyStringPtr(inspection.PromptVersion), PromptHash: inspection.PromptHash, DefaultProfileID: inspection.DefaultProfileID, Inputs: inputs, diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index a64ffbb..be53d9f 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -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 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 Scope: `internal/configuration/load_test.go`, `targets_test.go`, and focused diff --git a/engine.go b/engine.go index 02daa7c..7dca41c 100644 --- a/engine.go +++ b/engine.go @@ -251,7 +251,7 @@ func NewEngine(cfg Config, opts ...Option) (*Engine, error) { // InspectPrompt requires a nonblank promptID and performs an exact, // case-sensitive lookup in the captured configuration snapshot. A // 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 // message content files were structurally loaded. Inputs are returned in diff --git a/json_contract_test.go b/json_contract_test.go index a6d9c5b..e85878a 100644 --- a/json_contract_test.go +++ b/json_contract_test.go @@ -46,41 +46,28 @@ func TestGenerateResponseUsagePresenceJSON(t *testing.T) { } } -func TestPromptVersionJSONDistinguishesAbsenceAndDeclaredEmpty(t *testing.T) { - tests := []struct { - name string - value *string - wantPresent bool - wantValue string - }{ - {name: "absent"}, - {name: "declared empty", value: stringPointerForTest(""), wantPresent: true}, - {name: "declared text", value: stringPointerForTest("release/v1"), wantPresent: true, wantValue: "release/v1"}, +func TestRemovedPromptVersionIsAbsentFromJSON(t *testing.T) { + values := map[string]any{ + "prepared": promptkit.PreparedRun{PromptID: "prompt"}, + "result": promptkit.RunResult{PromptID: "prompt"}, + "observation": promptkit.ExecutionEvent{PromptID: "prompt"}, + "diagnostic target": promptkit.SmokeTestTarget{PromptID: "prompt"}, + "inspection": promptkit.PromptInspection{PromptID: "prompt"}, + "requirements": promptkit.RequirementInspection{PromptID: "prompt"}, + "identity": promptkit.PromptIdentity{ID: "prompt"}, } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - check := func(label string, marshal func() ([]byte, error)) { - t.Helper() - payload, err := marshal() - if err != nil { - t.Fatal(err) - } - object := decodeJSONObject(t, payload) - value, present := object["prompt_version"] - 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) + for name, value := range values { + t.Run(name, func(t *testing.T) { + payload, err := json.Marshal(value) + if err != nil { + t.Fatal(err) + } + object := decodeJSONObject(t, payload) + for _, key := range []string{"prompt_version", "PromptVersion", "Version"} { + if _, ok := object[key]; ok { + t.Fatalf("removed field %q serialized: %s", key, payload) } } - 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) assertJSONFields(t, object, "prompt_id", - "prompt_version", "prompt_hash", "selected_profile_id", "selected_backend_id", @@ -169,7 +155,6 @@ func TestRunResultJSONContractRoundTripsAllFields(t *testing.T) { "raw_output", "validation", "prompt_id", - "prompt_version", "prompt_hash", "session_id", "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) return promptkit.PreparedRun{ PromptID: "prompt.prepared", - PromptVersion: stringPointerForTest("2.1.0"), PromptHash: "prompt-hash", SelectedProfileID: "profile-prepared", SelectedBackendID: "backend-prepared", @@ -326,7 +310,6 @@ func fullyPopulatedRunResult() promptkit.RunResult { IsValid: false, }, PromptID: "prompt.result", - PromptVersion: stringPointerForTest("3.2.1"), PromptHash: "result-prompt-hash", SessionID: "session-result", RenderedPromptHash: "result-rendered-hash", diff --git a/listing.go b/listing.go index 7387435..e287353 100644 --- a/listing.go +++ b/listing.go @@ -50,14 +50,10 @@ type CollectionInfo struct { ReleaseVersion *string } -// PromptIdentity identifies one prompt ID and its optional descriptive version -// label in the effective configuration captured when an Engine is constructed. -// 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. +// PromptIdentity identifies one prompt in the effective configuration captured +// when an Engine is constructed. It has no stable JSON representation. type PromptIdentity struct { - ID string - Version *string + ID string } // 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 -// the engine was constructed, sorted lexically by ID. Each identity may include -// its descriptive version label. Its optional filter follows the same +// the engine was constructed, sorted lexically by ID. Its optional filter follows the same // NamespaceDefault, NamespaceNamed, NamespaceUnqualified, and NamespaceAll // behavior as [Engine.ListProfiles], using the prompt namespace by default. // At most one filter is accepted. @@ -119,7 +114,7 @@ func (e *Engine) ListPrompts(ctx context.Context, filters ...NamespaceFilter) ([ } public := make([]PromptIdentity, len(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 { return nil, mapPublicError(err) diff --git a/observations.go b/observations.go index 0e5ed78..9150f32 100644 --- a/observations.go +++ b/observations.go @@ -100,14 +100,10 @@ type ObservedTokenUsage struct { // its output. Failure is classified metadata; RetriesExhausted is a separate // flag and does not replace the underlying failure kind. type ExecutionEvent struct { - Kind ExecutionEventKind - RunID string - Time time.Time - 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 + Kind ExecutionEventKind + RunID string + Time time.Time + PromptID string ProfileID string BackendID string Model string @@ -134,7 +130,7 @@ func fromDomainExecutionEvent(value domain.ExecutionEvent) ExecutionEvent { } return ExecutionEvent{ 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, Attempt: value.Attempt, Dispatched: value.Dispatched, CapacityWait: value.CapacityWait, GenerationDuration: value.GenerationDuration, RetryDelay: value.RetryDelay, Duration: value.Duration, diff --git a/requirements.go b/requirements.go index fb5dc21..ab7ba60 100644 --- a/requirements.go +++ b/requirements.go @@ -119,9 +119,7 @@ type RequirementIssue struct { // prompt context. Input and variable entries are sorted by exact name. Issues // are deduplicated by code and associated names, then sorted by that tuple. // Their descriptions and entry explanations are safe summaries, not -// machine-readable details. PromptVersion is caller-owned descriptive metadata, -// not a selection key: nil means no label was declared; a non-nil empty string -// is explicit. +// machine-readable details. // // Complete describes the supported analysis's discovery coverage, not whether // requirements are supplied, templates will render, artifacts or schemas are @@ -133,10 +131,6 @@ type RequirementIssue struct { type RequirementInspection struct { // PromptID is the selected exact prompt ID. 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 // execution readiness. ProfileID string @@ -208,7 +202,7 @@ func fromDomainRequirementInspection(inspection *domain.RequirementInspection) * return nil } result := &RequirementInspection{ - PromptID: inspection.PromptID, PromptVersion: copyRequirementString(inspection.PromptVersion), + PromptID: inspection.PromptID, ProfileID: inspection.ProfileID, Complete: inspection.Complete, Inputs: make([]InputRequirement, len(inspection.Inputs)), Variables: make([]VariableRequirement, len(inspection.Variables)), diff --git a/smoke_diagnostics.go b/smoke_diagnostics.go index 0287300..c7a0557 100644 --- a/smoke_diagnostics.go +++ b/smoke_diagnostics.go @@ -117,12 +117,8 @@ type SmokeTestTarget struct { BackendID string // ProfileID is the selected profile, if any. ProfileID string - // PromptID identifies the selected prompt; PromptVersion carries optional - // descriptive metadata and never participates in selection. Nil means absent - // while a non-nil empty string is explicit. The pointer belongs to this - // returned target. - PromptID string - PromptVersion *string + // PromptID identifies the selected prompt. + PromptID string // DefaultSourceBackendID identifies the backend whose configured default // selected the profile, when that selection path was used. DefaultSourceBackendID string @@ -311,7 +307,6 @@ func fromDomainSmokeTestReport(report domain.SmokeTestReport) (*SmokeTestReport, BackendID: report.Target.BackendID, ProfileID: report.Target.ProfileID, PromptID: report.Target.PromptID, - PromptVersion: copyStringPtr(report.Target.PromptVersion), DefaultSourceBackendID: report.Target.DefaultSourceBackendID, SelectionSource: report.Target.SelectionSource, Endpoint: report.Target.Endpoint, diff --git a/types.go b/types.go index 49e7f9d..29703d7 100644 --- a/types.go +++ b/types.go @@ -87,8 +87,7 @@ const ( type RunRequest struct { // PromptID is the required prompt identifier. A namespace-scoped engine view // qualifies a slashless caller value; otherwise it selects the exact - // configured ID. Descriptive prompt-version labels do not participate in - // selection. + // configured ID. PromptID string // ProfileID selects an execution profile. A namespace-scoped engine view // qualifies a slashless caller value. When empty, the prompt's default @@ -163,11 +162,6 @@ type RunRequest struct { type PreparedRun struct { // PromptID is the selected prompt identifier. 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 string `json:"prompt_hash,omitempty"` // SelectedProfileID is the explicit request profile or prompt default that @@ -224,11 +218,6 @@ type RunResult struct { Validation ValidationResult `json:"validation"` // PromptID is the selected prompt identifier. 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 // PreparedRun. PromptHash string `json:"prompt_hash,omitempty"` @@ -404,19 +393,13 @@ type PromptInputDefinition struct { // PromptInspection is the caller-owned result of [Engine.InspectPrompt]. // It has no stable JSON representation. // -// PromptVersion is caller-owned metadata: nil means no label was declared and -// a non-nil empty string is explicit. Inputs contains copied declared input -// metadata in definition order. +// Inputs contains copied declared input metadata in definition order. // OutputContract is the normalized contract declared by the prompt definition, // rather than a request-level effective override. PromptHash is opaque. type PromptInspection struct { // PromptID is the exact selected prompt ID after any namespace-view // qualification. 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 string // DefaultProfileID is declared metadata and is not resolved by inspection.