Compare commits

..
Author SHA1 Message Date
m 45435814ee fix: disable hidden thinking for bounded local advice
CI / test (push) Successful in 1m6s
CI / test (pull_request) Successful in 1m6s
2026-08-23 04:01:09 +03:00
m c7170ee751 Merge pull request 'docs: record durable development gate evidence' (#175) from codex/wp-701-development-gate-live-evidence into main
CI / test (push) Successful in 1m6s
2026-08-23 00:55:29 +00:00
m e9f338484a docs: record durable development gate evidence
CI / test (push) Successful in 1m4s
CI / test (pull_request) Successful in 1m4s
2026-08-23 03:52:11 +03:00
m bb131147f8 Merge pull request 'fix: grant development gate owner access' (#174) from codex/wp-701-durable-development-gate into main
CI / test (push) Successful in 1m9s
2026-08-23 00:48:59 +00:00
7 changed files with 109 additions and 11 deletions
+10 -6
View File
@@ -96,11 +96,15 @@ func (a *OpenAICompatibleLocalAdapter) Discover(ctx context.Context) ([]Discover
}
type compatibleChatRequest struct {
Model string `json:"model"`
Messages []compatibleMessage `json:"messages"`
Temperature int `json:"temperature"`
Stream bool `json:"stream"`
MaxTokens int `json:"max_tokens"`
Model string `json:"model"`
Messages []compatibleMessage `json:"messages"`
Temperature int `json:"temperature"`
Stream bool `json:"stream"`
MaxTokens int `json:"max_tokens"`
ChatTemplateKwargs compatibleTemplateKwargs `json:"chat_template_kwargs"`
}
type compatibleTemplateKwargs struct {
EnableThinking bool `json:"enable_thinking"`
}
type compatibleMessage struct {
Role string `json:"role"`
@@ -121,7 +125,7 @@ func (a *OpenAICompatibleLocalAdapter) Advise(ctx context.Context, request cogni
if err := ValidateAdvisoryRequest(request); err != nil || request.ProviderModelID == "" || len(request.Context) != 0 {
return cognitive.AdvisoryResponse{}, ErrInvalidAdvisory
}
payload := compatibleChatRequest{Model: string(request.ProviderModelID), Messages: []compatibleMessage{{Role: "system", Content: "Provide non-canonical advisory text only. Never claim that an action occurred."}, {Role: "user", Content: request.Message}}, Temperature: 0, Stream: false, MaxTokens: request.MaxOutputBytes / 4}
payload := compatibleChatRequest{Model: string(request.ProviderModelID), Messages: []compatibleMessage{{Role: "system", Content: "Provide non-canonical advisory text only. Never claim that an action occurred."}, {Role: "user", Content: request.Message}}, Temperature: 0, Stream: false, MaxTokens: request.MaxOutputBytes / 4, ChatTemplateKwargs: compatibleTemplateKwargs{EnableThinking: false}}
var result compatibleChatResponse
status, err := a.requestJSON(ctx, http.MethodPost, "/chat/completions", payload, &result)
if err != nil {
@@ -2,15 +2,20 @@ package models
import (
"context"
"encoding/json"
"io"
"net/http"
"strings"
"testing"
"time"
"git.cin.su/m/Assistant/contracts/capability"
"git.cin.su/m/Assistant/contracts/cognitive"
)
type captureRoundTripper struct {
authorization string
body []byte
}
func TestOpenAICompatibleLocalAdapterUsesConfiguredTimeout(t *testing.T) {
@@ -31,7 +36,14 @@ func TestOpenAICompatibleLocalAdapterRejectsNonPositiveTimeout(t *testing.T) {
func (t *captureRoundTripper) RoundTrip(request *http.Request) (*http.Response, error) {
t.authorization = request.Header.Get("Authorization")
return &http.Response{StatusCode: http.StatusOK, Body: io.NopCloser(strings.NewReader(`{"data":[]}`)), Header: make(http.Header), Request: request}, nil
if request.Body != nil {
t.body, _ = io.ReadAll(request.Body)
}
body := `{"data":[]}`
if strings.HasSuffix(request.URL.Path, "/chat/completions") {
body = `{"choices":[{"finish_reason":"stop","message":{"role":"assistant","content":"ok"}}],"usage":{"prompt_tokens":1,"completion_tokens":1}}`
}
return &http.Response{StatusCode: http.StatusOK, Body: io.NopCloser(strings.NewReader(body)), Header: make(http.Header), Request: request}, nil
}
func TestOpenAICompatibleLocalAdapterUsesResolvedAPIKey(t *testing.T) {
@@ -57,3 +69,26 @@ func TestOpenAICompatibleLocalAdapterDoesNotSendAuthorizationWithoutKey(t *testi
t.Fatalf("unexpected authorization header")
}
}
func TestOpenAICompatibleLocalAdapterDisablesTemplateThinkingForBoundedAdvisory(t *testing.T) {
transport := &captureRoundTripper{}
adapter, err := NewOpenAICompatibleLocalAdapter("http://gateway/v1", transport)
if err != nil {
t.Fatal(err)
}
_, err = adapter.Advise(context.Background(), cognitive.AdvisoryRequest{Version: cognitive.CreatorAdvisoryV1, RequestID: "request-1", ActorID: "actor", PrincipalID: "principal", ScopeID: "scope", Message: "help", Locale: "ru-RU", MaxOutputBytes: 256, ProviderBindingID: "binding-1", ProviderBindingRevision: 1, ProviderInstanceID: "provider-1", ModelDescriptorID: "model-1", ProviderModelID: capability.ProviderModelID("medium-model")})
if err != nil {
t.Fatal(err)
}
var payload struct {
ChatTemplateKwargs struct {
EnableThinking bool `json:"enable_thinking"`
} `json:"chat_template_kwargs"`
}
if err := json.Unmarshal(transport.body, &payload); err != nil {
t.Fatal(err)
}
if payload.ChatTemplateKwargs.EnableThinking {
t.Fatal("expected bounded advisory to disable template thinking")
}
}
+2 -2
View File
@@ -1,5 +1,5 @@
{
"task_file": "dev/tasks/DEV-000197-durable-development-gate.json",
"task_id": "DEV-000197",
"task_file": "dev/tasks/DEV-000199-medium-advisory-thinking-control.json",
"task_id": "DEV-000199",
"task_revision": 1
}
@@ -0,0 +1,23 @@
{
"task_id": "DEV-000198",
"task_revision": 1,
"architecture_revision": "ADR-0018",
"base_repo_revision": "bb131147f80cb75c0ba3d80607d0f806bd378aa8",
"risk_tier": "E",
"intent": "Record live production evidence for durable governed self-development gate persistence and Work-owner access.",
"requirement_ids": ["WP-701", "live durable gate evidence"],
"allowed_change_scope": {"modules": ["governance status", "evidence"], "paths": ["docs/PROJECT_STATUS.md", "docs/evidence/governed-development-gate-persistence-2026-08-23-v1.json", "dev/ACTIVE_TASK.json", "dev/tasks/DEV-000198-development-gate-live-evidence.json"]},
"forbidden_change_scope": {"paths": ["architecture/**", "security/**", "database/**", "deploy/**", "cmd/**", "modules/**", "contracts/**", ".gitea/**"]},
"allowed_architecture_delta": {"new_cross_module_dependencies": 0, "new_canonical_owners": 0, "new_privileges": 0, "new_third_party_dependencies": 0, "new_database_owner_roles": 0},
"contracts": {"consume": ["Work development gate persistence contract", "production health"], "may_change": ["status and evidence projection only"]},
"semantic_owner": "governance",
"canonical_state": ["work.development_gates"],
"state_transitions": ["none; evidence records applied migration and owner read access"],
"side_effects_and_privileges": ["read-only production verification"],
"persistence_and_migrations": ["no migration"],
"failure_retry_restart": ["retain explicit external bridge gap"],
"assumptions": ["migration 037 and privilege forward migration 038 are present in production"],
"acceptance_scenarios": ["work_role can query the relation", "public health is ok", "status distinguishes durable gate persistence from bridge-backed execution"],
"required_tests": ["go test ./...", "go vet ./...", "go run ./cmd/devctl preflight -active dev/ACTIVE_TASK.json", "go run ./cmd/devctl check-diff -active dev/ACTIVE_TASK.json", "go run ./cmd/devctl check-architecture", "go run ./cmd/devctl/independent -task dev/tasks/DEV-000198-development-gate-live-evidence.json", "git diff --check", "CI", "production health and schema check"],
"terminal_gap_states": ["BLOCKED_BY_MISSING_CAPABILITY"]
}
@@ -0,0 +1,23 @@
{
"task_id": "DEV-000199",
"task_revision": 1,
"architecture_revision": "ADR-0018",
"base_repo_revision": "c7170ee751b715b0cf6721d8491530c185870b2a",
"risk_tier": "E",
"intent": "Disable provider template reasoning for bounded OpenAI-compatible local advisory requests so a loaded MEDIUM model can return bounded advisory content instead of consuming the entire output cap with hidden reasoning.",
"requirement_ids": ["WP-200", "model fleet/failover", "bounded advisory output"],
"allowed_change_scope": {"modules": ["models adapter"], "paths": ["adapters/models/openai_compatible_local.go", "adapters/models/openai_compatible_local_test.go", "dev/ACTIVE_TASK.json", "dev/tasks/DEV-000199-medium-advisory-thinking-control.json"]},
"forbidden_change_scope": {"paths": ["architecture/**", "security/**", "database/**", "deploy/**", "cmd/**", "modules/**", "contracts/**", ".gitea/**"]},
"allowed_architecture_delta": {"new_cross_module_dependencies": 0, "new_canonical_owners": 0, "new_privileges": 0, "new_third_party_dependencies": 0, "new_database_owner_roles": 0},
"contracts": {"consume": ["existing OpenAI-compatible local advisory contract"], "may_change": ["provider request serialization adds typed template control"]},
"semantic_owner": "cognitive adapter",
"canonical_state": [],
"state_transitions": ["bounded advisory request asks compatible runtimes to disable hidden template reasoning"],
"side_effects_and_privileges": ["bounded local provider inference only; no activation or promotion"],
"persistence_and_migrations": ["none"],
"failure_retry_restart": ["provider ignoring the optional request field remains an explicit qualification result"],
"assumptions": ["llama.cpp-compatible OpenAI endpoints ignore or honor the typed chat_template_kwargs field without breaking the existing contract"],
"acceptance_scenarios": ["request contains enable_thinking=false", "adapter still validates bounded completion", "provider failure remains typed and failover-compatible"],
"required_tests": ["go test ./...", "go vet ./...", "go run ./cmd/devctl preflight -active dev/ACTIVE_TASK.json", "go run ./cmd/devctl check-diff -active dev/ACTIVE_TASK.json", "go run ./cmd/devctl check-architecture", "go run ./cmd/devctl/independent -task dev/tasks/DEV-000199-medium-advisory-thinking-control.json", "git diff --check", "CI", "production medium bounded smoke and public health check"],
"terminal_gap_states": ["BLOCKED_BY_MISSING_CAPABILITY", "BLOCKED_BY_CONFLICT"]
}
+2 -2
View File
@@ -11,12 +11,12 @@
- `TRUTH_RESEARCH_STATUS = LIVE_CANARY_PERSISTED`; the web research canary preserved an OBSERVED/COMPLETE/NO-CONFLICT source chain while leaving the claim UNVERIFIED and belief PROVISIONAL. Evidence: `docs/evidence/truth-runtime-canary-2026-08-23-v1.json`.
- `LEARNING_REFLECTION_STATUS = LIVE_RECONCILED`; reflection worker returned no pending candidate and the durable state contains 31 RESOLVED candidates with no OPEN backlog. Evidence: `docs/evidence/reflection-runtime-reconciliation-2026-08-23-v1.json`.
- `BACKUP_RESTORE_STATUS = VERIFIED`; latest checksum and isolated restore evidence is retained in `docs/evidence/wp-002-postgres-restore-2026-08-22-v1.json`.
- `GOVERNED_SELF_DEVELOPMENT_STATUS = PROPOSAL_AND_SCAFFOLD_ONLY`; no bridge-backed source mutation, promotion or rollback is claimed.
- `GOVERNED_SELF_DEVELOPMENT_STATUS = DURABLE_GATE_PERSISTED`; Work-owned revisioned gate storage and optimistic-concurrency persistence are live. No bridge-backed source mutation, promotion or rollback is claimed. Evidence: `docs/evidence/governed-development-gate-persistence-2026-08-23-v1.json`.
- `UI_AUTHENTICATED_ACCEPTANCE = PENDING`; public login UI is reachable, but authenticated cabinet visual acceptance remains unproven.
## Current governance checkpoint
- `ACTIVE_TASK = dev/tasks/DEV-000196-agent-canary-live-evidence.json revision 1`
- `ACTIVE_TASK = dev/tasks/DEV-000198-development-gate-live-evidence.json revision 1`
- `LINEAGE_DECISION = docs/GOVERNANCE_LINEAGE_DECISION_2026-08-22.md`; historical packets remain provenance and are not current authority.
- `REGISTRY_STATUS = YAML and JSON semantic mirrors agree`
- `PRODUCTION_DOMAIN = docker.cin.su`; shared docker-test is not used for this project.
@@ -0,0 +1,13 @@
{
"captured_at": "2026-08-23",
"production_revision": "bb131147f80cb75c0ba3d80607d0f806bd378aa8",
"migration": "038_work_development_gates_privileges.sql",
"database_verification": {
"relation": "work.development_gates",
"work_role_select_count": 0,
"privilege_result": "SELECT succeeded as work_role"
},
"public_health": {"url": "https://assistant.cin.su/healthz", "status": "ok"},
"interpretation": "The governed self-development gate is now durable and accessible to its Work owner with revisioned persistence. This evidence does not prove external bridge execution, source mutation, promotion or rollback.",
"secrets_exposed": false
}