Render chat build metadata #95

Merged
m merged 1 commits from codex/creator-chat-model-status-v1 into main 2026-08-22 00:08:09 +00:00
4 changed files with 42 additions and 9 deletions
+13 -1
View File
@@ -15,6 +15,8 @@ import (
)
func TestChatPageServedWithoutInternalIDs(t *testing.T) {
t.Setenv("ASSISTANT_BUILD_REVISION", "0123456789abcdef")
t.Setenv("ASSISTANT_BUILD_TIME", "2026-08-22T03:04:05Z")
handler, err := newHandler("http://core", "http://continuity", "http://commit", http.DefaultClient, "http://cognitive")
if err != nil {
t.Fatal(err)
@@ -30,11 +32,21 @@ func TestChatPageServedWithoutInternalIDs(t *testing.T) {
t.Fatalf("/chat is missing human status marker %q", required)
}
}
for _, forbidden := range []string{"provider_id", "model_id", "binding_id", "workspace-id", "session-id"} {
for _, forbidden := range []string{"provider_id", "model_id", "binding_id", "workspace-id", "session-id", "__ASSISTANT_BUILD_REVISION__", "__ASSISTANT_BUILD_TIME__", "__ASSISTANT_BUILD_DATETIME__"} {
if strings.Contains(body, forbidden) {
t.Fatalf("/chat leaks internal field %q", forbidden)
}
}
if !strings.Contains(body, "версия 0123456789ab") || !strings.Contains(body, "обновлено 22.08.2026 03:04 UTC") || !strings.Contains(body, "datetime=\"2026-08-22T03:04:05Z\"") {
t.Fatalf("/chat does not render build metadata: %q", body)
}
for _, path := range []string{"/", "/chat.html"} {
alternate := httptest.NewRecorder()
handler.ServeHTTP(alternate, httptest.NewRequest(http.MethodGet, path, nil))
if alternate.Code != http.StatusOK || strings.Contains(alternate.Body.String(), "__ASSISTANT_BUILD_REVISION__") {
t.Fatalf("%s did not render build metadata: status=%d", path, alternate.Code)
}
}
}
func TestChatScriptExplainsSessionAndRuntimeFailures(t *testing.T) {
+1 -6
View File
@@ -133,7 +133,7 @@ func (g *gateway) ServeHTTP(w http.ResponseWriter, r *http.Request) {
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
return
}
if r.URL.Path == "/" {
if r.URL.Path == "/" || r.URL.Path == "/chat" || r.URL.Path == "/chat.html" {
g.serveEmbeddedHTML(w, "chat.html")
return
}
@@ -141,11 +141,6 @@ func (g *gateway) ServeHTTP(w http.ResponseWriter, r *http.Request) {
g.serveEmbeddedHTML(w, "index.html")
return
}
if r.URL.Path == "/chat" {
r = r.Clone(r.Context())
r.URL.Path = "/chat.html"
w.Header().Set("Cache-Control", "no-store")
}
g.static.ServeHTTP(w, r)
}
+2 -2
View File
@@ -1,5 +1,5 @@
{
"task_file": "dev/tasks/DEV-000094-semantic-local-recovery-routing.json",
"task_id": "DEV-000094",
"task_file": "dev/tasks/DEV-000095-chat-build-metadata-rendering.json",
"task_id": "DEV-000095",
"task_revision": 1
}
@@ -0,0 +1,26 @@
{
"task_id": "DEV-000095",
"task_revision": 1,
"architecture_revision": "ADR-0018",
"base_repo_revision": "8c2989f",
"risk_tier": "E",
"intent": "Render actual Domovoy build revision and update time on every public chat route instead of exposing unresolved template markers.",
"requirement_ids": ["Chat displays version and update time", "Public build metadata is truthful"],
"allowed_change_scope": {
"modules": ["creator-web", "development-governance"],
"paths": ["cmd/creator-web/server.go", "cmd/creator-web/chat_test.go", "dev/ACTIVE_TASK.json", "dev/tasks/DEV-000095-chat-build-metadata-rendering.json"]
},
"forbidden_change_scope": {"paths": ["architecture/**", "security/**", "database/**", "deploy/**", "contracts/**"]},
"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 Creator Web HTTP surface"], "may_change": []},
"semantic_owner": "none; presentation-only build metadata",
"canonical_state": [],
"state_transitions": [],
"side_effects_and_privileges": ["No mutation, provider call, credential access, or new privilege"],
"persistence_and_migrations": ["None"],
"failure_retry_restart": ["When build metadata environment values are absent, a safe development revision and startup timestamp remain renderable; no raw markers are sent"],
"assumptions": ["The existing container revision environment value is the deployment revision", "docker-test remains prohibited"],
"acceptance_scenarios": ["/chat renders revision and time instead of placeholders", "/chat.html cannot bypass metadata substitution", "public page does not expose internal IDs or unresolved build placeholders"],
"required_tests": ["go test ./cmd/creator-web", "go test ./...", "go vet ./...", "devctl preflight", "devctl check-diff", "git diff --check"],
"terminal_gap_states": ["BLOCKED_BY_ARCHITECTURE_GAP", "BLOCKED_BY_SPEC_GAP", "BLOCKED_BY_CONFLICT"]
}