Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
a6189c1
Increment Version to 0.2.1
JarbasAl Apr 15, 2026
ed7fb8a
feat: add SQLCipher encryption support (password kwarg) (#24)
JarbasAl Apr 15, 2026
eabc7d8
Increment Version to 0.3.0a1
JarbasAl Apr 15, 2026
8e3402f
Update Changelog
JarbasAl Apr 15, 2026
bbeb6d4
Preserve client metadata (supersedes #29) (#30)
JarbasAl May 18, 2026
46cd8b5
Increment Version to 0.3.0a2
JarbasAl May 18, 2026
228aad0
Update Changelog
JarbasAl May 18, 2026
9f578ce
ci: pass PYPI_TOKEN explicitly, drop secrets:inherit elsewhere (#33)
JarbasAl May 20, 2026
90507d1
Increment Version to 0.3.0a3
JarbasAl May 20, 2026
38b0836
Update Changelog
JarbasAl May 20, 2026
1c28bfa
ci: dedupe tests.yml — drop test-plain, rename to cipher-tests.yml (#34)
JarbasAl Jun 5, 2026
173f0b1
Increment Version to 0.3.0a4
JarbasAl Jun 5, 2026
588f9ec
Update Changelog
JarbasAl Jun 5, 2026
c6b044c
feat(db): schema v2 migration — fold legacy blacklist columns into me…
JarbasAl Jun 5, 2026
7f1a95c
Increment Version to 0.4.0a1
JarbasAl Jun 5, 2026
ba11435
Update Changelog
JarbasAl Jun 5, 2026
183a4e3
docs: zero-to-hero README and docs coverage (#38)
JarbasAl Jun 5, 2026
c94d9d0
Increment Version to 0.4.0a2
JarbasAl Jun 5, 2026
dacd741
Update Changelog
JarbasAl Jun 5, 2026
ba689ba
test: hivescope e2e + CI (#41)
JarbasAl Jul 4, 2026
593289e
Increment Version to 0.4.0a3
JarbasAl Jul 4, 2026
2a47ff8
Update Changelog
JarbasAl Jul 4, 2026
0262e7c
Update actions/checkout action to v7 (#40)
renovate[bot] Jul 4, 2026
1cfc0d9
Increment Version to 0.4.0a4
JarbasAl Jul 4, 2026
952579d
Update Changelog
JarbasAl Jul 4, 2026
63ec1d1
fix: advance last_seen atomically (#44)
goldyfruit Jul 16, 2026
131523c
ci: release safely after fork merges (#45)
goldyfruit Jul 16, 2026
a40c747
Increment Version to 0.4.0a5
goldyfruit Jul 16, 2026
3b24a8a
Update Changelog
goldyfruit Jul 16, 2026
37e9474
Revert unauthorized automated merges (#44, #45) (#47)
JarbasAl Jul 16, 2026
424bbba
Increment Version to 0.4.0a6
JarbasAl Jul 16, 2026
9387971
Update Changelog
JarbasAl Jul 16, 2026
862e594
docs: rewrite README in Simplified Technical English (#50)
JarbasAl Jul 31, 2026
22d5219
Increment Version to 0.4.0a7
JarbasAl Jul 31, 2026
cc892c9
Update Changelog
JarbasAl Jul 31, 2026
63f3d00
fix: index api_key, queried on every client connect (#52)
JarbasAl Aug 3, 2026
7b9523f
Increment Version to 0.4.1a1
JarbasAl Aug 3, 2026
78dff6d
Update Changelog
JarbasAl Aug 3, 2026
9fbd51b
fix: give each thread its own SQLite connection (#54)
JarbasAl Aug 3, 2026
7644e4d
Increment Version to 0.4.2a1
JarbasAl Aug 3, 2026
59e0472
Update Changelog
JarbasAl Aug 3, 2026
cd9882e
fix: worker thread can silently write to the real client db when a te…
JarbasAl Aug 10, 2026
681ddb5
Increment Version to 0.4.3a1
JarbasAl Aug 10, 2026
d40dfe7
Update Changelog
JarbasAl Aug 10, 2026
ef234f3
chore(ci): drop the broken, redundant Dependabot config (#58)
JarbasAl Aug 10, 2026
d5661cd
Increment Version to 0.4.3a2
JarbasAl Aug 10, 2026
c2248e2
Update Changelog
JarbasAl Aug 10, 2026
465da5f
Update actions/setup-python action to v7 (#49)
renovate[bot] Aug 10, 2026
c93529e
Update dependency python to 3.14 (#8)
renovate[bot] Aug 10, 2026
a43eea1
Increment Version to 0.4.3a3
JarbasAl Aug 10, 2026
b99e221
Increment Version to 0.4.3a4
JarbasAl Aug 10, 2026
d142c88
Update Changelog
JarbasAl Aug 10, 2026
535420d
Update Changelog
JarbasAl Aug 10, 2026
09e0d6a
docs: expand AGENTS.md with org-wide agent conventions (#62)
JarbasAl Aug 15, 2026
0b3c306
Increment Version to 0.4.3a5
JarbasAl Aug 15, 2026
1118a77
Update Changelog
JarbasAl Aug 15, 2026
0065649
test: fix e2e cache-invalidation helper to call invalidate_user (#64)
JarbasAl Sep 2, 2026
3d31b24
Increment Version to 0.4.3a6
JarbasAl Sep 2, 2026
da2699a
Update Changelog
JarbasAl Sep 2, 2026
e857671
refactor: drop the dead crypto_key column/field (v3-Noise-only; core …
JarbasAl Sep 4, 2026
8f7ecb3
Increment Version to 0.4.3a7
JarbasAl Sep 4, 2026
4c2c7d7
Update Changelog
JarbasAl Sep 4, 2026
b22a2a0
test: drop removed crypto_key field from client round-trip test (#69)
JarbasAl Sep 7, 2026
233590d
Increment Version to 0.4.3a8
JarbasAl Sep 7, 2026
9788c0d
Update Changelog
JarbasAl Sep 7, 2026
3c0ea70
docs: fix DatabaseFactory.create() call signature in operations guide…
JarbasAl Sep 7, 2026
adce721
Increment Version to 0.4.3a9
JarbasAl Sep 7, 2026
50e952b
Update Changelog
JarbasAl Sep 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions .github/dependabot.yml

This file was deleted.

6 changes: 3 additions & 3 deletions .github/workflows/build-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ name: Build Tests

on:
pull_request:
branches: [dev, master, main]
branches: [dev, master]
workflow_dispatch:

jobs:
build:
uses: OpenVoiceOS/gh-automations/.github/workflows/build-tests.yml@dev
secrets: inherit
with:
python_versions: '["3.10", "3.11", "3.12", "3.13", "3.14"]'
install_extras: ''
install_extras: 'test'
test_path: 'tests'
pr_comment: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository }}
29 changes: 29 additions & 0 deletions .github/workflows/cipher-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Cipher Tests

# Dedicated workflow for the [cipher] extra (sqlcipher3 + libsqlcipher-dev).
# The shared build-tests.yml covers the unencrypted path on Python 3.10-3.14;
# this one adds a single Python 3.11 run with sqlcipher installed so the
# encrypted backend is exercised on every PR.

on:
pull_request:
branches: [dev, master, main]
workflow_dispatch:

jobs:
test-cipher:
name: "SQLite + SQLCipher"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: "3.14"
- name: Install sqlcipher system library
run: |
sudo apt-get update
sudo apt-get install -y libsqlcipher-dev
- run: pip install -e ".[cipher]"
# schema-v2 features (migrate, refresh, _check_forward_compat) ship in the 0.6.0a1 prerelease
- run: pip install "hivemind-plugin-manager==0.6.0a1" pytest
- run: pytest tests/test_sqlitedb.py -q -p no:ovoscope
5 changes: 3 additions & 2 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ on:
jobs:
coverage:
uses: OpenVoiceOS/gh-automations/.github/workflows/coverage.yml@dev
secrets: inherit
with:
python_version: '3.11'
coverage_source: 'hivemind_sqlite_database'
test_path: 'tests/'
pre_install_pip: '"hivemind-plugin-manager==0.6.0a1"'
test_path: 'tests/ --ignore=tests/e2e'
install_extras: ''
min_coverage: 0
pr_comment: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository }}
3 changes: 2 additions & 1 deletion .github/workflows/license_check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ on:
jobs:
license_check:
uses: OpenVoiceOS/gh-automations/.github/workflows/license-check.yml@dev
secrets: inherit
with:
pr_comment: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository }}
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ name: Lint

on:
pull_request:
branches: [dev, master, main]
branches: [dev, master]
workflow_dispatch:

jobs:
lint:
uses: OpenVoiceOS/gh-automations/.github/workflows/lint.yml@dev
secrets: inherit
with:
ruff: true
pre_commit: false # set true if .pre-commit-config.yaml exists
pr_comment: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository }}
3 changes: 2 additions & 1 deletion .github/workflows/pip_audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ on:
jobs:
pip_audit:
uses: OpenVoiceOS/gh-automations/.github/workflows/pip-audit.yml@dev
secrets: inherit
with:
pr_comment: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository }}
24 changes: 24 additions & 0 deletions .github/workflows/policy-e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Policy Migration E2E

on:
pull_request:
branches: [dev, master]
workflow_dispatch:

jobs:
policy_e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: "3.14"
- run: pip install -e ".[test]"
# Cross-repo policy stack (published prereleases) + hivescope with db= injection
- run: >-
pip install
"hivescope==0.4.0a2"
"hivemind-core==4.3.0a2"
"hivemind-ovos-agent-plugin==0.2.0a1"
"hivemind-plugin-manager==0.6.0a1"
- run: pytest tests/e2e/test_policy_migration_e2e.py -q -p no:cacheprovider
3 changes: 2 additions & 1 deletion .github/workflows/publish_stable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ on:
jobs:
publish_stable:
uses: OpenVoiceOS/gh-automations/.github/workflows/publish-stable.yml@dev
secrets: inherit
secrets:
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
with:
branch: 'master'
version_file: 'hivemind_sqlite_database/version.py'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ on:

jobs:
release_preview:
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
uses: OpenVoiceOS/gh-automations/.github/workflows/release-preview.yml@dev
secrets: inherit
with:
package_name: 'hivemind_sqlite_database'
version_file: 'hivemind_sqlite_database/version.py'
4 changes: 3 additions & 1 deletion .github/workflows/release_workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ on:
pull_request:
types: [closed]
branches: [dev]
workflow_dispatch:

jobs:
publish_alpha:
uses: OpenVoiceOS/gh-automations/.github/workflows/publish-alpha.yml@dev
secrets: inherit
secrets:
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
with:
branch: 'dev'
base_branch: 'master'
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/repo-health.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ name: Repo Health

on:
pull_request:
branches: [dev, master, main]
branches: [dev, master]
workflow_dispatch:

jobs:
repo_health:
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
uses: OpenVoiceOS/gh-automations/.github/workflows/repo-health.yml@dev
secrets: inherit
with:
version_file: 'hivemind_sqlite_database/version.py'
126 changes: 126 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# AGENTS.md — `hivemind-sqlite-database`

Guidance for AI coding agents (and humans) working in this repository. Read it
fully before making changes.

SQLite (and optional SQLCipher-encrypted) `AbstractDB` backend plugin for hivemind-core, storing HiveMind client records (API keys, crypto keys, ACLs).
Part of the [HiveMind](https://github.com/JarbasHiveMind) ecosystem — a
protocol for connecting satellite devices to a hub running
[OpenVoiceOS](https://github.com/OpenVoiceOS). The hub is
[HiveMind-core](https://github.com/JarbasHiveMind/HiveMind-core); the plugin
contract (`AbstractDB`) and loader live in
[hivemind-plugin-manager](https://github.com/JarbasHiveMind/hivemind-plugin-manager).

## Setup

```bash
pip install -e .
# encrypted-database support (SQLCipher / AES-256):
pip install -e ".[cipher]" # needs libsqlcipher system lib (apt install libsqlcipher-dev)
```

## Test

```bash
pytest tests/
```

Single suite lives in `tests/test_sqlitedb.py`. The repo's own `tests.yml` runs it with `-p no:ovoscope` and exercises both the plain and the SQLCipher path. Cipher tests need `libsqlcipher-dev` installed.

## Lint/Typecheck

Ruff, via the shared `lint.yml` workflow (`ruff: true`, no pre-commit config present). No typecheck configured.

## Layout

- `hivemind_sqlite_database/__init__.py` — the entire plugin: `SQLiteDB` dataclass extending `AbstractDB`. Schema creation, `PRAGMA user_version` migration (v1→v2 folds legacy `intent_blacklist`/`skill_blacklist` columns into `Client.metadata`), and CRUD (`add_item`, `search_by_value`, `get_client_by_id`, `__iter__`, `__len__`, `commit`).
- `hivemind_sqlite_database/version.py` — version constants (do not edit).
- `tests/test_sqlitedb.py` — full behavioural suite.

Entry-point group: `hivemind.database` → `hivemind-sqlite-db-plugin = hivemind_sqlite_database:SQLiteDB`. Discovered by `hivemind-plugin-manager`; selected in hivemind-core config under `database.module`.

## Conventions

- Branches: `dev` (work) and `master` (stable). NEVER `main`.
- Never edit `version.py`; gh-automations bumps semver from conventional-commit prefixes (`feat:`/`fix:`/`feat!:`).
- New repos private by default.
- Commit identity: JarbasAi <jarbasai@mailfence.com>.
- Reference `OpenVoiceOS/gh-automations` reusable workflows at `@dev`.
- No Neon / `neon-*` references.
- No meta-commentary (no history, no dates) in code, docs, commits, or PRs — describe current state only.
- CI is provided by OpenVoiceOS/gh-automations.

## Working agreement (org-wide law)

- **Never push `dev` or `master`.** Work on a feature branch and open a
**draft** PR into `dev`. A human merges. You do not merge your own PRs.
- **Never merge or modify `Release X → master` PRs.** They are the maintainer's
stable-release mechanism, generated by automation.
- **One commit per PR** (squash before pushing). Conventional commits; `feat:`
only for a user-visible new capability. `fix:`, `docs:`, `chore:`, `ci:`
otherwise.
- **Disclose AI authorship.** Every PR/issue/comment an agent writes carries, at
the top: `> 🤖 Auto-generated by <model> via Claude Code — NOT human-reviewed.
Verify before acting.` PR bodies are plain human prose (3–6 short paragraphs),
no tables or section-symbol spray.
- **Never edit someone else's** issue, PR description, or comment. Add a comment
instead; on your own PRs, edit the body rather than piling on comments.
- No scratch files, committed virtualenvs, `__pycache__`, `.pyc`, `.egg-info`,
or build artifacts in a PR. `git show --stat` shows only intended files.

## Dependencies

- **Floor pins only** (`>=X.Y.Za1`), bumped when a feature or fix is actually
needed. No upper caps unless a specific released version is genuinely broken.
`pyproject.toml` currently pins `hivemind-plugin-manager>=0.5.0,<1.0.0` — that
upper cap is a deviation from the floor-pins-only rule; treat removing it (once
confirmed safe against 1.x) as a standing cleanup, not something to add to.
- **No lockfiles, ever.** Target the latest alphas (`--prerelease=allow`).
- Everything in `pyproject.toml` (deps, metadata, version). Never install from
git — depend on a published PyPI alpha.
- Apache-2.0. Do not add GPL/AGPL dependencies.

## Tests

- Adversarial by default. A regression test must **fail before the fix and pass
after** — prove it by reverting only the source (`git apply -R`, never
`git stash` across worktrees) and watching the test flip.
- Tests must be mutation-proof: gutting the feature must fail the test. A test
that only asserts a mock was called, without asserting the real behaviour, is
weak — note it.
- Never skip a test because an optional dependency is missing (cipher tests need
`libsqlcipher-dev`; install it, do not skip).
- CI green is permission to review, not to merge. A non-trivial change gets an
adversarial review before it lands.

## Repo-specific rules

- This is the AUTH hot path for hivemind-core admission: `get_client_by_id`
(used by `refresh()`) and the rest of the CRUD surface must fail SAFE. Every
query is wrapped in `try/except (sqlite3.Error, TypeError, ValueError)`,
logs, and returns `None`/`False`/`0` on error — never raises past the plugin
boundary, never fabricates a permissive client record. Preserve this on any
change; a bug here means a bad key silently gets treated as absent rather
than admitted, which is the safe direction — never invert it.
- ACL fields (`can_broadcast`, `can_escalate`, `can_propagate`, and the
blacklists folded into `metadata`) must round-trip exactly through
`add_item` → `_row_to_client`. Any schema or serialization change needs a
test that writes a `Client` with non-default ACL values and reads it back.
- `_VALID_COLUMNS` allowlist gates `search_by_value` keys; SQL column name is
interpolated only after passing that frozenset (issue #1 tracks an
SQL-security review — do not relax this allowlist without closing that
concern).
- Legacy `intent_blacklist`/`skill_blacklist`/`message_blacklist` columns
remain in the table but are NULLed on write; canonical data lives in the
`metadata` JSON column. `message_blacklist` is purged entirely (not part of
`Client`). Do not resurrect writes to the legacy columns.
- `migrate()` guards on `getattr(AbstractDB, "SCHEMA_VERSION", 1)` so it
tolerates older hivemind-plugin-manager that predates the constant — do not
assume the attribute exists.
- WAL journal mode is enabled for both plain and encrypted DBs;
`check_same_thread=False` with a `threading.Lock` guarding writes. Any new
write path must take that lock.
- Encrypted and plaintext databases are not interchangeable and there is no
migration between them; lost passphrase = unrecoverable data.
- `tests.yml` is a repo-local workflow separate from the shared build-tests;
both run the same suite.
Loading