Repository navigation
Conversation
…d workspace Docker clients (#17267)
…w-privileges and a pids limit from the shared hardening builder (#17267) SECURITY-SENSITIVE: container runtime privileges; review on Opus. Owner decision (c) on #17267: the non-behavioural subset only. Changed: - container_hardening: new baseline_hardening_kwargs() (security_opt no-new-privileges, cap_drop ALL, pids_limit); hardening_kwargs() now composes it, output byte-identical. CONTAINER_PIDS_LIMIT (env AUTOBOT_WORKSPACE_PIDS_LIMIT, default 512) moves here; the workspace constant aliases it. - docker_backend.py: both containers.run sites (cold start, snapshot restore) add **baseline_hardening_kwargs(). - container_pool.py: its only caller passes no container kwargs, so pooled containers were unhardened; the same subset is applied, and the floor wins over caller kwargs. - Guard extended: each docker_backend containers.run must spread the builder; pool and backend are consumers; contrast cases added. - Pin tests assert the full kwargs of every run site; they pass on the parent with the old kwargs and now differ by exactly the three keys. Unchanged: network, read_only, mounts/volumes, memory, cpus, user, environment. Refs #17267 — option (b) full hardening stays open
…no network and a read-only root unless a named opt-in says otherwise (#17267)
…that widen their reach (privileged, devices, host namespaces, docker socket or host-root binds) (#17267)
… the tree, not only the execution backend (#17267)
… sensitive host root, or is any socket (#17267)
…e_driver join the refused run kwargs (#17267)
…de the builder spread fails the guard (#17267)
… run and create sites (#17267)
…cker-py run kwarg and every cold start raised TypeError (#17267)
…reading as an empty pool (#17267)
…bsent, and a guard keeps it declared for CI (#17267)
…led; main's entries plus this branch's one scope (#17267)
…on decisions, pin the writer set (#17225)
…, adapt audit_logger, route SecurityLayer, one retention table (#17225) Owner decision 2026-10-10, D2/D3/D5/D6: - D2: services/audit/audit_log.py, services/event_log.py and knowledge/audit_log.py are deleted; their vocabularies move to services/audit/taxonomy.py and every caller uses the canonical service (voice_bundle_admin and auth via emit_compliance; the knowledge audit API via services/audit/knowledge_view.py, which ends the double write). Old keys are left to expire by their TTL; no stored data is touched. - D3: services/audit_logger.py is an adapter: an AuditEntry is recorded as a SECURITY AuditEvent and read back from the canonical trail. - D5: services/audit/retention.py is the one retention table; projection TTLs and the one purge path (services/audit/purge.py) read it. The nightly task no longer trims every audit:* zset at one period. - D6: SecurityLayer.audit_log records through emit_security; the JSONL file is no longer written or read. Fixes found on the way: audit.emit was shadowed by an EventType bridge, so emit(AuditEvent(...)) recorded a COMPLIANCE event named after the event's repr (7 producers); a producer on a thread with no loop now hands its write to the serving loop; reads scan newest-first; an unreadable trail raises instead of reading as empty (#13258). The writer guard detects audit ORM rows, INSERT INTO ...audit and file writes in modules binding an audit path, which found five stores the first inventory missed. D1 (which Postgres table) and D4 (daemon key move) are open; see docs/developer/AUDIT_SYSTEMS.md.
…its projection (#17225) Owner decision 2026-10-11 on D1: extend the existing Postgres audit_logs table rather than add audit_event. - Additive schema: category (NOT NULL, server default 'security'), actor, session_id, resource_ref and two indexes. Alembic 20261011_098 on the backend; add_audit_logs_canonical_columns on the SLM's slm_users database, which maps the same shared model. No existing row is rewritten; the pre-existing twelve columns are pinned unchanged. - One row constructor, autobot_shared/user_management/audit_rows.audit_row, used by the canonical service and by the shared RBAC denial, organisation and team writers, so both processes write one schema. The backend and SLM user_service.py still construct AuditLog directly; they move onto audit_row after #18267, which rewrites both files. - services/audit/store.py: record() writes the row, then the Redis projection; every query is one SQL statement on audit_logs; rebuild_projection() reconstructs the projection. store_authority declares audit_trail POSTGRES with a REDIS projection. - .secrets.baseline: drop the entries for the two deleted legacy modules.
…ontrol plane map has an audit-trail row (#17225) with audit_rows.audit_row, so every audit_logs row has one constructor. The writer guard drops the two user_service allowances and fails on any AuditLog(...) outside the row builder (the SLM's own node-audit model excepted). - CONTROL_PLANE_MAP.md: row 18, Audit trail, Enforced. - AUDIT_SYSTEMS.md: D1 done; rows 5 and 10-12 point at #18284, #18285 and #18286. - symbol_fork_baseline.json: drop KnowledgeAuditLog, audit_record, emit and query_events, which are no longer fork clusters. - audit_rows_test records the mapping without configuring the shared mapper registry, which needs each backend's concrete Organization.
…r indexes concurrently (#17225) Review of #18343: - 20261011_098 downgrade() dropped the four new columns, deleting every audit value written into them since the upgrade -- a deletion path in the audit store (#17038). It is now a documented no-op; the columns are additive and harmless to leave. The SLM migration has no down path and says it may not grow one that drops them. - Both index builds were plain CREATE INDEX, which blocks writes to audit_logs for the whole build. Alembic now uses postgresql_concurrently=True inside autocommit_block(); the SLM runner commits the columns and builds CONCURRENTLY IF NOT EXISTS on an autocommit connection. Both drop and rebuild an INVALID index a failed concurrent build left behind, so a re-run repairs rather than skips it. - Tests: downgrade has no statements; every create/drop index call is concurrent and inside autocommit_block; the SLM build runs in autocommit with CONCURRENTLY and rebuilds an invalid leftover.
…nces, and PATCH /users/me/preferences writes only the fields it was sent (#18240)
… announcer in @autobot/ui, consumed by both apps (#18240)
…llows the account (#18240) useUiMode owns data-ui on <html> (minimal|full) and the start preference (last|minimal|full), writes through to localStorage, and resolves the opening mode at login (ui_start === 'last' ? ui_mode : ui_start). theme-variant-init sets data-ui before mount, the same CSP-safe pattern as the variant beside it. html[data-ui="minimal"] .adv hides advanced chrome and .only-min shows only in Minimal, both without !important (the selector is more specific than a display utility). usePreferences now sends and applies ui_mode, ui_start and theme_variant with the appearance prefs. The endpoint is a partial PATCH since 0b2892a360, and the only caller still sends every field it owns, so nothing is reset. An account theme_variant of 'default' does not override a device that never chose one, so a deployment pinning another build-time default keeps it.
…les (#18240) nav.homeAria, vaultTip, preferencesTip, platformAdmin(+Aria/Tip), profileMenu, nav.uiMode.*, settings.preferredMode.*, settings.additionalThemes.*, ui.minimalNote and ui.minimalNoteAction, each really translated (ar, de, es, fa, fr, he, lv, pl, pt, ur) and appended to its group; no existing key is touched. settings.appearance.* from the plan is settings.additionalThemes.* because settings.appearance is already a string key. The SLM locales are regenerated by scripts/lift_locale_translations.py: its two "Full" keys now lift a translation from the new settings.preferredMode.full. nav.slmAdmin and nav.slmAdminTitle have no reference left in the app but stay, append-only: the same lift derives the SLM's "SLM Admin" translation from them.
…18240) UiModeSettingsCard (Settings > Appearance): two aria-pressed mode cards and a Start-in radiogroup (Last used / Minimal / Full) over the same useUiMode state the header toggle drives. ThemePresetPicker is extended, not duplicated, with an Additional themes group (AdditionalThemesGroup) fed by the installed-theme registry, each theme badged "Deployed via SLM" with a link to the SLM console; EmberThemeToggle keeps the built-in variants only so no theme is offered twice. ThemePresetPicker's inline sr-only announcer moves onto the kit useAnnounce, which takes it from 611 to 587 lines, under the limit, so its ceiling is deleted. SettingsView does not grow (784).
…er, UiModeToggle, ProfileMenu, MobileNavPanel and a BaseModal status panel (#18240) Split the 290-line header and the hand-rolled status overlay out of App.vue (1144 -> 499 lines, now under the 600 limit, so its grandfathered ceiling is deleted). The brand is the kit BrandMark linking Home; the health dot is an aria-hidden overlay and System status moved into the profile menu. Primary links are Home, Chat, Knowledge, Company OS and Analytics (advanced); Automation is pinned to the existing NavOverflowMenu. The right-hand cluster is Secrets (advanced), Preferences, the Minimal/Full toggle and the Platform admin shield (advanced, gated by service.management, opens the SLM console in a new tab). Every icon has an i18n aria-label and a kit BaseTooltip. The active link is a 2px accent underline. config/navItems.ts stays the one registry: it gains the adv and overflow flags and navIconItems; the profile menu loses Plugins (it lives in the SLM console nav; INTENTIONALLY_HIDDEN records why), Secrets and Preferences; paletteNavItems still derives from it. The mobile drawer renders the same registry. The SLM text link, DarkModeToggle and LanguageSwitcher are no longer in the nav. One shared useSystemStatus instance is provided by App.vue (composables/ systemStatusContext.ts) so the dot and the panel show one snapshot. New strings are committed separately (feat(i18n)). nav.slmAdmin* stays (the SLM locale lift derives from it). Ratchets only move down: App.vue's scoped style, a LoginForm .logo-mark rule that had pushed distinct_class_names over its baseline, and the raw status colours the header and panel used.
…ps it that way (#18240) useUserStore.applyTheme/updateTheme and the profile modal's own theme buttons set data-theme from a second preference (default light) that could disagree with useTheme's persisted choice. They are removed, together with PreferencesPanel in the profile modal (appearance settings live in Settings only). The meta theme-color the store set from two hex values moves into useTheme and follows the active theme's surface token instead. repo_tests/single_attribute_writer_18240_test.py fails if anything but useTheme writes data-theme, or anything but useUiMode (and its pre-mount copy in theme-variant-init.ts) writes data-ui, with contrast pairs for the matcher and a control that the scan sees each canonical writer.
Refs #17856 row 7 routeConfig, getAllRoutes, findRouteByPath, getNavigationMenus and RouteConfig have zero importers: no static import, no dynamic import(), no require, no import.meta.glob, no string path in a build/test/storybook/CI config; the only mentions are two superseded plans under docs/superpowers. Router entries it described are live in router/index.ts, or tracked: /monitoring and /monitoring/system redirect to the SLM console, /monitoring/analytics is CodebaseAnalytics, /tools/files is FileBrowser (mockup screen in step 5), /tools/voice lives in chat voice, /monitoring/rum is #18277, /monitoring/validation is #18278.
…overable and touch-safe, drop the double read on icon links (#18240)
…y at a fresh sign-in, never on session restore (#18240)
…sh sign-in, never on session restore (#18240)
…st and claim kit changes in pre-push (#17959)
…alid-index probe runs only on PostgreSQL (#17225) The writer guard's _RETIRED list named three deleted modules, which the stranded-recorder census read as stranded entries. The census had no way to record a path that must stay absent, so it gains one: TOMBSTONE_LEDGERS, keyed like a census record with a reason, excluded from the stranded check and checked the other way round -- an entry the tree holds again fails. The guard splits the list into _RETIRED_MODULES (deleted; the tombstone) and _RETIRED_WRITERS (adapters kept by D3/D6 that must not write again), and asserts the deleted modules stay deleted. _index_is_invalid in 20261011_098 queries pg_index only when the bind is PostgreSQL (review note on #18343).
…tems # Conflicts: # repo_tests/_reach_policy.py # repo_tests/python_file_size_ratchet_baseline.py # repo_tests/reach_scope_claim_17844_test.py # scripts/python_file_size_known_large.py
… dedupe and so proves nothing (#17959)
…e deleted audit modules (#17225) The stranded-recorder census found pipeline-scripts/hardcoded_values_baseline.txt still naming services/audit/audit_log.py, services/event_log.py and knowledge/audit_log.py, deleted by D2. A stranded entry is a shrink that did not happen; the three rows are removed.
…s bootstrap the backend and the repo root, 3 validators repaired, fresh_kb_setup retires (#18289) Shared (repoint, no behaviour change): constants.* and config.API_BASE_URL/OLLAMA_URL imports in 19 modules now come from autobot_shared (network_constants, ssot_constants); knowledge_categories moves to autobot_shared, its backend importers and the category migration follow. Backend tools: 18 more modules put autobot-backend and the repository root on their own path (the root is what provides autobot_shared; several had only the backend, or a wrong directory), and move from UNCLASSIFIED to BACKEND_TOOLS. The clean-import guard now also asserts autobot_shared resolves after the tool's own bootstrap. Repaired against today's APIs: validate_configuration, validate-security-config, validate_chat_knowledge, each run by a new test against the real backend. Retired: scripts/fresh_kb_setup.py, superseded by setup/knowledge/fresh_kb_setup.py (same job, has a test, repo_tests 14507 loads it).
…authenticated requests over HTTP (#18240)
… helper (#17941) one_brand_mark_and_announcer and single_attribute_writer hand-matched comment markers; they now use tools.lint._comment_syntax.code_lines with the file's own suffix. The jsdoc self-test cases become real /** */ blocks, since a bare ' * x' line outside a comment is code.
audio-extension-allowlist 6106, hardcoded-colour-scan 853, redaction-concept-census 3372, tracked-key-material 11077, undefined-css-var-scan 1491 -- each the guard's measured mid-window value.
|
Important Review skippedToo many files! This PR contains 231 files, which is 131 over the limit of 100. To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to a paid plan to raise the limit. This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry. ⚙️ Run configuration
⛔ Files ignored due to path filters (8)
📒 Files selected for processing (231)
You can disable this status message by setting the
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Closed and rebuilt as train #7b. #18373 is ejected: it breaks every frontend build through the |
Thinking Path
Merge train #7, under the owner decisions of 2026-10-11 and 2026-10-12 (every approved PR lands through a train). It is built on current
mainand lands with a merge commit. The drift-prone guards were pre-run locally on the combined tree: the reach declarations pass (555) after the re-pins below. The only remaining local failures are the threeinfra_validators_repaired_18289cases. They needaiofiles, which this machine has only in user site-packages, and the test's isolated-Iinterpreter hides those. CI installs the declared set into the interpreter, so this run is their real check.What Changed
Constituents (
#PR @ approved head):knowledge_categoriesintoautobot_shared.audit_logsbecomes the one system of record (tech-debt(audit): #6475 closed on three parallel audit systems — there are now six #17225). The tombstone ledgers are an inverse census check. The migrations are additive.Train-only commits:
repo_tests/reach_scope_claim_17844_test.py.one_brand_mark_and_announcer_18240_test.pyandsingle_attribute_writer_18240_test.pynow read code throughtools.lint._comment_syntax.code_linesinstead of hand-matching comment markers (tech-debt(guards): a text-keyed guard is satisfied by its own comment — 5 witnesses, 7 duplicated helpers, no shared one #17941). Their jsdoc self-test cases are now real/** */blocks.Refs #17267
Refs #18240
Refs #15469
Refs #17856
Refs #17959
Refs #18289
Refs #17225
Verification
Model Used
Claude Opus 5.5 (merge orchestration). Constituent reviews used Sonnet and Opus by risk tier.
🤖 Generated with Claude Code