Skip to content
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
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
14 changes: 11 additions & 3 deletions .actrc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@
# stay on the real self-hosted fleet (docs/src/ci/runner-contract.md).
-P self-hosted=catthehacker/ubuntu:act-24.04

# Windows / macOS jobs: `act` runs Linux containers only, so it CANNOT execute
# `runs-on: windows-latest` or `macos-latest` jobs. We intentionally do NOT map
# them to a Linux image — that would silently run OS-specific steps (pwsh paths,
# .exe, Expand-Archive) under Linux and report a false green. To smoke a Windows
# or macOS workflow locally, run it on a real host/runner, or scope your `act`
# invocation to the Linux jobs with `--job <linux-job-id>`.

# Cache directory (bind-mounted into act containers)
--cache-server-path ~/.cache/act

Expand All @@ -38,9 +45,10 @@
--secret-file .secrets

# Artifact server — captures upload-artifact outputs locally.
# On Windows, override to a writable path with --artifact-server-path
# (e.g. %TEMP%\act-artifacts).
--artifact-server-path /tmp/act-artifacts
# Use a repo-relative path so this resolves on Windows, macOS, and Linux hosts
# alike (the previous hardcoded /tmp/act-artifacts did not exist on Windows
# hosts). The directory is git-ignored.
--artifact-server-path ./.act-artifacts

# Bind ~/.cargo into containers so cargo registry downloads are cached across runs.
# Remove this line if your Docker daemon is on a remote host (bind-mounts won't work).
Expand Down
16 changes: 16 additions & 0 deletions .github/workflows/release-binaries.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,26 @@ jobs:
echo "$sum $(basename "$f")" >> checksums.txt
done

# Supply-chain SBOM (SPDX) over the published artifacts. continue-on-error so
# a tooling hiccup can NEVER block a release; the SBOM is attached only if
# generated. NOTE: unverified in local dev — validate on the first tag run.
- name: Generate SBOM (SPDX)
id: sbom
continue-on-error: true
uses: anchore/sbom-action@v0
with:
path: release-artifacts
format: spdx-json
output-file: release-artifacts/sbom.spdx.json
upload-artifact: false
upload-release-assets: false

- name: Create release with assets
uses: softprops/action-gh-release@v3
with:
files: |
release-artifacts/release-*/*
release-artifacts/checksums.txt
release-artifacts/sbom.spdx.json
generate_release_notes: true
fail_on_unmatched_files: false
71 changes: 71 additions & 0 deletions .github/workflows/version-tag-guard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Asserts that the workspace version in Cargo.toml matches the pushed git tag.
#
# Why: releases are driven by pushing a `v*` tag (release-binaries.yml,
# release-gui.yml, release-installers.yml all trigger on `tags: "v*"` and stamp
# the binary version from `github.ref_name`). The Cargo.toml
# `[workspace.package] version` is bumped by hand, so it can drift from the tag —
# e.g. tagging `v0.7.0` while Cargo.toml still says `0.6.0`. That ships a binary
# whose embedded `CARGO_PKG_VERSION` lies about its own release, which in turn
# breaks `vox upgrade`'s semver comparison and the GitHub update-notification
# check. This guard fails fast (before any artifact is built) on mismatch.
#
# This is a lightweight, hosted-only check so it never depends on the
# self-hosted fleet. Make it a required check on tag events to enforce.
name: version-tag-guard

on:
push:
tags:
- "v*"

permissions:
contents: read

concurrency:
group: version-tag-guard-${{ github.ref }}
cancel-in-progress: true

jobs:
assert-version-matches-tag:
runs-on: ubuntu-latest

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use the required self-hosted label set for this Basic Linux workflow.

This job currently uses ubuntu-latest; repository policy requires runs-on: [self-hosted, linux, x64] for Basic Linux workflows unless it is one of the documented exceptions.

As per coding guidelines, “Use runs-on: [self-hosted, linux, x64] for Basic Linux GitHub Actions workflows.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/version-tag-guard.yml at line 30, Replace the runner
selection for this workflow: change the runs-on value currently set to
"ubuntu-latest" to the required self-hosted matrix form runs-on: [self-hosted,
linux, x64] so the job uses the repository's Basic Linux self-hosted runner;
update the runs-on entry in the workflow (the runs-on key) accordingly.

Source: Coding guidelines

steps:
- uses: actions/checkout@v4

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate and print relevant sections for the referenced workflows
files=(
  ".github/workflows/version-tag-guard.yml"
  ".github/workflows/release-binaries.yml"
)

for f in "${files[@]}"; do
  if [ ! -f "$f" ]; then
    echo "MISSING FILE: $f" >&2
    continue
  fi
  echo "==== $f ===="
  # Print around likely mentioned lines; also include any uses: lines
  nl -ba "$f" | sed -n '1,220p' | sed -n '1p; /uses:/p;'
  echo "---- context around line 32 (best effort) ----"
  nl -ba "$f" | sed -n '20,50p'
  echo "---- context around line 135 (best effort) ----"
  nl -ba "$f" | sed -n '120,160p'
done

# Global search for unpinned uses: within these two workflows
echo "==== ACTION USES (all) in version-tag-guard.yml ===="
rg -n "^\s*-\s*uses:\s*[^#\s]+" .github/workflows/version-tag-guard.yml || true

echo "==== ACTION USES (all) in release-binaries.yml ===="
rg -n "^\s*-\s*uses:\s*[^#\s]+" .github/workflows/release-binaries.yml || true

# Check for checkout persistence setting
echo "==== checkout credential persistence settings ===="
rg -n "persist-credentials|persist_credentials" .github/workflows/version-tag-guard.yml .github/workflows/release-binaries.yml || true

Repository: vox-foundation/vox

Length of output: 174


🏁 Script executed:

#!/bin/bash
set -euo pipefail

files=(
  ".github/workflows/version-tag-guard.yml"
  ".github/workflows/release-binaries.yml"
)

awk_print_range() {
  local f="$1" start="$2" end="$3"
  awk -v s="$start" -v e="$end" '{if(NR>=s && NR<=e) printf "%5d %s\n", NR, $0}' "$f"
}

for f in "${files[@]}"; do
  echo "==== $f (exists? $(test -f "$f" && echo yes || echo no)) ===="
  if [ ! -f "$f" ]; then
    continue
  fi
  echo "---- context around line 32 ----"
  awk_print_range "$f" 20 50
  echo "---- context around line 135 ----"
  awk_print_range "$f" 120 160
  echo "---- all uses: lines in file ----"
  rg -n "^[[:space:]]*-[[:space:]]uses:" "$f" || true
  echo "---- uses: lines with version-like refs (not SHAs or v tags) ----"
  rg -n "^[[:space:]]*-[[:space:]]uses:[[:space:]]*[^#[:space:]]+" "$f" || true
  echo "---- checkout credential persistence settings (if any) ----"
  rg -n "persist-credentials|persist_credentials" "$f" || true
  echo
done

Repository: vox-foundation/vox

Length of output: 4767


🌐 Web query:

GitHub actions/checkout persist-credentials default value and security recommendation to set it to false

💡 Result:

The persist-credentials input for the GitHub actions/checkout action has a default value of true [1][2][3]. When set to true, the action configures the local git environment with the provided authentication token (commonly the GITHUB_TOKEN), which allows subsequent git commands (such as fetch, pull, or push) to run authenticated without additional configuration [1][3][4]. Security Recommendation It is widely recommended to set persist-credentials to false unless your workflow explicitly requires authenticated git operations (e.g., pushing commits back to the repository) [5]. Setting it to false is a security best practice for the following reasons: 1. Risk of Credential Exposure: By default, the authentication token is stored in the local git configuration of the checked-out repository [1][5][6]. If the workflow subsequently archives the repository directory as an artifact or if a malicious or compromised third-party action runs in the same environment, the token may be exposed or misused [5][6][7]. 2. Principle of Least Privilege: Disabling this option limits the window of opportunity for token misuse by ensuring that sensitive credentials are not unnecessarily persisted in the runner's file system [5]. To implement this security hardening, update your workflow step as follows: - uses: actions/checkout@v4 with: persist-credentials: false If you later determine that you need to perform authenticated git actions, you can manually authenticate using the token within the specific step, or re-enable the persistence only for the workflows that strictly require it [5].

Citations:


Pin third-party GitHub Actions to immutable SHAs + harden checkout credentials.

  • .github/workflows/version-tag-guard.yml uses actions/checkout@v4 (line 32): pin to a full commit SHA and set with: persist-credentials: false unless authenticated git operations are required.
  • .github/workflows/release-binaries.yml uses actions/checkout@v6 (line 32) and anchore/sbom-action@v0 (line 135): pin both to full commit SHAs.
🧰 Tools
🪛 zizmor (1.25.2)

[warning] 32-32: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[error] 32-32: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/version-tag-guard.yml at line 32, Pin the third‑party
GitHub Actions to immutable SHAs and harden checkout credentials: replace the
floating uses: actions/checkout@v4 entry with a pinned full commit SHA (uses:
actions/checkout@<full-sha>) and add a with: persist-credentials: false block to
the checkout step (unless the workflow actually needs authenticated git
operations), and likewise pin anchore/sbom-action (uses:
anchore/sbom-action@<full-sha>) in release-binaries.yml; ensure you update the
uses strings to full commit SHAs and add persist-credentials: false to the
checkout steps to prevent credential leakage.

Source: Linters/SAST tools


- name: Compare Cargo.toml workspace version to git tag
shell: bash
run: |
set -euo pipefail

tag="${GITHUB_REF_NAME}" # e.g. v0.7.0
tag_version="${tag#v}" # strip leading v -> 0.7.0

# Extract the FIRST `version = "..."` under the [workspace.package]
# table only, so we don't accidentally read a dependency's version.
cargo_version="$(
awk '
/^\[workspace\.package\]/ { in_wp = 1; next }
/^\[/ { in_wp = 0 }
in_wp && /^[[:space:]]*version[[:space:]]*=/ {
# version = "0.6.0" -> 0.6.0
gsub(/.*=[[:space:]]*"/, "")
gsub(/".*/, "")
print
exit
}
' Cargo.toml
)"

echo "git tag : ${tag} (version ${tag_version})"
echo "Cargo.toml ver : ${cargo_version}"

if [ -z "${cargo_version}" ]; then
echo "::error::Could not read [workspace.package] version from Cargo.toml"
exit 1
fi

if [ "${tag_version}" != "${cargo_version}" ]; then
echo "::error::Version mismatch — git tag is '${tag_version}' but Cargo.toml [workspace.package] version is '${cargo_version}'. Bump Cargo.toml (and Cargo.lock) before tagging, or retag to match."
exit 1
fi

echo "OK: Cargo.toml version matches the release tag."
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -234,5 +234,8 @@ _bundle_ai_fixture_*
# Vox GUI dev run logs
gui-*.log

# Local `act` artifact server output (see .actrc --artifact-server-path)
.act-artifacts/

# Superpowers brainstorm visual-companion scratch (local-only)
.superpowers/
15 changes: 15 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ edition = "2024"
license = "Apache-2.0"
authors = ["Bert Brainerd"]
repository = "https://github.com/vox-foundation/vox.git"
rust-version = "1.95"
rust-version = "1.96"
keywords = ["vox", "language", "compilers"]
categories = ["development-tools", "compilers"]

Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Multi-stage build for minimal production image (~50MB)
# Cross-platform lanes, feature matrix, and env toggles: docs/src/architecture/vox-cross-platform-runbook.md

FROM rust:1.95.0-slim-bookworm AS builder
FROM rust:1.96.0-slim-bookworm AS builder
# Install system dependencies (required by openssl-sys and other C-bound crates)
RUN apt-get update && apt-get install -y pkg-config libssl-dev build-essential && rm -rf /var/lib/apt/lists/*
WORKDIR /app
Expand Down
6 changes: 3 additions & 3 deletions Dockerfile.ci-runner
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
# (see .actrc); this image is for the real fleet and full local repro.
#
# Version SSOTs (keep aligned with the rest of the repo):
# - Rust 1.95.0 → root Dockerfile (`rust:1.95.0-slim-bookworm`)
# - Rust 1.96.0 → root Dockerfile (`rust:1.96.0-slim-bookworm`) / rust-toolchain.toml / contracts SSOT
# - Node 24 → docs-quality.yml / docs-deploy.yml `node-version: 24`
# - pnpm 9 → ci.yml / docs-quality.yml `pnpm/action-setup@v6` `version: 9`
# - Ubuntu 24.04 → matches `ubuntu-latest` on GitHub-hosted (2026-Q2)

ARG RUST_VERSION=1.95.0
ARG RUST_VERSION=1.96.0

FROM ubuntu:24.04

Expand Down Expand Up @@ -53,7 +53,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
bash \
&& rm -rf /var/lib/apt/lists/*

# Rust toolchain (pinned to RUST_VERSION arg; defaults to 1.95.0 — matches root Dockerfile)
# Rust toolchain (pinned to RUST_VERSION arg; defaults to 1.96.0 — matches root Dockerfile)
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
sh -s -- -y --default-toolchain "$RUST_VERSION" \
--component rustfmt,clippy,llvm-tools-preview \
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ Vox is marching toward a production-hardened v1.0 release. Surfaces are graded b
| Secrets & Safety | 🔵 Stable | [Clavis](crates/vox-secrets/) hardened vault and [Rule Pack](crates/vox-rule-pack/) CI guards. |
| Telemetry Facade | 🟣 Mature | Unified [vox-telemetry](crates/vox-telemetry/) with trace propagation and cost rollups. |
| **AI/ML Engine** | | |
| Inference (Mens) | 🟡 Preview | Native CUDA/Metal/CPU inference with [Candle/Burn](crates/vox-inference/). |
| Inference (Mens) | 🟡 Preview | Native CUDA/Metal/CPU inference with [Candle/Burn](crates/vox-populi/src/inference/). |
| Training (Populi) | 🟠 Emergent | QLoRA native pipeline; loss-parity verification in progress. |
| Visus (Vision) | 🟠 Emergent | [Voice of Vision](crates/vox-cli/src/commands/visus/) for automated GUI bug detection. |
| **Platform & UI** | | |
Expand Down
16 changes: 16 additions & 0 deletions contracts/capability/capability-registry.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9051,6 +9051,22 @@ curated:
mcp_tool: vox_test_decision
cli_path: null
parameters: null
- id: mcp.vox_tool_search
title: Tool Search
description_human: null
description_model: Search the MCP tool registry by keyword and return matching tools (name, description, input schema) for progressive tool disclosure.
intent_tags: []
side_effect_class: null
scope_kind: null
reversible: null
requires_repo: null
requires_git: null
preferred_for_models: null
human_takeover_friendly: null
mens_planner_visible: null
mcp_tool: vox_tool_search
cli_path: null
parameters: null
- id: mcp.vox_transfer_file
title: Transfer File
description_human: null
Expand Down
8 changes: 8 additions & 0 deletions contracts/capability/model-manifest.generated.json
Original file line number Diff line number Diff line change
Expand Up @@ -5208,6 +5208,14 @@
"mcp_tool": "vox_test_decision",
"title": "Test Decision"
},
{
"capability_id": "mcp.vox_tool_search",
"curated": true,
"description_model": "Search the MCP tool registry by keyword and return matching tools (name, description, input schema) for progressive tool disclosure.",
"implicit": false,
"mcp_tool": "vox_tool_search",
"title": "Tool Search"
},
{
"capability_id": "mcp.vox_transfer_file",
"curated": true,
Expand Down
7 changes: 7 additions & 0 deletions contracts/gui/surface-registry.v1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,13 @@ surfaces:
nav_icon: null
nav_group: null
notes: null
- view_key: null
cli_group: repl
representation_tier: none
nav_label: null
nav_icon: null
nav_group: null
notes: null
- view_key: repository
cli_group: repo
representation_tier: live_backend
Expand Down
1 change: 1 addition & 0 deletions contracts/mcp/http-read-role-governance.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ read_role_tools:
- vox_semantic_fs_discover
- vox_task_status
- vox_test_decision
- vox_tool_search
- vox_workspace_modules
5 changes: 5 additions & 0 deletions contracts/mcp/tool-registry.canonical.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1268,6 +1268,11 @@ tools:
product_lane: ai
http_read_role_eligible: true
tier: core
- name: vox_tool_search
description: Search the MCP tool registry by keyword and return matching tools (name, description, input schema) for progressive tool disclosure.
product_lane: ai
http_read_role_eligible: true
tier: core
- name: vox_transfer_file
description: Transfer ownership of a file to another agent.
product_lane: ai
Expand Down
20 changes: 20 additions & 0 deletions contracts/operations/catalog.v1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11806,6 +11806,26 @@ operations:
http_read_role_eligible: false
tier: core
cli: null
- id: tool.search
title: Tool Search
description: Search the MCP tool registry by keyword and return matching tools (name, description, input schema) for progressive tool disclosure.
description_human: null
product_lane: ai
intent_tags: []
side_effect_class: null
scope_kind: null
reversible: null
requires_repo: null
preferred_for_models: null
human_takeover_friendly: null
mens_planner_visible: null
canonical_name: null
latin_aliases: null
mcp:
name: vox_tool_search
http_read_role_eligible: true
tier: core
cli: null
- id: train
title: Train
description: CLI operation `vox train`
Expand Down
1 change: 1 addition & 0 deletions contracts/reports/gui-surface-coverage.v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -1191,6 +1191,7 @@
"test.all",
"test.decision",
"toestub.findings.upsert",
"tool.search",
"train",
"transfer.file",
"trust.override",
Expand Down
2 changes: 1 addition & 1 deletion contracts/reports/gui-surface-registry.v1.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"schema_version": 1,
"surface_count": 87,
"surface_count": 88,
"top_level_groups": [
"add",
"ars",
Expand Down
6 changes: 3 additions & 3 deletions contracts/reports/operations-catalog-inventory.v1.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"catalog_operations": 533,
"catalog_operations": 534,
"paired_operations": 11,
"mcp_only_operations": 255,
"mcp_only_operations": 256,
"cli_only_operations": 267,
"mcp_tool_count": 266,
"mcp_tool_count": 267,
"cli_path_count": 278
}
2 changes: 1 addition & 1 deletion contracts/toolchain/workspace-toolchain.v1.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
schema: vox.workspace.toolchain.v1
versions:
rust: "1.92.0"
rust: "1.96.0"
node: "22.0.0"
pnpm: "9.1.0"
cuda: "12.1"
Expand Down
16 changes: 13 additions & 3 deletions crates/vox-cli-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,22 @@ description = "Shared internals for the vox CLI binary (argv parsing helpers, ex
version.workspace = true
edition.workspace = true

[features]
# `db` (default-on) pulls the persistence-coupled crates and enables the
# benchmark-telemetry, gamify-shim, and workflow-journal modules. It is on by
# default so every existing consumer (vox-cli, vox-gui, vox-ml-cli) is unchanged.
# A `--no-default-features` build drops vox-db/vox-gamify/vox-repository entirely,
# giving the DB-free slice that the minimal `vox-langtool` binary reuses
# (see docs/plans/INSTALL-RELEASE-AUDIT.md, Phase 4.1).
default = ["db"]
db = ["dep:vox-db", "dep:vox-gamify", "dep:vox-repository"]

[dependencies]
vox-config = { workspace = true }
vox-db = { workspace = true }
vox-gamify = { workspace = true }
vox-db = { workspace = true, optional = true }
vox-gamify = { workspace = true, optional = true }
vox-foundation = { workspace = true }
vox-repository = { workspace = true }
vox-repository = { workspace = true, optional = true }
vox-secrets = { workspace = true }
anyhow = { workspace = true }
clap = { workspace = true, features = ["derive", "env"] }
Expand Down
7 changes: 7 additions & 0 deletions crates/vox-cli-core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
//! Shared library for CLI primitives.

pub mod artifact_policy;
// `benchmark_telemetry`, `gamify_shim`, and `workflow_journal_codex` depend on
// vox-db / vox-gamify / vox-repository, which are pulled only by the default-on
// `db` feature. A `--no-default-features` build (the DB-free slice reused by the
// minimal `vox-langtool` binary) drops them. See Cargo.toml [features].
#[cfg(feature = "db")]
pub mod benchmark_telemetry;
pub mod build_service;
pub mod cli_actions;
Expand All @@ -10,8 +15,10 @@ pub mod daemon_ipc;
pub mod db_types;
pub mod diagnostics;
pub mod fs_utils;
#[cfg(feature = "db")]
pub mod gamify_shim;
pub mod scientia;
#[cfg(feature = "db")]
pub mod workflow_journal_codex;
Comment on lines +21 to 26

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

scientia still escapes the new db feature gate.

vox-cli-core is now advertised as buildable with --no-default-features, but pub mod scientia; remains unconditional between two DB-gated exports. If scientia.rs still carries the DB/repository wiring described in the PR objective, the DB-free slice will fail to compile. Gate scientia here as well, or split any non-DB pieces into a separate always-on module. Based on PR objectives, scientia was intended to be part of the DB-gated surface.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/vox-cli-core/src/lib.rs` around lines 18 - 22, The module declaration
for scientia is currently unconditional and must be feature-gated to match the
DB-gated surface; change the unguarded "pub mod scientia;" to a DB-gated
declaration (e.g. #[cfg(feature = "db")] pub mod scientia;) or alternatively
move any non-DB code out of scientia into a separate always-on module and keep
DB-only wiring in a #[cfg(feature = "db")] scientia module so building with
--no-default-features succeeds; look for the existing module symbols "scientia",
"gamify_shim", and "workflow_journal_codex" to align gating consistently.


/// Global flags available before every subcommand.
Expand Down
Loading
Loading