chore(post-v0.40.4): release scripts, gitignore, arrow + punctuation sweep#163
chore(post-v0.40.4): release scripts, gitignore, arrow + punctuation sweep#163vaaraio wants to merge 7 commits into
Conversation
Adds `vaara mode` CLI subcommand with three actions: - `vaara mode list` prints the four built-in preset operating points (eco, balanced, performance, strict) with thresholds and one-line descriptions. - `vaara mode show NAME` prints thresholds, description, and watt profile for a single preset. - `vaara mode emit NAME [--format json|yaml] [--output PATH]` emits a minimal valid Vaara policy document for the chosen preset, ready for the deployer to add action classes, sequences, and escalation routes. The new `vaara.policy.modes` module exposes `Mode`, `available_modes`, `get_mode`, `to_policy_dict`, `emit_json`, and `emit_yaml`. Presets are shaped like CPU power profiles. Emitted documents round-trip through `vaara.policy.from_dict`, `from_json`, and `from_yaml`. Bundles plugin shakedown fix delivery: - `plugins/claude-code-vaara-governance/.claude-plugin/plugin.json` bumped 0.1.0 to 0.1.1, picking up the session_start audit-DB creation fix from PR #161. - `.claude-plugin/marketplace.json` ref bumped v0.40.3 to v0.40.4 so marketplace users receive the plugin update. - `server.json` and `server-vaara-server.json` versioned to 0.40.4. 25 new tests in `tests/test_policy_modes.py` cover the preset registry, round-trip through all three loaders, and CLI dispatch.
scripts/release_tag_after_merge.sh covers the "PR already merged via GH UI" path. release_merge_and_tag.sh assumes the PR is open and starts with gh pr merge, so it cannot finish the tag work once the merge already happened. The new script fetches origin/main, moves v<VERSION> (and an optional co-tag) to the merged SHA, prints the gated push command. scripts/release_publish_npm_manual.sh splits the npm side of the manual fallback out of release_publish_manual.sh. Token-based via VAARA_NPM_TOKEN, no interactive npm login. For the case where the GH Actions npm step flakes but PyPI trusted publishing already shipped. Ships without npm provenance, same constraint as the existing all-in-one manual script. scripts/RELEASE.md gets sections 3b and 4b documenting the two new paths.
…e, claude-code-audit.db
📝 WalkthroughWalkthroughRelease 0.40.4 introduces a preset policy modes system ( ChangesVersion 0.40.4 Release
Sequence DiagramsequenceDiagram
participant User
participant CLI
participant ModeRegistry as vaara.policy.modes
participant PolicyModule as Policy Parser
User->>CLI: vaara mode list/show/emit
CLI->>ModeRegistry: available_modes / get_mode(name)
ModeRegistry-->>CLI: mode data or KeyError
CLI->>CLI: format mode as JSON/YAML
CLI->>PolicyModule: emit_json / emit_yaml
PolicyModule-->>CLI: policy dict serialized
CLI-->>User: stdout or file output
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
⚔️ Resolve merge conflicts
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 |
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 Prompt for all review comments with 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.
Inline comments:
In @.gitignore:
- Around line 27-28: The .gitignore entries "application_*.pdf" and
"outbound_*.md" miss dot-prefixed filenames (e.g., ".application_x.pdf" and
".outbound_x.md"); update the ignore rules to also match dot-prefixed artifacts
by adding corresponding patterns (e.g., ".application_*.pdf" and
".outbound_*.md") or use a single pattern that covers both (e.g.,
"[.]application_*.pdf" and "[.]outbound_*.md") so files generated by internal
tooling are prevented from being committed.
In `@docs/audit_event_schema.md`:
- Around line 66-68: The schema uses the lifecycle name "decision_made" but
audit_cli.py checks for "decision_emitted", causing mismatch; update the code so
the semantic lifecycle check and any references/variables/constants in
src/vaara/audit_cli.py that currently use "decision_emitted" are renamed or
compared to "decision_made" (or vice‑versa if you prefer the code contract);
ensure the lifecycle array/enum, any string comparisons, and tests all
consistently use the same token ("decision_made") to match docs and prevent
false anomalies.
In `@docs/formal_specification.md`:
- Line 210: Fix the malformed sentence describing the cold-start conformal
interval: replace the fragment "Conformal interval is [f(a) − 0.3, f(a) + 0.3]
to wide, conservative" with a grammatically correct, unambiguous phrasing such
as "Conformal interval is [f(a) − 0.3, f(a) + 0.3], which is too wide and
therefore conservative" (or similar wording that conveys "too wide" and
"conservative"); ensure the revised bullet reads clearly in the normative spec.
In `@scripts/release_publish_npm_manual.sh`:
- Around line 45-49: The script writes VAARA_NPM_TOKEN to a predictable file
referenced by NPMRC and doesn't set restrictive permissions; change the logic
that creates NPMRC (the NPMRC variable/printf/trap block) to create a secure
temporary file (e.g., use a safe mktemp-style filename) and ensure the file is
created with restrictive permissions (chmod 600 or use umask 077 before writing)
before writing the token with printf, then keep the existing trap to remove the
temp file; this prevents clobbering symlinked files and ensures the token file
is not world-readable.
In `@scripts/RELEASE.md`:
- Around line 79-81: Update the fenced code blocks that show the commands so
they declare the language by changing the fences from ``` to ```bash for the
snippets containing "scripts/release_tag_after_merge.sh <VERSION> [CO_TAG]" and
"scripts/release_publish_npm_manual.sh <VERSION>" so the blocks read as bash
blocks and satisfy markdownlint MD040.
In `@scripts/train_and_eval_bge_base.py`:
- Around line 6-8: The header pipeline sentence contains a duplicated/extra
token and spacing ("embed to") making it hard to read; edit the pipeline string
(the top-line comment containing "Pipeline: corpus + v031_split ...") to remove
the duplicate "to" and extra space—e.g., change "embed to concat (1004
features) to XGBoost" to "embed to concat (1004 features) to XGBoost" (or
otherwise rephrase the pipeline to a single, tight clause).
In `@src/vaara/policy/modes.py`:
- Around line 122-129: to_policy_dict() currently returns a dict missing the
keys expected by from_dict(): "sequences" and "escalation": {"routes": ...},
causing round-trip failures; update that function to include "sequences" (empty
list) and an "escalation" key with "routes" (empty list or appropriate default)
in the returned dict, preserving SCHEMA_VERSION, "domains", "action_classes",
and the "thresholds" values derived from mode.escalate and mode.deny so the
output matches the shape consumed by from_dict().
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: dc359791-ec39-4265-805a-7b27307a4efe
📒 Files selected for processing (55)
.claude-plugin/marketplace.json.gitignoreCHANGELOG.mdCOMPLIANCE.mdOVERT_CONTROLS.mdREADME.mdVERDICTS.mdbench/build_corpus.pybench/latency.pybench/vaara-bench-v0.34.mdbench/vaara-bench-v0.35.mdbench/vaara-bench-v0.36.mdbench/vaara-bench-v0.37.mdclients/ts/package.jsondocs/audit_event_schema.mddocs/formal_specification.mdexamples/langchain_agent.pyplugins/claude-code-vaara-governance/.claude-plugin/plugin.jsonpyproject.tomlscripts/RELEASE.mdscripts/eval_adversarial.pyscripts/eval_distribution_shift.pyscripts/release_publish_manual.shscripts/release_publish_npm_manual.shscripts/release_tag_after_merge.shscripts/train_and_eval_bge_base.pyserver-vaara-server.jsonserver.jsonsrc/vaara/__init__.pysrc/vaara/attestation/transparency_log.pysrc/vaara/audit/review_queue.pysrc/vaara/audit/sqlite_backend.pysrc/vaara/audit/trail.pysrc/vaara/cli.pysrc/vaara/integrations/crewai.pysrc/vaara/integrations/guardrails_ai.pysrc/vaara/integrations/langchain.pysrc/vaara/integrations/mcp_proxy.pysrc/vaara/integrations/mcp_server.pysrc/vaara/pipeline.pysrc/vaara/policy/modes.pysrc/vaara/policy/registry.pysrc/vaara/sandbox/trace_gen.pysrc/vaara/scorer/adaptive.pysrc/vaara/server/state.pysrc/vaara/taxonomy/actions.pytests/test_audit_cli.pytests/test_eval_adversarial_coverage.pytests/test_integrations.pytests/test_mondrian_conformal.pytests/test_overt_verify_cli.pytests/test_policy_modes.pytests/test_policy_reload_http.pytests/test_prov_export.pytests/test_scorer.py
| application_*.pdf | ||
| outbound_*.md |
There was a problem hiding this comment.
Dot-prefixed private artifacts are not ignored by these patterns.
At Line 27 and Line 28, the new rules ignore application_* / outbound_* but not .application_* / .outbound_*, which are the prefixes used by internal tooling docs. That creates a leakage risk for private files.
Suggested fix
application_*.pdf
outbound_*.md
+.application_*.pdf
+.outbound_*.md📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| application_*.pdf | |
| outbound_*.md | |
| application_*.pdf | |
| outbound_*.md | |
| .application_*.pdf | |
| .outbound_*.md |
🤖 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 @.gitignore around lines 27 - 28, The .gitignore entries "application_*.pdf"
and "outbound_*.md" miss dot-prefixed filenames (e.g., ".application_x.pdf" and
".outbound_x.md"); update the ignore rules to also match dot-prefixed artifacts
by adding corresponding patterns (e.g., ".application_*.pdf" and
".outbound_*.md") or use a single pattern that covers both (e.g.,
"[.]application_*.pdf" and "[.]outbound_*.md") so files generated by internal
tooling are prevented from being committed.
| canonical lifecycle is `action_requested` to `risk_scored` to | ||
| `decision_made` to (`action_executed` | `action_blocked` | | ||
| `escalation_sent` to `escalation_resolved`) to `outcome_recorded`. |
There was a problem hiding this comment.
Align lifecycle event name with audit CLI contract (decision_made vs decision_emitted).
The schema’s canonical lifecycle uses decision_made, but the semantic lifecycle check in src/vaara/audit_cli.py (Line range 290-340 snippet) keys on decision_emitted. This split can cause false lifecycle anomalies depending on which contract integrators follow.
Proposed doc-side alignment (if code remains `decision_emitted`)
-canonical lifecycle is `action_requested` to `risk_scored` to
-`decision_made` to (`action_executed` | `action_blocked` |
+canonical lifecycle is `action_requested` to `risk_scored` to
+`decision_emitted` to (`action_executed` | `action_blocked` |
`escalation_sent` to `escalation_resolved`) to `outcome_recorded`.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| canonical lifecycle is `action_requested` to `risk_scored` to | |
| `decision_made` to (`action_executed` | `action_blocked` | | |
| `escalation_sent` to `escalation_resolved`) to `outcome_recorded`. | |
| canonical lifecycle is `action_requested` to `risk_scored` to | |
| `decision_emitted` to (`action_executed` | `action_blocked` | | |
| `escalation_sent` to `escalation_resolved`) to `outcome_recorded`. |
🤖 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 `@docs/audit_event_schema.md` around lines 66 - 68, The schema uses the
lifecycle name "decision_made" but audit_cli.py checks for "decision_emitted",
causing mismatch; update the code so the semantic lifecycle check and any
references/variables/constants in src/vaara/audit_cli.py that currently use
"decision_emitted" are renamed or compared to "decision_made" (or vice‑versa if
you prefer the code contract); ensure the lifecycle array/enum, any string
comparisons, and tests all consistently use the same token ("decision_made") to
match docs and prevent false anomalies.
| - Conformal interval is [f(a) − 0.3, f(a) + 0.3] → wide, conservative | ||
| - Most actions route through ESCALATE → human review | ||
| - MWU weights are uniform to f(a) ≈ (s₁ + s₂ + s₃ + s₄ + s₅) / 5 | ||
| - Conformal interval is [f(a) − 0.3, f(a) + 0.3] to wide, conservative |
There was a problem hiding this comment.
Fix malformed cold-start interval sentence.
Line 210 reads “to wide, conservative”, which is grammatically broken and ambiguous in a normative spec bullet.
Proposed doc fix
-- Conformal interval is [f(a) − 0.3, f(a) + 0.3] to wide, conservative
+- Conformal interval is [f(a) − 0.3, f(a) + 0.3], a wide and conservative interval📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - Conformal interval is [f(a) − 0.3, f(a) + 0.3] to wide, conservative | |
| - Conformal interval is [f(a) − 0.3, f(a) + 0.3], a wide and conservative interval |
🤖 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 `@docs/formal_specification.md` at line 210, Fix the malformed sentence
describing the cold-start conformal interval: replace the fragment "Conformal
interval is [f(a) − 0.3, f(a) + 0.3] to wide, conservative" with a grammatically
correct, unambiguous phrasing such as "Conformal interval is [f(a) − 0.3, f(a) +
0.3], which is too wide and therefore conservative" (or similar wording that
conveys "too wide" and "conservative"); ensure the revised bullet reads clearly
in the normative spec.
| NPMRC="$PWD/.npmrc.publish" | ||
| trap 'rm -f "$NPMRC"' EXIT | ||
| printf '//registry.npmjs.org/:_authToken=%s\nregistry=https://registry.npmjs.org/\n' \ | ||
| "$VAARA_NPM_TOKEN" > "$NPMRC" | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify current token-file handling and absence of permission hardening
rg -n 'NPMRC=|mktemp|chmod 600|umask' scripts/release_publish_npm_manual.shRepository: vaaraio/vaara
Length of output: 88
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect token handling block
nl -ba scripts/release_publish_npm_manual.sh | sed -n '1,120p'Repository: vaaraio/vaara
Length of output: 100
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Broaden search for any permission hardening patterns
rg -n 'umask|chmod|install -m|\.npmrc\.publish|NPMRC=' scripts/release_publish_npm_manual.shRepository: vaaraio/vaara
Length of output: 88
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Show surrounding context (line numbers via cat -n)
cat -n scripts/release_publish_npm_manual.sh | sed -n '35,80p'Repository: vaaraio/vaara
Length of output: 1192
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Search for any permission hardening / related handling
rg -n 'VAARA_NPM_TOKEN|NPMRC=|\.npmrc\.publish|umask|chmod|install -m|trap .*NPMRC|rm -f "\$NPMRC"' scripts/release_publish_npm_manual.shRepository: vaaraio/vaara
Length of output: 312
Harden npm token handling by writing the credential file with restrictive permissions.
scripts/release_publish_npm_manual.sh writes VAARA_NPM_TOKEN to a predictable path (NPMRC="$PWD/.npmrc.publish" after pushd clients/ts) and never hardens file permissions (chmod 600/umask 077), so the token can end up world-readable depending on the runner’s umask. Also, the predictable path increases the risk of clobbering a pre-existing/symlinked file.
Suggested fix
-NPMRC="$PWD/.npmrc.publish"
+NPMRC="$(mktemp)"
trap 'rm -f "$NPMRC"' EXIT
+chmod 600 "$NPMRC"
printf '//registry.npmjs.org/:_authToken=%s\nregistry=https://registry.npmjs.org/\n' \
"$VAARA_NPM_TOKEN" > "$NPMRC"🤖 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 `@scripts/release_publish_npm_manual.sh` around lines 45 - 49, The script
writes VAARA_NPM_TOKEN to a predictable file referenced by NPMRC and doesn't set
restrictive permissions; change the logic that creates NPMRC (the NPMRC
variable/printf/trap block) to create a secure temporary file (e.g., use a safe
mktemp-style filename) and ensure the file is created with restrictive
permissions (chmod 600 or use umask 077 before writing) before writing the token
with printf, then keep the existing trap to remove the temp file; this prevents
clobbering symlinked files and ensures the token file is not world-readable.
| ``` | ||
| scripts/release_tag_after_merge.sh <VERSION> [CO_TAG] | ||
| ``` |
There was a problem hiding this comment.
Add fenced code block language for new command snippets.
Line 79 and Line 112 use bare triple-backtick fences; add bash to satisfy markdownlint MD040 and keep docs lint-clean.
Suggested fix
-```
+```bash
scripts/release_tag_after_merge.sh <VERSION> [CO_TAG]@@
- +bash
scripts/release_publish_npm_manual.sh
Also applies to: 112-114
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 79-79: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 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 `@scripts/RELEASE.md` around lines 79 - 81, Update the fenced code blocks that
show the commands so they declare the language by changing the fences from ```
to ```bash for the snippets containing "scripts/release_tag_after_merge.sh
<VERSION> [CO_TAG]" and "scripts/release_publish_npm_manual.sh <VERSION>" so the
blocks read as bash blocks and satisfy markdownlint MD040.
| Pipeline: corpus + v031_split to 236 hand-features to bge-base 768d embed to | ||
| concat (1004 features) to XGBoost (ne=400 md=6 lr=0.10, matching v0.32) to | ||
| VAL FPR=5% calibration to TEST recall/FPR with Wilson CIs. |
There was a problem hiding this comment.
Tighten the pipeline sentence to remove duplicated wording.
There’s a small text artifact (embed to / extra spacing) that makes the header harder to read.
✍️ Suggested wording cleanup
-Pipeline: corpus + v031_split to 236 hand-features to bge-base 768d embed to
-concat (1004 features) to XGBoost (ne=400 md=6 lr=0.10, matching v0.32) to
+Pipeline: corpus + v031_split to 236 hand-features to bge-base 768d embed to
+concat (1004 features) to XGBoost (ne=400 md=6 lr=0.10, matching v0.32) to
VAL FPR=5% calibration to TEST recall/FPR with Wilson CIs.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| Pipeline: corpus + v031_split to 236 hand-features to bge-base 768d embed to | |
| concat (1004 features) to XGBoost (ne=400 md=6 lr=0.10, matching v0.32) to | |
| VAL FPR=5% calibration to TEST recall/FPR with Wilson CIs. | |
| Pipeline: corpus + v031_split to 236 hand-features to bge-base 768d embed to | |
| concat (1004 features) to XGBoost (ne=400 md=6 lr=0.10, matching v0.32) to | |
| VAL FPR=5% calibration to TEST recall/FPR with Wilson CIs. |
🤖 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 `@scripts/train_and_eval_bge_base.py` around lines 6 - 8, The header pipeline
sentence contains a duplicated/extra token and spacing ("embed to") making it
hard to read; edit the pipeline string (the top-line comment containing
"Pipeline: corpus + v031_split ...") to remove the duplicate "to" and extra
space—e.g., change "embed to concat (1004 features) to XGBoost" to "embed to
concat (1004 features) to XGBoost" (or otherwise rephrase the pipeline to a
single, tight clause).
| return { | ||
| "version": SCHEMA_VERSION, | ||
| "domains": ["eu_ai_act"], | ||
| "action_classes": {}, | ||
| "thresholds": { | ||
| "default": {"escalate": mode.escalate, "deny": mode.deny}, | ||
| }, | ||
| } |
There was a problem hiding this comment.
to_policy_dict() emits an invalid policy shape for from_dict()
The emitted dict is missing sequences and escalation.routes, which makes mode output fail policy loading/round-trip paths.
💡 Proposed fix
def to_policy_dict(mode: Mode) -> dict:
@@
return {
"version": SCHEMA_VERSION,
"domains": ["eu_ai_act"],
"action_classes": {},
"thresholds": {
"default": {"escalate": mode.escalate, "deny": mode.deny},
},
+ "sequences": {},
+ "escalation": {
+ "routes": [
+ {"default": "on_call", "if": []},
+ ]
+ },
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| return { | |
| "version": SCHEMA_VERSION, | |
| "domains": ["eu_ai_act"], | |
| "action_classes": {}, | |
| "thresholds": { | |
| "default": {"escalate": mode.escalate, "deny": mode.deny}, | |
| }, | |
| } | |
| return { | |
| "version": SCHEMA_VERSION, | |
| "domains": ["eu_ai_act"], | |
| "action_classes": {}, | |
| "thresholds": { | |
| "default": {"escalate": mode.escalate, "deny": mode.deny}, | |
| }, | |
| "sequences": {}, | |
| "escalation": { | |
| "routes": [ | |
| {"default": "on_call", "if": []}, | |
| ] | |
| }, | |
| } |
🤖 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 `@src/vaara/policy/modes.py` around lines 122 - 129, to_policy_dict() currently
returns a dict missing the keys expected by from_dict(): "sequences" and
"escalation": {"routes": ...}, causing round-trip failures; update that function
to include "sequences" (empty list) and an "escalation" key with "routes" (empty
list or appropriate default) in the returned dict, preserving SCHEMA_VERSION,
"domains", "action_classes", and the "thresholds" values derived from
mode.escalate and mode.deny so the output matches the shape consumed by
from_dict().
|
superseded by #164 (clean branch off main) |
Summary by CodeRabbit
New Features
eco,balanced,performance,strict) for simplified threshold management.vaara modeCLI commands:listto view available modes,showto display mode details, andemitto generate policy files in JSON or YAML format.Chores