qwen3-coder-next fabricates plausible-looking code in its Evidence
blocks instead of quoting from the actual files provided. This adds a
Python verification step that greps each fenced code block against the
real changed files and tags any finding whose evidence cannot be found
as UNVERIFIED.
This is a safeguard, not a fix — the model is fundamentally unreliable
for grounded code review. The longer-term fix is to replace qwen3-coder
with a model that stays grounded to context (Claude Haiku, devstral,
or deepseek-coder-v2 via the LiteLLM proxy / vLLM at 172.0.1.42).
The previous regex matched any line containing "password", "token", etc.
near certain punctuation characters. This silently removed function
signatures, variable declarations, and test assertions from the context
sent to the LLM — causing it to hallucinate 3 BLOCKERs per review:
- "function signature missing" (the `password: &str` param was scrubbed)
- "filter body empty" (the filter condition containing "password" was scrubbed)
- "password passed unencrypted" (the decrypt_token call line was scrubbed)
Fix: match actual credential VALUES only:
- Well-known token formats (AKIA..., ghp_..., xox...)
- keyword = "long_quoted_literal" (25+ chars, clearly a value not a name)
- Standalone base64 blob lines (60+ chars, PEM-style)
Never scrub a line just because it contains a credential-related word.
Rust 1.88 enforces clippy::uninlined_format_args as a style lint under
-D warnings. Change `writeln!(stdin, "{}", password)` to the inline
form `writeln!(stdin, "{password}")`.
Three changes:
- Exclude Cargo.lock/lockfiles from the diff — removes ~163 lines of
hash noise that waste the review budget with no value
- Raise line cap from 500 to 3000 and add a truncation notice when
the diff is cut, so the model knows the diff is incomplete
- Harden prompt: require quoted evidence for every finding; add explicit
self-verification step for missing-identifier claims (search full diff
before raising); tighten no-hallucinate instruction
Only a single hardcoded entry (word/document.xml) is ever accessed from
the ZIP archive; no arbitrary path extraction occurs, so path traversal
attacks cannot apply. Add a comment to make this invariant explicit for
future maintainers.
- Add extension allowlist (SAFE_TEXT_EXTENSIONS + SAFE_BINARY_EXTENSIONS)
rejecting unsupported file types at both upload_log_file and
upload_log_file_by_content entry points
- Add extract_text_content() with PDF text extraction via lopdf and
DOCX extraction via zip+quick-xml
- Binary files (PDF/DOCX) get extracted text written to .extracted.txt
for downstream PII detection
- Expand frontend file input accept list and add collapsible
supported-formats disclosure element
- Add 11 unit tests covering allowlist logic and extraction paths
AI history continuity: Changed the history-load query in chat_message to
JOIN ai_conversations and select by issue_id instead of single conversation_id.
This preserves full context when provider/model changes mid-triage.
Deep search: Added DISTINCT to list_issues SELECT and extended the search
filter with EXISTS subqueries covering ai_messages, resolution_steps,
log_files, and timeline_events. Ensures comprehensive search without
duplicate results.
Includes 11 new unit tests covering both features.
Cargo.toml was updated to 0.3.0 for the MCP feature but tauri.conf.json
was missed. Bundle artifact filenames are derived from tauri.conf.json,
so all builds were producing files named 0.2.68.
tea is not available in alpine:latest containers. Replace both tea calls
with curl API requests against the Gitea releases endpoint.
Also: auto-tag now reads src-tauri/Cargo.toml version first. If it is
ahead of the latest git tag (major/minor bump), that version is used
directly instead of incrementing the patch.
- call_tool: 30s hard timeout via tokio::time::timeout
- discover_server: 60s hard timeout wrapping full connect+discover sequence
- delete_mcp_server: write_audit_event before cascade delete, capturing
server name, tool count, and resource count
- initiate_mcp_oauth: append cryptographically random state nonce for CSRF
- pr-review.yml: rewrite prompt to require line-quoted evidence for every
finding and eliminate hallucinated false positives
- Implement AgentRegistry system with devops-incident-responder agent
- Add domain detection based on conversation keywords
- Inject devops-incident-responder as primary system prompt
- Auto-switch domain prompts silently when context shifts
- Fix version update script to handle JSON format correctly
- Always display version in bottom-left corner
- Add release notes fallback to git commits if CHANGELOG empty
This implements the full devops-incident-responder agent as the primary
system prompt, with domain-specific SME prompts layered on top based on
conversation content analysis. The version display bug is fixed by removing
the collapsed condition, and release notes now have a fallback mechanism.
Replace direct Ollama API calls with liteLLM proxy at
172.0.0.29:11434 using qwen2.5-72b (72B VLLM model). Increase
timeouts to 300s for larger model inference. Reuses existing
OLLAMA_API_KEY secret for liteLLM auth.
Also add push-to-master trigger on test.yml so merges to master
run the full CI suite (previously only pull_request events triggered).
Address security review findings:
- Validate event_type against whitelist of 7 known types (M-3)
- Validate metadata is valid JSON and under 10KB (M-2, M-4)
- Include metadata in audit log details (M-2)
- Wrap timeline insert + audit write + timestamp update in a
SQLite transaction for atomicity (M-5)
- Fix TypeScript TimelineEvent interface: add issue_id, metadata
fields and correct created_at type to string (L-3)
- Add timeline_events to IssueDetail TypeScript interface (L-4)
Add INCIDENT_RESPONSE_FRAMEWORK to domainPrompts.ts and append it to
all 17 domain prompts via getDomainPrompt(). Add system_prompt param
to chat_message command so frontend can inject domain expertise. Record
UTC timeline events (triage_started, log_uploaded, why_level_advanced,
root_cause_identified, rca_generated, postmortem_generated,
document_exported) at key moments with non-blocking calls.
Update tauriCommands.ts with getTimelineEventsCmd, optional metadata on
addTimelineEventCmd, and systemPrompt on chatMessageCmd.
12 new frontend tests (9 domain prompts, 3 timeline events).
Add format_event_type() and calculate_duration() helpers to convert
raw timeline events into human-readable tables and metrics. RCA now
includes an Incident Timeline section and Incident Metrics (event
count, duration, time-to-root-cause). Postmortem replaces placeholder
timeline rows with real events, calculates impact duration, and
auto-populates What Went Well from evidence.
10 new Rust tests covering timeline rendering, duration calculation,
and event type formatting.
- Add migration 017_create_timeline_events with indexes
- Update TimelineEvent struct with issue_id, metadata, UTC string timestamps
- Add TimelineEvent::new() constructor with UUIDv7
- Add timeline_events field to IssueDetail
- Rewrite add_timeline_event to write to new table + audit_log (dual-write)
- Add get_timeline_events command for ordered retrieval
- Update get_issue to load timeline_events
- Update delete_issue to clean up timeline_events
- Register get_timeline_events in generate_handler
- Add migration tests for table, indexes, and cascade delete
- Fix flaky derive_aes_key test (env var race condition in parallel tests)