From 8a3c48335075fb360d542b3389f7a41472bfde50 Mon Sep 17 00:00:00 2001 From: James Maes Date: Mon, 12 Oct 2026 14:48:47 -0500 Subject: [PATCH] chore: align with the QRun qbit repository standard - `.editorconfig` (Kingsrook 3-space layout) - `.github/dependabot.yml` (Maven + Actions, grouped minor/patch, at most 3 open PRs, target `develop`) - `mvnw` executable (100755) - `AGENTS.md` (same content as `CLAUDE.md`, as in the other qbits) - `LICENSE` appendix copyright holder `Kingsrook, LLC`, matching the other qbits, NOTICE and the pom developers (was `QRunIO, LLC`; please confirm) Co-Authored-By: Claude Opus 5.5 --- .editorconfig | 20 ++++++++++ .github/dependabot.yml | 25 ++++++++++++ AGENTS.md | 90 ++++++++++++++++++++++++++++++++++++++++++ LICENSE | 2 +- mvnw | 0 5 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 .editorconfig create mode 100644 .github/dependabot.yml create mode 100644 AGENTS.md mode change 100644 => 100755 mvnw diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..8db2889 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,20 @@ +# QRun-IO qbit .editorconfig: the Kingsrook layout (3-space indentation, never tabs). +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = space +indent_size = 3 +tab_width = 3 + +[*.md] +trim_trailing_whitespace = false + +[*.{yml,yaml}] +indent_size = 2 + +[*.{cmd,bat}] +end_of_line = crlf diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..9878878 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,25 @@ +# Weekly, grouped dependency updates. Minor and patch updates arrive as one PR per ecosystem; +# major updates stay separate so each gets its own review. At most three version-update PRs per +# ecosystem are open at once. Security updates are enabled in the repository settings and are +# not limited by this schedule. +version: 2 +updates: + - package-ecosystem: maven + directory: / + target-branch: develop + schedule: + interval: weekly + open-pull-requests-limit: 3 + groups: + maven-minor-and-patch: + update-types: [minor, patch] + + - package-ecosystem: github-actions + directory: / + target-branch: develop + schedule: + interval: weekly + open-pull-requests-limit: 3 + groups: + github-actions: + patterns: ['*'] diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..cab5abb --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,90 @@ +# AGENTS.md + +This file provides guidance to Codex when working with code in this repository. + +## Project Overview + +**QBit Assistant** adds an in-app AI assistant to any QQQ application. It owns the chat backend: +- conversations and audit tables +- the turn engine (the agent loop) +- the `/qqq/v1/assistant` routes, with SSE +- budgets, rate limits and the kill switch +- the model-provider SPI. + +The panel UI lives in `qqq-frontend-next`. Data access goes only through the **AI tool kernel in QQQ core** (`com.kingsrook.qqq.backend.core.actions.ai.AiToolKernel`). + +- Design spec: `QRun-IO/qqq` `docs/specs/2026-10-11-qqq-assistant-qbit-design.md`. The owner decisions D1 to D6 at its top are binding. +- Phase 1 is read and navigate only: no write tools and no approval cards. + +## Build Commands + +```bash +./mvnw verify # all modules, tests, JaCoCo gate (70% instructions / 90% classes) +./mvnw verify -Dqqq.snapshot.version=4.1.0-ASSISTDEV-SNAPSHOT # against a locally installed QQQ build with the kernel (+ developer panels) +./mvnw test -pl qbit-assistant -Dtest=RedTeamTest +ANTHROPIC_API_KEY=... ./mvnw verify -Dassistant.live=true -Dtest.excludedGroups= -Dgroups=live -Djacoco.skip=true -pl qbit-assistant-provider-anthropic -am +``` + +Always use the wrapper: Maven 3.10 cannot read the parent POM. The committed default QQQ version (`qqq.snapshot.version` in the root POM) must stay resolvable from Maven Central. Use a local kernel build only through `-D`. + +## Modules + +- `qbit-assistant` (`com.kingsrook.qbits.assistant`): + - `AssistantQBitProducer`, `AssistantQBitConfig` (with `AssistantModelRouting` and `AssistantBudgets`), `AssistantRuntime`, `AssistantSecurity`. + - `metadata/`: tables, owner key type, the Assistant Admin app, the retention process, and the `assistant.admin` custom permission checker. + - `model/`: entities for the `assistant*` tables. + - `persistence/AssistantStore`: the **only** code that calls QQQ data actions, and only on the QBit's own tables, under the user's session. + - `engine/`: `TurnEngine` (the loop), `ContextBuilder` (cache-prefix order), `SystemPrompt`, `PolicyService` (policy row, budgets), `RateLimiter`, the `TurnEvent` / `TurnEventLog` stream, and `MessageParts`. + - `api/`: `AssistantApi` (transport-free) and `AssistantRouteProvider` (Javalin, SSE). + - `provider/`: the provider-neutral SPI, plus `fake/ScriptedModelProvider` for tests, evals and demos. + - `developer/`: the record Developer-screen panel, on the core developer-panel contract. + - `processes/AssistantRetentionStep`. +- `qbit-assistant-provider-anthropic`: `AnthropicModelProvider` and `AnthropicMapping` (anthropic-java streaming). + +## Invariants (do not break) + +- **Sessions:** + - Never use `QSystemUserSession` or construct a `QSession` in main code (ArchUnit). + - Every route uses `ExecutorSessionUtils.setupSession` (the user's own session). + - `AssistantSecurity` only ever adds the user's OWN id key, or the all-access key for `assistant.admin` holders. +- **Data access:** + - Only `persistence/` calls QueryAction, InsertAction and the other data actions (ArchUnit). + - Tools run only through `AiToolKernel.execute`. + - Panel API queries also filter `userId = me`, so an admin's all-access key never mixes other users' conversations into the panel. +- **Caching:** the request prefix stays byte-stable. The order is tools (kernel-sorted), then system block 1 (rules + primer + app digest, LONG/1h), then system block 2 (user digest + date, SHORT/5m), then messages. Exactly one SHORT hint goes on the newest message. Don't put timestamps or ids in the system prompt. +- **Tool results:** + - Parallel tool results go back in ONE user message, in call order. + - Errors (DENIED, NOT_FOUND, INVALID_INPUT, ERROR) are `is_error` results. + - Unknown tools and over-limit calls also get error results. +- **Logging:** never log message content, prompts, tool results or keys. Structured end-of-turn log only. +- **Thinking:** thinking is never streamed or stored. The Anthropic adapter keeps the raw assistant message (with signatures) only in memory, as `providerState`, for the tool loop. +- **Links:** only `/app` or `/app/...` hrefs are emitted (`TurnEngine.isAppHref`). +- **Kill switch:** read fresh before every model call and every tool step. + +## Tests + +- `testing/` holds the fixture app on the memory backend: + - blog, page, media and analytics tables, plus audits + - sentinel values in hidden and password fields + - a prompt-injection record + - MOCK auth where the user-id prefix picks the permissions. +- `testing/` also holds `TurnRunner`, `GoldenTasks` and `EvalSupport`. They are published as a test-jar for the provider's live evals. +- Tags: + - `golden` (`GoldenEvalTest`) and `redteam` (`RedTeamTest`) run in every build. Any failure fails the build. + - `live` is excluded unless you pass `-Dtest.excludedGroups= -Dgroups=live` and set the key. + +## Code Style + +QQQ style: +- 3-space indent, braces on the next line, `return (x);` +- flower-box javadoc on every class and method +- fluent `withX` setters +- wrapper types. + +## Release + +- CircleCI qqq-orb 0.6.8. +- `develop` publishes SNAPSHOTs. +- `release/*` publishes RCs; the orb bumps `` in the root POM. +- `v*` tags publish releases. +- Both modules and the parent POM publish. The flatten plugin resolves `${revision}`. diff --git a/LICENSE b/LICENSE index b3f61de..4bb040e 100644 --- a/LICENSE +++ b/LICENSE @@ -176,7 +176,7 @@ END OF TERMS AND CONDITIONS - Copyright 2022-2025 QRunIO, LLC + Copyright 2024 Kingsrook, LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/mvnw b/mvnw old mode 100644 new mode 100755 -- 2.54.0