Pending: 0 Building: 0 Running: 2 Failed: 79
Created Date Type Name Commit Description State Age Up Time Life Time Action
merged [Campaign] Brain v17 Complete: v1.4 + v2.0 Foundation — WI-1..WI-11 [FIX] viin_ai_agent,viin_ai_search: mute expected warnings in negative-path tests Four post-install tests intentionally exercise error paths to verify graceful handling, but lack a @mute_logger wrapper, so runbot logs their expected warnings as test-suite noise: - test_run_ai_prompt_missing_model_skips_gracefully and test_run_ai_prompt_missing_prompt_skips_gracefully create server actions named 'WI17 No Model' / 'WI17 No Prompt' to drive ir_actions_server._run_action_ai_prompt down its skip branch, which logs at WARNING from odoo.addons.viin_ai_agent.models.ir_actions_server. - test_missing_model_name_raises_error and test_unknown_model_raises_error post a JSON-RPC request with no / invalid model_name; the controller raises ValidationError, which Odoo's HTTP dispatcher logs at WARNING from odoo.http. Wrap each test with the canonical @mute_logger pattern from commit 7d34381 (viin_ai_chat: mute expected log output in negative-path controller tests). Production behaviour is unchanged — the warning still fires when an admin actually misconfigures a server action or a caller passes a bad model_name; the decorator only suppresses the line within the test scope so the runbot output stays signal-rich. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Failed
merged [Campaign] Brain v17 Complete: v1.4 + v2.0 Foundation — WI-1..WI-11 [FIX] viin_brain: format collab step service filter tests for prettier Runbot ESLint+prettier (build 381264) reported 19 prettier/prettier violations in the new H1 test file: 4-space indentation, printWidth=100, and multi-line wrap of ``collabStepService.start({}, {...})`` were not applied when the file was first written. Reformat to satisfy the Odoo ``web/tooling/_eslintrc.json`` config (tabWidth=4, printWidth=100) so the test_pylint stage passes. No behavioural change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Killed Not finished
merged [Campaign] Brain v17 Complete: v1.4 + v2.0 Foundation — WI-1..WI-11 [REF] viin_brain: drop transient sequence field, order collab steps by id (H3+M5) The previous _append_step read the latest sequence and wrote last.sequence + 1 with no row lock. Two concurrent transactions appending to the same page therefore raced — both saw the same "last" record and both tried to insert the next sequence value, producing duplicate sequences (and an inconsistent replay order on reconnect). Drop the sequence field entirely and rely on the auto-incremented id column. PostgreSQL id is monotonic per-table, which is exactly what a relay buffer needs: stable replay order across reconnects. The buffer is not authoritative history (the source of truth is viin.brain.page.content_html), so gap-free numbering is not a requirement; only deterministic ordering is. Migration: TransientModel column drop is handled by the ORM at _auto_init during module update — no manual migration script needed. New code never references sequence so prune logic and history shape continue to work after the column disappears. Also move the json import in viin_brain_collab_step.py to the module top so it does not happen on every _get_history call (M5). Tests: - test_append_step_single: drop sequence assertion. - test_append_step_ordering: rewrite to verify id order matches the order callers invoked _append_step (and that step_json payloads come back in append order). - test_rolling_window_trim: verify pruning by inspecting surviving step_json values rather than sequence numbers. - test_get_history_order_and_shape: drop sequence key assertion; add explicit append-order assertion across client_id values. - test_history_endpoint_returns_steps: drop sequence key assertion. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Failed
merged [ADD/FIX] viin_ai: Phase 3.5 hardening + Phase 3.7 features (SRS v1.1 follow-up) [FIX] viin_ai_chat: tour menu xmlid typo (legacy cleanup) Tour tour_c2_ux_newbie_onboarding searched for an Apps tile with data-menu-xmlid='viin_ai_base.menu_root_viin_ai', but the actual xmlid declared in viin_ai_base/views/menus.xml is 'menu_root_ai'. Mismatch surfaced as a tour failure on every install — pre-existing legacy typo (not caused by this campaign). Plan §"Quy tắc fix legacy errors/warnings" allows root-cause fixes in cluster viin_ai_*; this is a 1-character correction with zero behavioural change beyond letting the tour find its target. Failed
merged [Campaign] Brain v17 Complete: v1.4 + v2.0 Foundation — WI-1..WI-11 [REF] viin_*: replace inline noqa markers with project-level ruff config Repo-wide cleanup: 78 noqa comments scattered across 9 files removed. Each suppression was investigated and replaced with either a root-cause fix (E731) or a project-level ruff per-file-ignores rule that documents the policy centrally instead of leaking it into every line. * pyproject.toml (new) — minimal ruff config: - "__init__.py" = ["F401"]: Odoo registers models/tests via import side-effects; F401 (unused-import) does not apply. - viin_ai_chat/controllers/chat_controller.py = ["BLE001"]: HTTP boundary controllers must broad-catch to convert exceptions into JSON-RPC error payloads instead of leaking tracebacks. - viin_ai_chat/models/discuss_channel.py = ["BLE001"]: discuss bot reply trigger runs after super().message_post() and must never propagate — a misconfigured agent or vendor outage cannot be allowed to break the user's chat post. * viin_ai_agent/models/agent.py — drop the lambda-as-default-no-op pattern (E731). run_streaming() now accepts on_delta=None directly and guards the call site with `if on_delta is not None`. Eliminates the noqa without introducing a module-level helper. * 6 __init__.py files (viin_brain/tests, viin_ai_base/tests, viin_brain_account_reports/tests, viin_web_editor + tests + tools) — 74 inline `# noqa: F401` markers removed. * viin_ai_chat/{controllers/chat_controller.py,models/discuss_channel.py} — 3 inline `# noqa: BLE001` markers removed; broad-except behavior preserved (it is the correct pattern for these boundary points). No runtime behavior change. No new dependencies. CI does not run ruff today (.github/workflows/*.yml has no lint job), so this commit is purely about code clarity and future-proofing the lint policy. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Failed
merged [Campaign] Brain v17 Complete: v1.4 + v2.0 Foundation — WI-1..WI-11 [REF] viin_brain: drop obsolete WI-B5 P7 snapshot embed mockup Design artifact from commit e3de353 (WI-B5 P7 snapshot embed buildout). The actual UI is now implemented under static/src/components/embed_picker/, snapshot_chrome/, and embed_blocks/, which are exercised by tours and unit tests. The HTML mockup is no longer referenced and adds 667 lines of unmaintained markup to the repo. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Killed Not finished
merged [Campaign] Brain v17 Complete: v1.4 + v2.0 Foundation — WI-1..WI-11 [REF] viin_ai_base: migrate vendor display name test off deprecated name_get After commit 816fc78 replaced AIVendor.name_get() with _compute_display_name(), test_name_get_includes_protocol still called .name_get() — which works via BaseModel.name_get() compat-wrapper but emits DeprecationWarning. Rename the test and read display_name directly to silence the warning and document the v17 API. Killed Not finished
merged [Campaign] Brain v17 Complete: v1.4 + v2.0 Foundation — WI-1..WI-11 [FIX] viin_brain,viin_brain_account_reports,viin_web_editor: fix lint errors - flake8 E402: move TransactionCase import above _logger assignment in test_perf_large_vault.py - ESLint parse error: remove nested block comment (/* */) inside JSDoc in tiptap_adapter.js - prettier: auto-fix quote style (single→double) and indentation in 13 JS files Failed
merged [Campaign] Brain v17 Complete: v1.4 + v2.0 Foundation — WI-1..WI-11 [FIX] viin_brain: add post_install tag to HttpCase tour tests (WI-9) TestBrainCollabActivationTour and TestCollabStepController were missing @tagged('post_install', '-at_install'). Without it, Odoo's MetaCase assigns default {'standard', 'at_install'} and start_tour() warns that HttpCase tests must run post_install when registry.loaded is False. Failed
merged [Campaign] Brain v17 Complete: v1.4 + v2.0 Foundation — WI-1..WI-11 [FIX] viin_brain,viin_web_editor: move ir.http override + fix JSON-RPC test format - Move session_info editor_backend injection from viin_web_editor to viin_brain to satisfy viin_web_editor spike/pure-asset contract (test_rollback.py AC-5) - Fix TestCollabStepController: wrap POST calls in JSON-RPC 2.0 envelope so Odoo's JsonRpcDispatcher passes params correctly to relay_step() Failed
merged [Campaign] Brain v17 Complete: v1.4 + v2.0 Foundation — WI-1..WI-11 [ADD] viin_brain: activate bus.bus OT collab step relay for real-time editing (WI-9) Implements ADR-002 Option 1: real-time collaborative editing via OdooEditor's bus.bus peer-to-peer OT mechanism, as documented in docs/brain/architecture/adr_002_crdt_collab.md. Changes: - viin.brain.collab.step: new transient model acting as a 100-step rolling buffer per page for reconnect replay (GET /viin_brain/collab/history/<id>). - BrainCollabController: POST /viin_brain/collab/step fans out edit steps via bus.bus channel editor_collaboration:viin.brain.page:content_html:<id> and stores steps in the rolling buffer. - collab_step_service.js: new OWL service that subscribes to the bus.bus collab channel, delivers peer steps to registered listeners, and exposes broadcastStep() / loadHistory() for the page editor. - page_editor.js: wires collab_step_service when realtime_collab=True — generates a stable tab clientId, subscribes on page open, loads missed history on reconnect, broadcasts edit steps fire-and-forget, applies peer HTML snapshots when no local save is pending, tears down on page switch / unmount. - ConflictDialog: retained as fallback for non-collaborative saves (force path and offline edge cases); disabled in the collab hot path (expectedToken=false, force=True per existing WI-13 flag). - ACL: editor + admin rows added for viin.brain.collab.step. - Tests: TransactionCase unit tests for the rolling buffer model + HttpCase controller smoke tests + tour verifying service registry wiring. Note: full 2-writer concurrent edit scenario (M>0 evidence) is PENDING — requires a live Odoo server with two authenticated browser sessions. Server is not running in this sprint environment. Test infrastructure is complete; manual verification procedure documented in brain_collab_activation_tour.js. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Killed Not finished
closed ai17 cleanup round 2: 0 pylint + 0 ruff violations [ADD] viindoo: WI15 quality gate test_result — pylint=0 ruff=0 (WI15) Failed
merged [Campaign] ai17 Cluster Audit & Phase 3.5 Bridge — WI-1..WI-6 (2026-04-28-ai17-cluster-bridge) [DOC] viindoo: sync ai17 cluster design docs — Phase 3.7/3.8 ADR alignment (WI-6) - roadmap.md: Phase 3.7 approval.chain + schedule marked superseded (ADR WI-2); Phase 3.5 updated to viin.ai.feedback (WI-5); Phase 3.8 expanded with 4 sub-modules - architecture.md: Layer 0-4 reality + Layer B (operating objects) section - operating-model.md: consolidated post-ADR; ratify 4-module Phase 3.8 breakdown - data-models.md: cleanup Phase 3.7 chain model refs; cross-link Phase 3.8 models - security.md: tiering section + adapter sudo enforcement points - observability.md: Phase 3.8 ops dashboard placeholder - migration.md: to_approvals → viin_approval merge note for v18 forward-port - glossary.md: Phase 3.8 terms: work_item, action_proposal, control_policy, ops adapter Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Failed
merged [Brain v1.3] Roadmap completion — 17 workitems [FIX] viin_brain*: fix CI lint errors from PR #19 review - viin_brain_{crm,hr,project,sale_management}: remove redundant `auto_install: False` (default value, triggers test_manifests lint) - viin_brain/tests/test_perf_large_vault.py: replace print() with _logger.info() (W8116) - viin_brain/tests/test_brain_acl_daily_note.py: absolute import → relative import (W8150) - viin_brain_account_reports/static/src: prettier --fix on embed_report_lazy_loader.js and slash_commands.js (7 violations) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Killed Not started Not finished
merged [Brain v1.3] Roadmap completion — 17 workitems [FIX] viin_brain: use raw SQL in test_orphan_parent_id_in_path_renders_as_masked _parent_store=True causes ORM writes to parent_path to be overridden by parent_id reconciliation. Use cr.execute() to inject the bogus ancestor id as the test comment describes ("via direct SQL or half-applied migration"). Also invalidate parent_path alongside breadcrumb_path after the SQL write. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Killed Not finished
merged [Brain v1.3] Roadmap completion — 17 workitems [DOC] viindoo: WI-18 v1.3 release notes + CHANGELOG WI-18 of campaign 2026-04-28-brain-v1_3-roadmap-completion. Adds docs/brain/release_notes_v1.3.md (8 required sections, 19-row roadmap status) and inserts ## [1.3.0] section into viin_brain/CHANGELOG.md covering WI-0 through WI-17 deliverables. CHANGELOG entries: 5 Added + 3 Changed + 4 Fixed + 3 Documentation (15 total >= 9 minimum per AC-7). Deferred-to-v1.3 block at the bottom of [1.2.0] removed; those P-issues now appear under [1.3.0] as completed entries. Release notes: 216 lines (>= 80 minimum per AC-9), 8 mandatory sections (Overview, What's New, Security & Quality, Performance, Architecture, Upgrade Notes, Known Limitations, Roadmap Status), 19-row Roadmap Status table covering WI-0 through WI-18. Stack policy: Real-time CRDT/OT collab framed as "Viindoo-equivalent extension"; explicit note that Odoo Enterprise modules are not part of the Viindoo stack. Failed
closed [IMP] viin_brain: remove migration script [IMP] viin_brain: remove migration script This module is currently under development, no consumer. Failed
merged [FIX] viin_brain, viin_web_editor: campaign 2026-04-27 brain v1.2 fix-followup (WI1+WI2+WI3) [FIX] viin_brain: WI-3 correct tour CSS selectors for moderation badge Fix selectors copied from brain_share_link.js that never matched the DOM: - .o_brain_vault_sidebar → .o_brain_sidebar (VaultSidebar root element) - .o_brain_sidebar_page → .o_brain_page_node (sidebar page item elements) Found during VALIDATE pass; brain_share_link.js has the same pre-existing bug and should be fixed in a follow-up. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Killed Not started Not finished
merged [v17] viin_brain + viin_web_editor: Polish v1.2 (WI-3..8) [DOC] viin_brain, viin_web_editor: WI-8 release notes v1.2 + README + P1..P15 status sync Failed
closed [IMP] viin_brain: remove migration script [IMP] viin_brain: remove migration script This module is currently under development, no consumer. Failed
merged [IMP] viin_ai_rag: remove orphan knowledge_article_id field and [REF] viin_brain, viin_ai_brain: drop group_brain_user, use base.group_user group_brain_user was effectively an alias of base.group_user (it just implied base.group_user and added no behavior). Carrying it around inflated ACL/ir.rule entries and produced redundant runtime state with no functional benefit. - security/res_groups.xml: remove group_brain_user; group_brain_editor now implies base.group_user directly. Two Brain groups remain: editor + admin. - ir.model.access.csv, ir_rules.xml: replace every group_brain_user reference with base.group_user. - Drop the auto-enroll machinery that only existed to put internal users into group_brain_user: remove hooks.py (post_init_hook), models/res_users.py (_brain_maybe_enroll), the brain_default_enable_for_all_employees setting field and its Settings UI block. Every internal user can use Brain by default; vault membership + role drive editor/admin capabilities. - Update __manifest__.py description (3 groups -> 2 groups), drop the post_init_hook key, and update the demo data note. - Tests: delete test_brain_security_default_enroll.py (covered a feature that no longer exists and imported the deleted hooks module), drop the cls.group_brain_user alias from common.py / test_brain_comment.py / test_brain_tools.py, and switch remaining references in test_brain_snapshot.py / test_brain_vault.py / test_brain_acl_multicompany.py to group_internal_user. - docs/brain/security.md, ai-bridge.md, roadmap.md: align wording with the 2-group model. Killed Not finished
merged [IMP] viin_ai_rag: remove orphan knowledge_article_id field and [REF] viin_brain, viin_ai_brain: drop group_brain_user, use base.group_user group_brain_user was effectively an alias of base.group_user (it just implied base.group_user and added no behavior). Carrying it around inflated ACL/ir.rule entries and produced redundant runtime state with no functional benefit. - security/res_groups.xml: remove group_brain_user; group_brain_editor now implies base.group_user directly. Two Brain groups remain: editor + admin. - ir.model.access.csv, ir_rules.xml: replace every group_brain_user reference with base.group_user. - Drop the auto-enroll machinery that only existed to put internal users into group_brain_user: remove hooks.py (post_init_hook), models/res_users.py (_brain_maybe_enroll), the brain_default_enable_for_all_employees setting field and its Settings UI block. Every internal user can use Brain by default; vault membership + role drive editor/admin capabilities. - Update __manifest__.py description (3 groups -> 2 groups), drop the post_init_hook key, and update the demo data note. - Tests: delete test_brain_security_default_enroll.py (covered a feature that no longer exists and imported the deleted hooks module), drop the cls.group_brain_user alias from common.py / test_brain_comment.py / test_brain_tools.py, and switch remaining references in test_brain_snapshot.py / test_brain_vault.py / test_brain_acl_multicompany.py to group_internal_user. - docs/brain/security.md, ai-bridge.md, roadmap.md: align wording with the 2-group model. Killed Not finished
merged [IMP] viin_ai_rag: remove orphan knowledge_article_id field and [IMP] viin_ai_rag: remove orphan knowledge_article_id field and selection Removes Knowledge module integration that was replaced by viin_ai_brain (Layer-3 connector). The `knowledge_article_id` field, `'knowledge'` source_type selection, and related `_extract_text` branch are no longer needed: - viin.ai.source.knowledge_article_id field deleted - source_type selection `'knowledge'` removed (base now has pdf, url, text only) - _extract_text dispatcher simplified (no knowledge.article logic) - Manifest: wording updated; no depends change - Docs: knowledge_article_id row removed; Brain coverage note points to viin_ai_brain Layer separation preserved: viin_ai_brain (Layer-3) owns Brain integration with correct key 'brain_page'. Resolves carry-over WI-4 from campaign 2026-04-26-ai17-lint-followup (wrong premise: bridge module for Odoo EE; correction: Brain is already in Viindoo stack via viin_ai_brain). Killed Not finished
closed [IMP] viin_ai_rag: remove orphan knowledge_article_id field and selection [IMP] viin_ai_rag: remove orphan knowledge_article_id field and selection Removes Knowledge module integration that was replaced by viin_ai_brain (Layer-3 connector). The `knowledge_article_id` field, `'knowledge'` source_type selection, and related `_extract_text` branch are no longer needed: - viin.ai.source.knowledge_article_id field deleted - source_type selection `'knowledge'` removed (base now has pdf, url, text only) - _extract_text dispatcher simplified (no knowledge.article logic) - Migration: pre-migrate.py maps knowledge→brain_page, drops orphan FK column - Manifest: wording updated; no depends change - Docs: knowledge_article_id row removed; Brain coverage note points to viin_ai_brain Layer separation preserved: viin_ai_brain (Layer-3) owns Brain integration with correct key 'brain_page'. Resolves carry-over WI-4 from campaign 2026-04-26-ai17-lint-followup (wrong premise: bridge module for Odoo EE; correction: Brain is already in Viindoo stack via viin_ai_brain). Killed Not finished
merged [FIX] ai17 lint follow-up: manifest, RST underline, prettier, comodel, access rule [FIX] viin_ai_brain: add base.group_user to viin.ai.brain.tools access rule ir.model.access.csv entry 'viin.ai.brain.tools all' had an empty group_id, which triggered: Rule viin.ai.brain.tools all has no group, this is a deprecated feature. Every access-granting rule should specify a group. Per Brain access matrix (docs/brain/security.md §4), viin.ai.brain.tools tools are available to all internal users. Set group_id = base.group_user. viin.ai.brain.tools is an AbstractModel dispatcher (no DB table); read-only access (perm_read=1, others=0) allows internal users to invoke tool methods via env['viin.ai.brain.tools'].tool_<name>() inside ir.actions.server code. Killed Not finished
merged ai17 lint cleanup: fix 6 CI lint categories (test_lint + test_pylint + test_eslint) [FIX] viin_ai_brain, viin_brain: eslint --fix prettier auto-format Run eslint --fix with Odoo web/tooling _eslintrc.json on viin_ai_brain/static/src and viin_brain/static/src to clear 132 prettier/prettier violations (single->double quote, line-wrap, indent) and 2 prefer-const (dx/dy in graph_canvas.js). 3 violations remain for separate manual commit (no-self-assign, unused _t, unused ns). Failed
merged [FIX] ci_workflows: Add addon repo clones [FIX] ci_workflows: Add addon repo clones Fixes nightly-extended failure where viin_ai_base could not resolve viin_api_request_logger from tvtmaaddons17, and reports-extended hard-fail on missing to_account_reports from erponline-enterprise17. All Odoo-touching jobs (pr-gate-core, nightly-extended, nightly-v3-visual, reports-extended) now: - Run on self-hosted runner [self-hosted, "Viindoo Runbot"] - Clone tvtmaaddons@17.0 and erponline-enterprise@17.0 via SSH - Extend ADDONS_PATH with all addon directories in correct precedence order: /tmp/odoo/addons,/tmp/tvtmaaddons,/tmp/erponline-enterprise,${{ github.workspace }} Reports-extended fail-fast stub removed; tour execution now runs with full addon resolution. ci.yaml::odoo-install remains gated (if: false) with updated TODO referencing follow-up ticket WI-ai17-odoo-install-ungate. Refs: Viindoo/ai #24939135709 Failed
merged [17.0][IMP] viin_brain: v3 UI absorption + v1.0 campaign close [IMP] viin_brain: default admin grants + group hygiene + category rename - Grant base.user_root + base.user_admin -> group_brain_admin at install (non-demo, per Odoo app convention — matches to_approvals pattern) This ensures admin users always reach Brain without relying on demo data reload, which is the correct production-grade fix for the AccessDenied mount issue that prompted WI-V3-R7's test-layer workaround. - group_brain_user implies base.group_user (Brain User is always an internal employee — standard Odoo module-group hygiene). - Rename category "Viindoo Brain" -> "Brain" in Settings > Users UI. Partial resolution of AUD-012. Full auto-grant of every base.group_user into group_brain_user remains scoped to WI-V3-R8 (v1.1). Failed
merged viin_brain: P3–P12 buildout + WI-14 UI panels (9 sprints — viindoo-brain v17 campaign) [FIX] ci: stabilize github action gates Failed
merged viin_brain: P3–P12 buildout + WI-14 UI panels (9 sprints — viindoo-brain v17 campaign) [FIX] pylint Failed
merged viin_brain: P3–P12 buildout + WI-14 UI panels (9 sprints — viindoo-brain v17 campaign) [FIX] ESLint/Prettier Failed
merged viin_brain: P3–P12 buildout + WI-14 UI panels (9 sprints — viindoo-brain v17 campaign) [FIX+IMP] Failed
merged viin_brain: P3–P12 buildout + WI-14 UI panels (9 sprints — viindoo-brain v17 campaign) [FIX] prettier Failed
merged viin_brain: P3–P12 buildout + WI-14 UI panels (9 sprints — viindoo-brain v17 campaign) update roadmap Killed Not finished
merged viin_brain: P3–P12 buildout + WI-14 UI panels (9 sprints — viindoo-brain v17 campaign) [IMP] viin_brain: reconcile audit closure and stabilize tours Failed
merged viin_brain: P3–P12 buildout + WI-14 UI panels (9 sprints — viindoo-brain v17 campaign) [IMP] viin_brain: align lint and editor module fixes Failed
merged viin_brain: P3–P12 buildout + WI-14 UI panels (9 sprints — viindoo-brain v17 campaign) [FIX] viin_brain: harden UI and browser tours Failed
merged viin_brain: P3–P12 buildout + WI-14 UI panels (9 sprints — viindoo-brain v17 campaign) fix layout Failed
merged viin_brain: P3–P12 buildout + WI-14 UI panels (9 sprints — viindoo-brain v17 campaign) fix(brain-layout): restore 3-column shell — flex-direction column, no duplicate header, BS tokens - .o_brain_app flex-direction: row → column so BrainHeader stacks as top bar instead of appearing as a left-side strip beside o_brain_app_body - Remove duplicate .o_brain_header block from brain_app.scss (source of truth stays in brain_header.scss; duplicate was overriding flex-wrap and height) - brain_header.scss: replace hardcoded hex trust-chip tokens (#E5F0FF, #1a5fad…) with Bootstrap semantic vars (--bs-info-bg-subtle, --bs-warning-text-emphasis…) so trust chips respond correctly to Odoo theme switching - Add min-height: 48px to .o_brain_header (was lost when duplicate was present) - Fix .o_brain_editor_placeholder: remove dashed border + secondary background that made the active editor look like an empty box; add ::before placeholder text only when contenteditable is empty and unfocused - Add missing CSS for P8 drag-reorder: .o_brain_page_drag_handle (grab cursor, hide-until-hover) .o_brain_page_node--dragging (opacity 0.4) .o_brain_page_node--drop-target (border-top primary color) - Add missing CSS for P6 metadata chips: .o_brain_page_meta_chips container .o_brain_meta_chip --restricted (warning palette) and --shared (info palette) Failed
merged viin_brain: P3–P12 buildout + WI-14 UI panels (9 sprints — viindoo-brain v17 campaign) feat(brain-p5p6p8): graph traversal tests + metadata chips + drag reorder P5 — test_graph_traversal.py (14 tests): - depth=0/1/2, direction outgoing/incoming/both, link_type filter - max_results cap, no-cycle guard, via_link_ids assertion - ACL: non-vault-member gets empty traversal; vault member sees full graph P6 — page_chrome metadata badges: - page_editor.js: track state.hasActiveShare (async share-link count) - page_editor.xml: o_brain_page_meta_chips row with restricted + shared badges P8 — VaultSidebar drag reorder (all/tree mode): - HTML5 drag-and-drop: draggable="true" on <li>, drag handle ⠿ - onDragStart/Over/Leave/Drop/End handlers; visual classes --dragging/--drop-target - _reorderPage(): swap sequence on drop then reload pages Killed Not finished