Name: [IMP] viin_brain,viin_web_editor: UI hardening v1 (token + polish + Odoo-native + v2 seams)

State: Failed finished in 19m

PR State: merged

PR Author: David Tran

PR Author Email:

PR: #27

Committer: David Tran

Committer Email: davidtran.hp@gmail.com

Commit: 6d7ec7c9a357c0fba5cdfb57bda3408fb540a787

Description:

                                            [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.
                                            

Branch: 17.0

Instance ID: 0

Age:

Up-time:

Subbuilds Name State Detail
Build 381500 Check the quality with Pylint: from test_lint to test_pylint 19m Failed Log
Build 381501 At install tests: from account to website_twitter 135m Succeed Log
Build 381502 Post install tests: step install all modules 69m Succeed Log
Build 381503 Post install tests: from account to payment_alipay 163m Succeed Log
Build 381504 Post install tests: from payment_aps to test_viin_web_cohort 199m Succeed Log
Build 381505 Post install tests: from test_website to to_website_apps_store 79m Succeed Log
Build 381506 Post install tests: from to_website_apps_store_loc to viin_estimate_sale 88m Succeed Log
Build 381507 Post install tests: from viin_event_checkin_website to viin_project_gantt 44m Succeed Log
Build 381508 Post install tests: from viin_project_progress to website_twitter 54m Succeed Log
Build 381509 Test install all modules without demo data: from account to website_twitter 54m Succeed Log
Create Date Level Message
05/03/2026 21:30:22 INFO
Updated repository Viindoo-odoo
05/03/2026 21:30:22 INFO
Updated repository Viindoo-tvtmaaddons
05/03/2026 21:30:22 INFO
Updated repository Viindoo-erponline-enterprise
05/03/2026 21:30:22 INFO
Updated repository Viindoo-branding
05/03/2026 21:30:22 INFO
Cloned repository Viindoo-ai
05/03/2026 21:50:12 ERROR
Subbuild # 381500: odoo.addons.test_pylint.tests.test_eslint: FAIL: TestESLint.test_eslint Traceback (most recent call last): File "/data/build/Viindoo-tvtmaaddons-17.0/test_pylint/tests/test_eslint.py", line 67, in test_eslint self.assertEqual(process.returncode, 0, msg=f""" AssertionError: 1 != 0 : stdout: /data/build/rb-6d7ec7c-221701/viin_brain/static/src/components/share_dialog/share_dialog.js 56:35 error Replace `⏎············?·_t("Share·%s",·this.state.pageName)⏎···········` with `·?·_t("Share·%s",·this.state.pageName)` prettier/prettier /data/build/rb-6d7ec7c-221701/viin_brain/static/src/views/form/brain_form_sidebar_universal.js 64:53 error Replace `'div.oe_chatter,·chatter'` with `"div.oe_chatter,·chatter"` prettier/prettier 69:40 error Replace `⏎········archEl.querySelector("div.o_brain_form_sidebar_hook")⏎····` with `archEl.querySelector("div.o_brain_form_sidebar_hook")` prettier/prettier /data/build/rb-6d7ec7c-221701/viin_brain/static/tests/seams/v2_extension_seams_tests.js 34:19 error Replace `⏎············mount.classList.contains("d-none"),⏎············"canvas·mount·is·hidden·by·default·(d-none)"⏎········` with `mount.classList.contains("d-none"),·"canvas·mount·is·hidden·by·default·(d-none)"` prettier/prettier 41:13 error Replace `"canvas·mount·declares·t-ref=\"canvasMount\""` with `'canvas·mount·declares·t-ref="canvasMount"'` prettier/prettier 56:16 error Replace `"Seam·4:·ShareDialog·template·has·empty·<t·t-slot=\"collabSection\"/>"` with `'Seam·4:·ShareDialog·template·has·empty·<t·t-slot="collabSection"/>'` prettier/prettier 60:45 error Replace `"exactly·one·<t·t-slot=\"collabSection\"/>·declared"` with `'exactly·one·<t·t-slot="collabSection"/>·declared'` prettier/prettier 83:16 error Replace `"Seam·6:·AI·block·HTML·output·carries·additive·o_brain_ai_state_<status>·class",` with `⏎········"Seam·6:·AI·block·HTML·output·carries·additive·o_brain_ai_state_<status>·class",⏎·······` prettier/prettier 84:1 error Replace `········` with `············` prettier/prettier 85:9 error Insert `····` prettier/prettier 86:1 error Replace `········` with `············` prettier/prettier 87:9 error Insert `····` prettier/prettier 88:1 error Insert `····` prettier/prettier 89:9 error Insert `····` prettier/prettier 90:1 error Insert `····` prettier/prettier 91:1 error Replace `········` with `············` prettier/prettier 92:1 error Insert `····` prettier/prettier 93:1 error Replace `············` with `················` prettier/prettier 94:9 error Insert `····` prettier/prettier 95:1 error Replace `········` with `············` prettier/prettier 96:9 error Insert `····` prettier/prettier 97:1 error Insert `····` prettier/prettier 98:13 error Insert `····` prettier/prettier 99:9 error Insert `····` prettier/prettier 100:1 error Replace `····}` with `········}⏎····` prettier/prettier /data/build/rb-6d7ec7c-221701/viin_brain/static/tests/tours/brain_ux_batch_a_tour.js 126:21 error Insert `⏎···············` prettier/prettier ✖ 26 problems (26 errors, 0 warnings) 26 errors and 0 warnings potentially fixable with the `--fix` option. Perhaps you might benefit from installing the tooling found at: https://github.com/odoo/odoo/wiki/Javascript-coding-guidelines#use-a-linter stderr:
05/03/2026 21:50:12 ERROR
Subbuild # 381500: odoo.modules.loading: Module test_pylint: 1 failures, 0 errors of 7 tests
05/03/2026 21:50:12 ERROR
Subbuild # 381500: odoo.modules.loading: At least one test failed when loading the modules.
05/03/2026 21:50:12 ERROR
Subbuild # 381500: odoo.tests.result: 1 failed, 0 error(s) of 24 tests when loading database 'rb-6d7ec7c-221701-381500'