|
|
|
merged
[Phase 7.4 Wave-C] AI connectors: viin_ai_expense, viin_ai_documents, viin_ai_website (+ v19 html.text.processor backport)
|
[FIX] viin_ai_website: blog_posts_by_author extract translatable author name (Runbot res.partner.name jsonb)
res.partner.name is a translatable JSONB column when to_partner_multilang is installed (Runbot), so the raw 'rp.name AS author' returned {'en_US': ...} instead of a plain author name. Apply the shipped SSOT idiom COALESCE(to_jsonb(rp.name)->>%(lang)s, to_jsonb(rp.name)->>'en_US', rp.name::text) used by all other connectors; execute() injects params['lang']. Verified GREEN with res.partner.name jsonb.
|
Succeed
|
|
|
|
|
|
|
|
merged
[Phase 7.4 Wave-C] AI connectors: viin_ai_expense, viin_ai_documents, viin_ai_website (+ v19 html.text.processor backport)
|
[DOC] roadmap,AGENTS,architecture: reflect Phase 7.4 Wave-C shipped (PR #83)
|
Failed
|
|
|
|
|
|
|
|
merged
[Phase 7.4 Wave-C] AI connectors: viin_ai_expense, viin_ai_documents, viin_ai_website (+ v19 html.text.processor backport)
|
[ADD] test_viin_ai: Wave-C cross-module full-stack tests (expense OCR->draft, weekly blog draft)
|
Killed
|
|
Not finished
|
|
|
|
|
|
merged
[Phase 7.4 Wave-B] AI connectors: viin_ai_mrp, viin_ai_project, viin_ai_marketing (+ viin_ai_agent archived-config visibility fix)
|
[DOC] roadmap: reconcile Wave-B module counts (24 planned, 8 net-new)
Post-review reconciliation of three doc-drift flags surfaced during Phase
7.4 Wave-B review:
- Section 2 header said '(20 module)' but the v1 planning table now
enumerates 24 module names (Wave-A/B rows appended without a bump) ->
corrected to 24.
- Section 4 dependency-graph box said 'Wave-A/B/C (8 module)' vs 9 module
names in section 3 -> relabelled '(8 new)': stock is a pre-existing
Phase-3.7 stub being extended, so 8 are net-new (matches the doc's
established stub-dagger convention). ASCII box interior width preserved.
- viin_ai_helpdesk 'depends viin_ai_chat' claim: investigated and
confirmed the manifest ([viin_ai_agent, viin_helpdesk]) is correct - no
chat symbol anywhere in the module, matches the connector norm (only
viin_ai_crm pulls chat); the AGENTS.md text was already fixed. No code
change - adding an unused dependency would be wrong.
|
Succeed
|
|
|
|
|
|
|
|
merged
[Phase 7.4 Wave-B] AI connectors: viin_ai_mrp, viin_ai_project, viin_ai_marketing (+ viin_ai_agent archived-config visibility fix)
|
[DOC] roadmap,AGENTS,architecture: reflect Phase 7.4 Wave-B shipped + reconcile module inventory drift
|
Killed
|
Not started
|
Not finished
|
|
|
|
|
|
merged
[Phase 7.4 Wave-B] AI connectors: viin_ai_mrp, viin_ai_project, viin_ai_marketing (+ viin_ai_agent archived-config visibility fix)
|
[FIX] viin_ai_agent: let AI managers see and unarchive archived tools (Phase 7.4 Wave-B)
|
Killed
|
Not started
|
Not finished
|
|
|
|
|
|
merged
[IMP] viin_ai: Phase 7.1 OCR domain-prefill + Phase 7.3 Aggregation Q&A
|
[FIX] viin_brain_account_reports: keep backlink scroll on report embed
The live-mount embed_report anchor dropped data-block-anchor, silently
breaking the Backlink panel's click-to-scroll/highlight for
account-report embeds (the panel's existing click handler queries a
compound selector requiring that attribute on the embed block).
Restored the attribute on the anchor payload and re-rendered it onto
the embed component's own template root so the selector matches
again.
Added regression coverage in the existing embed-report tour: insert
the embed, navigate away and back to force a real reload/remount,
open the Backlink panel's Embeds tab, click the row, and assert the
block highlights.
Signed-off-by: David Tran <davidtran.hp@gmail.com>
|
Succeed
|
|
|
|
|
|
|
|
merged
[IMP] viin_ai: Phase 7.1 OCR domain-prefill + Phase 7.3 Aggregation Q&A
|
[FIX] viin_brain: let a Brain Admin review AI content
Approving or rejecting AI content required an explicit editor or admin
member row on the vault, so a Brain Admin who had never been added to a
vault was refused - even though the record rules already grant that
group unconditional read and write on every page and vault, and even
though the same group may already moderate comments there.
Treat the group as a bypass, exactly as comment moderation does. This
grants no power the record rules did not already grant; it removes an
inconsistency. An explicit member row keeps its meaning, and a viewer,
a commenter or a plain non-member is still refused.
|
Killed
|
|
Not finished
|
|
|
|
|
|
merged
[IMP] viin_ai: Phase 7.1 OCR domain-prefill + Phase 7.3 Aggregation Q&A
|
[FIX] viin_ai_brain: never discard AI content silently
When the caret was not inside the editable - which happens whenever the
page does not end in a paragraph - the editor refused the insert and
reported nothing. The dialog closed anyway and the generated text was
lost: no exception, no notification, nothing in the document or the
database.
Place the caret at the end of the editable before inserting, and treat
anything other than a real insert - a refusal, or a step the editor
rolled back - as a failure. On failure the dialog stays open, the
generated text remains available to copy, and an error is shown.
Add a tour that drives the page shape which triggered the loss and
asserts the generated content reaches the database, and assert
server-side that approving an AI block really persists the review.
|
Failed
|
|
|
|
|
|
|
|
merged
[IMP] viin_ai: Phase 7.1 OCR domain-prefill + Phase 7.3 Aggregation Q&A
|
[FIX] viin_brain: rename property handle clearing pylint W0622 builtin-shadow
The flake8 cleanup lowercased the env-model handle `Property` to `property`
to satisfy N806, which shadows the Python builtin and trips the separate
test_pylint gate (W0622 redefining-builtin) in four viin_brain scopes.
Rename the handle to `property_model` - lowercase (keeps N806 clean) and not
a builtin (clears W0622). Pure rename, behaviour unchanged; both lint gates
and the viin_brain test suite pass.
|
Failed
|
|
|
|
|
|
|
|
merged
[IMP] viin_ai: Phase 7.1 OCR domain-prefill + Phase 7.3 Aggregation Q&A
|
[IMP] repo: resolve flake8 gate across all modules
Clean the full test_flake8 gate backlog (913 violations, 42
modules) to 0: rename-all pep8-naming (N806/N802/N803 lowercased,
incl. the `Model = self.env[...]` handles and unittest-mirror
helpers + their call-sites), line-wraps (B950 <=96), exception
chaining (B904 `from err`), f-string conversion (B907), W503/W504
by join/extract (never move-operator), B905 `strict=True`, B023
loop-var hoist, and `# noqa: B018` on the manifest literal dicts
(Odoo requires a literal dict).
Behavior-preserving: each module's full non-tour test suite
verified green after its renames.
|
Failed
|
|
|
|
|
|
|
|
merged
[IMP] viin_ai: Phase 7.1 OCR domain-prefill + Phase 7.3 Aggregation Q&A
|
[DOC] AGENTS: reflect Phase 7.1 prefill + Phase 7.3 aggregation module changes
|
Failed
|
|
|
|
|
|
|
|
open
[ADD] Brain per-app seed carriers: account/purchase/helpdesk/stock/hr_recruitment (close SIDEBAR-BIND L456)
|
[DOC] roadmap,AGENTS: Brain per-app carriers close SIDEBAR-BIND (L456) + ADR-012
|
Succeed
|
|
|
|
|
|
|
|
merged
[IMP] viin_ai_workflow + viin_ai_pulse: Phase 7.2 Scheduled agent UI
|
[FIX] viin_ai_rag: refuse keyless/misconfigured OCR as a clean config-gap
A vision-capable but keyless/misconfigured provider is now refused at pre-flight (status=error + actionable message + INFO log, no vendor call) instead of failing deep with a WARNING+traceback; genuine vendor failures still WARNING. Adds a behavior test and drops the now-unnecessary log mutes.
|
Succeed
|
|
|
|
|
|
|
|
merged
[IMP] viin_ai_workflow + viin_ai_pulse: Phase 7.2 Scheduled agent UI
|
[FIX] viin_ai_rag: mute expected OCR-failure log noise in tests
The no-key negative-path tests (deliberate provider failure, audio-refused)
and the FSM/embedding tests (which call the global _process_pending cron sweep
that incidentally OCRs the committed demo image source with no key) emitted
expected WARNING+traceback lines from viin.ai.media.process into the CI log.
Wrap only those expected emissions in mute_logger on the exact logger
(odoo.addons.viin_ai_rag.models.media): the model-side warning stays (prod
must see OCR failures) and every assertion is unchanged.
Test-only; no model/production change. Verified fresh-DB demo-on:
viin_ai_rag 0 failed 0 error, target log noise gone.
|
Killed
|
|
Not finished
|
|
|
|
|
|
merged
[IMP] viin_ai_workflow + viin_ai_pulse: Phase 7.2 Scheduled agent UI
|
[DOC] roadmap: Phase 7.2 term-sync + M7-3 ops test-bundle resolved
|
Failed
|
|
|
|
|
|
|
|
merged
[DOC] decisions: ratify ADR-013 + ADR-014 -> Accepted
|
[DOC] decisions: ratify ADR-013 (voice modality) + ADR-014 (dual-deployment BYOK/managed) -> Accepted
|
Killed
|
|
Not finished
|
|
|
|
|
|
merged
[IMP] viin_ai: promote to app + two-group config-admin + Phase 7.1 Vision/OCR
|
[IMP] viin_ai + viin_brain: branded module icons for the AI/Brain family (36 modules)
Add static/description/icon.png (+ icon.svg source) for every installable module
in the ai17 AI + Brain clusters, as one consistent Viindoo-branded icon family:
shared cyan #00BBCE -> purple #7F4282 gradient tile + white 4-point AI sparkle;
per-module white glyph differentiator (flagship viin_ai = neural hub-and-spoke).
Closes R8 (app viin_ai had no icon). v17 PNG-only convention; no manifest 'icon' key needed.
Rasterized via librsvg (gi.repository.Rsvg + cairo) - magick/convert SVG delegate
silently corrupts to 16-bit grayscale on this box, so it is deliberately not used.
|
Killed
|
|
|
|
|
|
|
|
merged
[IMP] viin_ai: promote to app + two-group config-admin + Phase 7.1 Vision/OCR
|
[DOC] update AGENTS.md + roadmap + ai docs: viin_ai app rename, 2-group + config-admin, Phase 7.1 vision/OCR
Reconcile live docs against two shipped work-items so docs don't drift
behind code (ai17-roadmap-agents-docs-drift-behind-git pattern):
Viec 1 (rename + app + security redesign, ADR-023):
- viin_ai_base -> viin_ai (git mv); pure meta bundle retired (deleted,
not re-created); viin_ai promoted to a sellable app (application=True,
99.9 EUR).
- Two-group model group_operator + group_admin (app-scoped, does NOT
imply base.group_system) + module-category xmlid fix
(base.module_category_productivity_ai).
- New viin.ai.config app-scoped config-admin TransientModel.
Viec 2 (Phase 7.1 Multimodal, vision/OCR branch, DONE):
- provider.call_vision / call_ocr implemented (were locked stubs).
- New viin.ai.media OCR pipeline in viin_ai_rag (sha256 dedup per
company, status machine, cron) + source_type image/pdf_ocr.
- viin_ai_agent._do_vision_call multimodal seam (additive).
- Voice (STT/TTS, call_transcription) stays DEFERRED - ADR-013
(Proposed, awaiting CEO ratify); no audio source type yet.
Files: AGENTS.md (module map), docs/roadmap.md (Hien trang + W26-W27
Phase 7.1 checklist + module inventory count 39->38), docs/ai/README.md,
docs/ai/architecture.md (fixed self-referential meta-bundle bundle
section + extensibility-anchor drift note + new OCR/vision flow
diagram), docs/ai/data-models.md + docs/ai/security.md (call_vision/
call_ocr stub language corrected to reflect shipped reality).
Verified: grep -rn "viin_ai_base" AGENTS.md docs/ (excl. decisions/) = 0.
grep -rn "meta module|1-click|1 meta|meta bundle|meta pack" AGENTS.md
docs/ (excl. decisions/) = 0 (only docs/history/ append-only record
retains the old phrasing, out of scope).
|
Killed
|
|
Not finished
|
|
|
|
|
|
merged
[IMP] viin_ai/viin_brain: Wave-1/2 residuals + Brain editor full-width + sidebar bind
|
[FIX] viin_ai_brain: move mid-doc page creation to setUpClass
Creating the "AI Block Mid-Doc Test Page" inside the test METHOD left it
in an uncommitted savepoint. The browser's pooled HTTP cursors only see
data COMMITTED by setUpClass, so the sidebar's _loadRoots RPC never found
the page and the tour timed out on fresh DBs (false-green on reused DBs
where the record was already committed).
Move the page creation from test_brain_ai_block_mid_doc_tour() into
setUpClass (classmethod, on cls) so it is committed before the browser
starts. Mirrors TourCaseBase which seeds Welcome + Ideas pages in
setUpClass for the same reason.
Verified: 0 failed, 0 error(s) of 2 tests (TestBrainAiBlockMidDocTour +
TestBrainAiBlockTour) on genuinely fresh DB test_middoc_fresh_1782879700
(-i viin_ai_brain,viin_ai_editor,viin_ai_ops,viin_brain, zero pre-committed
state).
|
Killed
|
|
|
|
|
|
|
|
merged
[IMP] viin_ai/viin_brain: Wave-1/2 residuals + Brain editor full-width + sidebar bind
|
[FIX] viin_brain: remove hardcoded `url` from 3 test-only tours (WI-9 redirect bug)
tour_service.js (Odoo 17 line 351) redirects to `tour.url` when it differs
from `options.startUrl`. All 3 tours had a static `url` field that differed
from the Python-supplied startUrl (which carries active_page_id +
active_vault_id), so the runner navigated away from the params-bearing URL
before BrainApp could read them - making active_page_id a no-op.
Fix: drop `url` from the 3 test-only tours so tour_service's
`if (tour.url && tour.url !== options.startUrl && options.redirect)` guard is
never entered. The Python wrappers already supply the correct start URL;
these tours exist only for automated tests so the `url` field is not needed.
Tours fixed:
- viin_brain_editor_overflow (was "/web#action=viin_brain.action_viin_brain_app")
- viin_brain_3pane_resize (was "/web#action=viin_brain.action_viin_brain_app")
- viin_brain_moderation_badge (was "/odoo/brain")
|
Failed
|
|
|
|
|
|
|
|
merged
[IMP] viin_ai/viin_brain: Wave-1/2 residuals + Brain editor full-width + sidebar bind
|
[FIX] viin_brain: remove hardcoded `url` from 3 test-only tours (WI-9 redirect bug)
tour_service.js (Odoo 17 line 351) redirects to `tour.url` when it differs
from `options.startUrl`. All 3 tours had a static `url` field that differed
from the Python-supplied startUrl (which carries active_page_id +
active_vault_id), so the runner navigated away from the params-bearing URL
before BrainApp could read them - making active_page_id a no-op.
Fix: drop `url` from the 3 test-only tours so tour_service's
`if (tour.url && tour.url !== options.startUrl && options.redirect)` guard is
never entered. The Python wrappers already supply the correct start URL;
these tours exist only for automated tests so the `url` field is not needed.
Tours fixed:
- viin_brain_editor_overflow (was "/web#action=viin_brain.action_viin_brain_app")
- viin_brain_3pane_resize (was "/web#action=viin_brain.action_viin_brain_app")
- viin_brain_moderation_badge (was "/odoo/brain")
|
Killed
|
|
Not finished
|
|
|
|
|
|
merged
[IMP] viin_ai/viin_brain: Wave-1/2 residuals + Brain editor full-width + sidebar bind
|
[FIX] viin_brain: prettier-format overflow tour JS (eslint gate)
Wrap string concatenations in throw new Error() calls across AC-OVF-1
and AC-OVF-2 steps to satisfy printWidth:100 (prettier 2.8.8 pinned).
Logic unchanged - only whitespace/line-break formatting.
|
Killed
|
|
Not finished
|
|
|
|
|
|
merged
[IMP] viin_ai/viin_brain: Wave-1/2 residuals + Brain editor full-width + sidebar bind
|
[FIX] viin_brain: 768px tablet context-pane horizontal-scroll defect
At 768px viewport the collapsed context pane (translateX(288px)) was
extending 288px beyond the viewport right edge. .o_brain_app_body clipped
it visually but document.documentElement.scrollWidth expanded to 1056px,
allowing real user scroll via window.scrollTo(288,0).
Root cause: .o_brain_app_body had no position:relative so the absolute
context pane's containing block was an outer Odoo ancestor wider than the
viewport; overflow-x:hidden on the app body did not clip the pane from the
document's scroll ancestor perspective.
Fix: add position:relative + overflow-x:hidden to .o_brain_app_body in the
tablet @media (min-width:768px) block. This makes the app body the containing
block for the pane (so translateX clips at the app body's 768px right edge)
and prevents the off-screen portion from contributing to document.scrollWidth.
The 2rem visible handle strip is still within bounds and remains clickable.
Also add defensive table { max-width:100% } inside .o_brain_editor_body_edit
for plain HTML tables (pasted content). Brain database blocks have their own
overflow-x:auto wrapper and are unaffected.
|
Failed
|
|
|
|
|
|
|
|
merged
[IMP] viin_ai_base: PII redaction default-ON (fail-safe) + Settings warning
|
[REF] viin_ai_base: reorder compute before CRUD per model-ordering convention
Move _compute_pii_redaction_cloud_exposure above get_values/set_values in
res_config_settings.py to comply with 17.0/model-ordering.md (compute methods
must precede CRUD/config overrides). Pure code-move, no logic change.
|
Killed
|
|
|
|
|
|
|
|
merged
[DOC] roadmap, AGENTS: reconcile Phase 7.4 Wave-A + P-OPS-1/4 shipped status (drift)
|
[FIX] CLAUDE.md & AGENTS.md: remove oudated rules.
|
Killed
|
Not started
|
Not finished
|
|
|
|
|
|
merged
[DOC] roadmap, AGENTS: reconcile Phase 7.4 Wave-A + P-OPS-1/4 shipped status (drift)
|
[DOC] roadmap, AGENTS: reconcile Phase 7.4 Wave-A + P-OPS-1/4 shipped status (drift)
Docs lagged behind code: Wave-A connectors (viin_ai_hr 0bf395a2, viin_ai_purchase d6dba427, viin_ai_stock anomaly+ABC fb0095b9) shipped 2026-06-29 but absent from AGENTS §2 map / §3 status and roadmap still marked them future; P-OPS-1/P-OPS-4 checklists still [ ] though shipped (35d3177c / b650d5a5).
14 status-only edits (8 roadmap.md + 6 AGENTS.md), each SHA-anchored. No docs/decisions/ touched (append-only). No scope/prose invented.
|
Killed
|
|
Not finished
|
|
|
|
|
|
merged
[ADD] Phase 7.4 Wave-A AI connectors: viin_ai_hr, viin_ai_purchase + viin_ai_stock extension
|
[FIX] viin_ai_purchase: mute expected deny-path ir_actions warning in ACL test
|
Killed
|
|
|
|
|
|
|
|
merged
[ADD] Phase 7.4 Wave-A AI connectors: viin_ai_hr, viin_ai_purchase + viin_ai_stock extension
|
[FIX] viin_ai_stock: behavior test for abc total==0 (LOW-S3)
Replace tautological static text-check with a true behavior test.
Isolation: create company_b + internal location (company_b) + product
(standard_price=0.0) + quant (qty=10). Run action as user_b who belongs
to company_b only. ir.rule stock_quant_rule filters stock.quant by
company_id -> user_b sees ONLY company_b quants (demo quants invisible).
Result: read_group returns one group (groups not empty) but total = qty *
0.0 = 0.0, exercising the 'if not total:' branch directly.
RED evidence (old code, pct=0.0 if total else 0.0 -> abc='A'):
AssertionError: [{'rank': 1, ..., 'abc_class': 'A'}] is not false
GREEN evidence (fix, if not total: return []):
22 tests, 0 failed, 0 error(s)
|
Killed
|
|
|
|
|
|
|
|
merged
[ADD] viin_ai: M5 completion (Cognitive Wave-2) + skill catalog curation
|
[DOC] decisions, roadmap, AGENTS: ADR-020 Wave-2 source (Anthropic) + ADR-021 Wave-1 reclaim (Viindoo-original) / CoWork removed / ERP-cloud catalog scope
|
Killed
|
|
|
|
|
|
|
|
merged
[ADD] viin_ai: M5 completion (Cognitive Wave-2) + skill catalog curation
|
[DOC] decisions, roadmap, AGENTS: ADR-020 Wave-2 source (Anthropic) + ADR-021 Wave-1 reclaim (Viindoo-original) / CoWork removed / ERP-cloud catalog scope
|
Failed
|
|
|
|
|
|
|
|
merged
[ADD] viin_ai: M5 completion (Cognitive Wave-2) + skill catalog curation
|
[DOC] decisions, roadmap, AGENTS: ADR-020 Wave-2 source (Anthropic) + ADR-021 Wave-1 reclaim (Viindoo-original) / CoWork removed / ERP-cloud catalog scope
|
Killed
|
|
Not finished
|
|
|
|
|
|
merged
[ADD] viin_ai_base/search/rag: ADR-011 provider active-default + AI/M5 docs reconcile
|
[DOC] roadmap, wi-004: tick verified-shipped checkboxes (M5 drift)
11 checkboxes were [ ] but the feature is actually shipped (each verified vs code, evidence inline):
- roadmap: viin.ai.skill 3-model, viin.ai.pulse.rule + viin.ai.signal, Pulse PASS/SKIP
cron gate on work.routine, execution_mode='scheduled' unblock, runbook ship.
- wi-004: 5 ADR (004-008) Status Accepted, WI-004 Active, cognitive-layer.md ship,
skill-catalog-from-cowork.md ship, decisions/README index, operational runbook.
Genuinely-pending left UNCHECKED (the M5 code gap, not drift): cost_avoided_weekly_usd
dashboard, +25 Pulse rules, 1-demo-per-model, Pulse<->L1 dynamic threshold, WoW demo CFO.
|
Killed
|
|
|
|
|
|
|
|
merged
[ADD] viin_brain, viin_ai_brain: KG-temporal Brain UI - ADR-006 UI-layer (C-gamma scrubber)
|
[FIX] viin_brain: graph canvas off-frame/resize/clip + playhead overshoot + template icon
A deep visual-QA sweep (rect/coordinate-measured) found visual defects that
pass DOM-presence checks but render wrong:
- Graph Canvas force layout centered nodes at the 600px default coordinate
space, so in the ~298px context pane 2 of 3 nodes rendered OFF the right edge
(DOM-present, invisible). Measure the real container size BEFORE the force
layout; re-run the layout (debounced 150ms) on pane resize so nodes re-center
within the measured width (verified cx within [0,width] at 213/298/498px).
- Canvas SVG was a hard 400px in a non-scrollable pane -> clipped ~6px below the
viewport. Size the wrapper to the available pane height (flex).
- Validity-strip playhead overshot the track by its own 2px width at max scrub
(left:100% + 2px marker). Offset by translateX(-pct*0.02px) so the marker
stays flush at 100% and is unchanged mid-track.
- "Meeting Notes" template shipped icon "notebook", which is not a Font Awesome
4.7 glyph (Odoo 17 ships FA4.7) -> empty icon box. Use the valid "sticky-note-o".
|
Killed
|
|
|
|
|
|
|
|
merged
[ADD] viin_brain, viin_ai_brain: KG-temporal Brain UI - ADR-006 UI-layer (C-gamma scrubber)
|
[IMP] viin_brain: mobile/tablet responsive - frozen-backdrop fix + context bottom-sheet
Mobile/tablet defects found by a live Playwright survey (phone 390 + tablet 768):
- BLOCKER "frozen UI" on phone: a global `.o_brain_drawer_backdrop` rule in
brain_create_drawer.scss (pointer-events:all, z-index:1040) collided with the
mobile sidebar backdrop of the same class, so the always-present phone backdrop
swallowed every tap. Rename the create-drawer backdrop to a private class.
- Phone: page context menu clamped on-screen (was off the left edge); header
actions wrap; sidebar containing-block fix; sidebar auto-closes after page nav.
- Tablet: "More" overflow menu + temporal slider + context-pane toggle handle
kept inside the viewport.
- NEW: phone context bottom-sheet - the context pane (Graph / temporal scrubber /
Fact History / Properties / Backlinks) was display:none on phone; now a
bottom-sheet (FAB trigger + backdrop + drag-dismiss) makes it reachable.
All changes gated to phone/tablet media queries + isMobileViewport; desktop
(>=1024px) byte-identical.
|
Killed
|
|
Not finished
|
|
|
|
|
|
merged
[ADD] viin_brain, viin_ai_brain: KG-temporal Brain UI - ADR-006 UI-layer (C-gamma scrubber)
|
[FIX] viin_brain: temporal tours to tabWidth=4 (real Viindoo Runbot eslint gate)
The previous prettier pass used standalone prettier 2.8.8 (tabWidth=2 default)
and was verified against odoo/addons/test_lint/tests/eslintrc - which carries NO
prettier rule, so it reported a false CLEAN. Viindoo Runbot actually runs the
tvtmaaddons17/test_pylint fork of test_eslint, which points at
web/tooling/_eslintrc.json (extends plugin:prettier/recommended, tabWidth=4,
printWidth=100, semi). Under that real gate the 3 new tour files were 359
prettier/prettier errors (2-space vs required 4-space). Reformat them with
`eslint --fix -c web/tooling/_eslintrc.json`. No behavior change (tours stay
green). The pre-existing graph_panel tour already used 4-space, hence it passed.
|
Killed
|
|
|
|
|
|
|
|
merged
[ADD] viin_brain, viin_ai_brain: KG-temporal Brain UI - ADR-006 UI-layer (C-gamma scrubber)
|
[FIX] viin_brain: prettier 2.8.8 on temporal tours + drop unused import (Runbot lint)
Runbot test_pylint gate was red: TestESLint flagged 12 prettier/prettier errors
across the 3 new temporal tour files, and TestFlake8 flagged F401 unused
`from odoo import fields` in test_brain_snapshot_as_of.py (the clock is patched
via the string path `patch('odoo.fields.Datetime.now', ...)`, never the symbol).
Reformat the tours with the pinned prettier 2.8.8 (es5) and remove the dead
import. No logic change.
|
Failed
|
|
|
|
|
|
|
|
merged
[ADD] viin_brain, viin_ai_brain: KG-temporal Brain UI - ADR-006 UI-layer (C-gamma scrubber)
|
[IMP] viin_ai_brain: Fact-history panel + ai_bridge recordStateAsOf (ADR-006)
Bridge the ADR-006 record-state-as-of tool into the Brain UI.
- FactHistoryPanel: reconstruct an ERP record's tracked-field state at a
chosen instant, mounted in BacklinkPanel via the ai_bridge seam and gated
on ai_bridge.available so viin_brain still installs standalone (cluster
decoupling, AGENTS.md section 4 #2).
- ai_bridge_service.recordStateAsOf(model, resId, asOf) -> orm.call
tool_brain_record_state_as_of. READ path: the tool self-guards via
check_access_rights + check_access_rule as the calling user (no sudo,
no T5 attribution needed for a read/display surface).
- ACL no-leak test (a user without access gets {state:{}}, not a sudo
bypass) + fact-history tour.
|
Failed
|
|
|
|
|
|
|
|
merged
[IMP] viin_ai_brain, viin_brain, docs: Brain Standard-17 closeout (11 tools + native OT + drift reconcile)
|
[IMP] viin_brain: harden CW2 collab tests per code-review
Post-review hardening for PR #68 (review report
.odoo-ai/reviews/pr68-2026-06-22/viin_brain.md):
- test_brain_collab_activation_tour.py: make the native-collab precondition
deterministic so the tour's channel assertion actually runs instead of being
silently skipped - set the admin notification_type to 'inbox' in setUpClass
(drives session.notification_type truthy -> _hasICEServers ->
_isCollaborationEnabled). The assertion still FAILS when wiring is wrong
(collaborationChannel/busService remain required). Add tearDownClass to
restore notification_type and reset realtime_collab=False (no state leak).
- test_brain_collab_block_roundtrip.py: exercise the real ORM path
(write content_html/blocks -> re-read) instead of calling the private
_derive_from_* helpers directly, keeping the suite red-able.
- test_brain_realtime_collab.py: assertEqual(stored, 'True') (exact) instead
of a permissive membership check.
- brain_collab_activation_tour.js: keep the canonical
odoo.loader.modules.get(...) pattern (matches Odoo 17 core rte.js; require()
is not a global in tour run callbacks) - add a comment to prevent re-flagging.
Review finding F-1 (switch to require) was a false positive.
- CHANGELOG.md: link ADR-002 for traceability.
Browser tour verified by Runbot (headless tour not runnable locally).
|
Killed
|
|
|
|
|
|
|
|
merged
[IMP] viin_ai_agent, viin_ai_base: streaming trace header lifecycle + provider Test Connection
|
[TEST] viin_ai_account, viin_ai_approval_account: capture expected deny-path WARNINGs
The negative ACL tests and the C1 confused-deputy guard test exercise deny paths
that legitimately log a WARNING (core ir.actions "Forbidden server action"; the
match_payment C1 "lacks write authority ... refusing to reconcile"). Wrap each
in assertLogs so the warning is both asserted (the guard fired) and captured (no
longer leaking to the runbot log). Strengthens the tests; no assertion removed.
|
Killed
|
|
|
|
|