671 lines
27 KiB
Markdown
671 lines
27 KiB
Markdown
# Prompt-Independent Profile Inspection Implementation Plan
|
|
|
|
**Status:** Ready for implementation.
|
|
|
|
## Purpose
|
|
|
|
This document is the decision-complete implementation plan for
|
|
[prompt-independent profile inspection](profile-inspection.md). It is written
|
|
for a coding agent that will implement each stage in order.
|
|
|
|
The feature roadmap owns the motivation, consumer workflow, policy choices,
|
|
compatibility requirements, non-goals, and target end state. This document
|
|
owns the concrete design, file-level changes, implementation sequence, test
|
|
ownership, documentation work, validation commands, and completion gates.
|
|
|
|
## Implementation Rules
|
|
|
|
- Complete the stages in order. Keep the repository compiling and the focused
|
|
tests passing at every stage boundary.
|
|
- Preserve unrelated working-tree changes. In particular, retain the accepted
|
|
feature roadmap and the corresponding future-roadmap and downstream-wishlist
|
|
edits that may already be uncommitted.
|
|
- Follow every policy under `docs/policy/`, the task-specific reading guide in
|
|
`docs/development.md`, and the accepted behavior in
|
|
`profile-inspection.md`.
|
|
- Keep the supported API in the root `promptkit` package. Profile repositories,
|
|
backend resolution, and target assembly remain below Go's `internal/`
|
|
boundary.
|
|
- Reuse the exact profile-source, backend-membership, and execution-target
|
|
precedence used by `Prepare`, `PrepareExecution`, and `Run`. Do not create a
|
|
second profile loader, backend registry, or target-merging implementation.
|
|
- Preserve the observable behavior and error ordering of existing preparation
|
|
and execution methods. The new inspection operation must not require a
|
|
prompt, prompt default profile, request override, credential value, capacity
|
|
admission, model client, renderer, artifact reader, schema source, or
|
|
validator.
|
|
- Treat structural validation as the existing profile, backend, and effective
|
|
target invariants. Do not add new endpoint URL policy, provider
|
|
connectivity checks, reserved-extra-parameter policy, credential syntax, or
|
|
file-format validation rules as part of this feature.
|
|
- Never read, retain, return, format, or log an environment credential value.
|
|
The result may contain only the effective environment-variable name and the
|
|
direct-key-required boolean.
|
|
- Return caller-owned public values. In particular, nested
|
|
`ExecutionTarget.ExtraParams` maps, slices, and objects must not alias
|
|
engine-owned state or another inspection result.
|
|
- Keep tests lean and behavior-focused. Reuse existing profile repository,
|
|
backend registry, target precedence, and preparation tests rather than
|
|
duplicating their complete matrices.
|
|
- Update exact contracts in GoDoc with the exported declarations. Update
|
|
current-state consumer, format, and internal documentation only after the
|
|
corresponding code exists.
|
|
- Do not add release notes, change a module version, create a release, or tag a
|
|
commit as part of this work.
|
|
|
|
## Fixed Design
|
|
|
|
### Public API
|
|
|
|
Add this root-package value immediately after `ExecutionTarget` in `types.go`:
|
|
|
|
```go
|
|
// ProfileInspection is the caller-owned result of Engine.InspectProfile.
|
|
// The exact GoDoc is specified below.
|
|
type ProfileInspection struct {
|
|
ProfileID string
|
|
EffectiveModelParams ExecutionTarget
|
|
APIKeyRequired bool
|
|
}
|
|
```
|
|
|
|
Add this method to `Engine` in `engine.go`, immediately before `Prepare`:
|
|
|
|
```go
|
|
func (e *Engine) InspectProfile(
|
|
ctx context.Context,
|
|
profileID string,
|
|
) (*ProfileInspection, error)
|
|
```
|
|
|
|
Do not accept `RunRequest`, `ExecutionTargetOverride`, an API key, an
|
|
environment override, or options on this method. Exact inspection of one
|
|
explicit profile ID is the complete operation.
|
|
|
|
`ProfileInspection` has no stable JSON contract. Do not add JSON tags,
|
|
`MarshalJSON`, `UnmarshalJSON`, or a custom string representation. Ordinary Go
|
|
encoding of the exported fields is not prohibited, but consumers must not be
|
|
promised compatibility for that encoding.
|
|
|
|
The exact type and method GoDoc must establish:
|
|
|
|
- surrounding whitespace is trimmed from `profileID`; the resulting nonblank
|
|
ID is looked up exactly and case-sensitively;
|
|
- the result applies the engine's ordinary in-memory, configured-source, and
|
|
built-in profile precedence;
|
|
- `EffectiveModelParams` contains framework defaults overlaid by the selected
|
|
backend and then the selected profile, with no request override;
|
|
- `EffectiveModelParams.BackendID` is empty for endpoint-only profiles;
|
|
- `EffectiveModelParams.APIKeyEnv` is an environment-variable name and never
|
|
its value;
|
|
- `APIKeyRequired` means a direct request credential is required and is
|
|
mutually exclusive with a nonblank effective `APIKeyEnv`;
|
|
- the method never derives an ID from a prompt's `default_profile`;
|
|
- the method performs no prompt lookup, rendering, artifact or schema work,
|
|
backend admission, provider connectivity check, or model generation;
|
|
- credential availability is not checked, so an absent or blank named
|
|
environment variable is not an error;
|
|
- the returned value and all nested mutable values are caller-owned;
|
|
- filesystem-backed inspection is a point-in-time lookup and does not freeze
|
|
a profile for a later execution;
|
|
- a nil engine matches `ErrInvalidConfig`;
|
|
- a blank ID matches `ErrInvalidRequest`;
|
|
- an absent exact ID matches `ErrProfileNotFound` and not `ErrProfileLoad`;
|
|
- malformed or unreadable profile data, an unknown backend, or an invalid
|
|
resolved target matches `ErrProfileLoad`;
|
|
- cancellation observed during profile loading matches `ErrProfileLoad` while
|
|
preserving the context error through `errors.Is`; and
|
|
- the method returns no partial result on error.
|
|
|
|
Update the `Engine` type GoDoc to include `InspectProfile` among the operations
|
|
safe for concurrent calls. Do not imply that injected collaborators become
|
|
safe when their existing contracts do not provide that guarantee.
|
|
|
|
Update `doc.go` in the same stage:
|
|
|
|
- include `Engine.InspectProfile` in the package's operation list;
|
|
- include inspection in the concurrency and caller-ownership summary; and
|
|
- list `ProfileInspection` among construction and inspection values without a
|
|
stable JSON representation.
|
|
|
|
Do not add `ProfileInspection` to the stable JSON list.
|
|
|
|
### Internal Result
|
|
|
|
Add this internal value to `internal/domain/domain.go` near
|
|
`ExecutionProfile` and `ExecutionTarget`:
|
|
|
|
```go
|
|
// ProfileInspection is the resolved result of exact profile inspection.
|
|
type ProfileInspection struct {
|
|
ProfileID string
|
|
EffectiveModelParams ExecutionTarget
|
|
APIKeyRequired bool
|
|
}
|
|
```
|
|
|
|
Do not add JSON or YAML tags. The internal value is a use-case result, not a
|
|
file format or persistence contract.
|
|
|
|
Add a root conversion in `convert.go`:
|
|
|
|
```go
|
|
func fromDomainProfileInspection(
|
|
inspection *domain.ProfileInspection,
|
|
) *ProfileInspection
|
|
```
|
|
|
|
The conversion must:
|
|
|
|
- return `nil` for a nil internal value;
|
|
- copy the scalar fields;
|
|
- convert the target through the existing `fromDomainExecutionTarget`; and
|
|
- therefore use the existing recursive `copyAnyMap` boundary for nested extra
|
|
parameters.
|
|
|
|
Do not add `APIKeyRequired` to the public `ExecutionTarget`. Keeping the
|
|
requirement on `ProfileInspection` preserves the existing stable JSON and
|
|
general execution-target contract.
|
|
|
|
### Shared Profile Selection
|
|
|
|
Add `internal/usecase/profile_inspection.go`. Define one private selection
|
|
value:
|
|
|
|
```go
|
|
type resolvedProfileSelection struct {
|
|
id string
|
|
profile *domain.ExecutionProfile
|
|
backend *domain.Backend
|
|
}
|
|
```
|
|
|
|
Add a private runner helper:
|
|
|
|
```go
|
|
func (r *Runner) resolveProfileSelection(
|
|
ctx context.Context,
|
|
profileID string,
|
|
) (*resolvedProfileSelection, error)
|
|
```
|
|
|
|
The helper must perform these operations in order:
|
|
|
|
1. trim surrounding whitespace from `profileID`;
|
|
2. reject a blank result with `ErrInvalidRequest`;
|
|
3. reject a nil runner profile repository with `ErrProfileLoad` rather than
|
|
panicking;
|
|
4. call the existing `profile.Repository.GetProfile` exactly once;
|
|
5. wrap every repository error with `ErrProfileLoad` while preserving the
|
|
underlying error with `%w`;
|
|
6. reject a nil profile returned without an error as `ErrProfileLoad`;
|
|
7. make a value copy of the selected profile before normalization so the
|
|
runner does not mutate repository-owned state;
|
|
8. trim the copied profile's backend ID;
|
|
9. when that ID is nonblank, resolve it exactly once through the existing
|
|
`BackendResolver`, preserving the current unknown-backend
|
|
`ErrProfileLoad` wrapping and backend ID context; and
|
|
10. return the normalized exact ID, copied profile, and optional defensive
|
|
backend value.
|
|
|
|
Do not inspect all sources, enumerate profiles, expose a source path, fall back
|
|
after a malformed higher-precedence match, or infer a backend from an endpoint
|
|
or model.
|
|
|
|
Refactor the profile-loading and backend-resolution block in
|
|
`Runner.resolvePreparation` to call `resolveProfileSelection`. Leave prompt
|
|
selection, prompt default-profile selection, prompt hashing, target overrides,
|
|
request credentials, output-contract resolution, artifact work, and all later
|
|
ordering where they currently occur.
|
|
|
|
This refactor must preserve:
|
|
|
|
- explicit request profile selection over prompt `default_profile`;
|
|
- the existing `ErrProfileRequired` result when neither exists;
|
|
- exact repository and backend lookup behavior;
|
|
- existing public not-found versus profile-load classification;
|
|
- request override precedence and target-presence tracking;
|
|
- credential checking during ordinary preparation; and
|
|
- current `Prepare`, `PrepareExecution`, `Run`, and `RunPrepared` behavior.
|
|
|
|
### Shared Target Resolution And Structural Validation
|
|
|
|
Continue using the existing `resolveExecutionTarget` for framework, backend,
|
|
profile, and optional request precedence. Do not duplicate or move the
|
|
individual merge rules into the inspection code.
|
|
|
|
Extract the two existing effective-target requiredness checks from
|
|
`resolvePreparation` into a private pure helper:
|
|
|
|
```go
|
|
func validateResolvedExecutionTarget(
|
|
target domain.ExecutionTarget,
|
|
) error
|
|
```
|
|
|
|
It checks only that the trimmed endpoint and model are nonblank and returns a
|
|
plain descriptive error. It does not validate URL syntax, contact the
|
|
endpoint, validate credentials, or introduce new parameter rules.
|
|
|
|
`resolvePreparation` calls this helper at the same current point: after
|
|
request override resolution and direct API-key assignment, and before
|
|
`validateAPIKey`. It wraps a failure with `ErrInvalidRequest`, preserving
|
|
ordinary preparation behavior.
|
|
|
|
Add the internal inspection method:
|
|
|
|
```go
|
|
func (r *Runner) InspectProfile(
|
|
ctx context.Context,
|
|
profileID string,
|
|
) (*domain.ProfileInspection, error)
|
|
```
|
|
|
|
It performs these operations:
|
|
|
|
1. trim and reject a blank ID as `ErrInvalidRequest`;
|
|
2. if the supplied context is already canceled, return an error wrapping both
|
|
`ErrProfileLoad` and `ctx.Err()` without touching the repository;
|
|
3. call `resolveProfileSelection`;
|
|
4. call `resolveExecutionTarget` with the selected backend, selected profile,
|
|
and a nil request override;
|
|
5. wrap any target-resolution error with `ErrProfileLoad`;
|
|
6. call `validateResolvedExecutionTarget` and wrap a failure with
|
|
`ErrProfileLoad`;
|
|
7. defensively clear `target.APIKey`;
|
|
8. copy `target.APIKeyRequired` into the result's `APIKeyRequired`; and
|
|
9. return the normalized profile ID and effective target.
|
|
|
|
Do not call `validateAPIKey`, `os.Getenv`, prompt repositories, artifact
|
|
readers, renderers, validators, capacity admission, output repair, or the
|
|
model client. Do not populate request target-presence state.
|
|
|
|
The internal `ExecutionTarget` may retain its private `APIKeyRequired` field;
|
|
the root conversion intentionally omits that private field from the public
|
|
target and publishes the separate inspection boolean.
|
|
|
|
### Root Facade And Error Mapping
|
|
|
|
`Engine.InspectProfile` follows the existing facade pattern:
|
|
|
|
1. reject a nil engine or nil runner with `ErrInvalidConfig`;
|
|
2. pass the context and string ID directly to `Runner.InspectProfile`;
|
|
3. map internal failures through the existing `mapPublicError`; and
|
|
4. convert a successful result with `fromDomainProfileInspection`.
|
|
|
|
No request conversion is needed. Do not add a public sentinel or typed error.
|
|
|
|
The existing error mapping already has the required ordering:
|
|
|
|
- an underlying `profile.ErrProfileNotFound` maps to
|
|
`ErrProfileNotFound` before the enclosing use-case `ErrProfileLoad` is
|
|
considered;
|
|
- other use-case `ErrProfileLoad` failures map to `ErrProfileLoad`; and
|
|
- `usecase.ErrInvalidRequest` maps to `ErrInvalidRequest`.
|
|
|
|
Do not reorder or otherwise change `errors.go` unless a focused test proves
|
|
that the existing mapping does not meet this plan. Preserve underlying
|
|
repository, backend, and context errors through `errors.Is`.
|
|
|
|
### Credentials, Ownership, And Concurrency
|
|
|
|
Inspection has no input through which a direct credential value can enter.
|
|
Backend and file-profile `APIKeyEnv` values remain names only. An in-memory
|
|
profile with `APIKeyRequired` clears an inherited backend environment name
|
|
through the existing target merge behavior.
|
|
|
|
The implementation must succeed for:
|
|
|
|
- a backend or profile naming an unset environment variable;
|
|
- a backend or profile naming an environment variable whose value is blank;
|
|
- an in-memory profile requiring a direct key when no key is supplied; and
|
|
- a profile requiring no credential.
|
|
|
|
The result expresses these effective states:
|
|
|
|
| `EffectiveModelParams.APIKeyEnv` | `APIKeyRequired` | Meaning |
|
|
| --- | --- | --- |
|
|
| nonblank | `false` | The profile resolves to the named environment source. |
|
|
| blank | `true` | A later execution must supply a direct key or explicit request environment override. |
|
|
| blank | `false` | The resolved target declares no credential requirement. |
|
|
|
|
The implementation must never produce a successful public result with both a
|
|
nonblank `APIKeyEnv` and `APIKeyRequired == true`.
|
|
|
|
Public ownership is enforced at the root conversion boundary. A consumer may
|
|
mutate the returned target and arbitrarily nested JSON-compatible extra
|
|
parameters without affecting:
|
|
|
|
- the engine registry or profile repository;
|
|
- a later `InspectProfile` call;
|
|
- `Prepare`, prepared execution, or `Run`; or
|
|
- another result already returned to a caller.
|
|
|
|
No new mutable engine state, cache, global registry, lock, or goroutine is
|
|
needed. Concurrency safety follows from the existing immutable registry and
|
|
repository contracts plus per-call values.
|
|
|
|
### Test Ownership
|
|
|
|
Add focused internal tests in
|
|
`internal/usecase/profile_inspection_test.go`. Use small repository and backend
|
|
fakes already present in the package where practical; do not build a parallel
|
|
fixture framework.
|
|
|
|
The internal tests own:
|
|
|
|
- blank-ID rejection;
|
|
- pre-canceled context classification without repository access;
|
|
- one exact profile and backend lookup;
|
|
- framework-default, backend, and profile target precedence through the
|
|
existing resolver;
|
|
- endpoint-only behavior;
|
|
- effective environment-name reporting without availability checks;
|
|
- direct-key-required behavior clearing an inherited backend environment
|
|
name;
|
|
- missing-profile and unknown-backend wrapping; and
|
|
- nil repository, nil returned profile, and invalid resolved target defenses
|
|
only if these cases are not already cheaply covered through existing runner
|
|
fakes.
|
|
|
|
Keep the internal matrix compact. Profile parser tests continue to own YAML,
|
|
duplicates, raw-key rejection, ranges, and source discovery. Backend tests
|
|
continue to own registration validation. Existing target tests continue to
|
|
own every merge field and numeric override boundary.
|
|
|
|
Add external-package public contract tests in `public_contract_test.go`. They
|
|
own:
|
|
|
|
- the exported method and result shape through normal Go use;
|
|
- a nil engine returning `ErrInvalidConfig`;
|
|
- blank, missing, malformed, and unknown-backend public error identities,
|
|
including that not-found does not also match `ErrProfileLoad`;
|
|
- a pre-canceled inspection preserving both `ErrProfileLoad` and the context
|
|
error without consulting the profile repository;
|
|
- successful inspection with an absent credential environment value;
|
|
- no prompt dependency, demonstrated with an empty configured prompt
|
|
`fs.FS`;
|
|
- no model invocation, using the existing deterministic fake client;
|
|
- the three credential-requirement result states;
|
|
- an endpoint-only profile's empty backend ID;
|
|
- deep caller ownership of nested extra parameters across repeated
|
|
inspections; and
|
|
- representative equivalence between `InspectProfile.EffectiveModelParams`
|
|
and `Prepare.EffectiveModelParams` for the same engine, profile, and source
|
|
state with no request execution override.
|
|
|
|
Combine closely related assertions into a few readable behavioral tests.
|
|
Do not add a JSON golden test because `ProfileInspection` deliberately has no
|
|
stable JSON contract. Do not duplicate the complete repository-precedence,
|
|
target-field, parser-error, or credential-execution suites at the root layer.
|
|
|
|
Existing tests that must continue passing without semantic edits include:
|
|
|
|
- profile repository and built-in fallback tests;
|
|
- backend registry defensive-copy and lookup tests;
|
|
- execution-target precedence tests;
|
|
- `Prepare` and `Run` profile/backend equivalence tests;
|
|
- prepared-execution snapshot and credential tests; and
|
|
- public error mapping tests.
|
|
|
|
### Documentation Ownership
|
|
|
|
After the implementation and public tests pass, update current-state
|
|
documentation:
|
|
|
|
- `docs/consumers/pkg-promptkit.md`: add a concise task-oriented section near
|
|
profile selection showing `Engine.InspectProfile`, explaining when to use it
|
|
instead of a synthetic `Prepare`, how to interpret `APIKeyEnv` and
|
|
`APIKeyRequired`, and that credential enforcement timing remains
|
|
application policy. Link to the exact GoDoc rather than restating every
|
|
error and field contract.
|
|
- `docs/formats.md`: update profile selection and backend-membership wording
|
|
so exact inspection is recognized as another consumer of the existing
|
|
source and profile precedence. Do not redefine the exported method here.
|
|
- `docs/internal/runner.md`: describe the shared profile-selection boundary
|
|
and explain that inspection stops after structural target resolution,
|
|
before credential availability and all prompt-dependent work.
|
|
- `docs/internal/sources.md`: record that exact profile inspection performs
|
|
one point-in-time profile-source lookup without reading prompt, input, or
|
|
schema sources, and replace any ambiguous use of “inspection value” for
|
|
`PreparedRun` with “preparation value.”
|
|
- `docs/internal/overview.md`: add profile inspection to the existing root
|
|
facade and `internal/usecase` responsibility descriptions. Do not add a new
|
|
component or package row.
|
|
- `docs/roadmap/future.md`: remove the statement that profile inspection is in
|
|
active planning and leave the remaining unselected ideas intact.
|
|
- `docs/roadmap/notarius-promptkit-wishlist.md` and
|
|
`docs/roadmap/weatherreporter-promptkit-wishlist.md`: change the profile
|
|
inspection disposition from accepted planning to implemented behavior and
|
|
link to the durable consumer guidance or GoDoc rather than treating the
|
|
roadmap as current-state documentation.
|
|
- `docs/roadmap/profile-inspection.md`: change its status to `Complete` only
|
|
after the code, tests, current-state documentation, and full validation are
|
|
complete.
|
|
- `docs/roadmap/implementation.md`: change its status to `Complete` only after
|
|
every completion gate in this plan is satisfied.
|
|
|
|
Do not update release guidance in this feature implementation. A later release
|
|
pass decides whether the change warrants a supplemental release document.
|
|
|
|
## Stage 1: Implement Shared Internal Profile Resolution
|
|
|
|
### Objective
|
|
|
|
Add the internal inspection result and operation, share profile/backend
|
|
selection and structural target validation with ordinary preparation, and
|
|
prove the internal behavior without publishing the root API yet.
|
|
|
|
### Implementation Prompt
|
|
|
|
Implement only Stage 1 of
|
|
`docs/roadmap/implementation.md`. Read the complete feature roadmap and the
|
|
implementation rules and fixed design above before editing.
|
|
|
|
1. Add `domain.ProfileInspection` to `internal/domain/domain.go` without
|
|
serialization tags.
|
|
2. Add `internal/usecase/profile_inspection.go` with
|
|
`resolvedProfileSelection`, `resolveProfileSelection`,
|
|
`validateResolvedExecutionTarget`, and `Runner.InspectProfile` exactly as
|
|
specified.
|
|
3. Refactor `Runner.resolvePreparation` in `internal/usecase/runner.go` to use
|
|
the shared selection and target-validation helpers while preserving its
|
|
current ordering, error classification, target overrides, credentials, and
|
|
results.
|
|
4. Add lean behavioral tests in
|
|
`internal/usecase/profile_inspection_test.go`.
|
|
5. Run the focused validation below and repair regressions before ending the
|
|
stage.
|
|
|
|
Do not add the root public type or method, update current-state documentation,
|
|
or alter profile formats, backend registration, credential availability,
|
|
capacity, model-client, or provider behavior in this stage.
|
|
|
|
### Focused Validation
|
|
|
|
Run:
|
|
|
|
```sh
|
|
gofmt -w internal/domain/domain.go \
|
|
internal/usecase/profile_inspection.go \
|
|
internal/usecase/profile_inspection_test.go \
|
|
internal/usecase/runner.go
|
|
go test ./internal/usecase ./internal/profile ./internal/profile/builtin \
|
|
./internal/backend
|
|
go test ./internal/usecase -run \
|
|
'TestRunner(InspectProfile|Prepare|Run|PrepareExecution|RunPrepared)'
|
|
go vet ./internal/usecase ./internal/profile ./internal/backend
|
|
```
|
|
|
|
### Completion Gate
|
|
|
|
Stage 1 is complete only when:
|
|
|
|
- inspection reaches profile and backend resolution without any prompt or
|
|
execution collaborator;
|
|
- profile/backend selection is shared with ordinary preparation;
|
|
- target merging and requiredness checks are shared rather than duplicated;
|
|
- inspection does not check credential values or capacity;
|
|
- internal errors preserve the required identities;
|
|
- the ordinary preparation and execution tests still pass without weakened
|
|
assertions; and
|
|
- no root public API or current-state documentation claims the feature yet.
|
|
|
|
## Stage 2: Publish The Root Facade And Public Contract
|
|
|
|
### Objective
|
|
|
|
Expose the minimal caller-owned inspection API through `Engine`, preserve
|
|
public error and JSON compatibility, and protect the consumer-visible
|
|
contract.
|
|
|
|
### Implementation Prompt
|
|
|
|
Implement only Stage 2 of
|
|
`docs/roadmap/implementation.md` after Stage 1 satisfies its completion gate.
|
|
Re-read the fixed public API, error, credential, ownership, and test sections
|
|
before editing.
|
|
|
|
1. Add `ProfileInspection` and its exact GoDoc to `types.go` immediately after
|
|
`ExecutionTarget`. Do not add JSON tags or change `ExecutionTarget`.
|
|
2. Add `fromDomainProfileInspection` to `convert.go` using
|
|
`fromDomainExecutionTarget`.
|
|
3. Add `Engine.InspectProfile` and its exact GoDoc to `engine.go` immediately
|
|
before `Prepare`.
|
|
4. Update `Engine` GoDoc to include concurrent inspection.
|
|
5. Update the package GoDoc in `doc.go` for operation discovery, concurrency,
|
|
ownership, and the non-stable JSON classification.
|
|
6. Add compact external-package contract coverage in
|
|
`public_contract_test.go`, using existing fixtures and fakes where they
|
|
remain clear.
|
|
7. Confirm that the existing `errors.go` mapping meets the plan; do not change
|
|
it unless a required public identity test fails for a genuine mapping
|
|
reason.
|
|
8. Run the focused validation below and repair regressions before ending the
|
|
stage.
|
|
|
|
Do not add enumeration, request overrides, profile fingerprints, JSON
|
|
stability, prompt inspection, environment credential checks, caching, or
|
|
current-state prose documentation in this stage.
|
|
|
|
### Focused Validation
|
|
|
|
Run:
|
|
|
|
```sh
|
|
gofmt -w doc.go types.go convert.go engine.go public_contract_test.go
|
|
go test .
|
|
go test ./internal/usecase
|
|
go test . -run 'Test(InspectProfile|.*Profile.*PublicError|.*Profile.*Contract)'
|
|
go vet .
|
|
go build .
|
|
```
|
|
|
|
If the repository's actual focused test names differ, use the implemented test
|
|
names rather than weakening or skipping the intended assertions.
|
|
|
|
### Completion Gate
|
|
|
|
Stage 2 is complete only when:
|
|
|
|
- a consumer can call `Engine.InspectProfile` through the root package;
|
|
- the result contains only the normalized ID, caller-owned effective target,
|
|
and direct-key-required signal;
|
|
- no credential value can enter the result;
|
|
- environment, direct, and no-credential states are unambiguous;
|
|
- nil, blank, missing, malformed, unknown-backend, and cancellation errors
|
|
have the required public identities;
|
|
- not-found remains distinct from profile-load failure;
|
|
- the effective target matches ordinary preparation absent request overrides;
|
|
- repeated calls and caller mutation cannot alter engine-owned state;
|
|
- no stable JSON or new error contract was introduced; and
|
|
- existing public preparation, execution, and stable JSON tests remain
|
|
unchanged and passing.
|
|
|
|
## Stage 3: Update Documentation And Validate The Repository
|
|
|
|
### Objective
|
|
|
|
Make implemented profile inspection discoverable in its canonical
|
|
documentation, reconcile temporary roadmap state, and complete full repository
|
|
validation.
|
|
|
|
### Implementation Prompt
|
|
|
|
Implement only Stage 3 of
|
|
`docs/roadmap/implementation.md` after Stages 1 and 2 satisfy their completion
|
|
gates.
|
|
|
|
1. Update `docs/consumers/pkg-promptkit.md`, `docs/formats.md`,
|
|
`docs/internal/runner.md`, `docs/internal/sources.md`, and
|
|
`docs/internal/overview.md` according to the documentation ownership
|
|
section above.
|
|
2. Update the future catalog and both downstream wishlist dispositions so they
|
|
no longer describe profile inspection as merely accepted work.
|
|
3. Check every changed Markdown link and confirm its file and heading target.
|
|
4. Run the full validation sequence below.
|
|
5. Only after every check passes, set the feature roadmap and this
|
|
implementation plan to `**Status:** Complete.`
|
|
6. Re-run `git diff --check` after the status edits.
|
|
|
|
Do not add release notes, an example program, a new public package, or a
|
|
duplicate API reference. Keep detailed contracts in GoDoc and task-oriented
|
|
usage in the consumer guide.
|
|
|
|
### Full Validation
|
|
|
|
Run from the repository root:
|
|
|
|
```sh
|
|
gofmt -w internal/domain/domain.go \
|
|
internal/usecase/profile_inspection.go \
|
|
internal/usecase/profile_inspection_test.go \
|
|
internal/usecase/runner.go \
|
|
doc.go types.go convert.go engine.go public_contract_test.go
|
|
gofmt -l $(git ls-files '*.go')
|
|
go test ./...
|
|
go test -race ./...
|
|
go vet ./...
|
|
go build ./...
|
|
go run ./examples/go-library/prepare
|
|
git diff --check
|
|
git status --short
|
|
```
|
|
|
|
The `gofmt -l` command must print no paths. The maintained example must remain
|
|
offline and must not require a real credential or provider.
|
|
|
|
Inspect the final diff and confirm:
|
|
|
|
- only files required by this feature and pre-existing user changes are
|
|
present;
|
|
- no credential values, private infrastructure details, workspace files,
|
|
local replacements, generated binaries, or unrelated formatting changes
|
|
were added;
|
|
- the public declarations and GoDoc own exact API behavior;
|
|
- current-state documentation describes only implemented behavior and links
|
|
to canonical owners;
|
|
- roadmap documents contain future scope or completion status rather than a
|
|
duplicate current API reference; and
|
|
- no release, commit, or tag was created.
|
|
|
|
### Completion Gate
|
|
|
|
The implementation is complete only when:
|
|
|
|
- every Stage 1 and Stage 2 gate remains satisfied;
|
|
- the complete ordinary and race-enabled suites pass;
|
|
- vet, build, formatting, the maintained offline example, Markdown links, and
|
|
whitespace checks pass;
|
|
- consumer, format, internal, future, and wishlist documentation are
|
|
consistent with the implemented boundary;
|
|
- both roadmap statuses are `Complete`;
|
|
- the working tree contains no unintended files or changes; and
|
|
- the repository is ready for maintainer review without a commit or release
|
|
having been created by this plan.
|
|
|
|
## Open Questions
|
|
|
|
None. The accepted feature roadmap and the fixed decisions above fully specify
|
|
the implementation boundary.
|