Commit Graph

125 Commits

Author SHA1 Message Date
daveadmin effd3289b4 feat: add Legal Translation tool (translate.php)
New dedicated tool for translating Norwegian legal documents (Barnevernet
letters, court decisions, correspondence) into the user's chosen language
with legal-terminology annotations.

- translate.php: new tool page with source/target language selectors,
  4-way UI lang switcher, file upload, doc picker, streaming results
- api/translate.php: NDJSON streaming endpoint; Azure GPT-4o-mini with
  legal-aware prompt that preserves Norwegian statute refs verbatim and
  annotates terms with no target-language equivalent; 2-credit cost
- assets/js/translate.js: form handler, NDJSON stream reader, copy button
- assets/css/tools.css: .lt-* styles for translation result + annotations
- includes/i18n.php: 22 lt_* keys × 4 languages; translate entry in nav
- includes/FreeTier.php: translate → 2 credits
- includes/CaseResults.php + case-result.php: translate in eligible tools,
  toolLabel, toolIcon, deriveTitle, rendering block, rerun map

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 09:59:06 +02:00
daveadmin 21c092e0d0 Legal Analysis: full language follow-through (UI + LLM)
The tool now respects the chosen UI language end-to-end — even if the
source document is Norwegian, a user on EN/UK/PL gets the analysis in
their language. Norwegian statute references (barnevernsloven § 4-25,
EMK Art. 8) and case names (Strand Lobben mot Norge 37283/13) are kept
verbatim because they are proper nouns.

LLM (LegalAnalysisAgent.php):
- extractIssues: prompt asks for question + brief_context in user's
  language; statute refs preserved
- answerIssue: Norwegian core system prompt (keeps fine-tune precision)
  + language-coercion line for non-NO; localised context/source labels
- synthesise: overall_assessment, next_steps, disclaimer in user's
  language; explicit per-language disclaimer text
- runFullAnalysis empty-case fallback also localised
- what_to_check translated per language

UI:
- 40 new la_* translation keys in i18n.php × 4 languages (NO/EN/UK/PL)
- legal-analysis.php: 4-way lang switcher, dbnToolsT() for every label,
  emits window.DBN_LA_I18N for runtime JS strings
- legal-analysis.js: t() helper reads from window.DBN_LA_I18N
- layout_footer.php: emits window.DBN_CURRENT_LANG +
  window.DBN_ADDON_I18N so the legal-analysis add-on button works in
  the page's language no matter which tool it's invoked from
- tools.js add-on: reads from DBN_ADDON_I18N, passes DBN_CURRENT_LANG
  to /api/legal-analysis.php so server responds in same language

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 08:43:15 +02:00
daveadmin 2509a596c1 Fix file picker double-open across all remaining tools
Same defensive guard as legal-analysis + summarize, now applied to the
upload-zone and audio-zone handlers in tools.js. Affects redact,
timeline, and transcribe (which all share these zones via tools.js's
setupUpload / setupAudioUpload). Stops native label-for clicks and the
input's own click from bubbling into the zone handler that would
otherwise programmatically re-open the picker.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 08:23:58 +02:00
daveadmin 5589e891f4 Fix file picker reopening after selection on legal-analysis + summarize
The "browse" label's native for=input trigger AND the upload-zone click
handler both called uploadInput.click(), so the picker opened twice when
the user clicked the browse text. Stop propagation on the label and the
input itself, plus tighten the zone handler to recognise any label-for
descendant.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 08:19:28 +02:00
daveadmin 7e6463ed22 Add Legal Analysis tool — two-pass DBN-legal pipeline
Restores the dbn-legal-agent-v3 fine-tune on ocelot (was silently aliased
to plain qwen2.5:14b in LiteLLM since the viper retirement) and ships a
new tool that uses it via a two-pass flow:

  Pass 1 (Azure 4o-mini)  → extract up to 5 distinct legal issues
  Pass 2 (ocelot v3 only) → answer each issue, ≤350 tokens, with corpus
  Pass 3 (Azure 4o-mini)  → synthesise overall assessment + next steps

The 12GB-VRAM constraint motivates the split: dbn-legal-agent-v3 stays
hot in VRAM through the 5 sequential per-issue calls because issue
extraction and synthesis run on Azure, not on ocelot.

New surface:
  - includes/LegalAnalysisAgent.php
  - api/legal-analysis.php           (NDJSON streaming endpoint)
  - legal-analysis.php               (dedicated tool page)
  - assets/js/legal-analysis.js      (streamed UI with per-issue cards)
  - Save-result + case-result.php rendering for legal-analysis output
  - Nav registration in all four UI languages

Add-on integration: a "⚖️🇳🇴 Run deep legal analysis on this text"
button now appears on Summarize, Ask, and Redact result pages and
streams the same pipeline inline below the existing result.

Existing tools relabelled: the misleading "🇳🇴 Norwegian specialist v3 "
option on advocate/deep-research/discrepancy/barnevernet is now honestly
"DBN Legal Agent" — now that the real fine-tune is actually deployed,
the label finally matches reality. The advocate.php v2 option was
removed since the v2 GGUF is retired.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 04:21:01 +02:00
daveadmin 2013648ee0 Add manual 'Save result' to all tools — replaces auto-save
All tool results can now be saved to My Case manually. Users click
'Save result', type a description, and confirm. This replaces the
previous silent auto-save on barnevernet/timeline/etc., giving users
control over what stays and what it's called (supports multiple runs
of the same tool with different titles).

- CaseResults: extend ELIGIBLE_TOOLS to include summarize, ask, redact,
  transcribe; add toolLabel/toolIcon entries; support explicit title
  via meta['title'] in save()
- api/case/save-result.php: new client-initiated save endpoint;
  accepts tool + title + input_payload + output_payload + meta
- Remove CaseResults::save() auto-save from barnevernet, deep-research,
  discrepancy, korrespond, timeline API endpoints
- tools.js: add showSaveResultButton() (exposed as window.dbnShowSaveResultButton);
  wire for ask, redact, timeline, transcribe (both file-upload and
  stored-audio paths)
- barnevernet.js: wire save button after final result render
- summarize.js: wire save button after renderFinal(); passes sumResults
  container so widget appears in the correct #sumResults div
- case-result.php: rich tool-specific rendering for summarize, ask,
  redact, transcribe, timeline; update re-run link map to include all
  new tools
- tools.css: styles for .save-result-widget and its states (idle,
  prompt, done, error)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 01:27:26 +02:00
daveadmin 0fcfed1a86 fix: allow empty text field when doc_ids supplied to all tool APIs
dbnToolsString was called with required=true (default), so it aborted
before dbnToolsInjectDocContent could inject content from the doc picker.
Now passes required=false and validates after injection so doc-only
submissions work in timeline, redact, ask, and summarize.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 00:39:46 +02:00
daveadmin fa42c7223a fix: remove browser-native required validation blocking doc picker submissions
Forms lacked novalidate and textareas had required, so the browser fired
HTML5 validation before tools.js could intercept — blocking submissions
where text came from the doc picker or file upload rather than the textarea.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 00:34:38 +02:00
daveadmin 2e8fda72d2 fix: fetch doc content from client_documents when no chunks exist
Documents saved via save-from-tool or case-upload store content directly
in client_documents.content without being chunked into client_chunks.
dbnToolsFetchDocChunks now falls back to client_documents.content for
any requested doc_ids that returned no rows from client_chunks.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 00:24:57 +02:00
daveadmin e768662efe Add Summarize Document tool — engine selector, file upload, optional corpus enrichment
- summarize.php: full custom inline form (replaces tool_form.php wrapper) with
  lang switcher, azure_mini/azure_full/gpu engine selector, 8 corpus-slice
  toggles (all off by default), doc picker, file upload zone, and textarea
- api/summarize.php: rewritten to streaming NDJSON (matches barnevernet pattern);
  accepts JSON payload with text, language, engine, slices[], doc_ids[]
- includes/LegalTools.php: adds corpusContextForSummarize() (keyword search via
  ClientRagPipeline) and summarizeWithContext() (engine-aware LLM call with
  optional corpus prepend); returns structured JSON matching existing summarize format
- assets/js/summarize.js: self-contained IIFE handling file upload via
  api/extract.php, slice toggles, NDJSON stream reader, result rendering,
  and trace panel update
- includes/i18n.php: adds 'summarize' to nav in all 4 languages (EN/NO/UK/PL),
  inserted after 'redact' in the tool order with icon 'SZ'

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 23:25:40 +02:00
daveadmin 8587ec372f fix: expose DBN_USER_TIER so plus/pro SSO users can use doc picker
isPaidUser() was checking DBN_FREE_TIER_BALANCE === undefined, which
is only true for CaveauAI sessions. SSO users (even plus/pro) always
have DBN_FREE_TIER_BALANCE set, so the picker was showing the upgrade
modal for everyone in the SSO flow. Now reads DBN_USER_TIER explicitly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 22:45:57 +02:00
daveadmin 212d3650f5 feat: add doc picker button to timeline and redact tool pages
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 22:33:04 +02:00
daveadmin f383ad5b74 feat: document & audio corpus picker for all tools
- Add "Select from My Docs" button to all text tool forms; free-tier
  users see an upgrade modal, paid (CaveauAI) users get a searchable
  multi-select modal backed by /api/dashboard/documents.php
- Add "Select from My Audio" picker on Transcribe with single-select
  and a "Save to My Audio" button for persisting uploaded clips
- New PHP helpers in bootstrap.php: dbnToolsFetchDocChunks,
  dbnToolsClientIdFromSession, dbnToolsInjectDocContent
- timeline, ask, redact APIs prepend selected document content
  (fetched from client_chunks SQL) before the textarea text
- api/dashboard/audio-upload.php stores audio files on server and
  creates a client_documents row with source_type='audio'
- api/transcribe.php falls back to stored audio via audio_doc_id POST
  field when no file is uploaded
- api/dashboard/documents.php supports ?source_type= filter
- tools.js: doc_ids added to JSON payload; stored-audio transcribe path
- New assets/css/doc-picker.css, assets/js/doc-picker.js
- SQL migration: scripts/sql/audio_docs_column.sql

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 21:38:04 +02:00
daveadmin 58e1d1dae1 Fix tool URLs in nav dropdown to use absolute paths
Relative slug.php URLs resolved to /dashboard/slug.php when the nav
was included from /dashboard/* pages. Prefix with / to make absolute.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 20:13:22 +02:00
daveadmin a9e64b65ce i18n all /dashboard/ corpus pages for en/no/uk/pl
- Add require_once bootstrap.php to all 6 dashboard page files so
  dbnToolsT() is available before layout_dashboard.php is included
- Add dash_upload_category_lbl key to no/uk/pl sections of i18n.php
  (was only in English); Kategori/Категорія/Kategoria
- Fix broken ternary on upload.php Category label — replace with
  dbnToolsT('dash_upload_category_lbl', $uiLang)
- layout_dashboard.php outputs window.DBN_I18N with all js_* keys
  so dashboard JS reads locale-aware strings from PHP translations

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 20:10:57 +02:00
daveadmin 90117fa9de feat(nav): unified navbar, account page, corpus summary widget, and i18n fixes
- New includes/nav.php: sticky site-wide nav with Tools dropdown, Dashboard
  link, compact language switcher, user identity → /account.php, Log out
- New account.php: credits & plan, profile, team, usage sections
- New api/corpus-summary.php: JSON endpoint for corpus doc count + last updated
- Replaces topbar in layout.php, layout_dashboard.php, and dashboard.php
- Fixes hardcoded Norwegian strings in dashboard.php credit cards via dbnToolsT()
- Adds 35 new i18n keys across all 4 languages (en/no/uk/pl) in i18n.php
- CSS: .dbn-nav navbar + .account-* account page styles in tools.css

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 19:11:39 +02:00
daveadmin 33dc5406b2 feat(auth): add login/logout, user identity, and soft auth gate
- api/logout.php: destroys session + clears cookie, redirects to /
- api/guest-session.php: sets guest flag, lets users explore without account
- layout.php: removes hard PHP redirect; authenticated users see email +
  "Logg ut" in topbar; guests see guest banner (sticky, dismissible) and
  auth gate modal (dismissible via localStorage) instead of redirect
- layout_footer.php: injects auth gate modal + JS for banner/modal dismiss
- layout_dashboard.php: adds username + "Logg ut" to dash-topbar
- index.php: adds "Utforsk uten konto" link under primary login CTA
- tools.css: .guest-banner, .auth-gate-*, .topbar-user, .dash-topbar__user

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 18:05:51 +02:00
daveadmin b6212b8729 fix(dashboard): use synthetic internal email for SSO owner row
client_users.email has a UNIQUE constraint. SSO users who already have a
CaveauAI account share the same email address, causing provision to fail
with "already belongs to another workspace".

Fix: SSO-provisioned client_users rows use dbn-sso-{client_id}@dbn.tools.internal
as the owner email so they never collide with real account rows. The real
email stays on clients.contact_email for display purposes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 17:51:35 +02:00
daveadmin 06d01a3bce feat(dashboard): add corpus dashboard at /dashboard/
Full private corpus dashboard for tools.dobetternorge.no users — each SSO
account gets an auto-provisioned CaveauAI tenant (clients row, corpus) on
first visit. Includes upload (file/paste/URL), RAG chat with SSE streaming
and citation chips, document CRUD, FalkorDB graph relations tab, and
improved save-from-tool flow with tag/preview support.

- dashboard/{index,documents,document,upload,chat,settings}.php
- api/dashboard/{corpus-init,documents,upload,ingest-status,chat-stream,
  save-from-tool,graph}.php
- includes/{CorpusProvision,layout_dashboard,layout_dashboard_footer}.php
- assets/css/dashboard.css  assets/js/corpus-save.js (routing upgrade)
- includes/{bootstrap,layout}.php extended for dashboard provisioning

Migration 141 (clients.dbn_sso_uid + import_method enum) applied on chloe.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 17:15:40 +02:00
daveadmin 83fc71414f Add premium My Case MVP 2026-05-23 10:17:34 +02:00
daveadmin e0aeefc73e Add member welcome modal and promote public login CTAs
- dashboard.php: welcome overlay modal on first visit, shows all 10 tool
  tips in a 2-col grid; localStorage key dbn-welcome-v1-seen persists
  dismiss; "Don't show again" checkbox (default checked); backdrop+Escape
  close without persisting
- index.php: Sign in / Join free buttons added to sticky nav; access gate
  section moved from page bottom to immediately after hero so login CTAs
  are the first thing a visitor sees without scrolling; gate card titles
  enlarged and top-border accent added for visual weight
- tools.css: .wlc-* welcome modal styles; .lt-nav__btn-signin/join nav
  CTA button styles; .lt-gate--prominent and .lt-gate__card-title--large

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 20:17:02 +02:00
daveadmin b27ad348ff Remove legal check fallback to fix 60s H2 stream idle timeout
With timeout=45s + fallback timeout=30s, the total silence was 75s,
exceeding the 60s H2 idle stream limit in the browser. Remove the
fallback: if dbn-legal-agent-v3 times out or fails, return empty
immediately. Legal check is non-critical (wrapped in try/catch in
generate()); the draft is still correct without it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 19:34:25 +02:00
daveadmin e3645ba908 Fix Korrespond stream disconnect: emit progress before legal check
The dbnToolsRunLegalCheck call blocks for 30-120s with no output,
causing the H2 idle stream timeout (~60s) to drop the connection.

Fix: emit 'Verifying legal authorities...' progress event just before
the legal check to reset the idle timer. Also reduce legal check
timeouts from 120s/60s to 45s/30s so the call completes within the
new 60s window even if LiteLLM is slow.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 19:26:45 +02:00
daveadmin b014638f39 feat(corpus): add save-to-corpus + private corpus search scope
- POST /api/save-to-corpus.php — saves tool output text to user's default CaveauAI corpus via ClientRagPipeline
- api/case/upload.php — dual-writes uploaded PDFs to CaveauAI client_documents (best-effort)
- assets/js/corpus-save.js — shared <dialog> handler for .js-save-corpus buttons on all tool pages
- includes/layout_footer.php — injects corpus-save.js + shared save dialog markup
- korrespond/deep-research/barnevernet/discrepancy JS — save-to-corpus buttons on output sections
- api/search.php + LegalTools::search() — corpus_scope param ('shared'|'private'|'both'), merges personal CaveauAI corpus with shared legal library when 'both'
- includes/tool_form.php + assets/js/tools.js — corpus scope radio toggle shown on search tab
- api/user-docs.php — add POST upload method for non-SSO authenticated users

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 17:50:32 +02:00
daveadmin ed329f9d05 Redirect authenticated users from landing page to dashboard
Logged-in users visiting tools.dobetternorge.no were landing on
/#access (the unauthenticated marketing view). Now they go straight
to /dashboard.php.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 08:16:14 +02:00
daveadmin fe9a1812f1 Promote why-ours strip to top; add pricing CTA section at bottom
- Add prominent navy why-ours banner strip between hero and tools grid:
  eyebrow, large title, sub-text, 3 checkmark bullet points, gold CTA button
- Add pricing CTA strip after trust section: eyebrow, title, sub-text,
  4 tier pill tags (€0/€9/€29/€79), navy CTA button to pricing.php
- Remove the small pill links from the bottom of the trust section
- All new sections fully translated in no/en/uk/pl (11 new i18n keys)
- Add .lt-why-strip and .lt-pricing-strip CSS in tools.css

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 07:55:09 +02:00
daveadmin 7edc42c483 Add EN/UK/PL translations across index, footer, and why-ours pages
- index.php: translate hardcoded hero kicker, stat, explore CTA, tools
  section title/sub, and learn-more arrow; add Pricing nav link
- footer.php: fully translate tagline, privacy note, nav links, and
  disclaimer into all 4 languages via dbnToolsT()
- includes/i18n.php: 15 new keys per language (hero_kicker, footer_*,
  tools_section_*, pricing_nav_link, why_ours_trust_link, learn_more)
- translations/why-ours.php: complete uk + pl translations (70 keys each)
- assets/css/tools.css: add .lt-nav__secondary-link style

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 07:48:40 +02:00
daveadmin abdad0f7e3 Fix infographic images not scaling to browser width
Removed hard-coded pixel width/height attributes from <img> tags and
tightened kdoc-diagram-img CSS (max-width:100%, overflow:hidden) so
images scale fluidly at all viewport sizes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 07:37:22 +02:00
daveadmin 2aa86a0950 Replace CSS comparison/graph diagrams with custom infographic images
Swaps the CSS-only kdoc-compare and kdoc-graph blocks for two custom
transparent-background PNGs (+ lossless WebP) designed by the user.
memoryVlibrary shows the two-path General AI vs DBN flow; norwegianLaw
shows the connected-law knowledge graph. Both served via <picture> with
WebP primary and PNG fallback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 07:23:53 +02:00
daveadmin fc84bb31fe Add why-ours.php — plain-language explainer page
Explains why Do Better Norge tools give different answers than ChatGPT:
RAG, BM25+vector search, reranker, knowledge graph, fine-tuned model.
Includes EN/NO translations, 5 optimised WebP/JPEG images, new kdoc-compare
and kdoc-graph CSS components. Link added from index.php trust section.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 06:48:02 +02:00
daveadmin 1f67f20581 Add EN/UK/PL translations to pricing.php
All pricing page content now flows through dbnToolsT() with 65 new
keys added to i18n.php for all four languages (no/en/uk/pl). A
language switcher pill bar is added at the top of the page.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 22:25:26 +02:00
daveadmin ba9cddf9a1 Add monetization spine + Build Your Own Case (Min Sak)
- Stripe: StripeClient.php, checkout/portal/webhook endpoints, idempotent event handling
- FreeTier: tier-aware credits (free/light/pro/pro_plus), bonus_balance, hourly caps per tier
- pricing.php + billing.php: 4-tier cards, 3 topups, Customer Portal, balance breakdown
- Min Sak: CaseStore.php, AzureDocIntelligence.php, AzureSearchAdmin.php — per-user hybrid RAG
- api/case/: upload, list, delete, ingest-callback (HMAC-auth'd from n8n)
- award-survey-credits: inter-site HMAC endpoint for dobetternorge.no survey bonus
- dashboard.php: tier badge, balance breakdown card, Min Sak CTA, survey CTA
- KorrespondAgent + all 3 other agents: use_my_case toggle wired to dbnToolsCaseContext()
- bootstrap.php: dbnToolsCaseContext(), dbnToolsIntersiteSecret(), dbnToolsCurrentTier()

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 20:52:54 +02:00
daveadmin ed5489d174 route dbn-legal-agent-v2 to qwen2.5:14b; add system prompt to legal check
cuttlefish lost; Gemma3 QLoRA approach abandoned. dbn-legal-agent-v2 in
LiteLLM now aliases to qwen2.5:14b on Colin. dbnToolsRunLegalCheck() adds
explicit system prompt since there is no longer a Modelfile-embedded one.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 05:16:15 +02:00
daveadmin 0e167bf464 Integrate dbn-legal-agent-v2: upgrade all v1 refs + add Korrespond legal-check
- Replace dbn-legal-agent with dbn-legal-agent-v2 in bootstrap.php
  (dbnToolsRunLegalCheck), DeepResearchAgent.php (interpretSeed,
  expandQueries, synthesis fallback, deploy label), BvjAnalyzerAgent.php
  (check_model label) — 8 locations total
- Add dbn-legal-agent-v2 legal threshold check to KorrespondAgent:
  called after selfCheck() in both generate() and refine(); result
  surfaced as legal_check[] in the API response
- Render legal_check card in korrespond.js using existing bvj-red-flag
  styles; shows only when non-empty
- Add .korr-legal-check CSS block in tools.css

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 23:59:07 +02:00
daveadmin 29579eae66 Add NO/UK/PL translations to all 6 doc pages
Per-page translation arrays in translations/*.php (EN/NO/UK/PL) for
korrespond-about, korrespond-guide, korrespond-tech, timeline-about,
timeline-guide, and timeline-tech. Generated via Azure gpt-4o-mini;
Norwegian legal/institution terms preserved as-is in all languages.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 16:58:15 +02:00
daveadmin 0201115fa3 Add output screenshot to How it works step 2 on timeline-about.php 2026-05-19 14:05:12 +02:00
daveadmin 81ba20c44a Add Timeline documentation pages (about, guide, tech)
3 new public pages matching the korrespond doc pattern: timeline-about.php
(marketing), timeline-guide.php (user guide), timeline-tech.php (tech
showcase). Hero images + 4 screenshots in assets/images/timeline/. Doc
links added to timeline.php and preview.php?tool=timeline.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 14:00:40 +02:00
daveadmin 1638db3eb9 Add output-draft screenshot inside step 2 card on about page 2026-05-19 13:39:58 +02:00
daveadmin b554d62cd7 Fix: force single-column steps grid on mobile to remove stretch gap under step 2 2026-05-19 13:02:42 +02:00
daveadmin 7c4b161f04 Add 3 public Korrespond documentation pages with AI hero images
- korrespond-about.php: marketing/hype page with hero image, features,
  3-step pipeline, screenshot gallery, dbn-legal-agent LLM spotlight,
  authority coverage grid, and CTA strip
- korrespond-guide.php: step-by-step user guide covering mode selection,
  recipient body presets, output types, tone, all form fields, clarify
  gate, output columns, and Refine pass
- korrespond-tech.php: technical showcase — Hard-RAG pipeline diagram,
  corpus stats, CITE:N verification system, fine-tuned model details,
  formal citation style guide, privacy section
- 5 UI screenshots + 3 AI-generated hero images in assets/images/korrespond/
- korrespond.php: add "About · User guide · How it works" inline links
- preview.php: add korrespond to localizedContent (en+no) and samples;
  render doc-page links in preview CTA section for korrespond slug
- tools.css: +600 lines .kdoc-* CSS (hero, features, pipeline, guide
  steps, tech diagrams, finetune block, privacy block, stat cards)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 12:49:38 +02:00
daveadmin 28932297b3 Add user context notes field to timeline tool
Adds an optional textarea below the main text input where users can provide
clarifications to guide the LLM — e.g. year anchors, actor aliases, or focus
instructions. Notes are injected into the prompt as a clearly delimited block
and translated across all four UI languages (en/no/uk/pl).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 12:36:37 +02:00
daveadmin dfb9692f45 Korrespond: stop mixing UI languages — all chrome follows user UI lang
Drafts still come back in Norwegian + working language (that is intentional),
but every piece of *chrome* now respects the user's UI lang consistently:

- Pass 1 classify LLM now writes missing-fact questions in the user's language
  (not always Norwegian), fixing the case where an English-UI user got "Hva er
  saksnummeret?" in the clarify panel.
- All PHP-emitted progress/status messages go through DbnKorrespondAgent::L()
  with en/no/pl/uk variants instead of hardcoded Norwegian.
- JS introduces an I18N dictionary + t() helper covering status messages,
  button labels, column headers, flag labels, refine panel title/hint,
  jurisdiction radio labels, clarify panel title/hint/buttons, the empty-state
  "Ready" block, and Copy/Copied/Download .txt.
- Static clarify and empty-state chrome use [data-i18n] attributes resolved at
  init and re-applied on every lang-switcher click.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 12:11:16 +02:00
daveadmin 5d8ae6b447 Korrespond: add Refine pass with jurisdiction-scoped formal citations
After the first draft is rendered, a "Refine with citations" panel offers a
3rd-pass rewrite scoped to the user's choice of Norwegian law, ECHR (EMK +
HUDOC case law), or both. Refine pulls fresh corpus chunks limited to the
chosen jurisdiction's slices, rewrites inline cites in formal style ("jf.
forvaltningsloven § 17", "jf. Strand Lobben m.fl. mot Norge, EMD-37283/13,
§§ 207–214"), and appends a Rettskilder block listing every authority.
Hard-RAG grounding carries through — refine cannot cite anything that
wasn't retrieved. Costs 1 additional credit; the original draft stays in
place and the refined version appears below it.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 11:50:36 +02:00
daveadmin b78a49e060 Add Korrespond tool: drafts replies & new correspondence to NO authorities
Two-pass wizard for drafting to NAV, Barnevernet, schools, Bufdir, kommune,
Statsforvalter, Trygderetten. Pass 1 (gpt-4o-mini) classifies the situation
and emits clarify questions if facts are missing; user answers inline and
resubmits without losing context. Pass 2 retrieves law passages via hard-RAG
(ClientRagPipeline with body-specific slice presets), drafts in Norwegian
bokmål with gpt-4o using [CITE:N] tokens, self-checks that every citation
maps to a real corpus passage, then translates to the working language.
Result is side-by-side Norwegian + EN/PL/UK with copy/download per side
and an expandable Cited Law panel.

Credit deducts only when Pass 2 actually runs, not on a clarify cycle.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 11:27:13 +02:00
daveadmin bc44b0eee2 Add My Documents panel to workbench + user-docs API
- api/user-docs.php: GET/DELETE shared dbn_user_docs table (SSO users only)
  connects to dobetternorge DB via DBN_DB_* env vars
- workbench.php: My Documents panel (section 05) for SSO/free-tier users;
  shows docs uploaded from either AI chat or tools, links to AI Chat for upload
- workbench.js: fetch + render doc list, delete with Qdrant cleanup
- tools.css: workbench-docs panel + item styles
- i18n.php: my_docs_* strings in all 4 languages

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 09:37:19 +02:00
daveadmin 47aa35e946 Add dbn-legal-agent targeted check step to BVJ Analyzer (Step 6b)
Probe testing revealed the fine-tune loops when asked to check a brief
directly (tool-planning architecture conflict) but answers focused legal
Q&A reliably in ~55s. New step 6b asks one targeted question per document
type (akuttvedtak → § 4-25 klar nødvendighet, adopsjon → Strand Lobben,
undersøkelse → fvl § 17/§ 41) and merges the finding into
procedural_red_flags with check_model provenance. Silent on timeout/error.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 22:38:29 +02:00
daveadmin 04555a96b1 Add Citation Explorer tool and graph-expansion badges to Advocate results
- citations.php + assets/js/citations.js: new tool page for browsing the
  FalkorDB citation graph by title/ID, with autocomplete, action pills
  (cites/cited_by/implements/chain), hop-by-hop navigation, and exploration trail
- advocate.js: tag graph-expanded source cards with 'via citation graph' badge
- DeepResearchAgent: propagate _graph_expanded flag through normalizeCorpusChunk
  and top_sources serialization so it reaches the frontend
- tools.css: add .dr-source-tag--graph variant (green pill)
- i18n.php: register 'citations' tool in all 4 languages with CIT icon

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 22:30:04 +02:00
daveadmin 60e341e98a corpus: expand catIds map and add health-law card
- Map 10 additional DB category slugs to UI cards (social-services,
  echr-case-law, child-abduction, anti-discrimination, children-rights,
  legislation, parliamentary, immigration, legal, civil-litigation, etc.)
- Add health-law card (1,874 docs were invisible — largest unmapped category)
- Add patient-rights, government-policy, policy-reports, ombudsman,
  bankruptcy mappings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 20:46:52 +02:00
daveadmin e977bbb6b3 Add Document Discrepancy Finder tool
8-step NDJSON-streaming pipeline that compares two Barnevernet documents:
classifies each doc, extracts parties and timelines, cross-references both
for contradictions/deletions/additions, retrieves corpus legal context, and
synthesises a full discrepancy report with tabbed UI.

New files: DiscrepancyAgent.php, api/discrepancy.php, discrepancy.php,
discrepancy.js. Modified: FreeTier.php (cost=4), i18n.php (all 4 langs),
tool-svgs.php (DC icon), tools.css (dc-* component styles).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 19:30:38 +02:00
daveadmin 1246b7a804 feat(workbench): add DBN Case Workbench guided case-preparation hub
Additive-only change: new workbench.php authenticated page with guided
intake flow, evidence map, tool sequence, output checklist, and
sessionStorage-only note persistence. Dashboard and public index get
a new Case Workbench card. No existing tools, APIs, or prompts modified.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 19:08:16 +02:00