Pending: 0 Building: 0 Running: 8 Failed: 178
Created Date Type Name Commit Description State Age Up Time Life Time Action
merged [IMP] viin_brain,viin_web_editor: UI hardening v1 (token + polish + Odoo-native + v2 seams) [FIX] viin_brain: brain_ux_batch_a_tour line 127 indent 15→16 sp (round 4 follow-up) Off-by-1 from round 4 sprint A. Original CI stdout said "Insert ⏎···············" (displayed as 15 dots) but prettier 2.7.1 actually wants 16 spaces (12 parent + 4 sp continuation indent — standard Odoo eslint config printWidth=100, tabWidth=4). Verified local with prettier 2.7.1 (CI runbot version, /tmp/prettier-test): $ eslint --no-eslintrc -c web/tooling/_eslintrc.json \ --resolve-plugins-relative-to /tmp/prettier-test \ <4 round-4 fixed files> exit=0 Refs PR #27. Killed Not finished
merged [IMP] viin_brain,viin_web_editor: UI hardening v1 (token + polish + Odoo-native + v2 seams) [ADD] tools: brain_v3_ci_check Rule 12 — no demo ref in tests (round 4 sprint C) Add CI guard preventing reintroduction of env.ref('*.demo_*') in test files across all 14 ai17 modules. Rule scans tests/test_*.py and tests/*_tests.py, skipping: - Python comment lines (#-prefixed) - Multi-line docstring blocks (tracked via triple-quote parity) - Files containing the marker '# CI-RULE12-EXEMPT: <reason>' Wired into main checkers list. Strict-mode invariant updates from 8 PASS / 1 pre-existing WARN baseline → 9 PASS / 1 pre-existing WARN (rule2 contenteditable=14 unchanged). Verified: $ python3 tools/brain_v3_ci_check.py --strict ✓ rule12_no_demo_ref_in_tests: Zero demo refs in test files across 14 module(s); 0 file(s) exempt via marker. Refs PR #27. Killed Not finished
merged 17.0 cognitive layer docs [ADD] docs: Phase 3.9 Cognitive Layer — 5 capability + 5 ADR + 1 WI Adopts CoWork-OS patterns: Memory cross-session L0-L3, Skill system additive runtime, KG temporal validity, Pulse cost gate, CoWork skill bundle (140 skill, 15 sub-pack, drop ~7 game). ADR-004 Memory layered + observation sidecar + data residency opt-in ADR-005 Skill additive runtime + version semver + skill pack ADR-006 KG temporal validity + as_of trên 4 Odoo model ADR-007 Pulse cost gate option A (compliant WI-002) ADR-008 CoWork-OS skill adoption + provenance MIT->AGPL WI-004 Cognitive Layer integration + operational runbook Campaign: 2026-05-03-ai17-cognitive-layer Plan: ~/.claude/plans/reflective-snuggling-gosling.md Killed Not started Not finished
merged [IMP] viin_brain,viin_web_editor: UI hardening v1 (token + polish + Odoo-native + v2 seams) [IMP] viin_brain: P7 H4 fix + WI-4 universal injector wire (round 3 sprint 3) P7 H4 — content_html sanitize_attributes=False - Brain embed blocks use data-snapshot-id, data-snapshot-kind, data-block-anchor, data-is-stale, data-mode attributes that are NOT in Odoo's safe_attrs whitelist (odoo/tools/mail.py:44-55). - With default sanitize_attributes=True, html_sanitize() with safe_attrs_only=True strips all data-snapshot-* on every WRITE, breaking embed chrome render after save→reload. - Fix: explicit sanitize_attributes=False preserves data-* while sanitize_tags=True (implicit) still blocks script/iframe/object tags so XSS posture intact. - Verified via JSON-RPC ORM write of 950-byte embed HTML → read back returns 906 bytes with data-snapshot-kind + o_brain_snapshot_chrome--snapshot class preserved. WI-4 (ADR-001) Universal Brain sidebar injection — restored - Original __manifest__.py:270-271 declares "WI-4 (ADR-001) — universal hook injection for mail.thread descendants" but stage 1 (function definition) shipped without stage 2 (caller wiring) per git archaeology of commit 26f2190. - Per ETHOS §4.1.1 boil-the-lake: the function intent was clear, only the wiring was missing; restore (wire) rather than delete. - Rewrote brain_form_sidebar_universal.js to patch FormCompiler .prototype.compile() (not FormController) and mutate source arch this.templates[key] BEFORE super.compile(). Detection: presence of <div class="oe_chatter"> proxies for mail.thread descendant (= has brain_page_count via mail_thread.py inheritance). Guards against double-inject (existing .o_brain_form_sidebar_hook from bridge XML) + WeakSet on processed templates. - Verified on 2 models with NO bridge XML: * project.project (Office Design ID=1) — BRAIN rail sidebar auto-renders * crm.team (Sales ID=1) — BRAIN rail sidebar auto-renders - Existing 5 bridges (res.partner, crm.lead, hr.employee, project.task, sale.order) continue to work unchanged — hookAlreadyPresent guard prevents double injection. NOTE — separate page_editor render race exists: bodyRef.el.innerHTML stays empty despite state.page.content_html containing 906 bytes after ORM write. JSON-RPC verifies content delivery; OWL render does not materialize. Investigation deferred — not introduced by this commit; unrelated to H4 sanitization fix. NOTE — universal injector stat button (Brain Pages count) appears on forms with <div name="button_box"> but the inserted <field name= "brain_page_count" widget="statinfo"> child does not visually render in project.project capture. Sidebar (primary deliverable) works on both test models. Stat button compilation pipeline interaction worth follow-up; sidebar functionality unblocked. AC-1 hex grep PASS, brain_v3_ci_check.py --strict 8 PASS / 1 pre-existing WARN (rule2 contenteditable baseline = 14 unchanged). Refs PR #27. Failed
merged 17.0 cognitive layer docs [ADD] docs: Phase 3.9 Cognitive Layer — 5 capability + 5 ADR + 1 WI Adopts CoWork-OS patterns: Memory cross-session L0-L3, Skill system additive runtime, KG temporal validity, Pulse cost gate, CoWork skill bundle (140 skill, 15 sub-pack, drop ~7 game). ADR-004 Memory layered + observation sidecar + data residency opt-in ADR-005 Skill additive runtime + version semver + skill pack ADR-006 KG temporal validity + as_of trên 4 Odoo model ADR-007 Pulse cost gate option A (compliant WI-002) ADR-008 CoWork-OS skill adoption + provenance MIT->AGPL WI-004 Cognitive Layer integration + operational runbook Campaign: 2026-05-03-ai17-cognitive-layer Plan: ~/.claude/plans/reflective-snuggling-gosling.md Killed Not finished
merged [IMP] viin_brain,viin_web_editor: UI hardening v1 (token + polish + Odoo-native + v2 seams) [IMP] viin_brain: P6 brand parity + P9 ShareDialog polish (round 3 sprint 2) P6 Properties — scope brand cyan to .o_brain_app .btn-primary - Add explicit cascade override in _app_shell.scss (Bootstrap 5.1.3 compiles .btn-primary to hex literals so --bs-primary scope override has zero effect; explicit property cascade is the only safe approach). - Switch '+ Add property' button class btn-light → btn-primary so it picks up the brand accent. Hover via color-mix() (same darkening visual as $darken-10% on Bootstrap baseline). - Scope is .o_brain_app to prevent leak into form/list views in sibling apps that share global Bootstrap tokens. P9 ShareDialog — iOS-style switch + dynamic title - Replace native <input type='checkbox'> for 'Public link' with OWL CheckBox component using Bootstrap 5 form-switch class (matches Odoo 17 boolean_toggle_field iOS-pill pattern). - Load page name via Promise.all alongside share-link search; render Dialog title 'Share <Page Name>' via dialogTitle getter (was hardcoded 'Share this page'). - onToggleLink signature updated for OWL CheckBox onChange contract (passes value, not DOM event). Evidence (visual-evidence MCP, ephemeral): - Session 20260503-2016-p8r3-sprint1-final shot-005: P11 CRM Lead ID=13 form sidebar rail mode renders with Brain stat buttons. - Session 20260503-2031-p8r3-sprint2-polish shot-002: P11 Project Task ID=1 form sidebar rail mode renders with Brain Pages + Brain Note stat buttons. - Session 20260503-2031 shot-005: P9 ShareDialog title 'Share Welcome' + iOS-switch toggle render confirmed. - Round 3 deferred items documented in phase-8-retroactive-evidence.md. AC-1 hex grep PASS, brain_v3_ci_check.py --strict 8 PASS / 1 pre-existing WARN (rule2 contenteditable baseline = 14, unchanged). Refs PR #27. Failed
merged [IMP] viin_brain,viin_web_editor: UI hardening v1 (token + polish + Odoo-native + v2 seams) [FIX] viin_brain: P11 BrainFormSidebar visible — display:contents wrapper Pre-existing P11 gap surfaced by P8 round 3 capture verification: BrainFormSidebar (panel/rail/strip layout modes) was completely invisible on every bridge form (HR Employee, Sale Order, CRM Lead, Project Task) despite the bridge XML hook + form_compilers registry entry + OWL component being correctly wired. Root cause: - brain_form_sidebar_compiler.js wraps the OWL component instance in <div class="o_brain_form_sidebar_container">, then appends that wrapper alongside the chatter container under parentEl(o_form_sheet_bg) — exactly matching mail's chatter pattern. - The wrapper had NO matching CSS rule in brain_form_sidebar.scss. - Default block layout: width:100% + display:block. - The form's flex-flow row container (.o_form_view.o_xxl_form_view, form_controller.scss:1099) treated the wrapper as a full-width row child, pushing the actual sidebar (.o_brain_form_sidebar.--{panel, rail,strip}) off the visible flex track. On standard desktop this put the sidebar below the page content, frequently off-viewport. Fix: - Add display:contents on .o_brain_form_sidebar_container so the wrapper participates in DOM but disappears from layout — its single child .o_brain_form_sidebar.--{mode} becomes the direct flex sibling of o_form_sheet_bg and o-mail-Form-chatter, matching the layout intent expressed in the compiler's append() call. Verified via Visual Evidence MCP session 20260503-1931-brain-ui-p8r3-batch4 on Sale Order S00007 at 1600x1100 viewport (≥SIZES.XXL → rail mode): - shot-002: rail collapsed (44px vertical "BRAIN" label) on far right alongside chatter - shot-003: rail expanded (320px panel) showing "Brain · Knowledge linked to this record" header + "PAGES MENTIONING THIS RECORD" section + empty state + "+ Create a note about this record" CTA — matches mockup P11 (docs/brain/mockups/v3/screenshots/P11.png) structurally. Brain v3 CI: 8 PASS / 1 pre-existing WARN (rule2 contenteditable). AC-1 hex grep: 0 violations (display:contents is a CSS keyword, no literals introduced). Refs PR #27. Failed
merged [IMP] viin_brain,viin_web_editor: UI hardening v1 (token + polish + Odoo-native + v2 seams) [FIX] viin_brain: P8 round 3 — ShareDialog uses dialog.add() service Pre-existing OwlError "Cannot make the given value reactive" surfaced in P8 round 3 boil-the-lake captures: clicking Share in the page header consistently overlayed the full-page Odoo Client Error. Root cause: <ShareDialog/> was rendered directly inside the BrainApp template via t-if="state.showShareDialog". Odoo 17 base Dialog.setup() calls useState(this.env.dialogData), and dialogData is only injected when a dialog is opened through the dialog service (DialogWrapper + WithEnv). With direct child rendering, env.dialogData is undefined and useState(undefined) throws. Refactor to canonical Odoo 17 pattern (per @web/core/dialog/dialog and ConfirmationDialog reference): open ShareDialog imperatively via dialog.add(), let the service inject `close` and provide env.dialogData. Changes: - brain_app.js: useService("dialog"); onOpenShare() now calls this.dialog.add(ShareDialog, {...}); state.showShareDialog and onCloseShare removed; ShareDialog dropped from static components. - brain_app.xml: removed <ShareDialog/> render block (replaced with a comment explaining the imperative-open requirement). - share_dialog.js: props.onClose -> props.close (service-injected); prop schema updated. - share_dialog.xml: <Dialog onClose=...> attribute removed (Dialog closes itself via env.dialogData); Cancel button calls props.close(). Verified via Visual Evidence MCP session 20260503-1844-brain-ui-p8r3-batch2: ShareDialog now opens cleanly with public-link toggle visible (shot-004). Brain v3 CI: 8 PASS / 1 pre-existing WARN (rule2 contenteditable baseline). AC-1 hex grep: 0 violations. Refs PR #27. Killed Not finished
merged [IMP] viin_brain,viin_web_editor: UI hardening v1 (token + polish + Odoo-native + v2 seams) [FIX] viin_brain: P8 retroactive UI polish — selected highlight + breadcrumb path Root cause for missing sidebar-active highlight: the brand-accent token chain `--o-brain-accent: var(--o-brand-primary, var(--bs-primary))` referenced CSS custom properties that Odoo 17 only exposes as Sass compile-time variables, never as runtime `:root{--bs-primary}`. The chain therefore resolved to nothing, `color-mix(in srgb, var(--o-brain- accent) 12%, transparent)` evaluated to fully transparent, and the `.o_brain_page_node.active > .o_brain_page_row` rule painted a zero-alpha background — making the active page indistinguishable from its neighbours even though the `.active` class was correctly added. The Viindoo Odoo 17 build exposes the runtime brand colour as `--primary` (Viindoo cyan #00bbce) plus the theme slot `--o-color-1`. Re-chain `--o-brain-accent` to `var(--primary, var(--o-color-1))` so the brand colour reaches every downstream token (`--o-brain-bg-hover`, `--o-brain-bg-selected`, focus rings, presence palette, AI badge, chip styles). Reviewer-side capture (commit binding via Visual Evidence manifest) now shows a visible cyan tint on the selected row — pixel sample (213, 239, 243) at 14% accent over light gray sidebar bg. Defensive `Number()` cast in `rowClass()` keeps the active class attached even when `activePageId` arrives as a string from URL hash or localStorage restore (was not the original culprit but cheap to keep). Breadcrumb now appends the current page name as a final segment so the visible breadcrumb reads `Vault › [Folder ›] Page` instead of just `Vault`. `breadcrumbDisplay.fullPath` (tooltip on truncated chains) tracks the same change so the tooltip stays consistent with the rendered breadcrumb. Tour AC-P7-2 (root page) updated to expect exactly 1 separator + a non-empty `.o_brain_breadcrumb_current` segment; AC-P7-3 (truncated deep path) tooltip expectation extended with the leaf page name. Evidence (P8 retroactive, reviewer-side, ephemeral 24h auto-cleanup): - session 20260503-1735-brain-ui-verify-g1-jsfix - shot-005-verify-g1-final-r2.png — sha256 9e438c47… - sidebar Welcome row paints (213, 239, 243) cyan tint vs Contracts row (118, 124, 129) plain gray (control sample) - breadcrumb header reads "Personal › Welcome" CI gate: brain_v3_ci_check.py --strict — 8 PASS, 1 pre-existing WARN (rule2_contenteditable in test file, unrelated). AC-1 hex grep PASS (0 hex in components/apps SCSS). Failed
merged [IMP] viin_brain,viin_web_editor: UI hardening v1 (token + polish + Odoo-native + v2 seams) [FIX] viin_brain: P8 revert ShareDialog collab seam wiring (pre-existing Share crash) P8 retroactive visual-evidence run captured ShareDialog crash on Share button click (Odoo Client Error). Initial hypothesis: P7 added `<t t-slot="collabSection"/>` caused regression. Root-cause analysis via baseline test on `~/git/ai17` at branch 17.0 (no hardening changes) showed identical crash hash on Share button click — **pre-existing bug**, NOT introduced by P7. Pre-existing crash blocks any in-place verification of the collab seam wiring. Reverted the JS slots prop + XML t-slot: - share_dialog.js: removed `slots: { type: Object, optional: true, shape: { collabSection: ... } }` from static props. - share_dialog.xml: removed `<t t-slot="collabSection"/>` and the earlier guarded `<t t-if=...><t t-slot/></t>`. Replaced with a `<!-- v2 inject point -->` comment marker as anchor for v2 xpath-inheritance. Updated docs/brain/v2-extension-points.md (seam #4) to: - Mark seam as DOC-ONLY in v1. - Document v2 attach pattern requiring (a) fix pre-existing Share crash first, (b) patch ShareDialog props to add slots, (c) xpath inherit template to inject t-slot at the comment marker. Other 5 P7 seams (presence palette, GraphPanel canvas mount, AIBlock state registry, Property type registry, Decorator providers doc) remain wired in v1 and verified via compiled-CSS evidence in P8 retroactive run (15x `0.15s ease` transitions, 68x `:focus-visible` rules, 8x `--o-brain-presence-color-1..8` vars, etc.). Phase: P8 convergence (visual-evidence retroactive) Pipeline: 20260503-brain-ui-hardening-v1 Plan: ~/.claude/plans/parsed-spinning-peacock.md Failed
merged [IMP] viin_brain,viin_web_editor: UI hardening v1 (token + polish + Odoo-native + v2 seams) [FIX] viin_brain: P8 remove duplicate imports in v2 extension seams test P7 added side-effect imports for ai_block_states and property_types registries followed by named imports from the same modules. The named imports already trigger module side-effects on first import, so the side-effect imports are redundant and trip eslint no-duplicate-imports. Verified registries call registry.add() at module top level; named import alone is sufficient. Fixes 2 NEW eslint errors discovered by P8 full-suite run. All other P8 test failures (11 TestBrainAclPortalShare + 4 TestCollabStepController + tour tests + 1 TestPyLint W0012) confirmed pre-existing on baseline 17.0 — NOT caused by this hardening pipeline. Verified via dedicated baseline runs on ~/git/ai17 at branch 17.0 (see ops/logs/runs/p0-baseline-* + dropdb cleanup). Phase: P8 convergence Pipeline: 20260503-brain-ui-hardening-v1 Plan: ~/.claude/plans/parsed-spinning-peacock.md Failed
merged docs: fix 4 broken viinforge cross-repo refs (DRY into conventions.md) [FIX] docs: replace 4 broken viinforge cross-repo refs with in-repo conventions section Pre-existing issue surfaced by post-merge audit of PR #24: 4 module READMEs (viin_brain, viin_ai_brain, viin_brain_account_reports, viin_web_editor) had identical paragraph linking to `../knowledge/viindoo/modules/viin_brain_v17_reuse_contract.md` — a file that lives in the viinForge repo, breaking when ai17 is checked out standalone. Resolution: - Add new section `§Brain JS/OWL — Odoo 17 import paths` (anchor `#brain-js-owl-imports`) to docs/conventions.md with the critical rule inline (use `@web_editor`, not `@html_editor` — v18+ only, silent blank-page JS resolution error). - Reference viinForge reuse-map doc as plain-text mention (not a markdown link) — viinForge is optional reference, not required for build/run. - Replace 4 README paragraphs (each 8 lines) with 1-line link to the conventions section. Net: 4 broken markdown links -> 0; copy-pasted bullet 4 places -> 1 canonical source; standalone ai17 checkout works. Killed Not started Not finished
merged docs(brain): index orphan ci-tour-gate.md + waves pointer [FIX] docs(brain): index ci-tour-gate.md in README The CI Tour Gate Infrastructure doc has been orphan since it was created (commit 825fae9, 2026-04-29 — pre-existing, surfaced by the post-merge audit of PR #24). Add it to the brain/README.md nav table. Also add explicit pointer from UI Design row to ui-design-waves.md (currently reachable in 2 hops via overview; this makes wave detail discoverable in 1 hop). Killed Not started Not finished
merged docs: compact and restructure ai17/docs (symmetric ai/ + brain/, integration.md, drift fix) [FIX] Update doc references outside docs/ for new paths After the docs/ restructure (commit dbb29f6), 13 files outside docs/ still pointed to old paths. Update them all: - README.md, REPO_LAYOUT.md, CONTRIBUTING.md, SUPPORT.md (top-level) -> docs/ai/{architecture,data-models,security,observability, operating-model,roadmap}.md - viin_ai_rag/__manifest__.py + viin_ai_rag/models/source.py - viin_ai_agent/models/agent.py + source_ext.py - viin_brain/CHANGELOG.md (release notes path) - viin_brain/docs/brain/contenteditable_policy.md (ADR-003 + wysiwyg progress) - viin_ai_base/docs/uat/checklist_2026-04-17.md - docs/decisions/wi-002-phase-3-7-vs-3-8.md (file:line citations) - docs/brain/graph.md (display label) Module-internal docs that already use stable docs/brain/* paths (viin_brain/models/*.py, viin_brain/tests/, viin_ai_brain/models/brain_page.py, viin_web_editor/tools/block_parser.py, ops/conflict_registry.md) require no change — those targets are unchanged by the restructure. Killed Not finished
merged docs: compact and restructure ai17/docs (symmetric ai/ + brain/, integration.md, drift fix) [FIX] docs(brain): remove ghost reference _drift_audit_2026-04-29.md The file docs/_drift_audit_2026-04-29.md never existed in this repo (was an artifact of campaign 2026-04-29 in viinforge). Replace the broken link with a reference to decisions/wi-001-cluster-audit.md, which is the audit summary card that IS in repo. After this, all internal markdown links resolve (broken-link gate returns 0). Killed Not finished
merged [ADD/FIX] viin_ai: Phase 3.5 hardening + Phase 3.7 features (SRS v1.1 follow-up) [FIX] cluster ai17: align prettier trailingComma to es5 (CI default) Runbot build 221688 build 381380 reported 261 prettier "Insert `,`" errors after build 221687's fix added trailing commas via local prettier --trailing-comma=all. Root cause: local eslint resolves eslint-plugin-prettier@5.5.5 from /home/tuan/node_modules (bundled prettier 3.x → default trailingComma=all), while the cluster-local node_modules carries eslint-plugin-prettier@4.2.5 with prettier 2.8.8 whose default is trailingComma=es5. CI runbot uses the cluster-local plugin chain (matches package.json), so trailing commas in function calls/parameters trip "Insert `,`" with all but "Delete `,`" with es5. Re-ran prettier 2.8.8 with no --trailing-comma override on all 149 ai17 static JS files; 76 files re-formatted (+261 −264 lines). Verified locally with eslint --resolve-plugins-relative-to ai17 (forces v4.x resolution that matches CI) → 0 errors on full set. Out of scope: - Build 381388 MemoryError on web/tests/test_assets.py test_logs_assets_generate_time during JS bundle minify is a runbot infra flake (Odoo upstream test, not in 221687 on same branch); net prettier delta of -3 lines cannot tip memory budget. Will retry on next build. Killed
merged [ADD/FIX] viin_ai: Phase 3.5 hardening + Phase 3.7 features (SRS v1.1 follow-up) [FIX] cluster ai17: address runbot lint + sql_template ACL failures (build 221687) CI runner Viindoo runbot exposed real failures on PR #23 commit abcb66e that local Chrome-flaky test runs had hidden: * test_pylint test_eslint (267 violations) — eslint v6 on dev box could not parse the ``es2022`` env key so every lint check silently exited config-error; CI runs eslint v8 cleanly. * test_pylint test_flake8 — 2 unused name lints * test_pylint test_pylint — UserError missing translation * viin_ai_agent.tests.test_sql_template — postgres ``operator does not exist: jsonb ~~ unknown`` on ``res_partner.name LIKE ...`` Fixes: page_editor.js:1484 — drop unused catch binding ``_err`` (eslint no-unused-vars). The empty ``catch {}`` form is supported since Odoo 17 ships ECMAScript 2019+ asset bundles. mail_compose_message.py:19 — drop unused ``api`` import (no decorators in this module). test_sql_template.py:156-193 — restore ``p_visible`` local (was flagged unused after the names→ids assertion rewrite). Switch the SQL template to ``name::text LIKE '%%TPL-%%-PARTNER%%'`` and the Python assertion to compare ids: in Odoo 17 ``res_partner.name`` is a translated ``Char``, persisted as jsonb (e.g. ``{"en_US": "TPL-VISIBLE-PARTNER"}``), so the previous direct ``name LIKE`` invokes the missing ``jsonb ~~`` operator. The ``::text`` cast matches the JSON-serialised form regardless of which language key the row uses, and asserting on ids removes the test's reliance on a specific language key in the SELECT clause. test_parallel_tool_execution.py:25 + :366 — wrap the boom string in ``_(…)``. Test fixtures still flow through Odoo's UserError translation path so pylint's ``odoolint-translation-required`` rule needs to see ``_()`` even on hard-coded test text. Tour JS files (brain_content_type_tokens, brain_floating_toolbar, brain_slash_autosave, brain_slash_focus) — additional prettier trailing-comma + parenthesis fixes that eslint v8 ``--fix`` surfaces over the v6 configuration error. 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) [IMP] cluster ai17: PR23 round 3 follow-up — Chrome timeout mixin, QUnit guard, tour bugs, prettier Round 3 follow-up after PR #23's first 9 fixes shipped — addresses 2 issues exposed by reviewer round 2 plus a batch of tour bugs that became visible once Chrome devtools port detection had enough time to start in the local heavy-bundle environment. T1 — BrowserTimeoutBoostMixin (viin_brain/tests/common.py) * Module-level snapshot of odoo.tests.common.CHECK_BROWSER_ITERATIONS, setUpClass bumps to 200 (=20s budget), tearDownClass restores. Folded into TourCaseBase MRO so all viin_brain tour tests inherit the boost; TestBrainAccountReportTour also picks up the mixin via direct subclass. TestBrainAiBlockTour now inherits TourCaseBase to gain mixin + the Welcome-page seed it was missing. * Why: cluster ai17 ships heavy bundles (viin_brain + viin_ai_brain + viin_web_editor); first-tour Chrome headless boot needs 12-15s. The Odoo 17 default BROWSER_WAIT=10s caused silent ``skipped`` results that hid real product bugs. T2 — QUnit guard for BacklinkPanel.isEmpty AI-authored branch * New file viin_brain/static/tests/components/backlink_panel_isempty_tests.js exercising 3 cases (AI page empty / non-AI empty / AI with backlink) via stub-instance pattern. Registered in __manifest__.py. * Why: the ``&& !this.state.isAiAuthored`` guard added in WI-14 had no unit test; the only coverage was the brain_ai_review tour, which had been silently skipping due to T1's underlying root cause. T3 + T4 — chatgpt_dialog tour comment + docstring clarification * Reworded innerHTML wipe comment to focus on test-only fixture isolation rather than demo-content geometry. * Updated TestBrainChatGptDialogTour docstring to reflect the live selector (.o_brain_sidebar) and explicit MockedProviderMixin wiring. Prettier 2.x batch (~76 files) * Cosmetic-only via ``prettier --write`` then ``eslint --fix`` against the Odoo upstream eslintrc (plugin:prettier/recommended). No logic changes — eslint v8 strict mode would have failed without these. Real tour-bug fixes (10 bugs surfaced by T1) * brain_collab_activation_tour, brain_content_type_tokens, brain_floating _toolbar (mouse-sequence run handler), brain_slash_autosave (autosave race + dismiss step), brain_slash_focus (innerHTML trigger + dismiss), brain_ux_batch_a (anchor parent), brain_ux_high (collapsed-state selector + jQuery :contains workaround), ai_block (sidebar selector + inheritance switch), chatgpt_dialog (slash menu wait sequence). * Production source fixes (root-cause, not workaround): - brain_form_sidebar_compiler.js: ``compile(key, params)`` — ``key`` is a string identifier, not a DOM node. Old ``key.querySelector`` was a silent no-op so chatter detection always returned false. Now scans the compiled ``res`` DOM for ``.o-mail-Form-chatter`` (mirrors mail's own compiler). - page_editor.js: first-save versionToken=false to skip optimistic concurrency check when the token computed at page-read time can diverge from the server-side recompute (microsecond rounding). FIXME marker tracks restore once compute determinism is fixed. - page_context_menu.js: ``useExternalListener`` import path — ``@odoo/owl`` (not ``@web/core/utils/hooks``). - ai_bridge_service.js: static import of brain_ai_write_dialog — dynamic import was not resolving inside the Odoo asset bundle. * 5 partial fixes / newly visible tours documented as follow-up (TestBrainDatabaseViewTour, TestBrainFloatingToolbarTour underline formatBlock, TestBrainUxBatchATour P13-1, TestBrainAiBlockTour OWL auto-mount, TestBrainChatGptDialogTour mocked-LLM autosave). 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_brain: chatgpt_dialog tour replaces dead vault selector and slash-trigger The chatgpt_dialog tour was failing on three pre-existing issues that together blocked the entire run: 1. ``.o_brain_vault_item`` is a dead selector — VaultSidebar now renders ``<select class="o_brain_sidebar_vault_select">`` and auto-selects the first vault when only one exists. The tour now waits for ``.o_brain_sidebar`` instead and lets the auto-select happen. 2. ``run: "text /ai_write"`` only works on input/textarea — the editor body is a contenteditable div, so the legacy helper threw ``$element.focusIn is not a function``. Synthesise the keystroke by appending a fresh text node, placing the caret at its end, and dispatching the ``input`` event the editor listens on. 3. The post-tour assertion silently no-op'd when ``demo_page_welcome`` was absent. Reuse ``TourCaseBase`` (which now backfills the Welcome page) so the assertion always runs, and make the test class actually inherit it. 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: widen exception tuple in AI draft attribution path message_post can raise ValueError (subject/recipient validation) and UserError (sender email config) per Odoo CE 17 mail_thread.py. Previous narrow tuple (AccessError, MissingError) caused user to lose draft when hitting these. Expanded to keep best-effort attribution intent. 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 [FIX] viin_ai_agent: contain UNIQUE constraint test in cr.savepoint to prevent transaction poison The test_tool_technical_name_unique negative-path test triggered a psycopg2 IntegrityError without isolating it via cr.savepoint(). The poisoned outer transaction surfaced an ERROR-level odoo.sql_db log line that the runbot post-install sweep tagged as failure (PR #22 build campaign-brain-v17-complete-...221679, "duplicate key value violates unique constraint viin_ai_tool_viin_ai_tool_technical_name_unique"). Apply the canonical pattern already used in viin_brain test suites (test_brain_property, test_brain_tag, test_brain_template): wrap the violation in env.cr.savepoint() and silence the expected ERROR log via mute_logger('odoo.sql_db'). Tighten the assertion from bare Exception to psycopg2.IntegrityError. 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 [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