Repository navigation
chore(git): rename Dev_new_gui to main and main to release across the repo (#16479) - #16487
Merged
Merged
Conversation
… repo (#16461) Simultaneous branch-name swap: every Dev_new_gui reference in executable and config files becomes main, and every main reference that names the release branch becomes release, never both collapsing into one name. Covers 54 workflows plus dependabot.yml, pre-commit config/hooks, git-hooks, scripts, Ansible deploy_ref defaults, the SLM/backend code defaults (SLM_REPO_BRANCH/AUTOBOT_GIT_BRANCH), frontend/backend literals and their tests, and current-process docs (CLAUDE.md, docs/developer/*, .claude/skills). Renames .github/workflows/sync-main-to-dev.yml to sync-main-to-release.yml and reverses its direction (main -> release), updating pipeline-scripts/release_sync_main.py, release_sync_pull.py and their tests to match. Adds the temporary .github/workflows/mirror-main-to-legacy-dev-branch.yml so the live updater keeps fetching Dev_new_gui as a fast-forwarded mirror of main until production is confirmed tracking main (#16461 also tracks its removal). Every branch-deletion/merge/retarget workflow and script keeps Dev_new_gui in its exclusion or never-target list for the same reason. pages.yml's ruby/setup-ruby@v1 is SHA-pinned in passing (#7091's gate fired on it once the file was touched); repo_tests/ci_dispatch_watchdog_test.py's file-size ceiling is lowered to match black's reformat (#5060 ratchet only turns down). Five files are left untouched: editing any of them trips a pre-existing, unrelated lint/hardcoded-value/async-IO/mypy gate on debt already in the file (a gate that cannot be baselined for a file the same change touches, per its own no-bypass rule) -- - docs/_config.yml (hardcoded GitHub URL pattern) - install.sh (chown/path/URL literals) - .claude/skills/claims-audit/generate_report.py (flake8/print()) - .github/workflows/slm-migration-gate.yml (hardcoded :5432) - autobot-backend/services/knowledge/code_indexer_test.py (26 pre-existing blocking-I/O-in-async findings) - autobot_shared/user_management/models/core_test.py (pre-existing mypy strict errors on importlib.util.module_from_spec's Optional return) Each needs its own debt fix before its branch-name reference(s) can be renamed. Dated historical records (docs/archives, changelog/, docs/research, docs/superpowers/plans+specs, docs/audit, docs/adr, docs/prd, docs/planning, docs/analysis, docs/design, docs/discovery, and auto-generated docs/verification*.json/md, docs/system-state.md) are left untouched.
3 tasks
Contributor
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Advanced Run ID: 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 |
This was referenced Sep 12, 2026
This was referenced Sep 12, 2026
Contributor
✅ SSOT Configuration Compliance: Passing🎉 No new hardcoded values of either class — Known backlog in |
Contributor
2 of 3 tasks
This was referenced Sep 12, 2026
Merged
Merged
7 tasks done
This was referenced Sep 12, 2026
This was referenced Sep 12, 2026
This was referenced Sep 12, 2026
This was referenced Sep 12, 2026
Merged
This was referenced Sep 13, 2026
3 tasks done
mrveiss
added a commit
that referenced
this pull request
Sep 13, 2026
…ain (#16464) (#16467) * fix(migrations): port 6 orphaned tables into the canonical Alembic chain (#16464) session_collaborations, terminal_activities, file_activities, browser_activities, desktop_activities and secret_usage are all declared in real ORM models (models/session_collaboration.py, models/activities.py) but were never reachable via `alembic upgrade head` -- they only existed in autobot-backend/database/migrations/, which migrations/alembic.ini does not point at (script_location = migrations, version_locations = migrations/versions). migrations/schema_bootstrap.py confirms there is no silent create_all() fallback against a real database either. Same class of bug as #10750 A2, which found and fixed 8 LLC tables in exactly this state. Highest-impact finding: every one of the five activity/secret_usage tables carries ForeignKey("users.id", ondelete="CASCADE"), and users.org_id is itself ForeignKey("organizations.id", ondelete="CASCADE"). A missing CASCADE target doesn't just make the table unreachable -- it makes hard-deleting a user, or an organization (which cascades into its users), fail outright against any properly-migrated database. Not hypothetical: confirmed on a live install (37's probe entities). Two new tests (tests/migrations/test_cascade_delete_orphaned_tables_16464.py) exercise exactly that at the database level and pin it fixed. session_collaborations is what api/collaboration.py's entire REST API depends on (#16429/#16443/#16455/#16462) -- every one of those routes 500'd (UndefinedTableError) against a real database until this migration. Also added: - Both new concepts (session_collaboration, activity_audit_trail) declared in autobot_shared/store_authority.py, with a SYSTEM_OF_RECORD = system_of_record(...) call at each model file's module level. - repo_tests/orphaned_database_migrations_test.py: a general guard that fails the moment a NEW table lands in database/migrations/ without a matching CREATE TABLE in migrations/versions/, so this class of defect can't recur silently and get found by hand again. Deliberately excluded: database/migrations/001_create_conversation_files.py looks like the same bug at a glance (same orphaned directory) but manages its own dedicated SQLite file via a self-contained, live-invoked migration runner -- checked and confirmed unrelated. Follow-up filed: #16466 (3 of the 5 activity-tracking backend modules -- terminal/file/browser -- have zero real callers; wire or retire). Migration is fully additive (CREATE TABLE / CREATE INDEX only, nothing dropped) and idempotent (has_table()-guarded). Deliberately fully inlined per-table rather than a shared helper, matching #10750 A2's own style -- repo_tests/orphaned_database_migrations_test.py reads table names via AST from literal op.create_table("name", ...) calls, and a name passed through a helper's parameter is invisible to that scan. * docs(changelog): add fragment for #16464 * security(chat): scan/redact PII and flag injection risk on every raw chat message (#16529, #16530) * security(chat): scan/redact PII and flag injection risk on every raw chat message (#16529, #16530) Internal audit of the LLM request pipeline found api/chat.py forwarded the raw user message to the LLM (and to persistent storage) without ever calling the existing PII pipeline (a2a/pii_pipeline.py) or the existing prompt-injection detector (security/prompt_injection_detector.py) -- both were wired to narrower features but never to the literal chat message on any turn. Adds security/chat_message_safety.py as the one choke point every raw- message entry point in chat.py now calls first: /chat, /chat/stream (both branches), the frontend's primary /chats/{id}/message path, /chat/direct, and /ai-stack + /stream-ai-stack. PII reuses the existing BLOCK/REDACT/HASH policy unchanged via scrub_outbound(); SSN/API-key/card/JWT-shaped content is rejected before the LLM call, lower-severity types are redacted in place. Injection detection flags and logs HIGH/CRITICAL hits rather than blocking outright -- measured directly against a benign-message sample while wiring this in, the shared detector's pattern set false-positives on ordinary chat phrasing ("you are a great assistant"), so a flat block would reject legitimate turns. The existing AUTOBOT_INJECTION_HARDBLOCK_ENABLED opt-in still rejects a message when an operator has turned on stricter enforcement. chat.py is a grandfathered file frozen at its current line count (#14236); the five call sites land as in-place line edits (tuple-assignment / inline-call) rather than new lines, so the file's size does not change. * fix(security): match the injection-detector singleton's locked construction args (#16529, #16530) get_prompt_injection_detector() is a lazy_singleton(PromptInjectionDetector): whichever caller constructs it first fixes its args for the process, and every later caller passing different args gets an error instead of the detector. Every existing call site (prompt_manager.py, screen_analysis_ prompt.py, chat_knowledge_prompt.py, intent_analyzer.py, ...) already uses strict_mode=True; the new chat safety module called it bare, so whichever of the two constructed first could poison the other depending on import/ call order. Caught by running the new tests alongside tests/test_injection_ detection.py, where TestPromptManagerInjectionDetection started failing with a "lazy_singleton: called with different args" log line. * fix(chat): surface a real 400 for a blocked streaming message, not a generic SSE error (#16529, #16530) Code-review follow-up on the /chat/stream path: scan_chat_message() ran inside _generate_llm_stream's try block, so a PIIBlocked/hard-block HTTPException(400) was caught by that function's own broad except Exception and downgraded to a generic {"type":"error"} SSE event at HTTP 200 -- the LLM was still never called (already covered by a test), but the client could not distinguish "blocked by policy" from "the LLM failed", unlike the other four call sites, which all return a real 400. Moves the scan into stream_message() itself, before stream_chat_response() ever constructs a StreamingResponse -- a StreamingResponse commits to its status code the moment it is returned, before its body generator is entered, so scanning there is the only way to get a genuine pre-stream 400. _generate_llm_stream no longer scans; by the time it runs, message.content is already clean. Also: standardised two more #16529-only comment tags to #16529/#16530 for consistency (a third stays #16529-only -- the full tag would exceed this frozen file's 120-char line limit), and added an injection-flagged-but-not- blocked behavioral test at each of the five call sites -- the existing tests only covered the PII-block path per site, not that the #16530 false-positive guard (flag-and-log, not block) actually holds through the real wiring and not just the primitive. * test(migrations): supply every required column in the cascade tests' activity inserts (#16464) migration-matrix was red on #16467: both cascade tests inserted activity rows with only (id, user_id), and the migrated schema declares NOT NULL columns on all four activity tables (terminal_activities.command, file_activities operation/path, browser_activities url/action, desktop_activities.action) -- NotNullViolationError. The migration was right; the fixture was incomplete. _required_columns reads every NOT NULL column without a default from the migrated schema and supplies a placeholder per type, failing by name on a type it has none for, so a future required column is caught rather than skipped. Migration and models unchanged. * chore(git): rename Dev_new_gui to main and main to release across the repo (#16461) (#16487) Simultaneous branch-name swap: every Dev_new_gui reference in executable and config files becomes main, and every main reference that names the release branch becomes release, never both collapsing into one name. Covers 54 workflows plus dependabot.yml, pre-commit config/hooks, git-hooks, scripts, Ansible deploy_ref defaults, the SLM/backend code defaults (SLM_REPO_BRANCH/AUTOBOT_GIT_BRANCH), frontend/backend literals and their tests, and current-process docs (CLAUDE.md, docs/developer/*, .claude/skills). Renames .github/workflows/sync-main-to-dev.yml to sync-main-to-release.yml and reverses its direction (main -> release), updating pipeline-scripts/release_sync_main.py, release_sync_pull.py and their tests to match. Adds the temporary .github/workflows/mirror-main-to-legacy-dev-branch.yml so the live updater keeps fetching Dev_new_gui as a fast-forwarded mirror of main until production is confirmed tracking main (#16461 also tracks its removal). Every branch-deletion/merge/retarget workflow and script keeps Dev_new_gui in its exclusion or never-target list for the same reason. pages.yml's ruby/setup-ruby@v1 is SHA-pinned in passing (#7091's gate fired on it once the file was touched); repo_tests/ci_dispatch_watchdog_test.py's file-size ceiling is lowered to match black's reformat (#5060 ratchet only turns down). Five files are left untouched: editing any of them trips a pre-existing, unrelated lint/hardcoded-value/async-IO/mypy gate on debt already in the file (a gate that cannot be baselined for a file the same change touches, per its own no-bypass rule) -- - docs/_config.yml (hardcoded GitHub URL pattern) - install.sh (chown/path/URL literals) - .claude/skills/claims-audit/generate_report.py (flake8/print()) - .github/workflows/slm-migration-gate.yml (hardcoded :5432) - autobot-backend/services/knowledge/code_indexer_test.py (26 pre-existing blocking-I/O-in-async findings) - autobot_shared/user_management/models/core_test.py (pre-existing mypy strict errors on importlib.util.module_from_spec's Optional return) Each needs its own debt fix before its branch-name reference(s) can be renamed. Dated historical records (docs/archives, changelog/, docs/research, docs/superpowers/plans+specs, docs/audit, docs/adr, docs/prd, docs/planning, docs/analysis, docs/design, docs/discovery, and auto-generated docs/verification*.json/md, docs/system-state.md) are left untouched. * test(migrations): say where the cascade tests' INSERT names come from (#16464) Review nit on #16467: the nosec justification said the names come from the schema; only the columns do -- the table is a literal from this module. * test(migrations): fill every required organizations/users column from the schema (#16464) migration-tests at eb2d22d: 1 failed, 159 passed. The organization cascade test inserted an organizations row without kb_inheritance_weight, which 20260616_060 adds NOT NULL and then strips of its server default, so the insert raised NotNullViolationError before any cascade was exercised. The activity-table inserts already read their required columns from information_schema; the organizations and users inserts were still hand-written and so drift whenever a migration adds a required column. _insert_row now serves all of them: every NOT NULL column without a default that the caller did not supply gets a typed placeholder, and an unknown type still fails by name. double precision joins the placeholders.
This was referenced Sep 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #16479
Refs #16461
Single-issue rationale: this delivers #16479, the in-repo half of the branch rename (#16461). The GitHub-side renames already ran, and production moving to
mainplus the mirror's removal are later steps of the same issue. So this PR references #16461 and doesn't close it.Thinking Path
The owner chose standard branch naming. The working branch
Dev_new_guiis nowmain, the default branch, and the oldmainis nowrelease. The GitHub-side renames are done:main→releaseDev_new_gui→main; GitHub retargeted every open PRmainDev_new_guimirror keeps the live updater fetching until production tracksmainThis PR makes the repository agree with the new names. The two names swap: old
Dev_new_guireferences becomemain, and oldmainreferences becomerelease, but only where they meant the release branch.mainas a function,__main__, a Redis database name or "main process" is untouched.What Changed
Dev_new_gui→main(505 lines across 204 files): workflow branch filters and ref checks,dependabot.yml, pre-commit and.claudehooks,tools/git-hooks, scripts, the updater defaults (git_tracker.pySLM_REPO_BRANCH,playbook_executor.pyAUTOBOT_GIT_BRANCH, the Ansibledeploy_ref),CLAUDE.mdand the current process docs. Dated historical records are left as they are.main→releasewhere it meant the release branch (a 172-line list, each line reviewed). This coversrelease.yml, the weekly sync, whose direction is nowmain→releaseand whose workflow is renamedsync-main-to-release.yml, the release-sync scripts and tests, and the protected-branch lists.Dev_new_guistays in every branch-automation exclusion list (cleanup, health and stale-branch reports, the parked-branch merger's never-target list, worktree cleanup) and in the push-protection hook, so nothing deletes, merges into or pushes to the mirror. Each entry is commented for removal under infra(git): rename Dev_new_gui to main and main to release, without breaking the live updater #16461.mirror-main-to-legacy-dev-branch.yml: fast-forwardsDev_new_guito every push onmain, with no force. It's temporary, and removed under infra(git): rename Dev_new_gui to main and main to release, without breaking the live updater #16461 once production tracksmain.Verification
main→releasechange is listed and was reviewed line by line before pushing.git grep Dev_new_guioutside dated history finds only the mirror workflow and the "kept for the mirror" exclusions: the mirror workflow, the marked exclusions, one#16461note inrelease_sync_main.py, and dated historical documents. Five files still blocked by pre-existing debt in the same file, and five rules whose reasons the new model contradicts, are tracked in infra(git): rename leftovers: five files blocked by pre-existing debt, and rules the new branch model contradicts #16482.bash -n, and Python compiles. CI on this PR is the first run under the new branch names.Model Used
Claude Opus 5 (coordinator, review of every release-context change) with a Claude Sonnet 5 subagent for the edits.
Why this PR only references #16479: its first criterion says no workflow, script, hook, config or code default names
Dev_new_gui. Five leftover files still do, includinginstall.sh'sDEFAULT_BRANCHandslm-migration-gate.yml, and they're deferred to #16482. #16479 is finished when #16482 lands.