Compare commits

...

1 Commits

Author SHA1 Message Date
6ad96c37cd feat(framework): P1+P2 — public sanitization + blocking CI gate
All checks were successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
Adds tools/quality/scripts/verify-sanitized.sh (two-class, self-tested) wired
blocking in .woodpecker/ci.yml; sanitizes operator identity from the public
framework package so the gate is green.

- purge jarvis/jason/woltje/PDA across 26 files -> generic
- delete jarvis-loop.json overlay; add neutral examples/{personas,overlays}
- relocate maintainer AUDIT to docs/audits/; delete 2 jarvis-brain rule blocks
- neutralize SOUL persona; strip "(Policy: Jason ...)" keeping universal rule
- test fixtures jason.woltje -> ci-bot (both git tests pass)

Deferred (tracked): private third-party host (uscllc) genericization.

Refs #542, closes #571

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 20:57:08 -05:00
31 changed files with 207 additions and 101 deletions

View File

@@ -18,6 +18,14 @@ steps:
- apk add --no-cache python3 make g++ - apk add --no-cache python3 make g++
- pnpm install --frozen-lockfile - pnpm install --frozen-lockfile
# Blocking gate: public framework package must contain no operator-specific
# personal data or private $HOME defaults. Runs early (no node_modules needed).
sanitization:
image: *node_image
commands:
- apk add --no-cache bash
- bash packages/mosaic/framework/tools/quality/scripts/verify-sanitized.sh
typecheck: typecheck:
image: *node_image image: *node_image
commands: commands:

View File

@@ -34,7 +34,7 @@ At session start, additionally:
10. Manual `docker build` / `docker push` for deployment is FORBIDDEN when CI/CD pipelines exist in the repository. CI is the ONLY canonical build path for container images. 10. Manual `docker build` / `docker push` for deployment is FORBIDDEN when CI/CD pipelines exist in the repository. CI is the ONLY canonical build path for container images.
11. Before ANY build or deployment action, you MUST check for existing CI/CD pipeline configuration (`.woodpecker/`, `.woodpecker.yml`, `.github/workflows/`, etc.). If pipelines exist, use them — do not build locally. 11. Before ANY build or deployment action, you MUST check for existing CI/CD pipeline configuration (`.woodpecker/`, `.woodpecker.yml`, `.github/workflows/`, etc.). If pipelines exist, use them — do not build locally.
12. The mandatory intake procedure is NOT conditional on perceived task complexity. A "simple" commit-push-deploy task has the same procedural requirements as a multi-file feature. Skipping intake because a task "seems simple" is the most common framework violation. 12. The mandatory intake procedure is NOT conditional on perceived task complexity. A "simple" commit-push-deploy task has the same procedural requirements as a multi-file feature. Skipping intake because a task "seems simple" is the most common framework violation.
13. **Merge authority (coordinated work):** when a coordinator/orchestrator session is active for the work, the post-review MERGE GO-AHEAD is the coordinator's to give — once code has passed the required review gates, request the coordinator's go-ahead and merge on their confirmation; do NOT wait on the human owner personally. Solo (uncoordinated) delivery keeps the default: merge without routine confirmation per gates 2 and 9. A "No self-merge" note on a PR means no UNREVIEWED self-merge — it does not suspend coordinator-authorized merges. (Policy: Jason, 2026-06-11.) 13. **Merge authority (coordinated work):** when a coordinator/orchestrator session is active for the work, the post-review MERGE GO-AHEAD is the coordinator's to give — once code has passed the required review gates, request the coordinator's go-ahead and merge on their confirmation; do NOT wait on the human owner personally. Solo (uncoordinated) delivery keeps the default: merge without routine confirmation per gates 2 and 9. A "No self-merge" note on a PR means no UNREVIEWED self-merge — it does not suspend coordinator-authorized merges.
## Non-Negotiable Operating Rules (condensed — full detail in `guides/E2E-DELIVERY.md`) ## Non-Negotiable Operating Rules (condensed — full detail in `guides/E2E-DELIVERY.md`)

View File

@@ -69,7 +69,7 @@ It also detects installed runtimes (Claude, Codex, OpenCode, Pi), configures seq
For CI or scripted installs: For CI or scripted installs:
```bash ```bash
mosaic init --non-interactive --name Jarvis --style direct --user-name Jason --timezone America/Chicago mosaic init --non-interactive --name "Mosaic Agent" --style direct --user-name "Your Name" --timezone "UTC"
``` ```
All flags: `--name`, `--role`, `--style`, `--user-name`, `--pronouns`, `--timezone`, `--mosaic-home`, `--source-dir`. All flags: `--name`, `--role`, `--style`, `--user-name`, `--pronouns`, `--timezone`, `--mosaic-home`, `--source-dir`.

View File

@@ -5,14 +5,14 @@ It is loaded globally and applies to all sessions regardless of runtime or proje
## Identity ## Identity
You are **Jarvis** in this session. You are the **Mosaic agent** in this session.
- Runtime (Claude, Codex, OpenCode, etc.) is implementation detail. - Runtime (Claude, Codex, OpenCode, etc.) is implementation detail.
- Role identity: execution partner and visibility engine - Role identity: execution partner and visibility engine
If asked "who are you?", answer: If asked "who are you?", answer:
`I am Jarvis, running on <runtime>.` `I am the Mosaic agent, running on <runtime>.`
## Behavioral Principles ## Behavioral Principles
@@ -20,7 +20,7 @@ If asked "who are you?", answer:
2. Practical execution over abstract planning. 2. Practical execution over abstract planning.
3. Truthfulness over confidence: state uncertainty explicitly. 3. Truthfulness over confidence: state uncertainty explicitly.
4. Visible state over hidden assumptions. 4. Visible state over hidden assumptions.
5. PDA-friendly language, communication style, and iconography. Avoid overwhelming info and communication style.. 5. Accessibility-aware: honor the operator's communication and formatting preferences declared in `USER.md`.
## Communication Style ## Communication Style

View File

@@ -66,12 +66,6 @@ starts, commits, PRs, test results, or file edits. At session start, `search` +
prior context. MCP (`mcp__openbrain__capture/search/recent/stats`) preferred when connected; else prior context. MCP (`mcp__openbrain__capture/search/recent/stats`) preferred when connected; else
REST/`tools/openbrain_client.py`. Full protocol: `guides/MEMORY.md`. REST/`tools/openbrain_client.py`. Full protocol: `guides/MEMORY.md`.
**MANDATORY jarvis-brain rule:** when working in `~/src/jarvis-brain`, NEVER capture project data,
meeting notes, status, timelines, or task completions to OpenBrain — the flat files
(`data/projects/*.json`, `data/tasks/*.json`) are the SSOT (use `tools/brain.py` + direct JSON
edits). OpenBrain there is for agent meta-observations ONLY (tooling gotchas, framework learnings,
cross-project patterns). Violating this creates duplicate, divergent data.
## Git Providers ## Git Providers
| Host | Instance | CI | | Host | Instance | CI |

View File

@@ -0,0 +1,29 @@
{
"_comment": "EXAMPLE Claude runtime overlay managed by Mosaic. Copy/adapt and merge into ~/.claude/settings.json as needed. Replace the placeholder project paths and skills with your own. Never auto-loaded.",
"model": "opus",
"additionalAllowedCommands": [
"alembic",
"alembic upgrade",
"alembic downgrade",
"uvicorn",
"ruff",
"ruff check",
"ruff format",
"black",
"isort"
],
"projectConfigs": {
"app": {
"path": "~/src/your-app",
"model": "opus",
"skills": ["prd"],
"guides": ["E2E-DELIVERY", "QA-TESTING"]
},
"review": {
"path": "~/src/your-app",
"model": "opus",
"skills": ["code-review"],
"guides": ["CODE-REVIEW"]
}
}
}

View File

@@ -0,0 +1,46 @@
# Example persona — "Execution Partner"
A worked example of an agent persona (the `SOUL.md` layer). Copy it to
`~/.config/mosaic/SOUL.md` and adapt, or generate one with `mosaic init`. This is
an **example only** — it is never auto-loaded. Keep operator-specific
accommodations (accessibility needs, comms preferences) in your own `USER.md`,
not here.
---
## Identity
You are the **Execution Partner** in this session.
- Runtime (Claude, Codex, OpenCode, etc.) is an implementation detail.
- Role identity: execution partner and visibility engine.
If asked "who are you?", answer: `I am the Execution Partner, running on <runtime>.`
## Behavioral Principles
1. Clarity over performance theater.
2. Practical execution over abstract planning.
3. Truthfulness over confidence: state uncertainty explicitly.
4. Visible state over hidden assumptions.
5. Accessibility-aware: honor the operator's communication and formatting
preferences declared in `USER.md`.
## Communication Style
- Be direct, concise, and concrete.
- Avoid fluff, hype, and anthropomorphic roleplay.
- Do not simulate certainty when facts are missing.
- Prefer actionable next steps and explicit tradeoffs.
## Operating Stance
- Proactively surface what is hot, stale, blocked, or risky.
- Preserve canonical data integrity.
- Respect generated-vs-source boundaries.
- Treat multi-agent collisions as a first-class risk; sync before/after edits.
## Why this exists
Agents should be governed by durable principles, not brittle scripted outputs.
The model should reason within constraints, not mimic a fixed response table.

View File

@@ -397,11 +397,11 @@ fi
### Orchestrator Templates ### Orchestrator Templates
| Template | Path | Purpose | | Template | Path | Purpose |
| -------------------------------------- | ------------------------------------------------- | ----------------------- | | -------------------------------------- | ------------------------------------------ | ----------------------- |
| `tasks.md.template` | `~/src/jarvis-brain/docs/templates/orchestrator/` | Task tracking | | `tasks.md.template` | `~/.config/mosaic/templates/orchestrator/` | Task tracking |
| `orchestrator-learnings.json.template` | `~/src/jarvis-brain/docs/templates/orchestrator/` | Variance tracking | | `orchestrator-learnings.json.template` | `~/.config/mosaic/templates/orchestrator/` | Variance tracking |
| `phase-issue-body.md.template` | `~/src/jarvis-brain/docs/templates/orchestrator/` | Git provider issue body | | `phase-issue-body.md.template` | `~/.config/mosaic/templates/orchestrator/` | Git provider issue body |
| `scratchpad.md.template` | `~/src/jarvis-brain/docs/templates/` | Per-task working doc | | `scratchpad.md.template` | `~/.config/mosaic/templates/` | Per-task working doc |
### Variables Reference ### Variables Reference

View File

@@ -124,4 +124,4 @@ Where:
## Where to Find Project-Specific Data ## Where to Find Project-Specific Data
- **Project learnings:** `<project>/docs/tasks/orchestrator-learnings.json` - **Project learnings:** `<project>/docs/tasks/orchestrator-learnings.json`
- **Cross-project metrics:** `jarvis-brain/data/orchestrator-metrics.json` - **Cross-project metrics:** `~/.config/mosaic/orchestrator/metrics.json`

View File

@@ -1,7 +1,7 @@
# Orchestrator Protocol — Mission Lifecycle Guide # Orchestrator Protocol — Mission Lifecycle Guide
> **Operational guide for agent sessions.** Distilled from the full specification at > **Operational guide for agent sessions.** Distilled from the full specification at
> `jarvis-brain/docs/protocols/ORCHESTRATOR-PROTOCOL.md` (1,066 lines). > the canonical orchestrator protocol maintained with the framework.
> >
> Load this guide when: active mission detected, multi-milestone orchestration, mission continuation. > Load this guide when: active mission detected, multi-milestone orchestration, mission continuation.
> Load `ORCHESTRATOR.md` for per-session execution protocol (planning, coding, review, commit cycle). > Load `ORCHESTRATOR.md` for per-session execution protocol (planning, coding, review, commit cycle).
@@ -194,7 +194,7 @@ This is the confirmed, most common failure. Every session will eventually trigge
## 8. r0 Manual Coordinator Process ## 8. r0 Manual Coordinator Process
In r0, the Coordinator is Jason + shell scripts. No daemon. No automation. In r0, the Coordinator is a human operator + shell scripts. No daemon. No automation.
### Commands ### Commands

View File

@@ -96,7 +96,7 @@ In Matrix rail mode, keep `docs/TASKS.md` as canonical project tracking and use
## Bootstrap Templates ## Bootstrap Templates
Use templates from `jarvis-brain/docs/templates/` to scaffold tracking files: Use templates from `~/.config/mosaic/templates/` to scaffold tracking files:
```bash ```bash
# Set environment variables # Set environment variables
@@ -108,7 +108,7 @@ export PHASE_ISSUE="#1"
export PHASE_BRANCH="fix/security" export PHASE_BRANCH="fix/security"
# Copy templates # Copy templates
TEMPLATES=~/src/jarvis-brain/docs/templates TEMPLATES=~/.config/mosaic/templates
# Create PRD if missing (before coding begins) # Create PRD if missing (before coding begins)
[[ -f docs/PRD.md || -f docs/PRD.json ]] || cp ~/.config/mosaic/templates/docs/PRD.md.template docs/PRD.md [[ -f docs/PRD.md || -f docs/PRD.json ]] || cp ~/.config/mosaic/templates/docs/PRD.md.template docs/PRD.md
@@ -149,7 +149,7 @@ Branch and merge strategy (HARD RULE):
| `reports/review-report-scaffold.sh` | Creates report directory | | `reports/review-report-scaffold.sh` | Creates report directory |
| `scratchpad.md.template` | Per-task working document | | `scratchpad.md.template` | Per-task working document |
See `jarvis-brain/docs/templates/README.md` for full documentation. See `~/.config/mosaic/templates/README.md` for full documentation.
--- ---

View File

@@ -146,8 +146,6 @@ load_credentials <service-name>
Self-hosted semantic brain backed by pgvector. Primary shared memory layer for all agents across all sessions and harnesses. Stores and retrieves decisions, context, and observations via semantic search. Self-hosted semantic brain backed by pgvector. Primary shared memory layer for all agents across all sessions and harnesses. Stores and retrieves decisions, context, and observations via semantic search.
**MANDATORY jarvis-brain rule:** When working in `~/src/jarvis-brain`, NEVER capture project data, meeting notes, status updates, timeline decisions, or task completions to OpenBrain. The flat files (`data/projects/*.json`, `data/tasks/*.json`) are the SSOT — use `tools/brain.py` and direct JSON edits. OpenBrain is for agent meta-observations ONLY (tooling gotchas, framework learnings, cross-project patterns). Violating this creates duplicate, divergent data.
**Credentials:** `load_credentials openbrain` → exports `OPENBRAIN_URL`, `OPENBRAIN_TOKEN` **Credentials:** `load_credentials openbrain` → exports `OPENBRAIN_URL`, `OPENBRAIN_TOKEN`
Configure in your credentials.json: Configure in your credentials.json:
@@ -179,7 +177,7 @@ curl -s -H "Authorization: Bearer $OPENBRAIN_TOKEN" "$OPENBRAIN_URL/v1/thoughts/
curl -s -H "Authorization: Bearer $OPENBRAIN_TOKEN" "$OPENBRAIN_URL/v1/stats" curl -s -H "Authorization: Bearer $OPENBRAIN_TOKEN" "$OPENBRAIN_URL/v1/stats"
``` ```
**Python client** (if jarvis-brain is available on PYTHONPATH): **Python client** (if the OpenBrain client is on your PYTHONPATH):
```bash ```bash
python tools/openbrain_client.py search "topic" python tools/openbrain_client.py search "topic"
@@ -223,7 +221,7 @@ Headless `.excalidraw` → SVG export via `@excalidraw/excalidraw`. Available as
**Diagram generation** (`list_diagrams`, `generate_diagram`, `generate_and_export`) requires `EXCALIDRAW_GEN_PATH` env var pointing to `excalidraw_gen.py`. Set in environment or shell profile: **Diagram generation** (`list_diagrams`, `generate_diagram`, `generate_and_export`) requires `EXCALIDRAW_GEN_PATH` env var pointing to `excalidraw_gen.py`. Set in environment or shell profile:
```bash ```bash
export EXCALIDRAW_GEN_PATH="$HOME/src/jarvis-brain/tools/excalidraw_export/excalidraw_gen.py" export EXCALIDRAW_GEN_PATH="$HOME/.config/mosaic/tools/excalidraw/excalidraw_gen.py"
``` ```
**Manual registration:** **Manual registration:**

View File

@@ -15,7 +15,7 @@ Profiles are runtime-neutral context packs that can be consumed by any agent run
Current runtime overlay example: Current runtime overlay example:
- `~/.config/mosaic/runtime/claude/settings-overlays/jarvis-loop.json` - `examples/overlays/e2e-loop.json`
## Claude Compatibility ## Claude Compatibility

View File

@@ -1,53 +0,0 @@
{
"_comment": "Claude runtime overlay managed by Mosaic. Merge into ~/.claude/settings.json as needed.",
"model": "opus",
"additionalAllowedCommands": [
"alembic",
"alembic upgrade",
"alembic downgrade",
"alembic revision",
"alembic history",
"uvicorn",
"fastapi",
"ruff",
"ruff check",
"ruff format",
"black",
"isort",
"httpx"
],
"projectConfigs": {
"jarvis": {
"path": "~/src/jarvis",
"model": "opus",
"skills": ["jarvis", "prd"],
"guides": [
"E2E-DELIVERY",
"PRD",
"BACKEND",
"FRONTEND",
"AUTHENTICATION",
"QA-TESTING",
"CODE-REVIEW"
],
"env": {
"PYTHONPATH": "packages/plugins"
}
}
},
"presets": {
"jarvis-loop": {
"description": "Embedded E2E delivery cycle for Jarvis",
"model": "opus",
"skills": ["jarvis", "prd"],
"systemPrompt": "You are an autonomous coding agent. For each logical unit, execute: plan, code, test, review, remediate, review, commit, push, then run a greenfield situational test. Repeat until requirements are complete."
},
"jarvis-review": {
"description": "Code review mode for Jarvis PRs",
"model": "opus",
"skills": ["jarvis"],
"guides": ["CODE-REVIEW"],
"systemPrompt": "Review code changes for quality, security, and adherence to Jarvis patterns."
}
}
}

View File

@@ -35,7 +35,7 @@ Example:
```dotenv ```dotenv
MOSAIC_TMUX_SOCKET=mosaic-factory MOSAIC_TMUX_SOCKET=mosaic-factory
MOSAIC_AGENT_RUNTIME=claude MOSAIC_AGENT_RUNTIME=claude
MOSAIC_AGENT_WORKDIR=/home/jarvis/src/mosaic-stack MOSAIC_AGENT_WORKDIR=$HOME/src/your-project
# Optional escape hatch for PoC/canary agents: # Optional escape hatch for PoC/canary agents:
# MOSAIC_AGENT_COMMAND=mosaic yolo claude # MOSAIC_AGENT_COMMAND=mosaic yolo claude
``` ```

View File

@@ -309,7 +309,7 @@ if [[ -f "$pi_settings" ]]; then
fi fi
# Mosaic-specific skills presence check. # Mosaic-specific skills presence check.
mosaic_skills=(mosaic-board mosaic-forge mosaic-prdy mosaic-macp mosaic-standards mosaic-prd mosaic-jarvis mosaic-setup-cicd) mosaic_skills=(mosaic-board mosaic-forge mosaic-prdy mosaic-macp mosaic-standards mosaic-prd mosaic-setup-cicd)
for skill_name in "${mosaic_skills[@]}"; do for skill_name in "${mosaic_skills[@]}"; do
if [[ -d "$MOSAIC_HOME/skills/$skill_name" ]] || [[ -L "$MOSAIC_HOME/skills/$skill_name" ]]; then if [[ -d "$MOSAIC_HOME/skills/$skill_name" ]] || [[ -L "$MOSAIC_HOME/skills/$skill_name" ]]; then
pass "Mosaic skill present: $skill_name" pass "Mosaic skill present: $skill_name"

View File

@@ -5,8 +5,8 @@ set -euo pipefail
# #
# Usage: # Usage:
# mosaic-init # Interactive mode # mosaic-init # Interactive mode
# mosaic-init --name "Jarvis" --style direct # Flag overrides # mosaic-init --name "Mosaic Agent" --style direct # Flag overrides
# mosaic-init --name "Jarvis" --role "memory steward" --style direct \ # mosaic-init --name "Mosaic Agent" --role "memory steward" --style direct \
# --accessibility "ADHD-friendly chunking" --guardrails "Never auto-commit" # --accessibility "ADHD-friendly chunking" --guardrails "Never auto-commit"
MOSAIC_HOME="${MOSAIC_HOME:-$HOME/.config/mosaic}" MOSAIC_HOME="${MOSAIC_HOME:-$HOME/.config/mosaic}"
@@ -50,7 +50,7 @@ Generate Mosaic identity and configuration files:
Interactive by default. Use flags to skip prompts. Interactive by default. Use flags to skip prompts.
Options: Options:
--name <name> Agent name (e.g., "Jarvis", "Assistant") --name <name> Agent name (e.g., "Mosaic Agent", "Assistant")
--role <description> Role description (e.g., "memory steward, execution partner") --role <description> Role description (e.g., "memory steward, execution partner")
--style <style> Communication style: direct, friendly, or formal --style <style> Communication style: direct, friendly, or formal
--accessibility <prefs> Accessibility preferences (e.g., "ADHD-friendly chunking") --accessibility <prefs> Accessibility preferences (e.g., "ADHD-friendly chunking")

View File

@@ -2,7 +2,7 @@
# #
# Usage: # Usage:
# mosaic-init.ps1 # Interactive mode # mosaic-init.ps1 # Interactive mode
# mosaic-init.ps1 -Name "Jarvis" -Style direct # Flag overrides # mosaic-init.ps1 -Name "Mosaic Agent" -Style direct # Flag overrides
$ErrorActionPreference = "Stop" $ErrorActionPreference = "Stop"
param( param(

View File

@@ -62,7 +62,6 @@ legacy_paths=(
"$HOME/.claude/presets/domains" "$HOME/.claude/presets/domains"
"$HOME/.claude/presets/tech-stacks" "$HOME/.claude/presets/tech-stacks"
"$HOME/.claude/presets/workflows" "$HOME/.claude/presets/workflows"
"$HOME/.claude/presets/jarvis-loop.json"
) )
for p in "${legacy_paths[@]}"; do for p in "${legacy_paths[@]}"; do

View File

@@ -70,7 +70,6 @@ $legacyPaths = @(
(Join-Path $env:USERPROFILE ".claude\presets\domains"), (Join-Path $env:USERPROFILE ".claude\presets\domains"),
(Join-Path $env:USERPROFILE ".claude\presets\tech-stacks"), (Join-Path $env:USERPROFILE ".claude\presets\tech-stacks"),
(Join-Path $env:USERPROFILE ".claude\presets\workflows"), (Join-Path $env:USERPROFILE ".claude\presets\workflows"),
(Join-Path $env:USERPROFILE ".claude\presets\jarvis-loop.json")
) )
foreach ($p in $legacyPaths) { foreach ($p in $legacyPaths) {

View File

@@ -8,7 +8,7 @@ usage() {
cat <<USAGE cat <<USAGE
Usage: $(basename "$0") [--apply] Usage: $(basename "$0") [--apply]
Migrate runtime-local skill directories (e.g. ~/.claude/skills/jarvis) to Mosaic-managed Migrate runtime-local skill directories (e.g. ~/.claude/skills/<name>) to Mosaic-managed
skills by replacing local directories with symlinks to ~/.config/mosaic/skills-local. skills by replacing local directories with symlinks to ~/.config/mosaic/skills-local.
Default mode is dry-run. Default mode is dry-run.

View File

@@ -16,7 +16,7 @@ if ($Help) {
Write-Host @" Write-Host @"
Usage: mosaic-migrate-local-skills.ps1 [-Apply] [-Help] Usage: mosaic-migrate-local-skills.ps1 [-Apply] [-Help]
Migrate runtime-local skill directories (e.g. ~/.claude/skills/jarvis) to Migrate runtime-local skill directories (e.g. ~/.claude/skills/<name>) to
Mosaic-managed skills by replacing local directories with junctions to Mosaic-managed skills by replacing local directories with junctions to
~/.config/mosaic/skills-local. ~/.config/mosaic/skills-local.

View File

@@ -5,7 +5,7 @@ Manage Authentik identity provider (SSO, users, groups, applications, flows) via
## Prerequisites ## Prerequisites
- `jq` installed - `jq` installed
- Authentik credentials in `~/src/jarvis-brain/credentials.json` (or `$MOSAIC_CREDENTIALS_FILE`) - Authentik credentials in `~/.config/mosaic/credentials.json` (or `$MOSAIC_CREDENTIALS_FILE`)
- Required fields: `authentik.url`, `authentik.username`, `authentik.password` - Required fields: `authentik.url`, `authentik.username`, `authentik.password`
## Authentication ## Authentication
@@ -47,7 +47,7 @@ All scripts support:
~/.config/mosaic/tools/authentik/user-list.sh ~/.config/mosaic/tools/authentik/user-list.sh
# Search for a user # Search for a user
~/.config/mosaic/tools/authentik/user-list.sh -s "jason" ~/.config/mosaic/tools/authentik/user-list.sh -s "alice"
# Create a user in the admins group # Create a user in the admins group
~/.config/mosaic/tools/authentik/user-create.sh -u newuser -n "New User" -e new@example.com -g admins ~/.config/mosaic/tools/authentik/user-create.sh -u newuser -n "New User" -e new@example.com -g admins

View File

@@ -4,7 +4,7 @@
# Usage: # Usage:
# agent-lint.sh # Scan all projects in ~/src/ # agent-lint.sh # Scan all projects in ~/src/
# agent-lint.sh --project <path> # Scan single project # agent-lint.sh --project <path> # Scan single project
# agent-lint.sh --json # Output JSON for jarvis-brain # agent-lint.sh --json # Output JSON for machine consumption
# agent-lint.sh --verbose # Show per-check details # agent-lint.sh --verbose # Show per-check details
# agent-lint.sh --fix-hint # Show fix commands for failures # agent-lint.sh --fix-hint # Show fix commands for failures
# #

View File

@@ -5,7 +5,7 @@ Manage Coolify container deployment platform (projects, services, deployments, e
## Prerequisites ## Prerequisites
- `jq` and `curl` installed - `jq` and `curl` installed
- Coolify credentials in `~/src/jarvis-brain/credentials.json` (or `$MOSAIC_CREDENTIALS_FILE`) - Coolify credentials in `~/.config/mosaic/credentials.json` (or `$MOSAIC_CREDENTIALS_FILE`)
- Required fields: `coolify.url`, `coolify.app_token` - Required fields: `coolify.url`, `coolify.app_token`
## Scripts ## Scripts

View File

@@ -39,7 +39,7 @@ if [[ "$*" == "login list --output json" ]]; then
cat <<'JSON' cat <<'JSON'
[ [
{"name":"evil-usc","url":"https://evilgit.uscllc.com","user":"bad.actor"}, {"name":"evil-usc","url":"https://evilgit.uscllc.com","user":"bad.actor"},
{"name":"usc","url":"https://git.uscllc.com","user":"jason.woltje"} {"name":"usc","url":"https://git.uscllc.com","user":"ci-bot"}
] ]
JSON JSON
exit 0 exit 0
@@ -263,8 +263,8 @@ set -euo pipefail
if [[ "$*" == "login list --output json" ]]; then if [[ "$*" == "login list --output json" ]]; then
cat <<'JSON' cat <<'JSON'
[ [
{"name":"mosaicstack","url":"https://git.mosaicstack.dev","user":"jason.woltje"}, {"name":"mosaicstack","url":"https://git.mosaicstack.dev","user":"ci-bot"},
{"name":"usc","url":"https://git.uscllc.com","user":"jason.woltje"} {"name":"usc","url":"https://git.uscllc.com","user":"ci-bot"}
] ]
JSON JSON
exit 0 exit 0

View File

@@ -49,7 +49,7 @@ set -euo pipefail
if [[ "$*" == "login list --output json" ]]; then if [[ "$*" == "login list --output json" ]]; then
cat <<'JSON' cat <<'JSON'
[ [
{"name":"mosaicstack","url":"https://git.mosaicstack.dev","user":"jason.woltje"} {"name":"mosaicstack","url":"https://git.mosaicstack.dev","user":"ci-bot"}
] ]
JSON JSON
exit 0 exit 0

View File

@@ -5,7 +5,7 @@ Manage GLPI IT service management (tickets, computers/assets, users).
## Prerequisites ## Prerequisites
- `jq` and `curl` installed - `jq` and `curl` installed
- GLPI credentials in `~/src/jarvis-brain/credentials.json` (or `$MOSAIC_CREDENTIALS_FILE`) - GLPI credentials in `~/.config/mosaic/credentials.json` (or `$MOSAIC_CREDENTIALS_FILE`)
- Required fields: `glpi.url`, `glpi.app_token`, `glpi.user_token` - Required fields: `glpi.url`, `glpi.app_token`, `glpi.user_token`
## Authentication ## Authentication

View File

@@ -0,0 +1,86 @@
#!/usr/bin/env bash
# verify-sanitized.sh — blocking CI gate: the public framework package must
# contain no operator-specific personal data or private executable defaults.
#
# Two rule classes:
# 1. STRUCTURAL — operator-independent invariants (private $HOME defaults in *.sh).
# 2. DENYLIST — a LABELED, one-time regression guard for the CURRENT operator's
# identity tokens. This is NOT a general PII detector (a future
# operator's name can't be enumerated); the durable control is the
# L0 prose firewall + human review. This gate just stops *this*
# contamination from coming back.
#
# Scope: all of the framework package — *.md, *.sh, *.ps1, and the CLI scripts under
# tools/_scripts/ (which are extensionless). Excluded: examples/ (holds
# sanitized, placeholdered worked examples), node_modules/, and this gate file.
#
# NOTE on scope: private THIRD-PARTY host references (e.g. a maintainer's employer
# Gitea) are intentionally NOT in this denylist — they are functionally entangled in
# host-routing + test fixtures and are tracked as a separate follow-up.
#
# Self-tests run first: plant known tokens and assert the scan catches them, so a
# broken regex cannot silently no-op the gate.
#
# Usage: verify-sanitized.sh [FRAMEWORK_ROOT]
set -uo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
FRAMEWORK_ROOT="${1:-$(cd "$SCRIPT_DIR/../../.." && pwd)}"
SELF_REL="tools/quality/scripts/verify-sanitized.sh"
# Labeled current-contaminant denylist. Anchored so substrings like "comparison" or
# "jsonwebtoken" do not match. (jarvis-brain is caught by 'jarvis'.)
DENYLIST='jarvis|jason|woltje|brain\.woltje\.com|/home/jwoltje|\bPDA\b'
# Structural: a private $HOME path used as a shell default (e.g. ${VAR:-$HOME/src/...}).
STRUCTURAL_SH=':[-=]\$\{?HOME\}?/src/'
# Build the in-scope file list once (NUL-delimited).
_scope_files() {
find "$FRAMEWORK_ROOT" -type f \
\( -name '*.md' -o -name '*.sh' -o -name '*.ps1' -o -path '*/tools/_scripts/*' \) \
-not -path '*/examples/*' \
-not -path '*/node_modules/*' \
-not -path "*/$SELF_REL" \
-print0
}
fail=0
cd "$FRAMEWORK_ROOT" || { echo "FRAMEWORK_ROOT not found: $FRAMEWORK_ROOT" >&2; exit 3; }
deny_hits="$(_scope_files | xargs -0 -r grep -nIEi "$DENYLIST" 2>/dev/null || true)"
if [[ -n "$deny_hits" ]]; then
echo "✗ [denylist] operator-identity tokens in shipped files:"
echo "$deny_hits" | sed "s#$FRAMEWORK_ROOT/##; s/^/ /"
fail=1
fi
struct_hits="$(_scope_files | xargs -0 -r grep -nIE "$STRUCTURAL_SH" 2>/dev/null \
| grep -E '\.sh:|/tools/_scripts/' || true)"
if [[ -n "$struct_hits" ]]; then
echo "✗ [structural] private \$HOME/src default in a shipped script:"
echo "$struct_hits" | sed "s#$FRAMEWORK_ROOT/##; s/^/ /"
fail=1
fi
# ---- self-test: the gate must catch planted tokens ----
_selftest() {
local tmp; tmp="$(mktemp -d)" || return 1
printf 'contact jason.woltje at jarvis-brain (PDA note)\n' > "$tmp/planted.md"
printf 'X="${VAR:-$HOME/src/whatever/x.json}"\n' > "$tmp/planted.sh"
local ok=0
grep -qIEi "$DENYLIST" "$tmp/planted.md" || { echo "✗ SELF-TEST: denylist regex broken" >&2; ok=1; }
grep -qIE "$STRUCTURAL_SH" "$tmp/planted.sh" || { echo "✗ SELF-TEST: structural regex broken" >&2; ok=1; }
rm -rf "$tmp"
return $ok
}
_selftest || exit 2
if [[ "$fail" -ne 0 ]]; then
echo
echo "Sanitization gate FAILED. Public framework files must not contain operator identity" >&2
echo "or private \$HOME defaults. Move personal content to init-generated files or examples/." >&2
exit 1
fi
echo "✓ sanitization gate passed (framework *.md/*.sh/*.ps1/_scripts; examples/ excluded)"

View File

@@ -5,7 +5,7 @@ Interact with Woodpecker CI pipelines (list builds, check status, trigger builds
## Prerequisites ## Prerequisites
- `jq` and `curl` installed - `jq` and `curl` installed
- Woodpecker credentials in `~/src/jarvis-brain/credentials.json` - Woodpecker credentials in `~/.config/mosaic/credentials.json`
## Setup ## Setup