Skip to content

legal batch: LEGAL footers + self-hosted fonts + license owner, and the sidecar-exchange first-contact consent gate - #3897

Merged
borisbat merged 10 commits into
masterfrom
bbatkin/legal-footer-license
Aug 28, 2026
Merged

legal batch: LEGAL footers + self-hosted fonts + license owner, and the sidecar-exchange first-contact consent gate#3897
borisbat merged 10 commits into
masterfrom
bbatkin/legal-footer-license

Conversation

@borisbat

Copy link
Copy Markdown
Collaborator

Behavior change: the first dasLLAMA server boot on an unconfigured box now asks once before contacting dasllama.io. Until a choice is recorded, nothing leaves the box and it tunes locally.

Gaijin legal reviewed daslang.io and dasllama.io. This branch lands everything actionable from that review. Both sites and the docs get a LEGAL footer block (Terms of Service, Privacy Policy, the BSD-3 license). Google Fonts is gone: Inter Tight and JetBrains Mono are vendored as variable woff2 per site and in the docs static tree, so no visitor request reaches Google. The GitHub LICENSE names the legal entity, Gaijin Games Kft.; site footers keep the Gaijin Entertainment brand. Disqus is removed from the blog - zero comments over its whole history, and it was the one cookie-setting embed.

The sidecar exchange gets a first-contact consent gate. The lookup sends the box identity (platform, CPU model, OS build - hardware-class data, no serials or user names), and legal asked for an Accept/Decline step before the first request. An explicit exchange_* key in a hand-written config or the environment is itself the expressed choice, and the boot announces which knob expressed it. A control-page-written (authoritative) config does not count - the page persists exchange defaults on every save. With no expressed choice, a real terminal asks inline; a supervised boot emits @sidecar consent state=needed, the watchdog raises a native Accept/Decline dialog, and the control page carries the same banner (POST /exchange/consent). Accept mid-tune rides the existing DAS_TUNE_CONTROL stop rail: abort at the kernel-family boundary (minting is end-gated, nothing is written), relaunch, run the lookup. The notice wording is a placeholder until legal delivers the final text.

The "~20 minutes" tune claim is re-stated as ~12 min from a measured first boot, everywhere it appears.

Where to look: modules/dasLLAMA/dasllama/dasllama_exchange.das (exchange_may_contact is the whole decision), utils/watchdog/watchdog.py (dialog + the consent stop mode), utils/dasllama-server/openai_server.das (handle_exchange_consent), control.html (banner + the always-share toggle now records consent), .github/workflows/pages.yml (the dasllama.io staging cp is now recursive - the fonts subdirectory would have failed the deploy).

Validation, claims, ledger

Validation

  • Playground Playwright suite: 52 passed, 0 failed, run with --grep-invert '@wasm' (the per-PR lane's filter) against the checked-in runtime artifacts; the diff's modules/ touch (dasLLAMA) is not part of the playground WASM runtime.
  • run.das -- --suite model-free: green end to end (the runner tees full logs; test_tune_interrupt 4/4 inside it).
  • test_exchange_client.das (dastest): 28 passed, 0 skipped - download gate, privacy strip, submit rails, and the consent additions; the consent gate is mutation-controlled (deleting it reds the suite).
  • Control-page Playwright suite: 106 passed against the RE-CAPTURED /exchange fixture (a real zero-config boot; carries consent/consent_notice/policy.configured).
  • Watchdog pytests: 8 passed on darwin/arm64; the Linux run is this PR's extended_checks step.
  • End-to-end consent proof on macOS server boots: unconsented non-TTY boot emits the consent event with zero lookup lines; a recorded "accepted" runs the lookup.
  • The ~12 min figure: one measured first boot, M1 Max, 2026-08-28 - 11:46 wall including cold JIT codegen, the kernel race (40 families raced of 42 planned), re-exec, and model load; quiet box (noise probe cv 0.32%). Recorded here as the number's provenance.
  • Two files took review fixes after the mechanical chain launched (dasllama_exchange.das, performance/REVIEW.md); the delta was revalidated with targeted gates (compile, lint, format --verify, the 28-test suite) rather than a second full preflight.
  • Known-red, with its control: preflight --full failed its three test gates on 5 pre-existing failures in tests/mcp/ (test_popen_argv_pipe, test_mcp_jsonrpc) - deterministic on this box, byte-identical test files vs master, a binary built before this branch existed, and a diff that touches no src/, daslib/, utils/mcp, or tests/mcp path. The other 17 gates passed.
  • External reviewer rounds: round 1 found the authoritative-toml consent bypass (fixed and negative-controlled); round 2 on the fixed tip reported no findings.

Claims - stated, not tested

  • The resolver wiring (exchange_scope_resolver calling exchange_may_contact) is proven by the e2e boots above; the composed decision is unit-tested, the private call site is not.
  • The @sidecar consent event's producer side is verified in the e2e transcripts only; the watchdog consumer side is unit-tested.
  • Env-expressed consent (DASLLAMA_EXCHANGE_URL/_ACCEPT setting configured) is unpinned in-process (load-once env); the TOML arms are tested per key, and the e2e announce line covers the env arm.
  • /exchange/consent handler branches (loopback guard, bad-body, the restart condition) have no route-level test - the guard is the is_loopback_req pattern every operator route shares, none of which do.
  • The Windows arms are untested on Windows: the MessageBoxW dialog (mocked at the seam), the set "VAR=" spellings in test_tune_interrupt, and the pipe-handle behavior of is_terminal under a supervisor. A false-positive TTY probe under a supervisor would block the boot; proven not to on darwin only.
  • test_tune_interrupt ran on macOS only; its cells are platform-guarded, not skip-armed.

Not done

  • EXCHANGE_CONSENT_NOTICE (das), CONSENT_TEXT (watchdog), and the captured fixture carry PLACEHOLDER wording - Gaijin legal delivers the final text; the copy-sync duty is performance/REVIEW.md's new rule.
  • A machine check of the notice-copy sync (a REVIEW.das comparing the das and Python constants) - recommended by the review round, not built.
  • The repo-root dasllama.tune.json (an old-format relic) is untouched, awaiting a ruling.

🤖 Generated with Claude Code

borisbat and others added 9 commits August 28, 2026 09:10
…ts, license owner, measured tune time

- footer LEGAL column (ToS / Privacy Policy / BSD-3 license) on every daslang.io
  page incl. the blog template and Sphinx docs layout, and on all dasllama.io pages
- Google Fonts CDN dropped: Inter Tight + JetBrains Mono vendored as variable
  woff2 (all subsets) under files/fonts/ per site and doc _static; zero requests
  to fonts.googleapis.com / gstatic remain
- LICENSE copyright owner: Gaijin Games Kft. (legal entity; site footers keep the
  Gaijin Entertainment brand), install/README.md aligned
- the ~20-minute tune claim re-stated as ~12 min from a measured first boot
  (M1 Max, 11:46 wall incl. cold JIT codegen, 42-family race, re-exec, model load)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FkBKGJisiiHXEgSsGjpqLm
… it was the one cookie-setting embed on the site

Removes the embed from build_blog.py (all 44 posts regenerated without it),
the orphaned wrapper CSS, and the README row.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FkBKGJisiiHXEgSsGjpqLm
… an expressed choice

An explicit exchange_* config key (TOML or env) is itself the choice; on the
zero-config path a <stem>.consent sidecar-sibling file governs. Unset: a real
terminal asks inline (Enter = Accept); a supervised boot emits `@sidecar consent
state=needed` and tunes locally - the watchdog raises a native Accept/Decline
dialog (osascript / MessageBoxW; the answer lands in the consent file the event
names, and Accept mid-tune rides the stop rail as the new non-sticky "consent"
mode), and the control page carries the same banner via POST /exchange/consent
(accept on an untuned box drains and exits 4 to run the lookup on relaunch).
Notice text is a placeholder pending legal; the das constant and the watchdog
copy point at each other.

Proven end-to-end: an unconsented non-TTY dasllama-server boot emits the consent
event with zero lookup lines; a recorded "accepted" runs the lookup. dastest
suite extended (consent round-trip, garbage file reads as never-asked,
policy.configured from TOML); 25/25 pass.

Also: ask.tune.json refreshed by today's measured tune; remaining ~20-min claims
in comments/docs restated as ~12 min.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FkBKGJisiiHXEgSsGjpqLm
… gate) - the "no prompts" claim was stale

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FkBKGJisiiHXEgSsGjpqLm
- utils/watchdog/test_consent.py: the @sidecar consent fold, the non-sticky
  env-free "consent" stop mode, and handle_consent_needed's contract with the
  dialog mocked at the show_consent_dialog seam - accept writes the file and
  stops a running tune, decline only records, walking away answers nothing
- tests/consent.spec.js (8 specs): banner on the zero-config path only, POST
  bodies both ways, declined as the change-your-mind path, configured policy
  and pre-consent servers render no banner, failed POST re-enables the buttons
- control.html: the banner additionally gates on consent_notice presence, so a
  server predating the consent API renders exactly as before

Full playwright suite 104/104; both watchdog pytest files green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FkBKGJisiiHXEgSsGjpqLm
…oundary, mints nothing

test_tune_interrupt spawns _interrupt_probe (one interrupt_gate() between a
BEFORE and an AFTER print) in a child process - the env is load-once, so a
child is the only honest way to flip it. Present control file: the @tune abort
event fires, "no sidecar written" prints, nothing past the gate runs. Negative
controls: a named-but-absent file and an unset env both pass through.
Registered in the model-free roster; the full gate ran green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FkBKGJisiiHXEgSsGjpqLm
…nts root, audits' checklist defects, gate tests

The review round's confirmed findings, one batch:

- consent bypass closed both ways: an AUTHORITATIVE (control-page-written) toml's
  exchange keys are no longer consent (the page persists them on every save);
  submit=always without an expressed choice degrades to the ask offer; the page's
  always-share toggle and an explicit sidecar apply now record the consent they
  express. The gate composition is extracted as exchange_may_contact and tested
  (mutation-controlled: deleting the gate now reds the suite)
- override announce: env/config-expressed consent prints the knob that waived
  the question; a recorded accept names the consent file; both env docs extended
  and ENVIRONMENT.md regenerated
- deploy breaker: pages.yml staged site-dasllama/files with a non-recursive cp -
  the new files/fonts/ subdirectory would have failed the deploy step (cp -R now)
- blog fonts 404: the template's fonts link lacked {{root}} - every generated
  blog/news page lost the self-hosted fonts; fixed + regenerated
- sidecars page: the transcript is relabeled "first start after Accept" (the
  promptless boot it shows), the measured-comment matches the run (40 raced of
  42 planned), the config-skips-question claim now names the hand-written-config
  and env arms only
- /exchange fixture RE-CAPTURED from a real zero-config boot (carries consent /
  consent_notice / policy.configured); consent specs are fixture-first + two new
  (accept-without-restart, always-share-records-consent); README rows list the
  new keys; dasllama_server.rst gains the /exchange/consent row (REVIEW.das green)
- ~20-min stragglers in control.html and dasllama-io.js -> ~12 min
- test_tune_interrupt: the "unset env" cell now explicitly unsets
  DAS_TUNE_CONTROL in the child (proven leak from a poisoned parent), and the
  tautological same-print assert is gone
- watchdog tests: stream_child dispatch (once per consent path), darwin dialog
  parse arms (Accept/Decline/gave-up/Escape), stdlib threading no longer mutated
- checklist self-review defects fixed in place: site, site-dasllama, dasLLAMA,
  dasLLAMA tests, dasllama-server, utils, workflows checklists + three new rules
  in performance/REVIEW.md (notice sync, gate coverage, no-stdin-block) and the
  web/examples/ui checklist restored after an accidental clobber (dragon catch)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FkBKGJisiiHXEgSsGjpqLm
…act, dragon N0 residuals, sibling-path dedup

- the resolver refactor had silently missed (a raw-newline artifact broke the
  replacement) - exchange_scope_resolver now genuinely calls exchange_may_contact,
  and the two embedded raw newlines are proper \n
- performance/REVIEW.md gate rules name the public seam; the notice-copy rule is
  self-maintaining (a new copy names itself there); utils/REVIEW.md routes
  watchdog consent-wording diffs to it; the dragon's N0 residuals across the
  eight rule docs (arch-doc census -> property, per-folder path form, rewraps)
- dupes triage: exchange_consent_path/exchange_state_path share the extracted
  sidecar_sibling_path helper

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FkBKGJisiiHXEgSsGjpqLm
Copilot AI lite review requested due to automatic review settings August 28, 2026 21:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR applies a legal/compliance batch across daslang.io + dasllama.io + docs, and introduces a first-contact consent gate for dasLLAMA’s sidecar-exchange so an unconfigured box won’t contact dasllama.io until the operator explicitly accepts/declines once.

Changes:

  • Add a GDPR-style first-contact consent decision path for the sidecar exchange across the boot resolver, watchdog (native dialog), and control page (POST /exchange/consent), plus tests/fixtures.
  • Self-host Inter Tight / JetBrains Mono (remove Google Fonts), and add LEGAL footer blocks (Terms/Privacy/License) across sites and Sphinx docs; remove Disqus from the blog.
  • Update review checklists + CI staging (recursive copy for dasllama.io files/ subdirs) and refresh various “~20 min” claims to “~12 min”.

Reviewed changes

Copilot reviewed 54 out of 114 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
web/examples/ui/REVIEW.md Adds a Playwright-run reporting rule for runtime-path changes in UI samples.
utils/watchdog/watchdog.py Implements supervised-session consent dialog handling and a non-sticky “consent” stop mode.
utils/watchdog/test_consent.py Adds unit tests for consent event folding, stop-mode semantics, and dialog dispatch.
utils/watchdog/README.md Documents the new @sidecar consent event and its watchdog handling.
utils/REVIEW.md Clarifies cross-tool checklist applicability and consent-wording checklist linkage.
utils/dasllama-server/tests/fixtures/exchange.json Updates captured /exchange fixture to include consent and configured fields.
utils/dasllama-server/tests/consent.spec.js Adds Playwright coverage for the control-page consent banner and POST flow.
utils/dasllama-server/test_exchange_client.das Adds dastest coverage for policy configured-flag and consent gating/recording.
utils/dasllama-server/REVIEW.md Tightens fixture capture rule and aligns route/fixture expectations for tests/control page.
utils/dasllama-server/README.md Documents new /exchange/consent endpoint and first-contact consent behavior.
utils/dasllama-server/openai_server.das Adds /exchange/consent handler; records consent when applying a sidecar.
utils/dasllama-server/main.das Updates startup comments to reflect ~12 minute tuning figure.
utils/dasllama-server/control.html Adds consent banner UI + POST handler; records consent when enabling always-share.
site/REVIEW.md Narrows the Playwright evidence rule and updates runtime-artifact scope list.
site/README.md Removes Disqus reference from blog behavior description.
site/playground/placeholder.html Switches to self-hosted fonts CSS.
site/playground/index.html Switches to self-hosted fonts CSS.
site/performance.html Switches to self-hosted fonts CSS and adds legal footer column.
site/index.html Switches to self-hosted fonts CSS and adds legal footer column.
site/files/forge.css Removes Disqus styling and expands footer grid for legal links.
site/files/fonts/fonts.css Adds local @font-face rules for self-hosted fonts.
site/examples.html Switches to self-hosted fonts CSS and adds legal footer column.
site/downloads.html Switches to self-hosted fonts CSS and adds legal footer column.
site/daspkg.html Switches to self-hosted fonts CSS and adds legal footer column.
site/dasllama.html Switches to self-hosted fonts CSS and adds legal footer column.
site/blog/template.html Switches blog template to self-hosted fonts CSS and adds legal footer column.
site/blog/build_blog.py Removes Disqus embed generation from blog build.
site/benchmarks.html Switches to self-hosted fonts CSS and adds legal footer column.
site-dasllama/sidecars.html Switches to self-hosted fonts, updates ~12 min copy, adds legal footer column.
site-dasllama/REVIEW.md Strengthens provenance requirements for numbers and adds deploy-step verification rule.
site-dasllama/ladder.html Switches to self-hosted fonts and adds legal footer column.
site-dasllama/index.html Switches to self-hosted fonts and adds legal footer column.
site-dasllama/files/fonts/fonts.css Adds local @font-face rules for self-hosted fonts on dasllama.io.
site-dasllama/files/dasllama-io.js Updates the empty-state tuning duration copy to ~12 min.
site-dasllama/files/dasllama-io.css Expands footer grid for legal links column.
modules/dasLLAMA/tests/test_tune_interrupt.das Adds end-to-end test for the supervisor stop rail via child process.
modules/dasLLAMA/tests/run.das Registers the new tune-interrupt test in the suite list.
modules/dasLLAMA/tests/_interrupt_probe.das Adds probe program used by the tune-interrupt test.
modules/dasLLAMA/REVIEW.md Clarifies architecture-doc indexing, override announce scope, and stdin-prompt ban.
modules/dasLLAMA/performance/REVIEW.md Adds explicit “consent wording sync” and exchange_may_contact routing rules.
modules/dasLLAMA/ENVIRONMENT.md Documents env vars as an expressed exchange-consent choice.
modules/dasLLAMA/dasllama/dasllama_exchange.das Implements consent state file, console prompt, @sidecar consent event, and exchange_may_contact.
modules/dasLLAMA/dasllama/dasllama_env.das Updates env knob docs to reflect consent-skipping behavior.
modules/dasLLAMA/ARCHITECTURE_MEASUREMENT.md Defines boundary for “override announce” rule (timing knobs vs numeric-impact knobs).
modules/dasLLAMA/ARCHITECTURE_ENGINE.md Documents consent gate behavior in engine architecture doc.
LICENSE Updates copyright owner to “Gaijin Games Kft.”
install/README.md Updates license/copyright line to match LICENSE header.
doc/source/reference/utils/dasllama_server.rst Documents new /exchange/consent endpoint.
doc/source/_templates/layout.html Adds LEGAL links block to every docs page footer.
doc/source/_static/fonts/fonts.css Adds local @font-face rules for docs self-hosted fonts.
doc/source/_static/custom.css Switches from Google Fonts import to local fonts and styles legal links block.
.github/workflows/REVIEW.md Tightens gate-step failure requirements and adds “state a local run” rule.
.github/workflows/pages.yml Fixes dasllama.io staging to copy files/ recursively (for fonts subdir).
.github/workflows/extended_checks.yml Adds watchdog consent tests to extended_checks lane.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread modules/dasLLAMA/dasllama/dasllama_exchange.das
Comment thread utils/dasllama-server/openai_server.das
Ctrl+D / closed stdin at the console prompt returned "" which stripped to the
Enter-defaults-to-Accept arm - a walkaway counting as consent. Enter arrives as
a newline (non-empty before the strip), so an empty read is EOF alone: record
nothing, tune locally, ask again next boot. Riding along: the consent route
answers malformed JSON with "invalid JSON: <err>" instead of the missing-field
message.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FkBKGJisiiHXEgSsGjpqLm
Copilot AI review requested due to automatic review settings August 28, 2026 21:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 54 out of 114 changed files in this pull request and generated no new comments.

Suppressed comments (2)

Previously missed (2) — in code that hasn't changed since the last review.

utils/watchdog/watchdog.py:702

  • handle_consent_needed writes the consent file using Path(path_text) directly. If the consent path is relative (common when the child emits main.tune.consent), this resolves against the watchdog process CWD, not --cwd (the child’s working directory). Running the watchdog from another directory (e.g. python /abs/path/watchdog.py) can therefore record consent into the wrong location and leave the real gate unanswered, causing repeated prompts.
    utils/dasllama-server/control.html:2376
  • When /exchange/consent replies with restarting:true, postConsent immediately calls loadExchange(). In a real restart this fetch will often fail (server is draining), and the catch in loadExchange overwrites the user-facing status with could not load /exchange, hiding the intended “restarting…” message.

@borisbat
borisbat merged commit eb8ad91 into master Aug 28, 2026
39 checks passed
@borisbat
borisbat deleted the bbatkin/legal-footer-license branch August 28, 2026 22:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants