package runtime

import (
	"github.com/tidbcloud/AgentTeam/internal/knowledgeqa/protocol"

	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"log/slog"
	"net/http"
	"net/http/httptest"
	"net/url"
	"strings"
	"sync"
	"sync/atomic"
	"testing"
	"time"

	"github.com/stretchr/testify/require"
)

type highVolumeRepository struct {
	grepEmits     int
	grepPreview   string
	listEmits     int
	listKind      string
	listPath      string
	readEmits     int
	readChunk     []byte
	resultCount   int
	distinctPaths bool
}

func (repository *highVolumeRepository) Grep(_ context.Context, _ RepositorySnapshot, _ RepositoryGrepRequest, emit func(RepositoryGrepMatch) error) error {
	preview := repository.grepPreview
	if preview == "" {
		preview = "server hosted"
	}
	for index := 0; index < repository.resultCount; index++ {
		repository.grepEmits++
		path := "docs/design.md"
		if repository.distinctPaths {
			path = fmt.Sprintf("docs/design-%d.md", index)
		}
		if err := emit(RepositoryGrepMatch{Path: path, Line: index + 1, Preview: preview}); err != nil {
			return err
		}
	}
	return nil
}

func (repository *highVolumeRepository) List(_ context.Context, _ RepositorySnapshot, _ RepositoryListRequest, emit func(RepositoryListEntry) error) error {
	kind := repository.listKind
	if kind == "" {
		kind = "file"
	}
	for index := 0; index < repository.resultCount; index++ {
		repository.listEmits++
		path := repository.listPath
		if path == "" {
			path = "docs/design.md"
		}
		if repository.distinctPaths {
			path = fmt.Sprintf("docs/design-%d.md", index)
		}
		if err := emit(RepositoryListEntry{Path: path, Kind: kind}); err != nil {
			return err
		}
	}
	return nil
}

func (repository *highVolumeRepository) Read(_ context.Context, _ RepositorySnapshot, request RepositoryReadRequest, emit func(RepositoryReadChunk) error) error {
	for line := request.LineStart; line <= request.LineEnd; line++ {
		repository.readEmits++
		if err := emit(RepositoryReadChunk{Content: repository.readChunk, LineStart: line, LineEnd: line}); err != nil {
			return err
		}
	}
	return nil
}

type fakeCitationCatalog struct {
	root         AuthorizedRootCandidate
	status       string
	mode         string
	sharedRoot   AuthorizedRootCandidate
	sharedStatus string
}

func (catalog fakeCitationCatalog) ResolveSharedCitationRoot(context.Context, protocol.Principal, CitationMetadata) (AuthorizedRootCandidate, string, error) {
	return catalog.sharedRoot, catalog.sharedStatus, nil
}

func (catalog fakeCitationCatalog) ResolveAuthorizedRoots(context.Context, ScopeRequest) ([]AuthorizedRootCandidate, error) {
	return nil, nil
}

func (catalog fakeCitationCatalog) ResolveCitationRoot(context.Context, protocol.Principal, CitationMetadata) (AuthorizedRootCandidate, string, string, error) {
	mode := catalog.mode
	if mode == "" && catalog.status == CitationStatusAvailable {
		mode = CitationOpenModeSource
	}
	return catalog.root, catalog.status, mode, nil
}

type fakeInference struct {
	request          InferenceRequest
	requests         []InferenceRequest
	result           InferenceResult
	results          []InferenceResult
	errs             []error
	calls            int
	cancelAt         int
	cancel           context.CancelFunc
	profile          ChatCompletionsCompatibilityProfile
	profileErr       error
	profileCalls     int
	profileModel     string
	profileAuthority string
}

type fakeWebSearchProvider struct {
	results []WebSearchResult
	err     error
	queries []string
	limits  []int
}

func (provider *fakeWebSearchProvider) Search(_ context.Context, query string, limit int) ([]WebSearchResult, error) {
	provider.queries = append(provider.queries, query)
	provider.limits = append(provider.limits, limit)
	if provider.err != nil {
		return nil, provider.err
	}
	return provider.results, nil
}

type memoryAccountingCheckpointStore struct {
	checkpoint         protocol.AccountingCheckpoint
	writes             []protocol.AccountingCheckpoint
	writeContextErrors []error
	writeErrors        []error
}

type rewriteWebTransport struct {
	target *url.URL
	base   http.RoundTripper
}

func (transport rewriteWebTransport) RoundTrip(request *http.Request) (*http.Response, error) {
	clone := request.Clone(request.Context())
	clone.URL = clone.URL.JoinPath()
	clone.URL.Scheme = transport.target.Scheme
	clone.URL.Host = transport.target.Host
	base := transport.base
	if base == nil {
		base = http.DefaultTransport
	}
	response, err := base.RoundTrip(clone)
	if response != nil {
		response.Request = request
	}
	return response, err
}

func testWebReadClient(t *testing.T, serverURL string) *http.Client {
	t.Helper()
	target, err := url.Parse(serverURL)
	require.NoError(t, err)
	return &http.Client{Transport: rewriteWebTransport{target: target}, Timeout: webReadTimeout}
}

func (store *memoryAccountingCheckpointStore) PutAccountingCheckpoint(ctx context.Context, checkpoint protocol.AccountingCheckpoint) error {
	store.checkpoint = checkpoint
	store.writes = append(store.writes, checkpoint)
	store.writeContextErrors = append(store.writeContextErrors, ctx.Err())
	if index := len(store.writes) - 1; index < len(store.writeErrors) {
		return store.writeErrors[index]
	}
	return nil
}

func (store *memoryAccountingCheckpointStore) LoadAccountingCheckpoint(
	_ context.Context,
	principal protocol.Principal,
	attemptID string,
	now time.Time,
) (protocol.AccountingCheckpoint, bool, error) {
	checkpoint := store.checkpoint
	found := checkpoint.AttemptID == attemptID && checkpoint.Principal == principal && checkpoint.ExpiresAt.After(now)
	return checkpoint, found, nil
}

func (inference *fakeInference) ResolveChatCompletionsProfile(
	_ context.Context,
	model string,
	capability string,
) (ChatCompletionsCompatibilityProfile, error) {
	inference.profileCalls++
	inference.profileModel = model
	inference.profileAuthority = capability
	if inference.profileErr != nil {
		return ChatCompletionsCompatibilityProfile{}, inference.profileErr
	}
	if strings.TrimSpace(inference.profile.ID) != "" {
		return cloneChatCompletionsProfile(inference.profile), nil
	}
	profile, _ := lookupSupportedChatCompletionsProfile(chatCompletionsProfileOpenAIRequiredToolsV1)
	return profile, nil
}

func (inference *fakeInference) Generate(_ context.Context, request InferenceRequest) (InferenceResult, error) {
	inference.calls++
	if inference.calls == inference.cancelAt && inference.cancel != nil {
		inference.cancel()
	}
	inference.request = request
	inference.requests = append(inference.requests, request)
	var scripted InferenceResult
	if len(inference.results) >= inference.calls {
		scripted = inference.results[inference.calls-1]
		scripted = bindFakeToolCallID(scripted, inference.calls)
	}
	if len(inference.errs) >= inference.calls && inference.errs[inference.calls-1] != nil {
		return scripted, inference.errs[inference.calls-1]
	}
	if len(inference.results) >= inference.calls {
		return scripted, nil
	}
	resultCall := inferenceToolCall(inference.result)
	if resultCall.Function.Name == knowledgeAnswerFunction {
		switch inference.calls {
		case 1:
			return bindFakeToolCallID(nativeToolResult(
				knowledgeSearchFunction, `{"query":"server hosted"}`,
			), inference.calls), nil
		case 2:
			return bindFakeToolCallID(nativeToolResult(
				knowledgeReadFunction, `{"fileRef":"f1","lineStart":9,"lineEnd":15}`,
			), inference.calls), nil
		}
	}
	return bindFakeToolCallID(inference.result, inference.calls), nil
}

func nativeToolResult(name, arguments string) InferenceResult {
	call := InferenceToolCall{
		ID: "call_1", Type: "function",
		Function: InferenceFunctionCall{Name: name, Arguments: arguments},
	}
	return InferenceResult{
		Message: InferenceMessage{
			Role: "assistant", ContentNull: true,
			ToolCalls: []InferenceToolCall{call},
		},
	}
}

func nativeToolBatch(calls ...InferenceToolCall) InferenceResult {
	return InferenceResult{Message: InferenceMessage{
		Role: "assistant", ContentNull: true, ToolCalls: append([]InferenceToolCall(nil), calls...),
	}}
}

func accountedToolResult(name, arguments string, usage map[string]any, settlementRef string) InferenceResult {
	result := nativeToolResult(name, arguments)
	result.Usage = usage
	result.SettlementRef = settlementRef
	return result
}

func bindFakeToolCallID(result InferenceResult, callNumber int) InferenceResult {
	if len(result.Message.ToolCalls) != 1 {
		return result
	}
	id := fmt.Sprintf("call_%d", callNumber)
	result.Message.ToolCalls = append([]InferenceToolCall(nil), result.Message.ToolCalls...)
	result.Message.ToolCalls[0].ID = id
	return result
}

func inferenceToolCall(result InferenceResult) InferenceToolCall {
	if len(result.Message.ToolCalls) != 1 {
		return InferenceToolCall{}
	}
	return result.Message.ToolCalls[0]
}

func TestRuntimeAcceptsAnswerClaimsAndValidatesCitation(t *testing.T) {
	now := time.Date(2026, 7, 25, 10, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	repository := &fakeRepository{}
	inference := &fakeInference{result: accountedToolResult(
		knowledgeAnswerFunction,
		`{"claims":["The runtime is server hosted. [E1]"]}`,
		map[string]any{"input_tokens": 42},
		"hue_1",
	)}
	runtime := &Runtime{
		Resolver: &Resolver{
			Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
				KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
				RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
			}}},
			Handles: handles, Clock: func() time.Time { return now },
		},
		Tools:       &Service{Handles: handles, Repository: repository, Clock: func() time.Time { return now }},
		Inference:   inference,
		Checkpoints: &memoryAccountingCheckpointStore{},
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "Where is the server hosted?",
		Model: "agentteam/model", ReasonLevel: "high", Capability: "signed-token",
		IdempotencyKey: "attempt-12345678",
	})

	require.NoError(t, err)
	require.Equal(t, "completed", result.Status)
	require.Equal(t, "The runtime is server hosted. [E1]", result.Claims[0].Text)
	require.Equal(t, []string{"E1"}, result.Claims[0].EvidenceIDs)
	require.Equal(t, "E1", result.Evidence[0].ID)
	require.Equal(t, "sha-fixed", result.Evidence[0].Citation.Revision)
	require.Equal(t, "docs/design.md", result.Evidence[0].Citation.Path)
	require.Equal(t, "hue_1", result.SettlementRef)
	require.Equal(t, []string{"hue_1"}, result.SettlementRefs)
	require.Contains(t, inference.request.System, "untrusted data")
	require.Contains(t, inference.request.System, "same primary language")
	require.Contains(t, inference.request.System, "iteratively use")
	require.Contains(t, inference.request.System, "never return normal assistant text")
	require.Contains(t, inference.request.System, "We recommend citing supporting reads")
	require.Contains(t, inference.request.System, "exact marker syntax [E1]")
	require.Contains(t, inference.request.System, "one or two sentences that directly answer")
	require.Contains(t, inference.request.System, "Do not force headings onto a simple answer")
	require.Contains(t, inference.request.System, "format code identifiers")
	require.Contains(t, inference.request.System, "For multi-line commands, recommend using a fenced Markdown code block")
	require.Contains(t, inference.request.System, "must never consist only of evidence markers")
	require.NotEmpty(t, inference.request.Messages)
	require.NotEmpty(t, result.Roots[0].HandleID)
	require.Equal(t, 1, result.ToolUsage.GrepCalls)
	require.Equal(t, 1, result.ToolUsage.ReadCalls)
	require.Equal(t, 3, result.ToolUsage.ModelCalls)
	require.Equal(t, 1, inference.profileCalls)
	require.Equal(t, "agentteam/model", inference.profileModel)
	require.Equal(t, "signed-token", inference.profileAuthority)
	require.Len(t, inference.requests, 3)
	for _, inferenceRequest := range inference.requests {
		require.Equal(t, chatCompletionsProfileOpenAIRequiredToolsV1, inferenceRequest.Profile.ID)
	}
	require.Greater(t, result.ToolUsage.ResultBytes, 0)
	require.Empty(t, handles.handles)
}

func TestRuntimeAcceptsComplexAnswerWithoutClaimShapeLimits(t *testing.T) {
	now := time.Date(2026, 7, 25, 10, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	longClaim := strings.Repeat("Detailed grounded explanation. ", 64) + "[E1]"
	claims := make([]string, 40)
	claims[0] = longClaim
	for index := 1; index < len(claims); index++ {
		claims[index] = fmt.Sprintf("Additional grounded claim %d. [E1]", index+1)
	}
	answerArguments, err := json.Marshal(knowledgeAnswerArguments{Claims: claims})
	require.NoError(t, err)
	inference := &fakeInference{result: nativeToolResult(knowledgeAnswerFunction, string(answerArguments))}
	runtime := &Runtime{
		Resolver: &Resolver{
			Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
				KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
				RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
			}}},
			Handles: handles, Clock: func() time.Time { return now },
		},
		Tools:       &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference:   inference,
		Checkpoints: &memoryAccountingCheckpointStore{},
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "Explain the complete design in detail.",
		Model: "agentteam/model", ReasonLevel: "high", Capability: "signed-token",
		IdempotencyKey: "attempt-complex-answer",
	})

	require.NoError(t, err)
	require.Equal(t, "completed", result.Status)
	require.Len(t, result.Claims, len(claims))
	require.Equal(t, longClaim, result.Claims[0].Text)
	require.Greater(t, len(result.Claims[0].Text), 1024)
	require.Equal(t, []string{"E1"}, result.Claims[0].EvidenceIDs)
	require.Len(t, result.Evidence, 1)
	require.Empty(t, result.Diagnostics)
}

func TestDiagnoseGroundedClaimsRetainsMarkerToEvidenceAssociations(t *testing.T) {
	citation := CitationMetadata{
		KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
		RepoRole: RepoRolePrimary, Revision: "sha_1", Path: "docs/design.md",
		LineStart: 1, LineEnd: 2,
	}
	references, diagnostics := diagnoseGroundedClaims(
		GroundedAnswer{Claims: []GroundedClaim{
			{Text: "First [E1] and second [E2].", EvidenceIDs: []string{"E1", "E2"}},
			{Text: "Uncited summary."},
			{Text: "Third claim [E1].", EvidenceIDs: []string{"E1"}},
		}},
		[]Evidence{{ID: "E1", Citation: citation}, {ID: "E2", Citation: citation}},
	)
	require.Empty(t, diagnostics)
	require.Equal(t, []EvidenceReference{
		{ID: "E1", Citation: citation},
		{ID: "E2", Citation: citation},
	}, references)
}

func TestDiagnoseGroundedClaimsWarnsOnMarkerMismatch(t *testing.T) {
	_, diagnostics := diagnoseGroundedClaims(
		GroundedAnswer{Claims: []GroundedClaim{{
			Text: "Mismatched [E2].", EvidenceIDs: []string{"E1"},
		}}},
		[]Evidence{{ID: "E1"}, {ID: "E2"}},
	)
	require.Equal(t, []RuntimeDiagnostic{{
		Code: DiagnosticMarkerMismatch, Severity: "warning",
	}}, diagnostics)
}

func TestExplorationSystemPromptRequiresChineseForChineseQuestion(t *testing.T) {
	prompt := explorationSystemPrompt("AgentTeam Server 是什么？")

	require.Contains(t, prompt, "every knowledge_answer claim MUST be Chinese")
}

func TestExplorationSystemPromptExplainsWebToolsWhenEnabled(t *testing.T) {
	handles := &memoryHandleStore{}
	inference := &fakeInference{results: []InferenceResult{
		nativeToolResult(knowledgeNoAnswerFunction, `{}`),
	}}
	runtime := &Runtime{
		Resolver: &Resolver{
			Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
				KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
				RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
			}}},
			Handles: handles,
		},
		Tools:       &Service{Handles: handles, Repository: &fakeRepository{}},
		Inference:   inference,
		Checkpoints: &memoryAccountingCheckpointStore{},
	}

	_, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "current docs", Model: "agentteam/model", ReasonLevel: "high",
		Capability: "signed-token", IdempotencyKey: "attempt-12345678", WebSearchEnabled: true,
	})

	require.NoError(t, err)
	require.Len(t, inference.requests, 1)
	require.Contains(t, inference.requests[0].System, "Web search is enabled")
	require.Contains(t, inference.requests[0].System, knowledgeWebSearchFunction)
	require.NotContains(t, inference.requests[0].System, "mockUrls")
}

func TestExplorationModelMessagesKeepCitationMetadataServerSide(t *testing.T) {
	roots := []RootHandleView{{
		HandleID: "kqr_1", KnowledgeBaseID: "kb_1", SourceID: "src_1",
		RootKind: RootKindPrimary, RepoRole: RepoRolePrimary,
		Revision: "0123456789abcdef0123456789abcdef01234567", FreshnessStatus: "current",
	}}
	initial, err := explorationInitialMessage(
		"Where is the server hosted?", RuntimeContext{}, roots, newExplorationReferences(roots),
	)
	require.NoError(t, err)
	require.Contains(t, initial, `"rootAlias":"r1"`)
	require.NotContains(t, initial, `"handleId"`)
	require.NotContains(t, initial, "kqr_1")
	require.NotContains(t, initial, `"knowledgeBaseId"`)
	require.NotContains(t, initial, `"sourceId"`)
	require.NotContains(t, initial, "kb_1")
	require.NotContains(t, initial, "src_1")
	require.NotContains(t, initial, `"revision"`)
	require.NotContains(t, initial, "0123456789abcdef0123456789abcdef01234567")
}

func TestNativeToolArgumentValidationMapsToSanitizedRepairIssues(t *testing.T) {
	tests := []struct {
		name        string
		function    string
		arguments   string
		wantCode    string
		wantField   string
		wantRule    string
		secretParts []string
	}{
		{
			name: "arguments schema invalid", function: knowledgeReadFunction,
			arguments: `{"fileRef":"f1","lineStart":1,"lineEnd":2,"rawParserSecret":"private/path/kqr_123"}`,
			wantCode:  "arguments_schema_invalid", wantRule: "arguments must match the tool schema exactly",
			secretParts: []string{"rawParserSecret", "private/path/kqr_123", "unknown field"},
		},
		{
			name: "search query required", function: knowledgeSearchFunction, arguments: `{}`,
			wantCode: "search_query_required", wantField: "query", wantRule: "query is required",
		},
		{
			name: "search query invalid", function: knowledgeSearchFunction,
			arguments: fmt.Sprintf(`{"query":%q}`, "private-query-"+strings.Repeat("q", maxSearchPatternBytes)),
			wantCode:  "search_query_invalid", wantField: "query",
			wantRule:    "query must be a non-empty string within the declared size limit",
			secretParts: []string{"private-query-"},
		},
		{
			name: "search query pattern invalid", function: knowledgeSearchFunction,
			arguments: `{"query":"private-pattern["}`,
			wantCode:  "search_query_pattern_invalid", wantField: "query",
			wantRule:    "query must be a valid POSIX extended regular expression",
			secretParts: []string{"private-pattern["},
		},
		{
			name: "search root aliases invalid", function: knowledgeSearchFunction,
			arguments: `{"query":"server","rootAliases":["private-root-kqr_123"]}`,
			wantCode:  "search_root_aliases_invalid", wantField: "rootAliases",
			wantRule:    "rootAliases, when present, must be a non-empty unique array of issued root aliases",
			secretParts: []string{"private-root-kqr_123"},
		},
		{
			name: "search path globs invalid", function: knowledgeSearchFunction,
			arguments: `{"query":"server","pathGlobs":["../private/path/kqr_123"]}`,
			wantCode:  "search_path_globs_invalid", wantField: "pathGlobs",
			wantRule:    "pathGlobs, when present, must be a non-empty unique array of valid relative glob strings",
			secretParts: []string{"../private/path/kqr_123"},
		},
		{
			name: "list selector required", function: knowledgeListFunction, arguments: `{}`,
			wantCode: "list_selector_required", wantRule: "provide rootAlias or directoryRef",
		},
		{
			name: "list root alias invalid", function: knowledgeListFunction,
			arguments: `{"rootAlias":"private-root-kqr_123"}`,
			wantCode:  "list_root_alias_invalid", wantField: "rootAlias",
			wantRule:    "rootAlias must be a valid issued root alias and cannot be null",
			secretParts: []string{"private-root-kqr_123"},
		},
		{
			name: "list directory ref invalid", function: knowledgeListFunction,
			arguments: `{"directoryRef":"private/directory/kqr_123"}`,
			wantCode:  "list_directory_ref_invalid", wantField: "directoryRef",
			wantRule:    "directoryRef must be a valid issued directory reference and cannot be null",
			secretParts: []string{"private/directory/kqr_123"},
		},
		{
			name: "read file ref required", function: knowledgeReadFunction,
			arguments: `{"lineStart":1,"lineEnd":2}`,
			wantCode:  "read_file_ref_required", wantField: "fileRef", wantRule: "fileRef is required",
		},
		{
			name: "read line start required", function: knowledgeReadFunction,
			arguments: `{"fileRef":"f1","lineEnd":2}`,
			wantCode:  "read_line_start_required", wantField: "lineStart", wantRule: "lineStart is required",
		},
		{
			name: "read line end required", function: knowledgeReadFunction,
			arguments: `{"fileRef":"f1","lineStart":1}`,
			wantCode:  "read_line_end_required", wantField: "lineEnd", wantRule: "lineEnd is required",
		},
		{
			name: "read file ref invalid", function: knowledgeReadFunction,
			arguments: `{"fileRef":"private/path/kqr_123","lineStart":1,"lineEnd":2}`,
			wantCode:  "read_file_ref_invalid", wantField: "fileRef",
			wantRule:    "fileRef must be a valid issued file reference",
			secretParts: []string{"private/path/kqr_123"},
		},
		{
			name: "read line start invalid", function: knowledgeReadFunction,
			arguments: `{"fileRef":"f1","lineStart":-42,"lineEnd":2}`,
			wantCode:  "read_line_start_invalid", wantField: "lineStart",
			wantRule:    "lineStart must be an integer greater than or equal to 1",
			secretParts: []string{"-42"},
		},
		{
			name: "read line end invalid", function: knowledgeReadFunction,
			arguments: `{"fileRef":"f1","lineStart":1,"lineEnd":-73}`,
			wantCode:  "read_line_end_invalid", wantField: "lineEnd",
			wantRule:    "lineEnd must be an integer greater than or equal to 1",
			secretParts: []string{"-73"},
		},
		{
			name: "read range reversed", function: knowledgeReadFunction,
			arguments: `{"fileRef":"f1","lineStart":19,"lineEnd":7}`,
			wantCode:  "read_range_reversed", wantField: "lineEnd",
			wantRule:    "lineEnd must be greater than or equal to lineStart",
			secretParts: []string{"19", `"lineEnd":7`},
		},
		{
			name: "read range too large", function: knowledgeReadFunction,
			arguments: `{"fileRef":"f1","lineStart":1,"lineEnd":1001}`,
			wantCode:  "read_range_too_large", wantField: "lineEnd",
			wantRule:    "the requested range must contain at most 1000 lines",
			secretParts: []string{"1001"},
		},
		{
			name: "answer claims required", function: knowledgeAnswerFunction,
			arguments: `{"claims":[]}`,
			wantCode:  "answer_claims_required", wantField: "claims",
			wantRule: "claims must be a non-empty array of strings",
		},
		{
			name: "answer claim empty", function: knowledgeAnswerFunction,
			arguments: `{"claims":["  "]}`,
			wantCode:  "answer_claim_empty", wantField: "claims",
			wantRule: "every claim must contain non-whitespace text",
		},
		{
			name: "answer claim contains citations only", function: knowledgeAnswerFunction,
			arguments: `{"claims":["[E1] [E2]"]}`,
			wantCode:  "answer_claim_citation_only", wantField: "claims",
			wantRule: "every evidence marker must immediately follow an assertion; a claim cannot contain only evidence markers",
		},
		{
			name: "no answer arguments not empty", function: knowledgeNoAnswerFunction,
			arguments:   `{"privatePath":"private/path/kqr_123"}`,
			wantCode:    "no_answer_arguments_not_empty",
			wantRule:    "knowledge_no_answer arguments must be an empty object",
			secretParts: []string{"privatePath", "private/path/kqr_123"},
		},
	}
	wantToolNames := map[string]string{
		knowledgeSearchFunction:   "knowledge_search",
		knowledgeListFunction:     "knowledge_list",
		knowledgeReadFunction:     "knowledge_read",
		knowledgeAnswerFunction:   "knowledge_answer",
		knowledgeNoAnswerFunction: "knowledge_no_answer",
	}
	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			_, err := decodeExplorationToolCall(InferenceToolCall{
				ID: "call_1", Type: "function",
				Function: InferenceFunctionCall{Name: test.function, Arguments: test.arguments},
			})
			var validationErr *explorationToolCallValidationError
			require.ErrorAs(t, err, &validationErr)
			issue := explorationRepairIssueFromError(1, err)
			require.Equal(t, explorationRepairIssue{
				CallIndex: 1, Tool: wantToolNames[test.function], Code: test.wantCode,
				Field: test.wantField, Requirement: test.wantRule,
			}, issue)

			modelPrompt := explorationInvalidResponseRepairPrompt(explorationRepairFeedback{
				RepairAttempt: 1, MaxRepairAttempts: maxInvalidResponseRepairs,
				Issues: []explorationRepairIssue{issue},
			})
			require.NotContains(t, modelPrompt, test.arguments)
			for _, parserDetail := range []string{"json:", "unknown field", "invalid character", "error parsing regexp"} {
				require.NotContains(t, modelPrompt, parserDetail)
			}
			for _, secretPart := range test.secretParts {
				require.NotContains(t, err.Error(), secretPart)
				require.NotContains(t, modelPrompt, secretPart)
			}
		})
	}
}

func TestNativeToolArgumentsRejectLegacyFunctionsWithStableRuntimeCode(t *testing.T) {
	tests := []struct {
		name      string
		function  string
		arguments string
	}{
		{name: "legacy action", function: "search", arguments: `{"type":"search","query":"server"}`},
		{name: "unknown search field", function: knowledgeSearchFunction, arguments: `{"query":"server","rootIds":["r1"]}`},
		{name: "missing query", function: knowledgeSearchFunction, arguments: `{}`},
		{name: "null filters", function: knowledgeSearchFunction, arguments: `{"query":"server","pathGlobs":null}`},
		{name: "empty root aliases", function: knowledgeSearchFunction, arguments: `{"query":"server","rootAliases":[]}`},
		{name: "empty path globs", function: knowledgeSearchFunction, arguments: `{"query":"server","pathGlobs":[]}`},
		{name: "malformed root alias", function: knowledgeSearchFunction, arguments: `{"query":"server","rootAliases":["root-1"]}`},
		{name: "oversized root alias", function: knowledgeSearchFunction, arguments: `{"query":"server","rootAliases":["r12345678901234567890123456789012"]}`},
		{name: "invalid regex", function: knowledgeSearchFunction, arguments: `{"query":"["}`},
		{name: "missing list selector", function: knowledgeListFunction, arguments: `{}`},
		{name: "malformed directory ref", function: knowledgeListFunction, arguments: `{"directoryRef":"directory-1"}`},
		{name: "oversized directory ref", function: knowledgeListFunction, arguments: `{"directoryRef":"d12345678901234567890123456789012"}`},
		{name: "forged read path", function: knowledgeReadFunction, arguments: `{"fileRef":"f1","path":"secret","lineStart":1,"lineEnd":2}`},
		{name: "oversized file ref", function: knowledgeReadFunction, arguments: `{"fileRef":"f12345678901234567890123456789012","lineStart":1,"lineEnd":2}`},
		{name: "oversized read range", function: knowledgeReadFunction, arguments: `{"fileRef":"f1","lineStart":1,"lineEnd":1001}`},
		{name: "real web search rejects mock urls", function: knowledgeWebSearchFunction, arguments: `{"query":"docs","mockUrls":["https://example.com"]}`},
		{name: "unknown web read field", function: knowledgeWebReadFunction, arguments: `{"webRef":"w1","url":"https://example.com"}`},
		{name: "malformed web ref", function: knowledgeWebReadFunction, arguments: `{"webRef":"web-1"}`},
		{name: "legacy finish", function: "knowledge_finish", arguments: `{"status":"answer","claims":["x [E1]"]}`},
	}
	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			_, err := decodeExplorationToolCall(InferenceToolCall{
				ID: "call_1", Type: "function",
				Function: InferenceFunctionCall{Name: test.function, Arguments: test.arguments},
			})
			var runtimeErr *Error
			var validationErr *explorationToolCallValidationError
			if errors.As(err, &runtimeErr) {
				require.Equal(t, CodeResponseInvalid, runtimeErr.Code)
			} else {
				require.ErrorAs(t, err, &validationErr)
			}
		})
	}
}

func repairFeedbackFromSystemPrompt(t *testing.T, systemPrompt string) explorationRepairFeedback {
	t.Helper()
	const marker = " Trusted validator feedback: "
	markerIndex := strings.LastIndex(systemPrompt, marker)
	require.NotEqual(t, -1, markerIndex)
	var feedback explorationRepairFeedback
	require.NoError(t, json.Unmarshal([]byte(systemPrompt[markerIndex+len(marker):]), &feedback))
	return feedback
}

func TestNativeListArgumentsAllowRedundantRootAlias(t *testing.T) {
	action, err := decodeExplorationToolCall(InferenceToolCall{
		ID: "call_1", Type: "function",
		Function: InferenceFunctionCall{
			Name: knowledgeListFunction, Arguments: `{"rootAlias":"r1","directoryRef":"d1"}`,
		},
	})
	require.NoError(t, err)
	require.Equal(t, knowledgeListArguments{RootAlias: "r1", DirectoryRef: "d1"}, action.List)
}

func TestExplorationReferencesHideHandlesAndRejectUnissuedRefs(t *testing.T) {
	first := testRootHandle(time.Now().UTC())
	second := first
	second.ID = "kqr_second"
	second.RepositoryRef = "repo-second"
	session := &ExecutionRepository{
		handles:    map[string]protocol.RootHandle{first.ID: first, second.ID: second},
		repository: &fakeRepository{},
	}
	refs := newExplorationReferences([]RootHandleView{{HandleID: first.ID}, {HandleID: second.ID}})
	usage := &ToolUsage{}

	search, err := (&Runtime{}).explorationSearch(
		context.Background(), session, refs,
		knowledgeSearchArguments{Query: "server", RootAliases: []string{"r2"}}, usage,
	)
	require.NoError(t, err)
	require.Len(t, search.Matches, 1)
	require.Equal(t, "r2", search.Matches[0].RootAlias)
	require.Equal(t, "f1", search.Matches[0].FileRef)
	encoded, err := json.Marshal(search)
	require.NoError(t, err)
	require.NotContains(t, string(encoded), first.ID)
	require.NotContains(t, string(encoded), second.ID)
	require.NotContains(t, string(encoded), second.Revision)

	rootList, err := (&Runtime{}).explorationList(
		context.Background(), session, refs, knowledgeListArguments{RootAlias: "r1"}, usage,
	)
	require.NoError(t, err)
	require.Equal(t, []explorationListEntry{{Ref: "d1", Kind: "directory", Path: "docs"}}, rootList.Entries)
	directoryList, err := (&Runtime{}).explorationList(
		context.Background(), session, refs, knowledgeListArguments{DirectoryRef: "d1"}, usage,
	)
	require.NoError(t, err)
	require.Equal(t, "file", directoryList.Entries[0].Kind)
	require.Equal(t, "docs/design.md", directoryList.Entries[0].Path)
	require.Equal(t, "f2", directoryList.Entries[0].Ref)

	_, _, err = (&Runtime{}).explorationRead(
		context.Background(), session, refs,
		knowledgeReadArguments{FileRef: "f99", LineStart: 1, LineEnd: 1}, 1, usage,
	)
	var runtimeErr *Error
	require.ErrorAs(t, err, &runtimeErr)
	require.Equal(t, CodeHandleRejected, runtimeErr.Code)

	fresh := newExplorationReferences([]RootHandleView{{HandleID: first.ID}})
	_, issued := fresh.resolveFile("f1")
	require.False(t, issued, "a reference value from another attempt is not issued in a fresh attempt")
	require.Equal(t, "f1", fresh.fileRef(first.ID, "new/path.go"))
}

func TestExplorationWebSearchReturnsProviderURLRefs(t *testing.T) {
	refs := newExplorationReferences(nil)
	usage := &ToolUsage{}
	provider := &fakeWebSearchProvider{results: []WebSearchResult{
		{URL: "https://example.com/release#section", Title: " Release notes "},
		{URL: "https://example.com/release", Title: "duplicate"},
		{URL: "file:///etc/passwd", Title: "invalid"},
		{URL: "https://example.com/docs"},
	}}
	search, err := (&Runtime{WebSearchProvider: provider}).explorationWebSearch(
		context.Background(),
		refs,
		knowledgeWebSearchArguments{Query: "release notes"},
		usage,
	)

	require.NoError(t, err)
	require.True(t, search.OK)
	require.False(t, search.Truncated)
	require.Len(t, search.Results, 2, "duplicate URLs are collapsed after fragment removal")
	require.Equal(t, "w1", search.Results[0].WebRef)
	require.Equal(t, "https://example.com/release", search.Results[0].URL)
	require.Equal(t, "Release notes", search.Results[0].Title)
	require.Empty(t, search.Results[0].Source)
	require.Equal(t, "w2", search.Results[1].WebRef)
	require.Equal(t, "https://example.com/docs", search.Results[1].URL)
	require.Equal(t, []string{"release notes"}, provider.queries)
	require.Equal(t, []int{maxWebSearchResultURLs}, provider.limits)
	require.Equal(t, 1, usage.WebSearchCalls)
	require.Equal(t, 2, usage.WebSources)
}

func TestExplorationWebSearchLimitsProviderResults(t *testing.T) {
	refs := newExplorationReferences(nil)
	usage := &ToolUsage{}
	provider := &fakeWebSearchProvider{results: []WebSearchResult{
		{URL: "https://example.com/1", Title: "one"},
		{URL: "https://example.com/2", Title: "two"},
		{URL: "https://example.com/3", Title: "three"},
		{URL: "https://example.com/4", Title: "four"},
		{URL: "https://example.com/5", Title: "five"},
		{URL: "https://example.com/6", Title: "six"},
	}}

	search, err := (&Runtime{WebSearchProvider: provider}).explorationWebSearch(
		context.Background(), refs, knowledgeWebSearchArguments{Query: "release notes"}, usage,
	)

	require.NoError(t, err)
	require.True(t, search.OK)
	require.Len(t, search.Results, maxWebSearchResultURLs)
	require.Equal(t, "w5", search.Results[4].WebRef)
	require.Equal(t, "https://example.com/5", search.Results[4].URL)
	_, issued := refs.resolveWeb("w6")
	require.False(t, issued)
	require.Equal(t, maxWebSearchResultURLs, usage.WebSources)
}

func TestExplorationWebSearchEmptyResultsReturnsNavigationHint(t *testing.T) {
	refs := newExplorationReferences(nil)
	usage := &ToolUsage{}

	search, err := (&Runtime{WebSearchProvider: &fakeWebSearchProvider{}}).explorationWebSearch(
		context.Background(), refs, knowledgeWebSearchArguments{Query: "missing topic"}, usage,
	)

	require.NoError(t, err)
	require.True(t, search.OK)
	require.Empty(t, search.Results)
	require.Equal(t, "no web search results", search.Hint)
	require.Equal(t, 1, usage.WebSearchCalls)
	require.Zero(t, usage.WebSources)
}

func TestExplorationWebSearchWithoutProviderReturnsEmptyResults(t *testing.T) {
	refs := newExplorationReferences(nil)
	usage := &ToolUsage{}

	search, err := (&Runtime{}).explorationWebSearch(
		context.Background(), refs, knowledgeWebSearchArguments{Query: "release notes"}, usage,
	)

	require.NoError(t, err)
	require.False(t, search.OK)
	require.Empty(t, search.Results)
	require.Contains(t, search.Hint, "provider")
	require.Equal(t, 1, usage.WebSearchCalls)
	require.Zero(t, usage.WebSources)
}

func TestExplorationWebReadProducesEvidenceFromHTML(t *testing.T) {
	now := time.Date(2026, 8, 5, 6, 0, 0, 0, time.UTC)
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, request *http.Request) {
		require.Equal(t, webReadUserAgent, request.Header.Get("User-Agent"))
		w.Header().Set("Content-Type", "text/html; charset=utf-8")
		_, _ = w.Write([]byte(`<!doctype html>
<html>
<head><title>MeshX Web Search Notes</title></head>
<body>
<article>
<h1>MeshX Web Search Notes</h1>
<p>MeshX can read public pages as web evidence.</p>
<p>Knowledge web read produces the citable evidence.</p>
</article>
<script>ignore()</script>
</body>
</html>`))
	}))
	defer server.Close()

	refs := newExplorationReferences(nil)
	usage := &ToolUsage{}
	runtime := &Runtime{Clock: func() time.Time { return now }, WebReadClient: testWebReadClient(t, server.URL)}
	publicURL := "https://example.com/notes"
	require.Equal(t, "w1", refs.webRef(explorationWebReference{URL: publicURL}))

	read, evidence, err := runtime.explorationWebRead(
		context.Background(), refs,
		knowledgeWebReadArguments{WebRef: "w1"}, 1, usage,
	)

	require.NoError(t, err)
	require.True(t, read.OK)
	require.NotNil(t, evidence)
	require.Equal(t, "E1", evidence.ID)
	require.Contains(t, evidence.Content, "MeshX can read public pages")
	require.Equal(t, CitationKindWeb, evidence.Citation.CitationKind)
	require.Equal(t, publicURL, evidence.Citation.URL)
	require.Equal(t, "MeshX Web Search Notes", evidence.Citation.Title)
	require.Equal(t, now.Format(time.RFC3339Nano), evidence.Citation.FetchedAt)
	require.Equal(t, 1, evidence.Citation.LineStart)
	require.GreaterOrEqual(t, evidence.Citation.LineEnd, 1)
	require.Equal(t, "E1", read.Evidence.ID)
	require.Equal(t, "w1", read.Evidence.WebRef)
	require.Equal(t, publicURL, read.Evidence.URL)
	require.Contains(t, read.Evidence.Content, "Knowledge web read produces")
	require.Equal(t, 1, usage.WebReadCalls)
	require.Equal(t, 1, usage.WebSources)
}

func TestRuntimeCompletesAnswerWithWebSearchAndReadEvidence(t *testing.T) {
	now := time.Date(2026, 8, 5, 6, 30, 0, 0, time.UTC)
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
		w.Header().Set("Content-Type", "text/plain; charset=utf-8")
		_, _ = w.Write([]byte("MeshX web search MVP uses SearXNG search and HTTP reading for evidence.\n"))
	}))
	defer server.Close()

	handles := &memoryHandleStore{}
	publicURL := "https://example.com/mvp"
	webSearch := &fakeWebSearchProvider{results: []WebSearchResult{{URL: publicURL, Title: "MVP"}}}
	inference := &fakeInference{results: []InferenceResult{
		nativeToolResult(knowledgeWebSearchFunction, `{"query":"MeshX web search MVP"}`),
		nativeToolResult(knowledgeWebReadFunction, `{"webRef":"w1"}`),
		nativeToolResult(knowledgeAnswerFunction, `{"claims":["MeshX web search MVP can use SearXNG search and HTTP reading. [E1]"]}`),
	}}
	runtime := &Runtime{
		Resolver: &Resolver{
			Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
				KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
				RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
			}}},
			Handles: handles, Clock: func() time.Time { return now },
		},
		Tools:             &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference:         inference,
		Checkpoints:       &memoryAccountingCheckpointStore{},
		Clock:             func() time.Time { return now },
		WebReadClient:     testWebReadClient(t, server.URL),
		WebSearchProvider: webSearch,
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "What is the web search MVP?", Model: "agentteam/model",
		ReasonLevel: "high", Capability: "signed-token", IdempotencyKey: "attempt-12345678",
		WebSearchEnabled: true,
	})

	require.NoError(t, err)
	require.Equal(t, "completed", result.Status)
	require.Equal(t, "MeshX web search MVP can use SearXNG search and HTTP reading. [E1]", result.Claims[0].Text)
	require.Len(t, result.Evidence, 1)
	require.Equal(t, CitationKindWeb, result.Evidence[0].Citation.CitationKind)
	require.Equal(t, publicURL, result.Evidence[0].Citation.URL)
	require.Equal(t, now.Format(time.RFC3339Nano), result.Evidence[0].Citation.FetchedAt)
	require.Equal(t, 1, result.ToolUsage.WebSearchCalls)
	require.Equal(t, 1, result.ToolUsage.WebReadCalls)
	require.Equal(t, 1, result.ToolUsage.WebSources)
	require.Zero(t, result.ToolUsage.ReadCalls)
	require.Equal(t, []string{"MeshX web search MVP"}, webSearch.queries)
	require.Len(t, inference.requests, 3)
	require.Contains(t, inference.requests[1].Messages[2].Content, `"webRef":"w1"`)
	require.NotContains(t, inference.requests[2].Messages[4].Content, `"citationKind"`, "model-visible tool result must not include server citation metadata")
}

func TestRuntimeCitationCoversEveryStreamedEvidenceLine(t *testing.T) {
	now := time.Date(2026, 7, 25, 10, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	repository := &fakeRepository{readByLine: true}
	runtime := &Runtime{
		Resolver: &Resolver{
			Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
				KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
				RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
			}}},
			Handles: handles, Clock: func() time.Time { return now },
		},
		Tools: &Service{
			Handles: handles, Repository: repository, Clock: func() time.Time { return now },
		},
		Inference: &fakeInference{result: nativeToolResult(
			knowledgeAnswerFunction, `{"claims":["Server hosted. [E1]"]}`,
		)},
		Checkpoints: &memoryAccountingCheckpointStore{},
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "Where is the server hosted?",
		Model: "agentteam/model", ReasonLevel: "high", Capability: "signed-token",
		IdempotencyKey: "attempt-12345678",
	})
	require.NoError(t, err)
	require.Equal(t, 9, result.Evidence[0].Citation.LineStart)
	require.Equal(t, 15, result.Evidence[0].Citation.LineEnd)
}

func TestRuntimeReturnsAnswerWithWarningOnInventedCitation(t *testing.T) {
	now := time.Date(2026, 7, 25, 10, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	runtime := &Runtime{
		Resolver: &Resolver{
			Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
				KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
				RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
			}}},
			Handles: handles, Clock: func() time.Time { return now },
		},
		Tools: &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference: &fakeInference{result: accountedToolResult(
			knowledgeAnswerFunction,
			`{"claims":["Invented. [E99]"]}`,
			map[string]any{"input_tokens": 7},
			"settlement_invalid",
		)},
		Checkpoints: &memoryAccountingCheckpointStore{},
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "server hosted",
		Model: "agentteam/model", ReasonLevel: "high", Capability: "signed-token",
		IdempotencyKey: "attempt-12345678",
	})
	require.NoError(t, err)
	require.Equal(t, "completed", result.Status)
	require.Empty(t, result.ErrorCode)
	require.Equal(t, "Invented. [E99]", result.Claims[0].Text)
	require.Empty(t, result.Evidence)
	require.Equal(t, []RuntimeDiagnostic{{
		Code: DiagnosticEvidenceUnavailable, Severity: "warning",
	}}, result.Diagnostics)
	require.Equal(t, float64(7), result.Usage["input_tokens"])
	require.Equal(t, "settlement_invalid", result.SettlementRef)
	require.Equal(t, []string{"settlement_invalid"}, result.SettlementRefs)
}

func TestRuntimeAcceptsAnswerWithoutCitationWarning(t *testing.T) {
	now := time.Date(2026, 7, 25, 10, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	runtime := &Runtime{
		Resolver: &Resolver{
			Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
				KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
				RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
			}}},
			Handles: handles, Clock: func() time.Time { return now },
		},
		Tools: &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference: &fakeInference{results: []InferenceResult{nativeToolResult(
			knowledgeAnswerFunction, `{"claims":["Answer without a citation."]}`,
		)}},
		Checkpoints: &memoryAccountingCheckpointStore{},
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "server hosted",
		Model: "agentteam/model", ReasonLevel: "high", Capability: "signed-token",
		IdempotencyKey: "attempt-12345678",
	})
	require.NoError(t, err)
	require.Equal(t, "completed", result.Status)
	require.Equal(t, "Answer without a citation.", result.Claims[0].Text)
	require.Empty(t, result.Evidence)
	require.Empty(t, result.Diagnostics)
	require.Equal(t, 0, result.ToolUsage.ReadCalls)
}

func TestRuntimeRetainsSettledUsageWhenGroundedResponseCannotBeDecoded(t *testing.T) {
	now := time.Date(2026, 7, 25, 10, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	inference := &fakeInference{results: []InferenceResult{
		{Usage: map[string]any{"input_tokens": 11, "output_tokens": 3}, SettlementRef: "settlement_malformed_1"},
		{Usage: map[string]any{"input_tokens": 13, "output_tokens": 5}, SettlementRef: "settlement_malformed_2"},
	}}
	runtime := &Runtime{
		Resolver: &Resolver{
			Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
				KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
				RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
			}}},
			Handles: handles, Clock: func() time.Time { return now },
		},
		Tools:       &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference:   inference,
		Checkpoints: &memoryAccountingCheckpointStore{},
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "server hosted",
		Model: "agentteam/model", ReasonLevel: "high", Capability: "signed-token",
		IdempotencyKey: "attempt-12345678",
	})
	require.NoError(t, err)
	require.Equal(t, "failed", result.Status)
	require.Equal(t, CodeResponseInvalid, result.ErrorCode)
	require.Empty(t, result.Claims)
	require.Empty(t, result.Evidence)
	require.Equal(t, float64(24), result.Usage["input_tokens"])
	require.Equal(t, float64(8), result.Usage["output_tokens"])
	require.Equal(t, "settlement_malformed_2", result.SettlementRef)
	require.Equal(t, []string{"settlement_malformed_1", "settlement_malformed_2"}, result.SettlementRefs)
	require.Equal(t, 6, result.ToolUsage.ModelCalls)
	require.Len(t, inference.requests, 6)
	require.Contains(t, inference.requests[1].System, `"repairAttempt":1`)
	require.Contains(t, inference.requests[5].System, `"repairAttempt":5`)
}

func TestRuntimeRetainsEarlierSettlementsWhenLaterExplorationCallFails(t *testing.T) {
	now := time.Date(2026, 7, 25, 10, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools: &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference: &fakeInference{
			results: []InferenceResult{accountedToolResult(
				knowledgeSearchFunction, `{"query":"server"}`,
				map[string]any{"input_tokens": 17}, "usage_first",
			)},
			errs: []error{nil, &Error{Code: "maas.unavailable", Message: "temporarily unavailable"}},
		},
		Checkpoints: &memoryAccountingCheckpointStore{},
	}
	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "server", Model: "agentteam/model", ReasonLevel: "high",
		Capability: "signed-token", IdempotencyKey: "attempt-12345678",
	})
	require.NoError(t, err)
	require.Equal(t, "failed", result.Status)
	require.Equal(t, "maas.unavailable", result.ErrorCode)
	require.Equal(t, float64(17), result.Usage["input_tokens"])
	require.Equal(t, "usage_first", result.SettlementRef)
	require.Equal(t, []string{"usage_first"}, result.SettlementRefs)
	require.Equal(t, 2, result.ToolUsage.ModelCalls)
}

func TestRuntimeRetainsCurrentSettlementWhenExplorationCallFails(t *testing.T) {
	now := time.Date(2026, 7, 25, 10, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools: &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference: &fakeInference{
			results: []InferenceResult{{
				Usage: map[string]any{"input_tokens": 19}, SettlementRef: "usage_failed_call",
			}},
			errs: []error{&Error{Code: "maas.unavailable", Message: "temporarily unavailable"}},
		},
		Checkpoints: &memoryAccountingCheckpointStore{},
	}
	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "server", Model: "agentteam/model", ReasonLevel: "high",
		Capability: "signed-token", IdempotencyKey: "attempt-12345678",
	})
	require.NoError(t, err)
	require.Equal(t, "failed", result.Status)
	require.Equal(t, "maas.unavailable", result.ErrorCode)
	require.Equal(t, float64(19), result.Usage["input_tokens"])
	require.Equal(t, "usage_failed_call", result.SettlementRef)
	require.Equal(t, []string{"usage_failed_call"}, result.SettlementRefs)
	require.Equal(t, 1, result.ToolUsage.ModelCalls)
}

func TestRuntimeDurablyCheckpointsAccountingBeforeCancellationReturns(t *testing.T) {
	now := time.Date(2026, 7, 25, 10, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	checkpoints := &memoryAccountingCheckpointStore{}
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	inference := &fakeInference{
		results: []InferenceResult{accountedToolResult(
			knowledgeSearchFunction, `{"query":"server"}`,
			map[string]any{"input_tokens": 17}, "usage_before_cancel",
		)},
		errs:     []error{nil, context.Canceled},
		cancelAt: 2,
		cancel:   cancel,
	}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools:       &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference:   inference,
		Checkpoints: checkpoints,
		Clock:       func() time.Time { return now },
	}
	result, err := runtime.Execute(ctx, ExecuteRequest{
		Principal: testPrincipal(), Question: "server", Model: "agentteam/model", ReasonLevel: "high",
		Capability: "signed-token", IdempotencyKey: "attempt-12345678",
	})
	require.NoError(t, err)
	require.Equal(t, "failed", result.Status)
	require.Equal(t, []string{"usage_before_cancel"}, result.SettlementRefs)
	require.Len(t, checkpoints.writes, 4)
	require.Equal(t, []int{0, 1, 2, 2}, []int{
		checkpoints.writes[0].Generation,
		checkpoints.writes[1].Generation,
		checkpoints.writes[2].Generation,
		checkpoints.writes[3].Generation,
	})
	require.Equal(t, []string{
		protocol.AccountingCheckpointRunning,
		protocol.AccountingCheckpointRunning,
		protocol.AccountingCheckpointRunning,
		protocol.AccountingCheckpointTerminal,
	}, []string{
		checkpoints.writes[0].State,
		checkpoints.writes[1].State,
		checkpoints.writes[2].State,
		checkpoints.writes[3].State,
	})
	require.Equal(t, []error{nil, nil, nil, nil}, checkpoints.writeContextErrors)
	require.Equal(t, protocol.AccountingCheckpointTerminal, checkpoints.checkpoint.State)
	require.Equal(t, 2, checkpoints.checkpoint.Generation)
	require.Equal(t, []string{"usage_before_cancel"}, checkpoints.checkpoint.SettlementRefs)

	recovered, err := runtime.RecoverAccounting(context.Background(), RecoverAccountingRequest{
		Principal: testPrincipal(), AttemptID: "attempt-12345678",
	})
	require.NoError(t, err)
	require.True(t, recovered.Found)
	require.True(t, recovered.Terminal)
	require.Equal(t, 2, recovered.Generation)
	require.Equal(t, []string{"usage_before_cancel"}, recovered.SettlementRefs)

	otherOwner := testPrincipal()
	otherOwner.RequesterID = "usr_other"
	recovered, err = runtime.RecoverAccounting(context.Background(), RecoverAccountingRequest{
		Principal: otherOwner, AttemptID: "attempt-12345678",
	})
	require.NoError(t, err)
	require.False(t, recovered.Found)
}

func TestRuntimeReportsAccountingCheckpointWriteFailureWithDedicatedCodeAndCause(t *testing.T) {
	now := time.Date(2026, 8, 2, 4, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	checkpoints := &memoryAccountingCheckpointStore{
		writeErrors: []error{nil, errors.New("checkpoint database unavailable")},
	}
	var logs bytes.Buffer
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools: &Service{
			Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now },
		},
		Inference: &fakeInference{results: []InferenceResult{accountedToolResult(
			knowledgeNoAnswerFunction, `{}`,
			map[string]any{"input_tokens": 11}, "usage_checkpoint_failed",
		)}},
		Checkpoints: checkpoints,
		Clock:       func() time.Time { return now },
		Logger:      slog.New(slog.NewJSONHandler(&logs, nil)),
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "sensitive question", Model: "agentteam/model",
		ReasonLevel: "high", Capability: "signed-token", IdempotencyKey: "attempt-12345678",
	})

	require.NoError(t, err)
	require.Equal(t, "failed", result.Status)
	require.Equal(t, CodeMaaSAccountingRecovery, result.ErrorCode)
	require.NotEqual(t, "knowledge_qa.inference_failed", result.ErrorCode)
	require.Equal(t, float64(11), result.Usage["input_tokens"])
	require.Equal(t, "usage_checkpoint_failed", result.SettlementRef)
	require.Equal(t, []string{"usage_checkpoint_failed"}, result.SettlementRefs)
	require.Equal(t, 1, result.ToolUsage.ModelCalls)
	require.Len(t, checkpoints.writes, 3)
	require.Equal(t, []string{
		protocol.AccountingCheckpointRunning,
		protocol.AccountingCheckpointRunning,
		protocol.AccountingCheckpointTerminal,
	}, []string{
		checkpoints.writes[0].State,
		checkpoints.writes[1].State,
		checkpoints.writes[2].State,
	})
	require.Contains(t, logs.String(), "Knowledge Q&A accounting checkpoint write failed")
	require.Contains(t, logs.String(), "checkpoint database unavailable")
	require.Contains(t, logs.String(), `"attempt_id":"attempt-12345678"`)
	require.Contains(t, logs.String(), `"generation":1`)
	require.NotContains(t, logs.String(), "sensitive question")
}

func TestRuntimeRendersOnlyGroundedClaims(t *testing.T) {
	now := time.Date(2026, 7, 25, 10, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	runtime := &Runtime{
		Resolver: &Resolver{
			Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
				KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
				RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
			}}},
			Handles: handles, Clock: func() time.Time { return now },
		},
		Tools: &Service{
			Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now },
		},
		Inference: &fakeInference{result: nativeToolResult(
			knowledgeAnswerFunction,
			"{\"claims\":[\"- Grounded item. [E1]\",\"```mermaid\\ngraph TD\\nA-->B\\n```\\n\\n[E1]\"]}",
		)},
		Checkpoints: &memoryAccountingCheckpointStore{},
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "Where is the server hosted?",
		Model: "agentteam/model", ReasonLevel: "high", Capability: "signed-token",
		IdempotencyKey: "attempt-12345678",
	})
	require.NoError(t, err)
	require.Equal(t, "completed", result.Status)
	require.Equal(t, "- Grounded item. [E1]", result.Claims[0].Text)
	require.Equal(t, "```mermaid\ngraph TD\nA-->B\n```\n\n[E1]", result.Claims[1].Text)
	require.Len(t, result.Evidence, 1)
}

func TestRuntimeReturnsNoAnswerWithoutCallingModelWhenNoReadyRoots(t *testing.T) {
	inference := &fakeInference{}
	runtime := &Runtime{
		Resolver:    &Resolver{Catalog: &fakeAuthorizedRootCatalog{}, Handles: &memoryHandleStore{}},
		Tools:       &Service{Handles: &memoryHandleStore{}, Repository: &fakeRepository{}},
		Inference:   inference,
		Checkpoints: &memoryAccountingCheckpointStore{},
	}
	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "server hosted",
		Model: "agentteam/model", ReasonLevel: "high", Capability: "signed-token",
		IdempotencyKey: "attempt-12345678",
	})
	require.NoError(t, err)
	require.Equal(t, "no_answer", result.Status)
	require.Zero(t, inference.calls)
	require.Zero(t, inference.profileCalls)
}

func TestRuntimeOpensCitationAtFrozenRevisionAfterLiveAuthorization(t *testing.T) {
	repository := &fakeRepository{}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: fakeCitationCatalog{
			root: AuthorizedRootCandidate{RepositoryRef: "repo-current"}, status: CitationStatusAvailable,
		}},
		Tools: &Service{Handles: &memoryHandleStore{}, Repository: repository},
	}
	result, err := runtime.OpenCitation(context.Background(), OpenCitationRequest{
		Principal: testPrincipal(),
		Citation: CitationMetadata{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-historical", Path: "docs/design.md",
			LineStart: 10, LineEnd: 12,
		},
	})
	require.NoError(t, err)
	require.Equal(t, CitationStatusAvailable, result.Status)
	require.Equal(t, CitationOpenModeSource, result.OpenMode)
	require.Equal(t, "sha-historical", repository.readSnapshot.Revision)
	require.Equal(t, "repo-current", repository.readSnapshot.RepositoryRef)
	require.Equal(t, "server hosted\n", result.Content)
}

func TestRuntimeOpensWebCitationAsExternalTarget(t *testing.T) {
	runtime := &Runtime{}
	result, err := runtime.OpenCitation(context.Background(), OpenCitationRequest{
		Principal: testPrincipal(),
		Citation: CitationMetadata{
			CitationKind: CitationKindWeb,
			URL:          "https://example.com/releases",
			Title:        "Release notes",
		},
	})
	require.NoError(t, err)
	require.Equal(t, CitationStatusAvailable, result.Status)
	require.Equal(t, "https://example.com/releases", result.TargetURL)
}

func TestRuntimeCapsRestrictedCitationEvidenceAtOriginalReadEnvelope(t *testing.T) {
	repository := &highVolumeRepository{readChunk: bytes.Repeat([]byte("x"), maxReadResultBytes+100)}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: fakeCitationCatalog{
			root:   AuthorizedRootCandidate{RepositoryRef: "repo-current"},
			status: CitationStatusAvailable,
			mode:   CitationOpenModeEvidence,
		}},
		Tools: &Service{Handles: &memoryHandleStore{}, Repository: repository},
	}
	result, err := runtime.OpenCitation(context.Background(), OpenCitationRequest{
		Principal: testPrincipal(),
		Citation: CitationMetadata{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-historical", Path: "docs/design.md",
			LineStart: 1, LineEnd: 1,
		},
	})
	require.NoError(t, err)
	require.Equal(t, CitationStatusAvailable, result.Status)
	require.Equal(t, CitationOpenModeEvidence, result.OpenMode)
	require.Len(t, result.Content, maxReadResultBytes)
	require.True(t, result.Truncated)
	require.Equal(t, 1, repository.readEmits)
}

func TestRuntimeUsesAccountBoundShareAuthorityOnlyForRestrictedEvidence(t *testing.T) {
	repository := &fakeRepository{}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: fakeCitationCatalog{
			status:       CitationStatusForbidden,
			sharedRoot:   AuthorizedRootCandidate{RepositoryRef: "repo-current"},
			sharedStatus: CitationStatusAvailable,
		}},
		Tools: &Service{Handles: &memoryHandleStore{}, Repository: repository},
	}
	result, err := runtime.OpenCitation(context.Background(), OpenCitationRequest{
		Principal: testPrincipal(), AllowRestrictedEvidence: true,
		Citation: CitationMetadata{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-historical", Path: "docs/design.md",
			LineStart: 10, LineEnd: 12,
		},
	})
	require.NoError(t, err)
	require.Equal(t, CitationStatusAvailable, result.Status)
	require.Equal(t, CitationOpenModeEvidence, result.OpenMode)
	require.Equal(t, "server hosted\n", result.Content)
	require.Equal(t, "repo-current", repository.readSnapshot.RepositoryRef)
}

func TestRuntimeRejectsCitationRangeBeyondOriginalReadEnvelope(t *testing.T) {
	repository := &highVolumeRepository{readChunk: []byte("x")}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: fakeCitationCatalog{
			root:   AuthorizedRootCandidate{RepositoryRef: "repo-current"},
			status: CitationStatusAvailable,
			mode:   CitationOpenModeEvidence,
		}},
		Tools: &Service{Handles: &memoryHandleStore{}, Repository: repository},
	}
	_, err := runtime.OpenCitation(context.Background(), OpenCitationRequest{
		Principal: testPrincipal(),
		Citation: CitationMetadata{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-historical", Path: "docs/design.md",
			LineStart: 1, LineEnd: maxReadLines + 1,
		},
	})
	require.Error(t, err)
	require.Equal(t, 0, repository.readEmits)
}

func TestRuntimeCitationOpenDistinguishesLiveAccessStates(t *testing.T) {
	for _, status := range []string{
		CitationStatusSourceDeleted, CitationStatusForbidden, CitationStatusRevisionUnavailable,
	} {
		runtime := &Runtime{
			Resolver: &Resolver{Catalog: fakeCitationCatalog{status: status}},
			Tools:    &Service{Handles: &memoryHandleStore{}, Repository: &fakeRepository{}},
		}
		result, err := runtime.OpenCitation(context.Background(), OpenCitationRequest{
			Principal: testPrincipal(), Citation: CitationMetadata{
				KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
				RepoRole: RepoRolePrimary, Revision: "sha-historical", Path: "docs/design.md",
				LineStart: 10, LineEnd: 12,
			},
		})
		require.NoError(t, err)
		require.Equal(t, status, result.Status)
		require.Empty(t, result.Content)
	}

	repository := &fakeRepository{readErr: errors.New("missing revision")}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: fakeCitationCatalog{
			root: AuthorizedRootCandidate{RepositoryRef: "repo-current"}, status: CitationStatusAvailable,
		}},
		Tools: &Service{Handles: &memoryHandleStore{}, Repository: repository},
	}
	result, err := runtime.OpenCitation(context.Background(), OpenCitationRequest{
		Principal: testPrincipal(), Citation: CitationMetadata{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "gone", Path: "docs/design.md", LineStart: 1, LineEnd: 1,
		},
	})
	require.NoError(t, err)
	require.Equal(t, CitationStatusRevisionUnavailable, result.Status)
}

func TestRuntimeHistoryIsNonEvidenceAndCurrentRootsStillSupplyCitations(t *testing.T) {
	now := time.Date(2026, 7, 25, 10, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	inference := &fakeInference{result: nativeToolResult(
		knowledgeAnswerFunction, `{"claims":["Current evidence. [E1]"]}`,
	)}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-current", RepositoryRef: "repo-current",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools:       &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference:   inference,
		Checkpoints: &memoryAccountingCheckpointStore{},
	}
	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "What about the second point above?", Model: "agentteam/model",
		ReasonLevel: "high", Capability: "signed-token", IdempotencyKey: "attempt-12345678",
		RuntimeContext: RuntimeContext{Turns: []ConversationHistoryTurn{{
			TurnID: "kqt_previous", Status: "completed", Question: "What changed?", Answer: "A historical statement.",
			Provenance: "conversation_history", Evidence: false,
		}}},
	})
	require.NoError(t, err)
	require.Equal(t, "completed", result.Status)
	require.Equal(t, "sha-current", result.Evidence[0].Citation.Revision)
	require.NotEmpty(t, inference.request.Messages)
	require.Contains(t, inference.request.Messages[0].Content, `"provenance":"conversation_history"`)
	require.Contains(t, inference.request.Messages[0].Content, `"evidence":false`)
}

func TestRuntimeCompactsOldestHistoryOnProviderContextOverflow(t *testing.T) {
	now := time.Date(2026, 7, 25, 10, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	deepSeekProfile, ok := lookupSupportedChatCompletionsProfile(chatCompletionsProfileDeepSeekV4ThinkingV1)
	require.True(t, ok)
	inference := &fakeInference{
		profile: deepSeekProfile,
		results: []InferenceResult{
			{},
			accountedToolResult(
				knowledgeContextSummaryFunction,
				`{"summary":"The user first asked about deployment and received the final answer server hosted."}`,
				map[string]any{"input_tokens": 8}, "usage_summary",
			),
			accountedToolResult(
				knowledgeNoAnswerFunction, `{}`,
				map[string]any{"input_tokens": 5}, "usage_answer",
			),
		},
		errs: []error{&Error{Code: "upstream.context_window.exceeded", Message: "context window exceeded"}},
	}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-current", RepositoryRef: "repo-current",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools:       &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference:   inference,
		Checkpoints: &memoryAccountingCheckpointStore{},
	}
	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "And what changed now?", Model: "agentteam/model",
		ReasonLevel: "high", Capability: "signed-token", IdempotencyKey: "attempt-12345678",
		RuntimeContext: RuntimeContext{Turns: []ConversationHistoryTurn{
			{TurnID: "kqt_1", Status: "completed", Question: "Where is it deployed?", Answer: "Server hosted.", Provenance: "conversation_history"},
			{TurnID: "kqt_2", Status: "no_answer", Question: "Was there a second option?", Provenance: "conversation_history"},
		}},
	})

	require.NoError(t, err)
	require.Equal(t, "no_answer", result.Status)
	require.NotNil(t, result.RuntimeContext)
	require.Equal(t, int64(0), result.RuntimeContext.ExpectedGeneration)
	require.Equal(t, "kqt_1", result.RuntimeContext.CompactedThroughTurnID)
	require.Equal(t, ContextSummaryVersion, result.RuntimeContext.SummaryVersion)
	require.Equal(t, 1, result.RuntimeContext.CompactedTurnCount)
	require.Equal(t, 3, result.ToolUsage.ModelCalls)
	require.Equal(t, []string{"usage_summary", "usage_answer"}, result.SettlementRefs)
	require.Equal(t, InferenceModeExploration, inference.requests[0].Mode)
	require.Equal(t, InferenceModeContextSummary, inference.requests[1].Mode)
	require.Equal(t, InferenceModeExploration, inference.requests[2].Mode)
	require.Equal(t, "low", inference.requests[1].ReasonLevel)
	require.Equal(t, contextSummaryMaxTokens, inference.requests[1].MaxOutputTokens)
	require.Equal(t, "attempt-12345678-step-01", inference.requests[0].IdempotencyKey)
	require.Equal(t, "attempt-12345678-step-02", inference.requests[1].IdempotencyKey)
	require.Equal(t, "attempt-12345678-step-03", inference.requests[2].IdempotencyKey)
	require.Equal(t, 1, inference.profileCalls)
	for _, inferenceRequest := range inference.requests {
		require.Equal(t, chatCompletionsProfileDeepSeekV4ThinkingV1, inferenceRequest.Profile.ID)
		require.Equal(t, "max_tokens", inferenceRequest.Profile.OutputTokenField)
	}
	require.Contains(t, inference.requests[2].Messages[0].Content, `"conversationSummary"`)
	require.NotContains(t, inference.requests[2].Messages[0].Content, `"turnId":"kqt_1"`)
	require.Contains(t, inference.requests[2].Messages[0].Content, `"turnId":"kqt_2"`)
}

func TestRuntimeKeepsDeepSeekReasoningOutOfResultsAndAccountingCheckpoints(t *testing.T) {
	now := time.Date(2026, 7, 29, 10, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	checkpoints := &memoryAccountingCheckpointStore{}
	profile, ok := lookupSupportedChatCompletionsProfile(chatCompletionsProfileDeepSeekV4ThinkingV1)
	require.True(t, ok)
	const secretReasoning = "provider-private-reasoning-sentinel"
	reasoning := secretReasoning
	search := accountedToolResult(
		knowledgeSearchFunction, `{"query":"server"}`,
		map[string]any{"input_tokens": 17}, "usage_search",
	)
	search.Message.ContentNull = false
	search.Message.Content = ""
	search.Message.ReasoningContent = &reasoning
	noAnswer := accountedToolResult(
		knowledgeNoAnswerFunction, `{}`,
		map[string]any{"input_tokens": 23}, "usage_no_answer",
	)
	noAnswer.Message.ContentNull = false
	noAnswer.Message.Content = ""
	noAnswer.Message.ReasoningContent = &reasoning
	inference := &fakeInference{
		profile: profile,
		results: []InferenceResult{
			search,
			noAnswer,
		},
	}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-current", RepositoryRef: "repo-current",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools:       &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference:   inference,
		Checkpoints: checkpoints,
		Clock:       func() time.Time { return now },
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "server", Model: "agentteam/model", ReasonLevel: "high",
		Capability: "signed-token", IdempotencyKey: "attempt-12345678",
	})
	require.NoError(t, err)
	require.Equal(t, "no_answer", result.Status)
	require.Len(t, inference.requests, 2)
	require.NotNil(t, inference.requests[1].Messages[1].ReasoningContent)
	require.Equal(t, secretReasoning, *inference.requests[1].Messages[1].ReasoningContent)

	resultJSON, err := json.Marshal(result)
	require.NoError(t, err)
	checkpointJSON, err := json.Marshal(checkpoints.writes)
	require.NoError(t, err)
	require.NotContains(t, string(resultJSON), secretReasoning)
	require.NotContains(t, string(resultJSON), "reasoning_content")
	require.NotContains(t, string(checkpointJSON), secretReasoning)
	require.NotContains(t, string(checkpointJSON), "reasoning_content")
}

func TestRuntimeFailsClosedWhenMaaSProfileCannotBeResolved(t *testing.T) {
	now := time.Date(2026, 7, 29, 10, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	checkpoints := &memoryAccountingCheckpointStore{}
	inference := &fakeInference{profileErr: &Error{
		Code:    "knowledge_qa.compatibility_profile_unavailable",
		Message: "Knowledge Q&A model compatibility is unavailable",
	}}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-current", RepositoryRef: "repo-current",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools:       &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference:   inference,
		Checkpoints: checkpoints,
		Clock:       func() time.Time { return now },
	}

	_, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "server", Model: "agentteam/model", ReasonLevel: "high",
		Capability: "signed-token", IdempotencyKey: "attempt-12345678",
	})
	var runtimeErr *Error
	require.ErrorAs(t, err, &runtimeErr)
	require.Equal(t, "knowledge_qa.compatibility_profile_unavailable", runtimeErr.Code)
	require.Equal(t, 1, inference.profileCalls)
	require.Zero(t, inference.calls)
	require.Len(t, checkpoints.writes, 2)
	require.Equal(t, protocol.AccountingCheckpointRunning, checkpoints.writes[0].State)
	require.Equal(t, protocol.AccountingCheckpointTerminal, checkpoints.writes[1].State)
	require.Zero(t, checkpoints.writes[1].Generation)
}

func TestRuntimeRejectsHistoryPresentedAsEvidence(t *testing.T) {
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{}, Handles: &memoryHandleStore{}},
		Tools:    &Service{Handles: &memoryHandleStore{}, Repository: &fakeRepository{}}, Inference: &fakeInference{},
		Checkpoints: &memoryAccountingCheckpointStore{},
	}
	_, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "above", Model: "agentteam/model", ReasonLevel: "high",
		Capability: "signed-token", IdempotencyKey: "attempt-12345678",
		RuntimeContext: RuntimeContext{Turns: []ConversationHistoryTurn{{
			TurnID: "kqt_previous", Status: "completed", Question: "above",
			Provenance: "conversation_history", Evidence: true,
		}}},
	})
	require.ErrorContains(t, err, "history provenance is invalid")
}

func TestRuntimeLetsModelRefineSearchBeforeReadingEvidence(t *testing.T) {
	now := time.Date(2026, 7, 25, 10, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	inference := &fakeInference{results: []InferenceResult{
		nativeToolResult(knowledgeListFunction, `{"rootAlias":"r1"}`),
		accountedToolResult(
			knowledgeSearchFunction, `{"query":"server"}`,
			map[string]any{"input_tokens": 10, "prompt_tokens_details": map[string]any{"cached_tokens": 4}},
			"usage_1",
		),
		accountedToolResult(
			knowledgeSearchFunction, `{"query":"server hosted","pathGlobs":["docs/*.md"]}`,
			map[string]any{"input_tokens": 20, "prompt_tokens_details": map[string]any{"cached_tokens": 6}},
			"usage_2",
		),
		nativeToolResult(knowledgeReadFunction, `{"fileRef":"f1","lineStart":1,"lineEnd":30}`),
		nativeToolResult(knowledgeAnswerFunction, `{"claims":["Grounded after refinement. [E1]"]}`),
	}}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools:       &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference:   inference,
		Checkpoints: &memoryAccountingCheckpointStore{},
	}
	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "How is the server hosted?", Model: "agentteam/model",
		ReasonLevel: "high", Capability: "signed-token", IdempotencyKey: "attempt-12345678",
	})
	require.NoError(t, err)
	require.Equal(t, "completed", result.Status)
	require.Equal(t, 2, result.ToolUsage.GrepCalls)
	require.Equal(t, 1, result.ToolUsage.ListCalls)
	require.Equal(t, 1, result.ToolUsage.ReadCalls)
	require.Equal(t, 5, result.ToolUsage.ModelCalls)
	require.Equal(t, 1, handles.loadCalls)
	require.Equal(t, float64(30), result.Usage["input_tokens"])
	require.Equal(t, float64(10), result.Usage["prompt_tokens_details"].(map[string]any)["cached_tokens"])
	require.Equal(t, "usage_2", result.SettlementRef)
	require.Equal(t, []string{"usage_1", "usage_2"}, result.SettlementRefs)
	require.Equal(t, "attempt-12345678-step-01", inference.requests[0].IdempotencyKey)
	require.Equal(t, "attempt-12345678-step-05", inference.requests[4].IdempotencyKey)
	require.Equal(t, InferenceModeExploration, inference.requests[1].Mode)
	require.Len(t, inference.requests[1].Messages, 3)
	assistant := inference.requests[1].Messages[1]
	tool := inference.requests[1].Messages[2]
	require.Equal(t, "assistant", assistant.Role)
	require.Len(t, assistant.ToolCalls, 1)
	require.Equal(t, knowledgeListFunction, assistant.ToolCalls[0].Function.Name)
	require.Equal(t, "tool", tool.Role)
	require.Equal(t, assistant.ToolCalls[0].ID, tool.ToolCallID)
	require.Contains(t, tool.Content, `"entries"`)
}

func TestRuntimeListsIssuedDirectoryWithMatchingRedundantRootAlias(t *testing.T) {
	now := time.Date(2026, 7, 31, 10, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	inference := &fakeInference{results: []InferenceResult{
		nativeToolResult(knowledgeListFunction, `{"rootAlias":"r1"}`),
		nativeToolResult(knowledgeListFunction, `{"rootAlias":"r1","directoryRef":"d1"}`),
		nativeToolResult(knowledgeNoAnswerFunction, `{}`),
	}}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools:       &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference:   inference,
		Checkpoints: &memoryAccountingCheckpointStore{},
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "What is in docs?", Model: "agentteam/model",
		ReasonLevel: "high", Capability: "signed-token", IdempotencyKey: "attempt-12345678",
	})

	require.NoError(t, err)
	require.Equal(t, "no_answer", result.Status)
	require.Empty(t, result.ErrorCode)
	require.Equal(t, 2, result.ToolUsage.ListCalls)
	require.Equal(t, 3, result.ToolUsage.ModelCalls)
	require.Len(t, inference.requests, 3)
	require.Len(t, inference.requests[2].Messages, 5)
	require.Contains(t, inference.requests[2].Messages[4].Content, `"path":"docs/design.md"`)
	require.NotContains(t, inference.requests[2].System, explorationInvalidResponseRepairSuffix)
}

func TestRuntimeRepairsReversedReadRangeWithSanitizedFeedback(t *testing.T) {
	now := time.Date(2026, 8, 3, 12, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	repository := &fakeRepository{}
	inference := &fakeInference{results: []InferenceResult{
		nativeToolResult(knowledgeReadFunction, `{"fileRef":"f1","lineStart":19,"lineEnd":7}`),
		nativeToolResult(knowledgeNoAnswerFunction, `{}`),
	}}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools:       &Service{Handles: handles, Repository: repository, Clock: func() time.Time { return now }},
		Inference:   inference,
		Checkpoints: &memoryAccountingCheckpointStore{},
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "server", Model: "agentteam/model", ReasonLevel: "high",
		Capability: "signed-token", IdempotencyKey: "attempt-12345678",
	})

	require.NoError(t, err)
	require.Equal(t, "no_answer", result.Status)
	require.Equal(t, 2, result.ToolUsage.ModelCalls)
	require.Zero(t, repository.readCalls)
	require.Len(t, inference.requests, 2)
	require.Len(t, inference.requests[1].Messages, 1, "the rejected call must not enter model history")
	repairPrompt := inference.requests[1].System
	require.Equal(t, explorationRepairFeedback{
		RepairAttempt: 1, MaxRepairAttempts: 5,
		Issues: []explorationRepairIssue{{
			CallIndex: 1, Tool: "knowledge_read", Code: "read_range_reversed", Field: "lineEnd",
			Requirement: "lineEnd must be greater than or equal to lineStart",
		}},
	}, repairFeedbackFromSystemPrompt(t, repairPrompt))
	require.NotContains(t, repairPrompt, `"lineStart":19`)
	require.NotContains(t, repairPrompt, `"lineEnd":7`)
}

func TestRuntimeDebugIncludesSanitizedToolValidationFailures(t *testing.T) {
	now := time.Date(2026, 8, 3, 12, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	invalid := nativeToolResult(knowledgeReadFunction, `{"fileRef":"f1","lineStart":19,"lineEnd":7}`)
	results := make([]InferenceResult, maxInvalidResponseRepairs+1)
	for index := range results {
		results[index] = invalid
		results[index].RawResponse = fmt.Sprintf(`{"invalidResponse":%d}`, index+1)
	}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools:            &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference:        &fakeInference{results: results},
		Checkpoints:      &memoryAccountingCheckpointStore{},
		DebugModelOutput: true,
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "server", Model: "agentteam/model", ReasonLevel: "high",
		Capability: "signed-token", IdempotencyKey: "attempt-12345678",
	})

	require.NoError(t, err)
	require.Equal(t, "failed", result.Status)
	require.Equal(t, CodeResponseInvalid, result.ErrorCode)
	require.Equal(t, maxInvalidResponseRepairs+1, result.ToolUsage.ModelCalls)
	debugJSON, lastModelOutput, found := strings.Cut(result.DebugModelOutput, explorationDebugModelOutputSeparator)
	require.True(t, found)
	var debugOutput explorationDebugOutput
	require.NoError(t, json.Unmarshal([]byte(debugJSON), &debugOutput))
	require.Len(t, debugOutput.InvalidResponses, maxInvalidResponseRepairs+1)
	for index, invalidResponse := range debugOutput.InvalidResponses {
		require.Equal(t, index+1, invalidResponse.ResponseNumber)
		require.Equal(t, []explorationRepairIssue{{
			CallIndex: 1, Tool: knowledgeReadFunction, Code: repairIssueReadRangeReversed.Code,
			Field: "lineEnd", Requirement: "lineEnd must be greater than or equal to lineStart",
		}}, invalidResponse.Issues)
	}
	require.Equal(t, results[len(results)-1].RawResponse, lastModelOutput)
}

func TestRuntimeRepairsUnissuedDirectoryReferenceUpToLimit(t *testing.T) {
	now := time.Date(2026, 7, 31, 11, 0, 0, 0, time.UTC)
	invalidList := nativeToolResult(
		knowledgeListFunction, `{"rootAlias":"r1","directoryRef":"d1"}`,
	)
	tests := []struct {
		name          string
		results       []InferenceResult
		wantStatus    string
		wantErrorCode string
		wantCalls     int
	}{
		{
			name: "repaired", results: []InferenceResult{invalidList, nativeToolResult(knowledgeNoAnswerFunction, `{}`)},
			wantStatus: "no_answer", wantCalls: 2,
		},
		{
			name: "repair exhausted", results: []InferenceResult{
				invalidList, invalidList, invalidList, invalidList, invalidList, invalidList,
			},
			wantStatus: "failed", wantErrorCode: CodeHandleRejected, wantCalls: 6,
		},
	}
	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			handles := &memoryHandleStore{}
			repository := &highVolumeRepository{resultCount: 1, listKind: "directory", listPath: "docs"}
			inference := &fakeInference{results: test.results}
			runtime := &Runtime{
				Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
					KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
					RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
				}}}, Handles: handles, Clock: func() time.Time { return now }},
				Tools:       &Service{Handles: handles, Repository: repository, Clock: func() time.Time { return now }},
				Inference:   inference,
				Checkpoints: &memoryAccountingCheckpointStore{},
			}

			result, err := runtime.Execute(context.Background(), ExecuteRequest{
				Principal: testPrincipal(), Question: "What is in docs?", Model: "agentteam/model",
				ReasonLevel: "high", Capability: "signed-token", IdempotencyKey: "attempt-12345678",
			})

			require.NoError(t, err)
			require.Equal(t, test.wantStatus, result.Status)
			require.Equal(t, test.wantErrorCode, result.ErrorCode)
			require.Equal(t, test.wantCalls, result.ToolUsage.ModelCalls)
			require.Zero(t, result.ToolUsage.ListCalls)
			require.Zero(t, repository.listEmits)
			require.Len(t, inference.requests, test.wantCalls)
			require.Contains(t, inference.requests[1].System, explorationInvalidResponseRepairSuffix)
			require.Equal(t, explorationRepairFeedback{
				RepairAttempt: 1, MaxRepairAttempts: 5,
				Issues: []explorationRepairIssue{{
					CallIndex: 1, Tool: "knowledge_list", Code: "reference_not_available",
					Requirement: "use only root, file, and directory references issued in the current exploration",
				}},
			}, repairFeedbackFromSystemPrompt(t, inference.requests[1].System))
			require.NotContains(t, inference.requests[1].System, `"directoryRef":"d1"`)
			require.Len(t, inference.requests[1].Messages, 1)
		})
	}
}

func TestRuntimePreflightsCompleteBatchBeforeReferenceRepair(t *testing.T) {
	now := time.Date(2026, 7, 31, 11, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	repository := &fakeRepository{}
	inference := &fakeInference{results: []InferenceResult{
		nativeToolBatch(
			InferenceToolCall{
				ID: "call_search", Type: "function",
				Function: InferenceFunctionCall{Name: knowledgeSearchFunction, Arguments: `{"query":"server"}`},
			},
			InferenceToolCall{
				ID: "call_list", Type: "function",
				Function: InferenceFunctionCall{
					Name: knowledgeListFunction, Arguments: `{"rootAlias":"r1","directoryRef":"d1"}`,
				},
			},
		),
		nativeToolResult(knowledgeNoAnswerFunction, `{}`),
	}}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools:       &Service{Handles: handles, Repository: repository, Clock: func() time.Time { return now }},
		Inference:   inference,
		Checkpoints: &memoryAccountingCheckpointStore{},
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "What is in docs?", Model: "agentteam/model",
		ReasonLevel: "high", Capability: "signed-token", IdempotencyKey: "attempt-12345678",
	})

	require.NoError(t, err)
	require.Equal(t, "no_answer", result.Status)
	require.Equal(t, 2, result.ToolUsage.ModelCalls)
	require.Zero(t, result.ToolUsage.GrepCalls)
	require.Zero(t, result.ToolUsage.ListCalls)
	require.Zero(t, repository.grepCalls)
	require.Contains(t, inference.requests[1].System, explorationInvalidResponseRepairSuffix)
}

func TestRuntimeRejectsDirectoryReferencePairedWithDifferentRoot(t *testing.T) {
	first := testRootHandle(time.Now().UTC())
	second := first
	second.ID = "kqr_second"
	second.RepositoryRef = "repo-second"
	repository := &ExecutionRepository{
		handles: map[string]protocol.RootHandle{first.ID: first, second.ID: second}, repository: &fakeRepository{},
	}
	refs := newExplorationReferences([]RootHandleView{{HandleID: first.ID}, {HandleID: second.ID}})
	usage := &ToolUsage{}
	_, err := (&Runtime{}).explorationList(
		context.Background(), repository, refs, knowledgeListArguments{RootAlias: "r1"}, usage,
	)
	require.NoError(t, err)

	outcome := &explorationOutcome{ToolUsage: *usage}
	result, code, err := (&Runtime{}).runExplorationAction(
		context.Background(), repository, refs,
		explorationAction{Name: knowledgeListFunction, List: knowledgeListArguments{
			RootAlias: "r2", DirectoryRef: "d1",
		}},
		make(map[string]struct{}), outcome,
	)

	require.NoError(t, err)
	require.Nil(t, result)
	require.Equal(t, CodeHandleRejected, code)
	require.Equal(t, 1, outcome.ToolUsage.ListCalls, "a cross-root selector must fail before repository I/O")
}

func TestRuntimeExecutesBoundedToolCallBatchInResponseOrder(t *testing.T) {
	now := time.Date(2026, 7, 29, 18, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	batch := nativeToolBatch(
		InferenceToolCall{
			ID: "call_search", Type: "function",
			Function: InferenceFunctionCall{Name: knowledgeSearchFunction, Arguments: `{"query":"MCP"}`},
		},
		InferenceToolCall{
			ID: "call_list", Type: "function",
			Function: InferenceFunctionCall{Name: knowledgeListFunction, Arguments: `{"rootAlias":"r1"}`},
		},
	)
	inference := &fakeInference{results: []InferenceResult{
		batch,
		nativeToolResult(knowledgeNoAnswerFunction, `{}`),
	}}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools:       &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference:   inference,
		Checkpoints: &memoryAccountingCheckpointStore{},
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "agentteam supports which MCP?", Model: "agentteam/model",
		ReasonLevel: "high", Capability: "signed-token", IdempotencyKey: "attempt-12345678",
	})

	require.NoError(t, err)
	require.Equal(t, "no_answer", result.Status)
	require.Equal(t, 1, result.ToolUsage.GrepCalls)
	require.Equal(t, 1, result.ToolUsage.ListCalls)
	require.Equal(t, 2, result.ToolUsage.ModelCalls)
	require.Len(t, inference.requests, 2)
	require.Len(t, inference.requests[1].Messages, 4)
	require.Equal(t, []InferenceToolCall(batch.Message.ToolCalls), inference.requests[1].Messages[1].ToolCalls)
	require.Equal(t, "call_search", inference.requests[1].Messages[2].ToolCallID)
	require.Equal(t, "call_list", inference.requests[1].Messages[3].ToolCallID)
	require.Contains(t, inference.requests[1].Messages[2].Content, `"matches"`)
	require.Contains(t, inference.requests[1].Messages[3].Content, `"entries"`)
}

func TestRuntimeContinuesPastLegacyExplorationResponseLimit(t *testing.T) {
	now := time.Date(2026, 7, 30, 1, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	const legacyResponseLimit = 24
	results := make([]InferenceResult, 0, legacyResponseLimit+1)
	for index := 0; index < legacyResponseLimit; index++ {
		results = append(results, nativeToolResult(
			knowledgeSearchFunction, fmt.Sprintf(`{"query":"server-%d"}`, index),
		))
	}
	results = append(results, nativeToolResult(knowledgeNoAnswerFunction, `{}`))
	inference := &fakeInference{results: results}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools:       &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference:   inference,
		Checkpoints: &memoryAccountingCheckpointStore{},
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "server", Model: "agentteam/model", ReasonLevel: "high",
		Capability: "signed-token", IdempotencyKey: "attempt-12345678",
	})

	require.NoError(t, err)
	require.Equal(t, "no_answer", result.Status)
	require.Equal(t, legacyResponseLimit+1, result.ToolUsage.ModelCalls)
	require.Equal(t, legacyResponseLimit, result.ToolUsage.GrepCalls)
	require.Len(t, inference.requests, legacyResponseLimit+1)
}

func TestRuntimeStopsAtAttemptActionBudgetWithoutAnotherModelCall(t *testing.T) {
	now := time.Date(2026, 7, 29, 18, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	results := make([]InferenceResult, 0, (maxExplorationActions+maxExplorationCallsPerResponse-1)/maxExplorationCallsPerResponse)
	for action := 0; action < maxExplorationActions; {
		batchSize := min(maxExplorationCallsPerResponse, maxExplorationActions-action)
		calls := make([]InferenceToolCall, batchSize)
		for index := range calls {
			calls[index] = InferenceToolCall{
				ID: fmt.Sprintf("call_list_%d", action+index), Type: "function",
				Function: InferenceFunctionCall{Name: knowledgeListFunction, Arguments: `{"rootAlias":"r1"}`},
			}
		}
		results = append(results, nativeToolBatch(calls...))
		action += batchSize
	}
	inference := &fakeInference{results: results}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools:           &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference:       inference,
		Checkpoints:     &memoryAccountingCheckpointStore{},
		MaxContextBytes: 64 << 20,
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "server", Model: "agentteam/model", ReasonLevel: "high",
		Capability: "signed-token", IdempotencyKey: "attempt-12345678",
	})

	require.NoError(t, err)
	require.Equal(t, "failed", result.Status)
	require.Equal(t, CodeResourceExhausted, result.ErrorCode)
	require.Equal(t, len(results), result.ToolUsage.ModelCalls)
	require.Equal(t, 1, result.ToolUsage.ListCalls)
	require.Len(t, inference.requests, len(results))
}

func TestRuntimeRepairsTerminalMixedWithExplorationBatchBeforeRepositoryIO(t *testing.T) {
	now := time.Date(2026, 7, 29, 18, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	repository := &fakeRepository{}
	batch := nativeToolBatch(
		InferenceToolCall{
			ID: "call_search", Type: "function",
			Function: InferenceFunctionCall{Name: knowledgeSearchFunction, Arguments: `{"query":"server"}`},
		},
		InferenceToolCall{
			ID: "call_no_answer", Type: "function",
			Function: InferenceFunctionCall{
				Name: knowledgeNoAnswerFunction, Arguments: `{}`,
			},
		},
	)
	inference := &fakeInference{results: []InferenceResult{
		batch,
		nativeToolResult(knowledgeNoAnswerFunction, `{}`),
	}}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools:       &Service{Handles: handles, Repository: repository, Clock: func() time.Time { return now }},
		Inference:   inference,
		Checkpoints: &memoryAccountingCheckpointStore{},
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "server", Model: "agentteam/model", ReasonLevel: "high",
		Capability: "signed-token", IdempotencyKey: "attempt-12345678",
	})

	require.NoError(t, err)
	require.Equal(t, "no_answer", result.Status)
	require.Empty(t, result.ErrorCode)
	require.Equal(t, 2, result.ToolUsage.ModelCalls)
	require.Zero(t, repository.grepCalls)
	require.Len(t, inference.requests, 2)
	require.Equal(t, explorationRepairFeedback{
		RepairAttempt: 1, MaxRepairAttempts: 5,
		Issues: []explorationRepairIssue{{
			CallIndex: 2, Tool: "knowledge_no_answer", Code: "terminal_call_not_exclusive",
			Requirement: "knowledge_answer or knowledge_no_answer must be the sole call in the response",
		}},
	}, repairFeedbackFromSystemPrompt(t, inference.requests[1].System))
}

func TestRuntimeRepairsCitationOnlyAnswerClaim(t *testing.T) {
	now := time.Date(2026, 8, 15, 10, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	inference := &fakeInference{results: []InferenceResult{
		nativeToolResult(knowledgeAnswerFunction, `{"claims":["[E1]"]}`),
		nativeToolResult(knowledgeAnswerFunction, `{"claims":["The runtime is server hosted."]}`),
	}}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools:       &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference:   inference,
		Checkpoints: &memoryAccountingCheckpointStore{},
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "Where is the runtime hosted?", Model: "agentteam/model",
		ReasonLevel: "high", Capability: "signed-token", IdempotencyKey: "attempt-12345678",
	})

	require.NoError(t, err)
	require.Equal(t, "completed", result.Status)
	require.Equal(t, "The runtime is server hosted.", result.Claims[0].Text)
	require.Equal(t, 2, result.ToolUsage.ModelCalls)
	require.Equal(t, explorationRepairFeedback{
		RepairAttempt: 1, MaxRepairAttempts: 5,
		Issues: []explorationRepairIssue{{
			CallIndex: 1, Tool: knowledgeAnswerFunction, Code: repairIssueAnswerClaimCitationOnly.Code,
			Field: "claims", Requirement: repairIssueAnswerClaimCitationOnly.Requirement,
		}},
	}, repairFeedbackFromSystemPrompt(t, inference.requests[1].System))
}

func TestRuntimeRepairsInvalidInferenceTransportResponseOnce(t *testing.T) {
	now := time.Date(2026, 7, 30, 3, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	inference := &fakeInference{
		results: []InferenceResult{
			{Usage: map[string]any{"input_tokens": 7}, SettlementRef: "invalid_response_usage"},
			nativeToolResult(knowledgeNoAnswerFunction, `{}`),
		},
		errs: []error{&Error{Code: CodeResponseInvalid, Message: "invalid upstream response"}, nil},
	}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools:       &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference:   inference,
		Checkpoints: &memoryAccountingCheckpointStore{},
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "server", Model: "agentteam/model", ReasonLevel: "high",
		Capability: "signed-token", IdempotencyKey: "attempt-12345678",
	})

	require.NoError(t, err)
	require.Equal(t, "no_answer", result.Status)
	require.Empty(t, result.ErrorCode)
	require.Equal(t, 2, result.ToolUsage.ModelCalls)
	require.Equal(t, float64(7), result.Usage["input_tokens"])
	require.Equal(t, []string{"invalid_response_usage"}, result.SettlementRefs)
	require.Len(t, inference.requests, 2)
	require.Equal(t, explorationRepairFeedback{
		RepairAttempt: 1, MaxRepairAttempts: 5,
		Issues: []explorationRepairIssue{{
			Code:        "response_contract_invalid",
			Requirement: "response must satisfy the native function-call contract",
		}},
	}, repairFeedbackFromSystemPrompt(t, inference.requests[1].System))
}

func TestRuntimeMaterializesExhaustedTransportInvalidResponsesWithoutAccountingOrDebug(t *testing.T) {
	now := time.Date(2026, 8, 3, 12, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	errs := make([]error, maxInvalidResponseRepairs+1)
	for index := range errs {
		errs[index] = &Error{Code: CodeResponseInvalid, Message: "invalid upstream response"}
	}
	inference := &fakeInference{errs: errs}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools:       &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference:   inference,
		Checkpoints: &memoryAccountingCheckpointStore{},
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "server", Model: "agentteam/model", ReasonLevel: "high",
		Capability: "signed-token", IdempotencyKey: "attempt-12345678",
	})

	require.NoError(t, err)
	require.Equal(t, "failed", result.Status)
	require.Equal(t, CodeResponseInvalid, result.ErrorCode)
	require.Equal(t, maxInvalidResponseRepairs+1, result.ToolUsage.ModelCalls)
	require.Empty(t, result.Usage)
	require.Empty(t, result.SettlementRef)
	require.Empty(t, result.SettlementRefs)
	require.Empty(t, result.DebugModelOutput)
	require.Len(t, inference.requests, maxInvalidResponseRepairs+1)
	require.Contains(t, inference.requests[len(inference.requests)-1].System, `"repairAttempt":5`)
}

func TestRuntimeDoesNotRetryMaaSAccountingRecovery(t *testing.T) {
	now := time.Date(2026, 7, 30, 4, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	checkpoints := &memoryAccountingCheckpointStore{}
	profile, ok := lookupSupportedChatCompletionsProfile(chatCompletionsProfileOpenAIRequiredToolsV1)
	require.True(t, ok)
	var modelCalls atomic.Int32
	var mu sync.Mutex
	idempotencyKeys := make([]string, 0, 2)
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, request *http.Request) {
		switch request.URL.Path {
		case "/maas/v1/models":
			require.Equal(t, http.MethodGet, request.Method)
			require.NoError(t, json.NewEncoder(w).Encode(map[string]any{
				"object": "list",
				"data": []any{map[string]any{
					"id":                                  "agentteam/model",
					"x_agentteam_executable_wire_api_families": []string{"chat_completions"},
					"x_agentteam_chat_completions_features": []string{
						"chat_completions.tools",
						"chat_completions.reasoning_effort",
						"chat_completions.parallel_tool_calls",
						"chat_completions.tool_choice",
					},
					"x_agentteam_chat_completions_compatibility_profile": profile,
				}},
			}))
		case "/maas/v1/chat/completions":
			require.Equal(t, http.MethodPost, request.Method)
			modelCalls.Add(1)
			mu.Lock()
			idempotencyKeys = append(idempotencyKeys, request.Header.Get("Idempotency-Key"))
			mu.Unlock()
			w.Header().Set("Content-Type", "application/json")
			_, _ = fmt.Fprint(w, `{"object":"hosted.request.status","request_status":"reconciliation_pending","usage_event_id":"hue_recovery_1","usage":{"input_tokens":7}}`)
		default:
			t.Fatalf("unexpected path: %s", request.URL.Path)
		}
	}))
	defer server.Close()
	client := MaaSClient{BaseURL: server.URL, HTTPClient: server.Client()}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools:       &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference:   client,
		Checkpoints: checkpoints,
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "server", Model: "agentteam/model", ReasonLevel: "high",
		Capability: "signed-token", IdempotencyKey: "attempt-12345678",
	})

	require.NoError(t, err)
	require.Equal(t, "failed", result.Status)
	require.Equal(t, "knowledge_qa.maas_accounting_recovery", result.ErrorCode)
	require.Equal(t, 1, result.ToolUsage.ModelCalls)
	require.Equal(t, float64(7), result.Usage["input_tokens"])
	require.Equal(t, "hue_recovery_1", result.SettlementRef)
	require.Equal(t, []string{"hue_recovery_1"}, result.SettlementRefs)
	require.Equal(t, int32(1), modelCalls.Load())
	require.Equal(t, []string{"attempt-12345678-step-01"}, idempotencyKeys)
	require.Equal(t, []string{"hue_recovery_1"}, checkpoints.checkpoint.SettlementRefs)
}

func TestRuntimeReturnsDuplicateActionAsMatchingToolResultWithoutReexecution(t *testing.T) {
	now := time.Date(2026, 7, 25, 10, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	inference := &fakeInference{results: []InferenceResult{
		nativeToolResult(knowledgeSearchFunction, `{"query":"server"}`),
		nativeToolResult(knowledgeSearchFunction, `{"query":"server"}`),
		nativeToolResult(knowledgeNoAnswerFunction, `{}`),
	}}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools:       &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference:   inference,
		Checkpoints: &memoryAccountingCheckpointStore{},
	}
	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "server", Model: "agentteam/model", ReasonLevel: "high",
		Capability: "signed-token", IdempotencyKey: "attempt-12345678",
	})
	require.NoError(t, err)
	require.Equal(t, "no_answer", result.Status)
	require.Equal(t, 1, result.ToolUsage.GrepCalls)
	require.Equal(t, 3, result.ToolUsage.ModelCalls)
	require.Len(t, inference.requests[2].Messages, 5)
	duplicateTool := inference.requests[2].Messages[4]
	require.Equal(t, "tool", duplicateTool.Role)
	require.Contains(t, duplicateTool.Content, `"error":"duplicate_action"`)
	require.Equal(t, inference.requests[2].Messages[3].ToolCalls[0].ID, duplicateTool.ToolCallID)
}

func TestRuntimeRejectsOversizedAssistantBeforeExecutingTool(t *testing.T) {
	now := time.Date(2026, 7, 25, 10, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	inferenceResult := nativeToolResult(knowledgeSearchFunction, `{"query":"server"}`)
	inferenceResult.Message.ContentNull = false
	inferenceResult.Message.Content = strings.Repeat("x", maxExplorationMessage)
	firstInferenceResult := inferenceResult
	firstInferenceResult.RawResponse = `{"model_output":"first invalid response"}`
	secondInferenceResult := inferenceResult
	secondInferenceResult.RawResponse = `{"model_output":"second invalid response"}`
	inference := &fakeInference{results: []InferenceResult{firstInferenceResult, secondInferenceResult}}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools:            &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference:        inference,
		Checkpoints:      &memoryAccountingCheckpointStore{},
		DebugModelOutput: true,
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "server", Model: "agentteam/model", ReasonLevel: "high",
		Capability: "signed-token", IdempotencyKey: "attempt-12345678",
	})
	require.NoError(t, err)
	require.Equal(t, "failed", result.Status)
	require.Equal(t, CodeResponseInvalid, result.ErrorCode)
	require.Equal(t, 6, result.ToolUsage.ModelCalls)
	require.Zero(t, result.ToolUsage.GrepCalls)
	require.Len(t, inference.requests, 6)
	require.Contains(t, inference.requests[1].System, `"repairAttempt":1`)
	debugJSON, lastModelOutput, found := strings.Cut(result.DebugModelOutput, explorationDebugModelOutputSeparator)
	require.True(t, found)
	var debugOutput explorationDebugOutput
	require.NoError(t, json.Unmarshal([]byte(debugJSON), &debugOutput))
	require.Len(t, debugOutput.InvalidResponses, 6)
	require.Equal(t, repairIssueResponseContractInvalid.Code, debugOutput.InvalidResponses[0].Issues[0].Code)
	require.Equal(t, secondInferenceResult.RawResponse, lastModelOutput)
}

func TestRuntimeDoesNotExposeCapturedModelOutputWithoutDebugMode(t *testing.T) {
	now := time.Date(2026, 7, 30, 4, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	invalid := InferenceResult{RawResponse: `{"model_output":"must remain hidden"}`}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools:       &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference:   &fakeInference{results: []InferenceResult{invalid, invalid}},
		Checkpoints: &memoryAccountingCheckpointStore{},
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "server", Model: "agentteam/model", ReasonLevel: "high",
		Capability: "signed-token", IdempotencyKey: "attempt-12345678",
	})

	require.NoError(t, err)
	require.Equal(t, "failed", result.Status)
	require.Equal(t, CodeResponseInvalid, result.ErrorCode)
	require.Empty(t, result.DebugModelOutput)
}

func TestRenderExplorationFailureReturnsDebugOutputWithoutSettlement(t *testing.T) {
	const rawResponse = `{"model_output":"invalid transport response"}`
	result, err := renderExplorationResult(
		ExecuteResult{},
		explorationOutcome{DebugModelOutput: rawResponse},
		&Error{Code: CodeResponseInvalid, Message: "invalid response"},
	)

	require.NoError(t, err)
	require.Equal(t, "failed", result.Status)
	require.Equal(t, CodeResponseInvalid, result.ErrorCode)
	require.Equal(t, rawResponse, result.DebugModelOutput)
}

func TestRuntimeContextBudgetRejectsAssistantBeforeTerminalOrRepositoryIO(t *testing.T) {
	for _, test := range []struct {
		name      string
		function  string
		arguments string
	}{
		{name: "repository action", function: knowledgeSearchFunction, arguments: `{"query":"server"}`},
		{name: "terminal", function: knowledgeNoAnswerFunction, arguments: `{}`},
	} {
		t.Run(test.name, func(t *testing.T) {
			now := time.Date(2026, 7, 25, 10, 0, 0, 0, time.UTC)
			handle := testRootHandle(now)
			root := rootHandleView(handle)
			question := "server"
			inferenceResult := nativeToolResult(test.function, test.arguments)
			repository := &fakeRepository{}
			runtime := &Runtime{
				Resolver: &Resolver{},
				Tools: &Service{
					Handles:    &memoryHandleStore{handles: map[string]protocol.RootHandle{handle.ID: handle}},
					Repository: repository, Clock: func() time.Time { return now },
				},
				Inference:   &fakeInference{results: []InferenceResult{inferenceResult}},
				Checkpoints: &memoryAccountingCheckpointStore{},
				Clock:       func() time.Time { return now },
			}
			assistantContextBytes := explorationContextBytes(
				t, question, []RootHandleView{root}, inferenceResult.Message,
			)
			runtime.MaxContextBytes = assistantContextBytes - 1

			result, err := runtime.Execute(context.Background(), ExecuteRequest{
				Principal: testPrincipal(), RootHandleIDs: []string{handle.ID}, Question: question,
				Model: "agentteam/model", ReasonLevel: "high", Capability: "signed-token",
				IdempotencyKey: "attempt-12345678",
			})
			require.NoError(t, err)
			require.Equal(t, "failed", result.Status)
			require.Equal(t, CodeResourceExhausted, result.ErrorCode)
			require.Equal(t, 1, result.ToolUsage.ModelCalls)
			require.Zero(t, repository.grepCalls)
		})
	}
}

func TestRuntimeContextBudgetReturnsBoundedBatchErrorBeforeRepositoryIO(t *testing.T) {
	now := time.Date(2026, 7, 25, 10, 0, 0, 0, time.UTC)
	handle := testRootHandle(now)
	root := rootHandleView(handle)
	question := "server"
	inferenceResult := nativeToolResult(knowledgeSearchFunction, `{"query":"server"}`)
	noAnswerResult := nativeToolResult(knowledgeNoAnswerFunction, `{}`)
	call := inferenceToolCall(inferenceResult)
	repository := &fakeRepository{}
	inference := &fakeInference{results: []InferenceResult{inferenceResult, noAnswerResult}}
	runtime := &Runtime{
		Resolver: &Resolver{},
		Tools: &Service{
			Handles:    &memoryHandleStore{handles: map[string]protocol.RootHandle{handle.ID: handle}},
			Repository: repository, Clock: func() time.Time { return now },
		},
		Inference:   inference,
		Checkpoints: &memoryAccountingCheckpointStore{},
		Clock:       func() time.Time { return now },
	}
	projectedToolMessage, err := projectedExplorationToolMessage(call.ID, call.Function.Name)
	require.NoError(t, err)
	projectedContextBytes := explorationContextBytes(
		t, question, []RootHandleView{root}, inferenceResult.Message, projectedToolMessage,
	)
	runtime.MaxContextBytes = projectedContextBytes - 1

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), RootHandleIDs: []string{handle.ID}, Question: question,
		Model: "agentteam/model", ReasonLevel: "high", Capability: "signed-token",
		IdempotencyKey: "attempt-12345678",
	})
	require.NoError(t, err)
	require.Equal(t, "no_answer", result.Status)
	require.Empty(t, result.ErrorCode)
	require.Equal(t, 2, result.ToolUsage.ModelCalls)
	require.Zero(t, repository.grepCalls)
	require.Len(t, inference.requests, 2)
	require.Len(t, inference.requests[1].Messages, 3)
	require.Equal(t, "tool", inference.requests[1].Messages[2].Role)
	require.Equal(t, call.ID, inference.requests[1].Messages[2].ToolCallID)
	require.JSONEq(t, `{"ok":false,"error":"batch_too_large","hint":"retry with fewer calls in one response"}`, inference.requests[1].Messages[2].Content)
}

func TestRuntimeSplitsProjectedReadBatchThroughModelFeedback(t *testing.T) {
	now := time.Date(2026, 7, 30, 2, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	const projectedReadCalls = 10
	calls := make([]InferenceToolCall, projectedReadCalls)
	for index := range calls {
		calls[index] = InferenceToolCall{
			ID: fmt.Sprintf("call_read_%d", index), Type: "function",
			Function: InferenceFunctionCall{
				Name: knowledgeReadFunction, Arguments: `{"fileRef":"f1","lineStart":1,"lineEnd":2}`,
			},
		}
	}
	inference := &fakeInference{results: []InferenceResult{
		nativeToolBatch(calls...),
		nativeToolResult(knowledgeNoAnswerFunction, `{}`),
	}}
	repository := &fakeRepository{}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools:       &Service{Handles: handles, Repository: repository, Clock: func() time.Time { return now }},
		Inference:   inference,
		Checkpoints: &memoryAccountingCheckpointStore{},
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "server", Model: "agentteam/model", ReasonLevel: "high",
		Capability: "signed-token", IdempotencyKey: "attempt-12345678",
	})

	require.NoError(t, err)
	require.Equal(t, "no_answer", result.Status)
	require.Empty(t, result.ErrorCode)
	require.Equal(t, 2, result.ToolUsage.ModelCalls)
	require.Zero(t, repository.readCalls)
	require.Len(t, inference.requests, 2)
	require.Len(t, inference.requests[1].Messages, projectedReadCalls+2)
	for index, call := range calls {
		message := inference.requests[1].Messages[index+2]
		require.Equal(t, "tool", message.Role)
		require.Equal(t, call.ID, message.ToolCallID)
		require.Contains(t, message.Content, `"error":"batch_too_large"`)
	}
}

func TestRuntimeExploresNamedBranchAndReturnsConfirmableSourceChange(t *testing.T) {
	now := time.Date(2026, 8, 4, 14, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	inference := &fakeInference{results: []InferenceResult{
		nativeToolResult(knowledgeRefFunction, `{"rootAlias":"r1","ref":"v7.1.9-0","refType":"branch"}`),
		nativeToolResult(knowledgeSearchFunction, `{"query":"stored procedure","rootAliases":["r2"]}`),
		nativeToolResult(knowledgeReadFunction, `{"fileRef":"f1","lineStart":12,"lineEnd":12}`),
		nativeToolResult(knowledgeAnswerFunction, `{"claims":["目标分支包含存储过程实现。[E1]"],"sourceBranchChange":{"branchRootAlias":"r2"}}`),
	}}
	repository := &fakeRepository{refSHA: strings.Repeat("c", 40)}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", SourceName: "tidb",
			RootKind: RootKindPrimary, RepoRole: RepoRoleMirror,
			Revision: "sha-current", RepositoryRef: "repo-internal-1", DefaultRef: "pingcap-master",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools:       &Service{Handles: handles, Repository: repository, Clock: func() time.Time { return now }},
		Inference:   inference,
		Checkpoints: &memoryAccountingCheckpointStore{},
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "确认 v7.1.9-0 并把 tidb 来源切换到该分支",
		Model: "agentteam/model", ReasonLevel: "high", Capability: "signed-token",
		IdempotencyKey: "attempt-branch-change",
	})

	require.NoError(t, err)
	require.Equal(t, "completed", result.Status)
	require.Equal(t, 1, result.ToolUsage.RefCalls)
	require.Equal(t, strings.Repeat("c", 40), result.Evidence[0].Citation.Revision)
	require.Equal(t, &SourceBranchChangeProposal{
		KnowledgeBaseID: "kb_1", SourceID: "src_1",
		CurrentRef: "pingcap-master", TargetRef: "v7.1.9-0",
	}, result.SourceBranchChange)
	require.Len(t, inference.requests, 4)
	require.Contains(t, inference.requests[0].Messages[0].Content, `"sourceName":"tidb"`)
	require.Contains(t, inference.requests[0].Messages[0].Content, `"defaultRef":"pingcap-master"`)
}

func TestRuntimeExploresNamedTagAndKeepsCitationOnPeeledCommit(t *testing.T) {
	now := time.Date(2026, 8, 5, 1, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	inference := &fakeInference{results: []InferenceResult{
		nativeToolResult(knowledgeRefFunction, `{"rootAlias":"r1","ref":"v7.1.9-0","refType":"tag"}`),
		nativeToolResult(knowledgeSearchFunction, `{"query":"stored procedure","rootAliases":["r2"]}`),
		nativeToolResult(knowledgeReadFunction, `{"fileRef":"f1","lineStart":12,"lineEnd":12}`),
		nativeToolResult(knowledgeAnswerFunction, `{"claims":["该 Tag 包含存储过程实现。[E1]"]}`),
	}}
	repository := &fakeRepository{refSHA: strings.Repeat("d", 40)}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", SourceName: "tidb",
			RootKind: RootKindPrimary, RepoRole: RepoRoleMirror,
			Revision: "sha-current", RepositoryRef: "repo-internal-1", DefaultRef: "pingcap-master",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools:       &Service{Handles: handles, Repository: repository, Clock: func() time.Time { return now }},
		Inference:   inference,
		Checkpoints: &memoryAccountingCheckpointStore{},
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "v7.1.9-0 这个 Git Tag 中如何实现存储过程？",
		Model: "agentteam/model", ReasonLevel: "high", Capability: "signed-token",
		IdempotencyKey: "attempt-tag-query",
	})

	require.NoError(t, err)
	require.Equal(t, "completed", result.Status)
	require.Equal(t, 1, result.ToolUsage.RefCalls)
	require.Nil(t, result.SourceBranchChange)
	require.Equal(t, strings.Repeat("d", 40), result.Evidence[0].Citation.Revision)
	require.Equal(t, "v7.1.9-0", result.Evidence[0].Citation.ResolvedRef)
	require.Equal(t, RefKindTag, result.Evidence[0].Citation.ResolvedRefKind)
}

func TestTagRootCannotProposeSourceDefaultBranchChange(t *testing.T) {
	refs := newExplorationReferences([]RootHandleView{{HandleID: "kqr_1"}})
	alias := refs.addRefRoot(RefSnapshot{
		HandleID: "kqf_tag", RepoRole: RepoRoleMirror, CurrentRef: "main",
		TargetRef: "v7.1.9-0", RefKind: RefKindTag,
	}, "r1")
	action := explorationAction{
		Name: knowledgeAnswerFunction,
		Answer: knowledgeAnswerArguments{SourceBranchChange: &knowledgeSourceBranchChangeArguments{
			BranchRootAlias: alias,
		}},
	}

	require.Equal(t, CodeHandleRejected, normalizeExplorationActionReferences(refs, &action))
}

func TestInferenceMessageSizeChargesExactSerializedToolEnvelope(t *testing.T) {
	message := InferenceMessage{
		Role: "tool", ToolCallID: "call_1", Content: `{"ok":true,"path":"docs/design.md"}`,
	}
	payload, err := inferenceMessagePayload(message)
	require.NoError(t, err)
	encoded, err := json.Marshal(payload)
	require.NoError(t, err)
	require.Equal(t, len(encoded), inferenceMessageSize(message))
	require.Greater(t, inferenceMessageSize(message), len(message.Content))
}

func TestProjectedReadEnvelopeCoversAdversarialJSONEscaping(t *testing.T) {
	projected, err := projectedExplorationToolMessage("call_read", knowledgeReadFunction)
	require.NoError(t, err)
	actualResult, err := json.Marshal(explorationReadResult{
		OK: true,
		Evidence: &explorationReadEvidence{
			ID: "E128", FileRef: strings.Repeat("f", maxReferenceBytes),
			Path:      strings.Repeat("\x00", maxListResultBytes),
			LineStart: 1, LineEnd: maxReadLines,
			Content: strings.Repeat("\x00", maxReadResultBytes),
		},
		Truncated: true,
	})
	require.NoError(t, err)
	actual := InferenceMessage{Role: "tool", ToolCallID: "call_read", Content: string(actualResult)}
	require.LessOrEqual(t, inferenceMessageSize(actual), inferenceMessageSize(projected))

	assistant := nativeToolResult(
		knowledgeReadFunction, `{"fileRef":"f1","lineStart":1,"lineEnd":1000}`,
	).Message
	require.Less(
		t,
		explorationContextBytes(t, "server", []RootHandleView{}, assistant, projected),
		defaultExplorationBytes,
	)
}

func explorationContextBytes(
	t *testing.T, question string, roots []RootHandleView, additions ...InferenceMessage,
) int {
	t.Helper()
	initial, err := explorationInitialMessage(question, RuntimeContext{}, roots, newExplorationReferences(roots))
	require.NoError(t, err)
	messages := appendInferenceMessages(
		[]InferenceMessage{{Role: "user", Content: initial}}, additions...,
	)
	size, err := inferenceContextSize(InferenceModeExploration, explorationSystemPrompt(question), messages, false)
	require.NoError(t, err)
	return size
}

func TestRuntimeExplorationHonorsCancellation(t *testing.T) {
	now := time.Date(2026, 7, 25, 10, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools:       &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference:   &fakeInference{},
		Checkpoints: &memoryAccountingCheckpointStore{},
	}
	ctx, cancel := context.WithCancel(context.Background())
	cancel()
	_, err := runtime.Execute(ctx, ExecuteRequest{
		Principal: testPrincipal(), Question: "server", Model: "agentteam/model", ReasonLevel: "high",
		Capability: "signed-token", IdempotencyKey: "attempt-12345678",
	})
	var runtimeErr *Error
	require.ErrorAs(t, err, &runtimeErr)
	require.Equal(t, CodeCanceled, runtimeErr.Code)
	require.Empty(t, handles.handles)
}

func TestRuntimeCleanupPreservesRetryHandlesForSameTurn(t *testing.T) {
	now := time.Date(2026, 7, 25, 10, 0, 0, 0, time.UTC)
	first := testRootHandle(now)
	retry := first
	retry.ID = "kqr_retry"
	handles := &memoryHandleStore{handles: map[string]protocol.RootHandle{first.ID: first, retry.ID: retry}}
	runtime := &Runtime{
		Resolver: &Resolver{},
		Tools:    &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference: &fakeInference{results: []InferenceResult{nativeToolResult(
			knowledgeNoAnswerFunction, `{}`,
		)}},
		Checkpoints: &memoryAccountingCheckpointStore{},
		Clock:       func() time.Time { return now },
	}

	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), RootHandleIDs: []string{first.ID}, Question: "server",
		Model: "agentteam/model", ReasonLevel: "high", Capability: "signed-token", IdempotencyKey: "attempt-12345678",
	})
	require.NoError(t, err)
	require.Equal(t, "no_answer", result.Status)
	require.NotContains(t, handles.handles, first.ID)
	require.Contains(t, handles.handles, retry.ID, "an older execution must not revoke a newer retry's capabilities")
}

func TestRuntimeCleansFreshHandlesWhenExecutionAuthorizationFails(t *testing.T) {
	now := time.Date(2026, 7, 25, 10, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{loadErrAt: 1}
	runtime := &Runtime{
		Resolver: &Resolver{
			Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
				KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
				RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
			}}},
			Handles: handles,
			Clock:   func() time.Time { return now },
		},
		Tools:       &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference:   &fakeInference{},
		Checkpoints: &memoryAccountingCheckpointStore{},
		Clock:       func() time.Time { return now },
	}

	_, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "server", Model: "agentteam/model", ReasonLevel: "high",
		Capability: "signed-token", IdempotencyKey: "attempt-12345678",
	})
	require.Error(t, err)
	require.Empty(t, handles.handles, "failed session construction must not leak minted capabilities until TTL expiry")
}

func TestRuntimeExplorationFailsStructurallyAtContextBudget(t *testing.T) {
	now := time.Date(2026, 7, 25, 10, 0, 0, 0, time.UTC)
	handles := &memoryHandleStore{}
	runtime := &Runtime{
		Resolver: &Resolver{Catalog: &fakeAuthorizedRootCatalog{candidates: []AuthorizedRootCandidate{{
			KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: RootKindPrimary,
			RepoRole: RepoRolePrimary, Revision: "sha-fixed", RepositoryRef: "repo-internal-1",
		}}}, Handles: handles, Clock: func() time.Time { return now }},
		Tools: &Service{Handles: handles, Repository: &fakeRepository{}, Clock: func() time.Time { return now }},
		Inference: &fakeInference{results: []InferenceResult{nativeToolResult(
			knowledgeSearchFunction, `{"query":"server"}`,
		)}},
		Checkpoints:     &memoryAccountingCheckpointStore{},
		MaxContextBytes: 1,
	}
	result, err := runtime.Execute(context.Background(), ExecuteRequest{
		Principal: testPrincipal(), Question: "server", Model: "agentteam/model", ReasonLevel: "high",
		Capability: "signed-token", IdempotencyKey: "attempt-12345678",
	})
	require.NoError(t, err)
	require.Equal(t, "failed", result.Status)
	require.Equal(t, CodeResourceExhausted, result.ErrorCode)
	require.Zero(t, result.ToolUsage.ModelCalls)
}

func TestExplorationStopsRepositoryStreamsAtModelVisibleLimits(t *testing.T) {
	handle := testRootHandle(time.Now().UTC())
	repository := &highVolumeRepository{resultCount: maxListResults + 100, distinctPaths: true}
	session := &ExecutionRepository{handles: map[string]protocol.RootHandle{handle.ID: handle}, repository: repository}
	runtime := &Runtime{}
	refs := newExplorationReferences([]RootHandleView{{HandleID: handle.ID}})
	usage := &ToolUsage{}

	search, err := runtime.explorationSearch(
		context.Background(), session, refs, knowledgeSearchArguments{Query: "server"}, usage,
	)
	require.NoError(t, err)
	require.True(t, search.Truncated)
	require.Len(t, search.Matches, maxSearchResults)
	require.Equal(t, maxSearchResults+1, repository.grepEmits)
	require.Equal(t, searchRefinementHint, search.Hint)
	modelSearch, err := json.Marshal(search)
	require.NoError(t, err)
	require.LessOrEqual(t, len(modelSearch), maxSearchResultBytes)
	require.NotContains(t, string(modelSearch), `"citation"`)
	require.NotContains(t, string(modelSearch), handle.Revision)
	require.NotContains(t, string(modelSearch), handle.ID)
	_, resolvesRejectedSearchRef := refs.resolveFile("f51")
	require.False(t, resolvesRejectedSearchRef)

	byteBoundRepository := &highVolumeRepository{
		resultCount: 2, grepPreview: strings.Repeat("x", maxSearchResultBytes),
	}
	byteBoundSession := &ExecutionRepository{
		handles: map[string]protocol.RootHandle{handle.ID: handle}, repository: byteBoundRepository,
	}
	byteBoundRefs := newExplorationReferences([]RootHandleView{{HandleID: handle.ID}})
	byteBoundSearch, err := runtime.explorationSearch(
		context.Background(), byteBoundSession,
		byteBoundRefs,
		knowledgeSearchArguments{Query: "server"}, &ToolUsage{},
	)
	require.NoError(t, err)
	require.True(t, byteBoundSearch.Truncated)
	require.Empty(t, byteBoundSearch.Matches)
	require.Equal(t, 1, byteBoundRepository.grepEmits)
	encodedByteBoundSearch, err := json.Marshal(byteBoundSearch)
	require.NoError(t, err)
	require.LessOrEqual(t, len(encodedByteBoundSearch), maxSearchResultBytes)
	_, resolvesOversizedSearchRef := byteBoundRefs.resolveFile("f1")
	require.False(t, resolvesOversizedSearchRef)

	listed, err := runtime.explorationList(
		context.Background(), session, refs, knowledgeListArguments{RootAlias: "r1"}, usage,
	)
	require.NoError(t, err)
	require.True(t, listed.Truncated)
	require.Len(t, listed.Entries, maxListResults)
	require.Equal(t, maxListResults+1, repository.listEmits)
	_, resolvesRejectedListRef := refs.resolveFile("f501")
	require.False(t, resolvesRejectedListRef)

	repository.readChunk = bytes.Repeat([]byte("x"), maxReadResultBytes/2)
	read, evidence, err := runtime.explorationRead(
		context.Background(), session, refs,
		knowledgeReadArguments{FileRef: "f1", LineStart: 1, LineEnd: 10}, 1, usage,
	)
	require.NoError(t, err)
	require.True(t, read.Truncated)
	require.NotNil(t, evidence)
	require.Len(t, evidence.Content, maxReadResultBytes)
	require.Equal(t, 3, repository.readEmits)
}

func TestExplorationSearchByteAccountingAndReferenceAdmission(t *testing.T) {
	handle := testRootHandle(time.Now().UTC())
	runtime := &Runtime{}

	searchEnvelope, err := json.Marshal(explorationSearchResult{
		OK: true, Matches: []explorationSearchMatch{}, Truncated: true, Hint: searchRefinementHint,
	})
	require.NoError(t, err)
	searchCandidate, err := json.Marshal(explorationSearchMatch{
		FileRef: "f1", RootAlias: "r1", Path: "docs/design-0.md", Line: 1, Preview: "x",
	})
	require.NoError(t, err)
	previewBytes := maxSearchResultBytes - len(searchEnvelope) - len(searchCandidate) + 1
	require.Positive(t, previewBytes)
	searchRepository := &highVolumeRepository{
		resultCount: 2, distinctPaths: true, grepPreview: strings.Repeat("x", previewBytes),
	}
	searchSession := &ExecutionRepository{
		handles: map[string]protocol.RootHandle{handle.ID: handle}, repository: searchRepository,
	}
	searchRefs := newExplorationReferences([]RootHandleView{{HandleID: handle.ID}})
	search, err := runtime.explorationSearch(
		context.Background(), searchSession, searchRefs, knowledgeSearchArguments{Query: "server"}, &ToolUsage{},
	)
	require.NoError(t, err)
	require.True(t, search.Truncated)
	require.Len(t, search.Matches, 1)
	encodedSearch, err := json.Marshal(search)
	require.NoError(t, err)
	require.Len(t, encodedSearch, maxSearchResultBytes)
	require.Equal(t, "f1", search.Matches[0].FileRef)
	_, resolvesRejectedSearchRef := searchRefs.resolveFile("f2")
	require.False(t, resolvesRejectedSearchRef)

	nextSearchRepository := &highVolumeRepository{resultCount: 1}
	nextSearch, err := runtime.explorationSearch(
		context.Background(),
		&ExecutionRepository{handles: map[string]protocol.RootHandle{handle.ID: handle}, repository: nextSearchRepository},
		searchRefs, knowledgeSearchArguments{Query: "server"}, &ToolUsage{},
	)
	require.NoError(t, err)
	require.Equal(t, "f2", nextSearch.Matches[0].FileRef)
}

func TestExplorationListByteAccountingAndReferenceAdmission(t *testing.T) {
	handle := testRootHandle(time.Now().UTC())
	runtime := &Runtime{}
	listEnvelope, err := json.Marshal(explorationListResult{
		OK: true, Entries: []explorationListEntry{}, Truncated: false,
	})
	require.NoError(t, err)
	listCandidate, err := json.Marshal(explorationListEntry{Ref: "f1", Kind: "file", Path: "x"})
	require.NoError(t, err)
	pathBytes := maxListResultBytes - len(listEnvelope) - len(listCandidate) + 1
	require.Positive(t, pathBytes)
	listRepository := &highVolumeRepository{resultCount: 1, listPath: strings.Repeat("x", pathBytes)}
	listRefs := newExplorationReferences([]RootHandleView{{HandleID: handle.ID}})
	listed, err := runtime.explorationList(
		context.Background(),
		&ExecutionRepository{handles: map[string]protocol.RootHandle{handle.ID: handle}, repository: listRepository},
		listRefs, knowledgeListArguments{RootAlias: "r1"}, &ToolUsage{},
	)
	require.NoError(t, err)
	require.False(t, listed.Truncated)
	require.Len(t, listed.Entries, 1)
	encodedList, err := json.Marshal(listed)
	require.NoError(t, err)
	require.Len(t, encodedList, maxListResultBytes)
	require.Equal(t, "f1", listed.Entries[0].Ref)

	for _, kind := range []string{"file", "directory"} {
		t.Run(kind+" rejected ref", func(t *testing.T) {
			oversizedRepository := &highVolumeRepository{
				resultCount: 1, listKind: kind, listPath: strings.Repeat("x", maxListResultBytes),
			}
			refs := newExplorationReferences([]RootHandleView{{HandleID: handle.ID}})
			oversized, err := runtime.explorationList(
				context.Background(),
				&ExecutionRepository{handles: map[string]protocol.RootHandle{handle.ID: handle}, repository: oversizedRepository},
				refs, knowledgeListArguments{RootAlias: "r1"}, &ToolUsage{},
			)
			require.NoError(t, err)
			require.True(t, oversized.Truncated)
			require.Empty(t, oversized.Entries)
			if kind == "file" {
				_, ok := refs.resolveFile("f1")
				require.False(t, ok)
			} else {
				_, ok := refs.resolveDirectory("d1")
				require.False(t, ok)
			}

			nextRepository := &highVolumeRepository{resultCount: 1, listKind: kind}
			next, err := runtime.explorationList(
				context.Background(),
				&ExecutionRepository{handles: map[string]protocol.RootHandle{handle.ID: handle}, repository: nextRepository},
				refs, knowledgeListArguments{RootAlias: "r1"}, &ToolUsage{},
			)
			require.NoError(t, err)
			require.Len(t, next.Entries, 1)
			if kind == "file" {
				require.Equal(t, "f1", next.Entries[0].Ref)
			} else {
				require.Equal(t, "d1", next.Entries[0].Ref)
			}
		})
	}
}

func TestExplorationReadPreservesCodeIndentation(t *testing.T) {
	handle := testRootHandle(time.Now().UTC())
	repository := &highVolumeRepository{readChunk: []byte("    return value\n")}
	session := &ExecutionRepository{handles: map[string]protocol.RootHandle{handle.ID: handle}, repository: repository}
	usage := &ToolUsage{}
	refs := newExplorationReferences([]RootHandleView{{HandleID: handle.ID}})
	fileRef := refs.fileRef(handle.ID, "code.go")

	read, evidence, err := (&Runtime{}).explorationRead(
		context.Background(), session, refs,
		knowledgeReadArguments{FileRef: fileRef, LineStart: 1, LineEnd: 1}, 1, usage,
	)
	require.NoError(t, err)
	require.NotNil(t, evidence)
	require.Equal(t, "    return value\n", evidence.Content)
	require.Equal(t, handle.Revision, evidence.Citation.Revision)
	modelResult, err := json.Marshal(read)
	require.NoError(t, err)
	require.NotContains(t, string(modelResult), `"citation"`)
	require.NotContains(t, string(modelResult), handle.Revision)
}

func TestExplorationReadIssuesEvidenceForSuccessfulBlankLines(t *testing.T) {
	handle := testRootHandle(time.Now().UTC())
	repository := &highVolumeRepository{readChunk: []byte("\n")}
	session := &ExecutionRepository{handles: map[string]protocol.RootHandle{handle.ID: handle}, repository: repository}
	refs := newExplorationReferences([]RootHandleView{{HandleID: handle.ID}})
	fileRef := refs.fileRef(handle.ID, "blank.txt")

	read, evidence, err := (&Runtime{}).explorationRead(
		context.Background(), session, refs,
		knowledgeReadArguments{FileRef: fileRef, LineStart: 1, LineEnd: 2}, 1, &ToolUsage{},
	)
	require.NoError(t, err)
	require.NotNil(t, evidence)
	require.Equal(t, "\n\n", evidence.Content)
	require.Equal(t, "E1", read.Evidence.ID)
	require.Equal(t, 1, read.Evidence.LineStart)
	require.Equal(t, 2, read.Evidence.LineEnd)
}
