Documentation
¶
Overview ¶
Package detectiveai contains provider-neutral, reviewable Detective AI proposals. Model output is never an authority to read, write, or execute.
Index ¶
- Constants
- Variables
- type Assistant
- type CaseEdit
- type Command
- type ConfirmRequest
- type ConfirmationPorts
- type ContextReviewRequest
- type Draft
- type ExtractedValue
- type FailureExplanation
- type Match
- type Proposal
- type ProposalStore
- type Provenance
- type QueryDraft
- type Receipt
- type Request
- type Resource
- type Response
- type ReviewedDraftRequest
- type RunDraft
- type Scope
- type Snapshot
- type Source
- type SourceEvidence
Constants ¶
const ( KindContext = "extract-context" KindQuery = "draft-query" KindCheck = "draft-check" KindValidator = "draft-validator" KindScenario = "draft-scenario" KindCase = "edit-case" KindRun = "run-check" KindExplain = "explain-failure" )
Variables ¶
Functions ¶
This section is empty.
Types ¶
type Assistant ¶
type Assistant struct {
Provider ai.LLMProvider
Store ProposalStore
Now func() time.Time
NewID func() (string, error)
}
Assistant runs the existing aichat tool loop. Its handlers can only inspect the supplied authorized snapshot and persist validated review proposals.
type CaseEdit ¶
type CaseEdit struct {
CaseID string `json:"caseId"`
ExpectedVersion int64 `json:"expectedVersion"`
Title string `json:"title,omitempty"`
Context map[string]detective.InputValue `json:"context,omitempty"`
Findings []detective.Finding `json:"findings,omitempty"`
Status string `json:"status,omitempty"`
ClosureReason string `json:"closureReason,omitempty"`
}
CaseEdit contains only user-editable fields; server-owned timeline, run links, actor, and version are not present in model-generated payloads.
type Command ¶
type Command struct {
Scope Scope `json:"scope"`
OperationID string `json:"operationId"`
Proposal Proposal `json:"proposal"`
Binding detective.OperationBinding `json:"binding"`
}
Command is formed only by Confirm after it rechecks scope, freshness and authority. Hosts translate it to their existing saved-query/Detective route.
type ConfirmRequest ¶
type ConfirmationPorts ¶
type ConfirmationPorts interface {
ProposalStore
Current(context.Context, Scope) (Snapshot, error)
// Authorize checks current principal/action/resource permissions. It must
// not treat a version advanced by this same completed operation as lost
// permission; Core checks freshness for new operations separately.
Authorize(context.Context, Scope, Proposal) error
AuthorizeSources(context.Context, Scope, []SourceEvidence) error
// PriorReceipt returns an immutable, scoped operation receipt, if any.
// The adapter must reauthorize the principal before revealing it and bind
// lookup to the same operation scope used by Dispatch's atomic receipt.
PriorReceipt(context.Context, Scope, string) (Receipt, bool, error)
Dispatch(context.Context, Command) (Receipt, error)
}
ConfirmationPorts are host-owned deterministic authorization and mutation routes. Dispatch must persist its idempotency receipt and audit atomically.
type ContextReviewRequest ¶
type ContextReviewRequest struct {
ProposalID string `json:"proposalId"`
Digest string `json:"digest"`
CaseID string `json:"caseId"`
ExpectedVersion int64 `json:"expectedVersion"`
Context map[string]detective.InputValue `json:"context"`
}
ContextReviewRequest records the human-edited values to apply to an existing Case. Core derives a separate, digest-bound Case edit proposal; confirming that proposal uses the same audited deterministic Case route.
type Draft ¶
type Draft struct {
Kind string `json:"kind"`
Title string `json:"title"`
Context map[string]ExtractedValue `json:"context,omitempty"`
Query *QueryDraft `json:"query,omitempty"`
Check *detective.Check `json:"check,omitempty"`
Validator *detective.PublishedValidator `json:"validator,omitempty"`
Scenario *detective.Scenario `json:"scenario,omitempty"`
Case *CaseEdit `json:"case,omitempty"`
Run *RunDraft `json:"run,omitempty"`
Explanation *FailureExplanation `json:"explanation,omitempty"`
Sources []Provenance `json:"sources"`
Ambiguities []string `json:"ambiguities,omitempty"`
}
Draft is the strict, one-of model tool argument. Every proposal has a visible source trail; confidence is attached to each extracted value.
type ExtractedValue ¶
type ExtractedValue struct {
Value detective.InputValue `json:"value"`
Provenance []Provenance `json:"provenance"`
}
type FailureExplanation ¶
type Proposal ¶
type Proposal struct {
ID string `json:"id"`
ParentProposalID string `json:"parentProposalId,omitempty"`
Scope Scope `json:"scope"`
Basis Snapshot `json:"basis"`
Draft Draft `json:"draft"`
Sources []SourceEvidence `json:"sources"`
ExpectedCounts map[string]int `json:"expectedCounts,omitempty"`
CreatedAt time.Time `json:"createdAt"`
ExpiresAt time.Time `json:"expiresAt"`
Digest string `json:"digest"`
}
Proposal is stored privately with the exact trusted scope and snapshot basis used for review. Digest binds its complete immutable payload.
func PrepareContextCaseEdit ¶
func PrepareContextCaseEdit(ctx context.Context, scope Scope, request ContextReviewRequest, ports ConfirmationPorts, now time.Time, makeID func() (string, error)) (Proposal, error)
PrepareContextCaseEdit turns a human-reviewed extraction into a separate private Case edit proposal. It does not mutate the Case. Its confirmed dispatch must merge only the reviewed context through the Case endpoint, preserve server-owned fields, and write its audit/receipt atomically.
func PrepareReviewedDraft ¶
func PrepareReviewedDraft(ctx context.Context, scope Scope, request ReviewedDraftRequest, ports ConfirmationPorts, now time.Time, makeID func() (string, error)) (Proposal, error)
PrepareReviewedDraft binds a human-edited query, Check, Validator, Scenario, Case or run draft to a fresh private proposal. It inherits the originally validated citations, rechecks current authority and revisions, and leaves all mutation to a later explicit Confirm. Extraction-to-Case uses the specialized PrepareContextCaseEdit path.
type ProposalStore ¶
type ProposalStore interface {
Save(context.Context, Proposal) error
Get(context.Context, string) (Proposal, error)
}
ProposalStore must store proposals privately by ID and return immutable copies. An adapter enforces project/actor access on both operations.
type Provenance ¶
type Provenance struct {
SourceID string `json:"sourceId"`
Start int `json:"start"` // byte offsets into Source.Text
End int `json:"end"`
Quote string `json:"quote,omitempty"` // exact bounded Source.Text span, private review evidence
Confidence float64 `json:"confidence"`
Ambiguous bool `json:"ambiguous,omitempty"`
}
type QueryDraft ¶
type QueryDraft struct {
ID string `json:"id"`
Title string `json:"title"`
Type string `json:"type"`
Text string `json:"text"`
ConnectionID string `json:"connectionId,omitempty"`
Inputs []detective.Input `json:"inputs,omitempty"`
ExpectedRevision string `json:"expectedRevision,omitempty"`
}
QueryDraft is deliberately inert. The host maps it to its existing saved query write contract after confirmation and its own source authorization.
type Receipt ¶
type Receipt struct {
OperationID string `json:"operationId"`
ScopeKey string `json:"scopeKey"`
Project string `json:"project"`
Actor string `json:"actor"`
ProposalID string `json:"proposalId"`
PayloadDigest string `json:"payloadDigest"`
ResourceID string `json:"resourceId"`
At time.Time `json:"at"`
}
func Confirm ¶
func Confirm(ctx context.Context, scope Scope, request ConfirmRequest, ports ConfirmationPorts, now time.Time) (Receipt, error)
Confirm accepts only a server-derived scope. It reloads the private stored proposal, verifies its digest and current revision basis, reauthorizes the principal, then delegates the mutation to an audited deterministic route. Dispatch must bind OperationID to Command.Binding and return the same receipt for an authorized exact retry; conflicting retries fail closed.
type Resource ¶
type Resource struct {
ID string `json:"id"`
Title string `json:"title"`
Revision string `json:"revision"`
Inputs []detective.Input `json:"inputs,omitempty"`
Environment string `json:"environment,omitempty"`
}
Resource is a bounded, trusted catalog summary. Revision is the immutable query revision or the decimal version of a Detective resource.
type ReviewedDraftRequest ¶
type ReviewedDraftRequest struct {
ProposalID string `json:"proposalId"`
Digest string `json:"digest"`
Draft Draft `json:"draft"`
}
ReviewedDraftRequest edits an existing proposal without changing its cited source trail. The host supplies Scope separately and must decode this body strictly; a successful review creates another private proposal, not a write.
type Scope ¶
type Scope struct {
Key string `json:"key"` // normalized store/Space/project/branch identity
Project string `json:"project"`
Actor string `json:"actor"`
}
Scope is supplied only by an authenticated host adapter. The model never receives an actor credential, and request JSON cannot override this scope.
type Snapshot ¶
type Snapshot struct {
CatalogRevision string `json:"catalogRevision"`
Environments []string `json:"environments"`
Queries []Resource `json:"queries"`
Checks []Resource `json:"checks"`
Validators []Resource `json:"validators"`
Scenarios []Resource `json:"scenarios"`
Cases []Resource `json:"cases"`
Runs []Resource `json:"runs"`
}
Snapshot comes from the host's authorized project reads, never model text. A proposal binds to CatalogRevision and the referenced resource revisions.
type Source ¶
type Source struct {
ID string `json:"id"`
Kind string `json:"kind"`
Revision string `json:"revision"`
Text string `json:"text"` // bounded input; only cited Quote spans may be privately persisted
}
Source is host-supplied pasted text or an authorized resource excerpt. Its full Text is sent to the provider but is not retained by Core. Validated Provenance.Quote spans can be retained in private proposals for review.