Harden autonomy dashboard and Obsidian integration#17
Conversation
…d execution orchestrator New integrations: - ObsidianOrchestrator: push session history and prompts to Obsidian vault - obsidian-sync.ts: historical migration script for EventStore → Obsidian - ExecutionOrchestrator: watcher-to-Obsidian pipeline with self-healing Enhancements: - Config: RefinerConfig now supports atlassian and obsidian config blocks - ConfigManager: getAtlassianConfig() and getObsidianConfig() static helpers - BackgroundService: watcher integration with execution orchestrator - Dashboard: additional operator controls and Obsidian sync status - Timeline: expanded session tracking and lesson correlation - LessonExtractor: derive and persist prompt improvement lessons from history Tests: background-service, config, lessons, obsidian-orchestrator, watcher-index, self-healing Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…guration Documents the semantic block fields for wiring LocalOpenAiProvider to Ollama (port 11434) or LM Studio. Active config goes in .gemini-refiner.json which is gitignored. Example shows gemma3 models with 120s timeout for local use. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c8ca890641
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const repoId = store.ensureRepository(this.resolveSelectedPath(c.req.query("project"))).id; | ||
| const provider = new TimelineProvider(); | ||
| const timeline = provider.getUnifiedTimeline(50); | ||
| const timeline = provider.getUnifiedTimeline(50, repoId); |
There was a problem hiding this comment.
Preserve the global timeline when no project is selected
When the dashboard calls this endpoint it still uses fetch('/api/timeline') with no project query, so resolveSelectedPath(...) falls back to this.rootPath and this new repoId is always passed to getUnifiedTimeline. In a dashboard with multiple visible projects, the “Global Intelligence Stream” now omits all non-root project activity instead of showing the unified timeline; only callers that add ?project= get scoped data.
Useful? React with 👍 / 👎.
| WHERE l.approved = 1 | ||
| AND l.execution_id IS NOT NULL | ||
| AND l.source = 'auto-extracted-failure' | ||
| AND e.status = 'failed' |
There was a problem hiding this comment.
Skip failures that already healed successfully
This selector continues to return an approved failure lesson as long as the original execution row is failed. A successful healAndRetry creates a separate completed exec_heal_* execution but does not change the original execution or otherwise mark the lesson as healed, so every background cycle selects the same failure again until MAX_HEALING_RETRIES is exhausted, causing duplicate healed prompts/model calls after a success.
Useful? React with 👍 / 👎.
| } catch (error) { | ||
| RuntimeLogger.error("Failed to sync to Obsidian Wiki", error); | ||
| } |
There was a problem hiding this comment.
Surface Obsidian sync write failures
When an Obsidian vault write fails, this catch logs and resolves normally. BackgroundAutonomyService.syncObsidian treats any resolved syncToWiki call as success and records “Synced to Obsidian Vault,” so missing or unwritable vaults produce false success signals even though no wiki file was written.
Useful? React with 👍 / 👎.
Summary
Verification