Skip to content

ci: bootstrap release workflow - #9

Merged
KooshaPari merged 1 commit into
mainfrom
ci/add-release-workflow
Apr 24, 2026
Merged

ci: bootstrap release workflow#9
KooshaPari merged 1 commit into
mainfrom
ci/add-release-workflow

Conversation

@KooshaPari

@KooshaPari KooshaPari commented Apr 24, 2026

Copy link
Copy Markdown
Owner

User description

Adds .github/workflows/release.yml for tag-triggered or manual publish via CARGO_REGISTRY_TOKEN. Follow-up to #247.

Note

Medium Risk
Introduces automated publishing to crates.io on v* tags or manual dispatch, which can affect release integrity if misconfigured (e.g., --no-verify or selecting unintended crates). Scope is limited to CI configuration.

Overview
Adds a new GitHub Actions Release workflow (.github/workflows/release.yml) that publishes to crates.io when pushing v* tags, or via workflow_dispatch with an optional crate input.

The job checks out code, installs the stable Rust toolchain, and runs cargo publish --no-verify either for a specified crate or by iterating over publishable packages from cargo metadata (skipping failures such as already-published or path-dep crates).

Reviewed by Cursor Bugbot for commit 42601ae. Bugbot is set up for automated code reviews on this repo. Configure here.


CodeAnt-AI Description

Add a release workflow for publishing crates to crates.io

What Changed

  • Adds a release workflow that runs on version tags or can be started manually
  • Lets maintainers publish one chosen crate or publish all publishable crates in the repo
  • Uses the release environment token for crates.io publishing and skips crates that are already published or not eligible

Impact

✅ Faster crate releases
✅ Manual single-crate publishing
✅ Fewer failed release runs

🔄 Retrigger CodeAnt AI Review

Details

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

@KooshaPari
KooshaPari merged commit 14252ad into main Apr 24, 2026
@gemini-code-assist

Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@codeant-ai

codeant-ai Bot commented Apr 24, 2026

Copy link
Copy Markdown

CodeAnt AI is reviewing your PR.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@coderabbitai

coderabbitai Bot commented Apr 24, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@KooshaPari has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 43 minutes and 57 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 43 minutes and 57 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0e7058ee-73e7-4418-aeca-cae925e2c549

📥 Commits

Reviewing files that changed from the base of the PR and between e1cfe53 and 42601ae.

📒 Files selected for processing (1)
  • .github/workflows/release.yml
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/add-release-workflow
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch ci/add-release-workflow

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codeant-ai codeant-ai Bot added the size:M This PR changes 30-99 lines, ignoring generated files label Apr 24, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Script injection via unsanitized workflow dispatch input
    • Replaced direct shell interpolation of workflow input with environment variable intermediary to prevent script injection attacks.

Create PR

Or push these changes by commenting:

@cursor push 7cfe916542
Preview (7cfe916542)
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -21,9 +21,10 @@
       - name: Publish to crates.io
         env:
           CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
+          CRATE_INPUT: ${{ inputs.crate }}
         run: |
-          if [ -n "${{ inputs.crate }}" ]; then
-            cargo publish -p "${{ inputs.crate }}" --no-verify
+          if [ -n "$CRATE_INPUT" ]; then
+            cargo publish -p "$CRATE_INPUT" --no-verify
           else
             for name in $(cargo metadata --format-version=1 --no-deps | jq -r '.packages[] | select(.publish != []) | .name'); do
               echo "Publishing $name"

You can send follow-ups to the cloud agent here.

Reviewed by Cursor Bugbot for commit 42601ae. Configure here.

CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: |
if [ -n "${{ inputs.crate }}" ]; then
cargo publish -p "${{ inputs.crate }}" --no-verify

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Script injection via unsanitized workflow dispatch input

High Severity

The ${{ inputs.crate }} expression is interpolated directly into the run: shell script, creating a script injection vulnerability. A user with write access could supply a crafted crate name (e.g., containing "; malicious-command; echo ") that breaks out of the string context and executes arbitrary commands — with access to CARGO_REGISTRY_TOKEN in the environment. The safe pattern is to pass the input through an intermediate environment variable (e.g., CRATE_INPUT: ${{ inputs.crate }}) and reference "$CRATE_INPUT" in the shell script instead.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 42601ae. Configure here.

Comment on lines +28 to +30
for name in $(cargo metadata --format-version=1 --no-deps | jq -r '.packages[] | select(.publish != []) | .name'); do
echo "Publishing $name"
cargo publish -p "$name" --no-verify || echo " skip $name (likely path-dep or already published)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟠 Architect Review — HIGH

When publishing all crates, the workflow wraps cargo publish in || echo ..., which causes every publish failure (including auth, network, or packaging errors) to be treated as success, so the Release job can complete green even if some or all crates fail to publish.

Suggestion: Remove the blanket || echo so cargo publish failures fail the step, and if desired, explicitly detect and ignore only the "already uploaded" case by inspecting the error output or exit code before deciding to continue.

Fix in Cursor | Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is an **Architect / Logical Review** comment left during a code review. These reviews are first-class, important findings — not optional suggestions. Do NOT dismiss this as a 'big architectural change' just because the title says architect review; most of these can be resolved with a small, localized fix once the intent is understood.

**Path:** .github/workflows/release.yml
**Line:** 28:30
**Comment:**
	*HIGH: When publishing all crates, the workflow wraps `cargo publish` in `|| echo ...`, which causes every publish failure (including auth, network, or packaging errors) to be treated as success, so the Release job can complete green even if some or all crates fail to publish.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
If a suggested approach is provided above, use it as the authoritative instruction. If no explicit code suggestion is given, you MUST still draft and apply your own minimal, localized fix — do not punt back with 'no suggestion provided, review manually'. Keep the change as small as possible: add a guard clause, gate on a loading state, reorder an await, wrap in a conditional, etc. Do not refactor surrounding code or expand scope beyond the finding.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix

@codeant-ai

codeant-ai Bot commented Apr 24, 2026

Copy link
Copy Markdown

CodeAnt AI finished reviewing your PR.

@KooshaPari
KooshaPari deleted the ci/add-release-workflow branch April 26, 2026 18:42
@codeant-ai

codeant-ai Bot commented May 3, 2026

Copy link
Copy Markdown

CodeAnt AI is running the review.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@codeant-ai codeant-ai Bot added size:M This PR changes 30-99 lines, ignoring generated files and removed size:M This PR changes 30-99 lines, ignoring generated files labels May 3, 2026
@codeant-ai

codeant-ai Bot commented May 3, 2026

Copy link
Copy Markdown

Sequence Diagram

This PR adds a GitHub Actions Release workflow that publishes Rust crates to crates.io when version tags are pushed or the workflow is manually dispatched, optionally targeting a single crate or iterating all publishable crates.

sequenceDiagram
    participant Developer
    participant GitHubActions
    participant CratesRegistry

    Developer->>GitHubActions: Push v tag or manual dispatch
    GitHubActions->>GitHubActions: Checkout code and set up Rust toolchain

    alt crate specified
        GitHubActions->>CratesRegistry: Publish specified crate with token
    else no crate specified
        loop each publishable crate
            GitHubActions->>CratesRegistry: Publish crate with token and skip on non fatal error
        end
    end
Loading

Generated by CodeAnt AI

else
for name in $(cargo metadata --format-version=1 --no-deps | jq -r '.packages[] | select(.publish != []) | .name'); do
echo "Publishing $name"
cargo publish -p "$name" --no-verify || echo " skip $name (likely path-dep or already published)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟠 Architect Review — HIGH

In the "publish all" branch, cargo publish failures are always treated as skippable (via || echo), so crates.io errors such as an invalid registry token, outages, or rate limiting are silently ignored and the workflow can complete successfully even if every publish failed.

Suggestion: Remove the blanket || echo or restrict it to clearly non-fatal conditions (for example, "already uploaded"), and otherwise propagate a non-zero exit code so the job fails on real publish errors, optionally tracking and summarizing which crates were successfully published or skipped.

Fix in Cursor | Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is an **Architect / Logical Review** comment left during a code review. These reviews are first-class, important findings — not optional suggestions. Do NOT dismiss this as a 'big architectural change' just because the title says architect review; most of these can be resolved with a small, localized fix once the intent is understood.

**Path:** .github/workflows/release.yml
**Line:** 30:30
**Comment:**
	*HIGH: In the "publish all" branch, cargo publish failures are always treated as skippable (via `|| echo`), so crates.io errors such as an invalid registry token, outages, or rate limiting are silently ignored and the workflow can complete successfully even if every publish failed.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
If a suggested approach is provided above, use it as the authoritative instruction. If no explicit code suggestion is given, you MUST still draft and apply your own minimal, localized fix — do not punt back with 'no suggestion provided, review manually'. Keep the change as small as possible: add a guard clause, gate on a loading state, reorder an await, wrap in a conditional, etc. Do not refactor surrounding code or expand scope beyond the finding.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix

@codeant-ai

codeant-ai Bot commented May 3, 2026

Copy link
Copy Markdown

CodeAnt AI finished running the review.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@codeant-ai

codeant-ai Bot commented May 3, 2026

Copy link
Copy Markdown

CodeAnt AI is running the review.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@codeant-ai codeant-ai Bot added size:M This PR changes 30-99 lines, ignoring generated files and removed size:M This PR changes 30-99 lines, ignoring generated files labels May 3, 2026
@codeant-ai

codeant-ai Bot commented May 3, 2026

Copy link
Copy Markdown

Sequence Diagram

This PR adds a GitHub Actions workflow that, on tagged pushes or manual dispatch, publishes either a specific crate or all publishable crates to crates.io using the configured registry token.

sequenceDiagram
    participant Developer
    participant GitHubActions as GitHub Actions
    participant ReleaseWorkflow as Release workflow
    participant CratesRegistry as Crates registry

    Developer->>GitHubActions: Push v tag or trigger release
    GitHubActions->>ReleaseWorkflow: Start publish job
    ReleaseWorkflow->>ReleaseWorkflow: Check if crate input is provided

    alt Specific crate provided
        ReleaseWorkflow->>CratesRegistry: Publish selected crate with registry token
    else No crate input
        ReleaseWorkflow->>CratesRegistry: Iterate publishable crates and publish with registry token
    end
Loading

Generated by CodeAnt AI

Comment on lines +28 to +30
for name in $(cargo metadata --format-version=1 --no-deps | jq -r '.packages[] | select(.publish != []) | .name'); do
echo "Publishing $name"
cargo publish -p "$name" --no-verify || echo " skip $name (likely path-dep or already published)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟠 Architect Review — HIGH

The bulk "publish all" loop treats every cargo publish failure as success via || echo, so auth errors, crates.io outages, or packaging issues can produce a green workflow even when no crates (or only a subset) are actually published.

Suggestion: Track publish outcomes in the loop and let the step fail (non-zero exit) when any crate fails for reasons other than explicitly allowed cases (e.g., already published/path-dep), emitting a final summary and failing the job when the release is incomplete.

Fix in Cursor | Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is an **Architect / Logical Review** comment left during a code review. These reviews are first-class, important findings — not optional suggestions. Do NOT dismiss this as a 'big architectural change' just because the title says architect review; most of these can be resolved with a small, localized fix once the intent is understood.

**Path:** .github/workflows/release.yml
**Line:** 28:30
**Comment:**
	*HIGH: The bulk "publish all" loop treats every `cargo publish` failure as success via `|| echo`, so auth errors, crates.io outages, or packaging issues can produce a green workflow even when no crates (or only a subset) are actually published.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
If a suggested approach is provided above, use it as the authoritative instruction. If no explicit code suggestion is given, you MUST still draft and apply your own minimal, localized fix — do not punt back with 'no suggestion provided, review manually'. Keep the change as small as possible: add a guard clause, gate on a loading state, reorder an await, wrap in a conditional, etc. Do not refactor surrounding code or expand scope beyond the finding.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix

@codeant-ai

codeant-ai Bot commented May 3, 2026

Copy link
Copy Markdown

CodeAnt AI finished running the review.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

KooshaPari added a commit that referenced this pull request May 31, 2026
* Initial policy-contract import

Co-authored-by: Codex <noreply@openai.com>

* Ignore zig build cache artifacts

Co-authored-by: Codex <noreply@openai.com>

* Clarify partial scan failure handling

Co-authored-by: Codex <noreply@openai.com>

* Document apply mode restriction

Co-authored-by: Codex <noreply@openai.com>

* Clarify wrapper smoke usage

Co-authored-by: Codex <noreply@openai.com>

* Allow remediation dispatch to succeed after comment posting

Co-authored-by: Codex <noreply@openai.com>

* docs: mass injection of standardized Phenotype governance and worktree policies

* docs: Turn 7 mass injection of standardized Phenotype governance and worktree policies

* docs: Turn 10 mass synchronization - CI/Release/Docs/Dependencies

* docs: Turn 10/11 mass synchronization - Governance/CI/Release/Docs/Archival

* docs: Turn 12 mass synchronization - Quality/Protection/Security/Automation

* docs: Turn 13 mass synchronization - Release/Dependabot/Security/Contribution

* docs: Turn 14 mass synchronization - Hooks/Containers/Badges/Deployment

* docs: Turn 23 mass synchronization - Structure and Environment Health

* docs: Turn 23 mass synchronization - Structure and Environment Health

* chore: add worktrees/ to gitignore

Standardize working directory ignore patterns.

Co-authored-by: kooshapari

* chore: add worktrees/ to gitignore (#6)

* docs: Turn 23 mass synchronization - Structure and Environment Health

* docs: Turn 23 mass synchronization - Structure and Environment Health

* chore: add worktrees/ to gitignore

Standardize working directory ignore patterns.

Co-authored-by: kooshapari

---------

Co-authored-by: Koosha Paridehpour <koosha@phenotype.ai>

* feat: add forge as a policy guardian alongside droid/codex

- Add forge permissions.yaml support with commandAllowlist/Requestlist/Denylist
- Add --forge-settings CLI argument
- Add _apply_forge_rules() function for YAML policy application
- Update render_platform_payload() to include forge platform
- Update _build_success_entries() to track forge artifacts
- Update resolve.py to output forge.settings.yaml

* feat: add forge as a policy guardian alongside droid/codex (#7)

- Add forge permissions.yaml support with commandAllowlist/Requestlist/Denylist
- Add --forge-settings CLI argument
- Add _apply_forge_rules() function for YAML policy application
- Update render_platform_payload() to include forge platform
- Update _build_success_entries() to track forge artifacts
- Update resolve.py to output forge.settings.yaml

Co-authored-by: Koosha Paridehpour <koosha@phenotype.ai>

* feat: add forge as policy guardian and sync governance structure (#8)

* docs: Turn 23 mass synchronization - Structure and Environment Health

* docs: Turn 23 mass synchronization - Structure and Environment Health

* chore: add worktrees/ to gitignore

Standardize working directory ignore patterns.

Co-authored-by: kooshapari

* feat: add forge as a policy guardian alongside droid/codex

- Add forge permissions.yaml support with commandAllowlist/Requestlist/Denylist
- Add --forge-settings CLI argument
- Add _apply_forge_rules() function for YAML policy application
- Update render_platform_payload() to include forge platform
- Update _build_success_entries() to track forge artifacts
- Update resolve.py to output forge.settings.yaml

---------

Co-authored-by: Koosha Paridehpour <koosha@phenotype.ai>

* chore: replace BMAD/spec-kitty refs with AgilePlus governance in CLAUDE.md

Remove BMAD plugin references, slash command instructions, and spec-kitty/openspec
mentions. Add standardized AgilePlus governance block pointing to agileplus-specs/
directory and spec docs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: add VitePress docsite scaffold

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: add spec documentation (PRD, ADR, FR, PLAN, trackers)

Add standardized specification documents for the project:
- PRD.md: Product requirements with epics and acceptance criteria
- ADR.md: Architecture decision records
- FUNCTIONAL_REQUIREMENTS.md: FR-prefixed SHALL statements
- PLAN.md: Phased work breakdown structure
- docs/reference/FR_TRACKER.md: FR implementation status
- docs/reference/CODE_ENTITY_MAP.md: Code-to-requirements mapping

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Auto: Sync and evaluate feat/forge-guardian-and-governance-sync (#10)

* docs: Turn 23 mass synchronization - Structure and Environment Health

* docs: Turn 23 mass synchronization - Structure and Environment Health

* chore: add worktrees/ to gitignore

Standardize working directory ignore patterns.

Co-authored-by: kooshapari

* feat: add forge as a policy guardian alongside droid/codex

- Add forge permissions.yaml support with commandAllowlist/Requestlist/Denylist
- Add --forge-settings CLI argument
- Add _apply_forge_rules() function for YAML policy application
- Update render_platform_payload() to include forge platform
- Update _build_success_entries() to track forge artifacts
- Update resolve.py to output forge.settings.yaml

---------

Co-authored-by: Koosha Paridehpour <koosha@phenotype.ai>

* Auto: Sync and evaluate chore/add-worktrees-gitignore (#9)

* docs: Turn 23 mass synchronization - Structure and Environment Health

* docs: Turn 23 mass synchronization - Structure and Environment Health

* chore: add worktrees/ to gitignore

Standardize working directory ignore patterns.

Co-authored-by: kooshapari

---------

Co-authored-by: Koosha Paridehpour <koosha@phenotype.ai>

* fix: resolve all 16 baseline test failures and clean lint (#16)

Core fixes to policy_lib.py:
- Add evaluate_with_quality() to ConditionGroup returning (ok, partial_fail, reasons)
  3-tuple; any-mode now signals partial_fail when required fails but optional passes
- Fix all-mode to evaluate every item before deciding (no early exit), collecting
  complete reason list for diagnostic accuracy
- CommandRule.evaluate uses evaluate_with_quality and emits request on partial_fail
  instead of falling through silently to the next rule
- Fix _parse_match error message for non-string/non-dict match values

sync_host_rules.py:
- Map request action to cursor_deny (cursor treats request as deny in shell layer)
- Include unconditional rules in wrapper_rules when include_conditional=True
- _normalize_for_wrapper: generate proper wrapper entry with empty conditions group
  for unconditional rules instead of returning empty dict
- Remove forge from _build_success_entries (not a policy-enforced platform)
- Use .get() with default [] in _count_platform_rules and
  _managed_segment_length_after to avoid KeyError on partial renders
- Fix _had_managed_segment_before forge path: call _load_json(path) instead of
  referencing undefined variable policy

wrappers/policy-wrapper-dispatch.sh:
- emit_fallback: output sys.argv[2] (decision) not sys.argv[3] (reason) as fallback

wrappers/zig/src/main.zig:
- Exit with code 1 on bad usage and invalid bundle JSON (was returning 0)
- Always overwrite best_error when a higher-rank rule wins (was keeping stale error
  from a lower-rank rule that errored)

tests/test_policy_contract.py:
- Fix test_wrapper_allow_and_request_rule_parity: call _run_wrapper_with_command
  with local command variable instead of _run_wrapper (which used self.command)
- Fix test_wrapper_action_precedence_with_omitted_on_mismatch_fields: same fix for
  both sub-test assertions; correct second expectation from request to deny
  (deny rank > request rank when both match unconditionally)
- Remove unused EXIT_CODE_ARG import (ruff F401)

.github/workflows: add job-level permissions block to governance job
lint: add noqa E402 with justification for sys.path-before-import pattern

Co-authored-by: Claude Code <claude@anthropic.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add comprehensive feature comparison matrix (#17)

Co-authored-by: Claude Code <claude@anthropic.com>

* docs(spec): expand PRD, FUNCTIONAL_REQUIREMENTS, and ADR with real content (#19)

Replace sparse stubs with substantive spec docs grounded in the actual
codebase. PRD adds target-user table, full acceptance criteria for all
four epics (scope resolution, conditional rules, host sync, governance
validation), and explicit non-goals. FUNCTIONAL_REQUIREMENTS expands
from 13 to 24 FRs across six categories (FR-RES, FR-COND, FR-HOST,
FR-GOV, FR-SCHEMA) with implementation file references. ADR expands
from 4 to 7 records adding decisions for policy hash design, Python-as-
reference-resolver, and snapshot-based drift detection.

Co-authored-by: Claude Code <claude@anthropic.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(spec): add USER_JOURNEYS.md with 6 real end-to-end flows (#20)

Adds USER_JOURNEYS.md covering the six primary actor journeys:
CI pipeline policy resolution, conditional rule authoring,
harness artifact application, snapshot drift detection,
schema validation, and cross-language wrapper evaluation.
Each journey includes ASCII flow diagrams and FR traceability.

Co-authored-by: Claude Code <claude@anthropic.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: update docs and configs

* chore: sync

* chore: add docs gitignore and update playwright config

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: commit working changes from work-audit session 2026-03-28

* docs: add docs-site scaffold and verification harness (#21)

Co-authored-by: Claude Code <claude@anthropic.com>
Co-authored-by: Codex <codex@phenotype.dev>

* feat: apply phenotype governance standards

- Add CODEOWNERS with @KooshaPari as sponsor
- Add AGENTS.md extending phenotype-governance
- Add issue/PR templates for task discovery
- Add linter configs where applicable
- Add CI workflow for automated quality gates

* feat: add TEST_COVERAGE_MATRIX.md

Added:
- TEST_COVERAGE_MATRIX.md - test coverage tracking

Stabilization complete

* docs: add SPEC.md and PLAN.md

* chore: add AgilePlus scaffolding

* docs: add journeys, stories, and traceability documentation

* chore(infra): add standardized infrastructure files

* feat(policy): standardize error codes to kebab-case across all wrappers

* ci: migrate to reusable workflows from template-commons

- Use reusable-rust-ci.yml, reusable-python-ci.yml, reusable-typescript-ci.yml
- Add security scanning with reusable-security-scan.yml
- Add governance validation with validate-governance.yml

* feat: migrate federation tools from agentops-policy-federation

* ci(legacy-enforcement): add legacy tooling anti-pattern gate (WARN mode)

Adds legacy-tooling-gate.yml monitoring for anti-patterns per CLAUDE.md.

Refs: CLAUDE.md Technology Adoption Philosophy

* feat: complete federation merge - add cli, extensions, policies, schemas, scripts, tests

* chore(ci): pin floating external actions to SHAs in sast.yml (#2)

* chore(ci): pin floating external actions to SHAs in security-deep-scan.yml (#3)

* chore(ci): pin floating external actions to SHAs in security-guard.yml (#4)

* chore(ci): pin floating external actions to SHAs in security.yml (#5)

* chore: add OpenSSF Scorecard workflow (audit #256) (#6)

* chore(deps-dev): bump postcss (#1)

Bumps the npm_and_yarn group with 1 update in the / directory: [postcss](https://github.com/postcss/postcss).


Updates `postcss` from 8.5.8 to 8.5.10
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](postcss/postcss@8.5.8...8.5.10)

---
updated-dependencies:
- dependency-name: postcss
  dependency-version: 8.5.10
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* docs(agents): harmonize AGENTS.md to thin pointer

- Consolidates governance guidance into canonical hierarchy
- Points to ~/.claude/AGENTS.md, /repos/CLAUDE.md, repo CLAUDE.md
- Reduces per-repo guidance duplication
- Maintains ~23-line pointer format for easy scanning

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(tests): unblock wrapper import errors via conftest mocks

Mock opencode, codex, cursor, kilo, forgecode, droid wrapper libraries
and their submodules in conftest.py to prevent ModuleNotFoundError during
test discovery. Tests can now be discovered and executed.

Previously: test collection failed immediately at import.
Now: test discovery succeeds; 3+ tests pass (failures due to mocked impls).

Enables CI/CD test execution.
Traces to: GOVERNANCE — test blockage

* test(pyo3): add end-to-end PolicyStack ↔ policy-engine integration tests

Added tests/test_pyo3_integration.py: comprehensive integration test suite for
PyO3 bindings. Covers:
- RuleEvaluator construction and rule addition (FR-SHARED-007)
- Metadata assignment and tracking (FR-SHARED-005, 003)
- ConditionGroup and context evaluation (FR-SHARED-002)
- MatcherKind and OnMismatchAction enum variants (FR-SHARED-001, 004)
- Decision creation and traced evaluation (FR-SHARED-006)
- Multi-rule evaluation and rule clearing
- Primary integration scenario: ACL rule evaluation against user context

All 12 tests passing. Binding now verified for PolicyStack consumption.

Traces to: W-51 (Phase-1 consolidation complete)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(changelog): enrich unreleased section with concrete features and fixes

Mined commit history (b981c9b..f6b552f) and categorized 10 commits into:
- Added: federation merge, PyO3 integration tests, spec docs, docsite, AgilePlus
- Changed: error code standardization, governance standards, reusable workflows
- Fixed: baseline test suite, PyO3 import errors
- Security: legacy tool enforcement gate

Total: 7 Added, 3 Changed, 2 Fixed, 1 Security entries documented with commit hashes.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* chore(release): v0.1.0 — federation merge + PyO3 integration + governance standards

* docs(readme): add Install section with Python setup instructions

* chore(codeql): pin actions to SHA

Pin GitHub Actions references for the PinnedDependencies wave.

Validation:
- CodeRabbit passed/skipped
- GitGuardian passed
- Socket passed
- SonarCloud passed
- Semgrep passed

Co-authored-by: Codex <noreply@openai.com>

* docs(coc): add Contributor Covenant 2.1 (#8)

* chore: pin Python 3.12 via .python-version (#9)

* chore: refresh GitHub Actions workflow cache

* chore: add least-privilege permissions to workflows (#10)

* chore(ci): add least-privilege permissions to benchmark.yml

* chore(ci): add least-privilege permissions to ci.yml

* chore(ci): add least-privilege permissions to coverage.yml

* chore(ci): add least-privilege permissions to legacy-tooling-gate.yml

* chore(ci): add least-privilege permissions to phenotype-quality-gate.yml

* chore(ci): add least-privilege permissions to quality-gate.yml

* chore(ci): add least-privilege permissions to sast.yml

* chore(ci): add least-privilege permissions to scorecard.yml

* chore(ci): add least-privilege permissions to security-deep-scan.yml

* chore(ci): add least-privilege permissions to security-guard.yml

* chore(ci): add least-privilege permissions to traceability.yml

* chore(docs): trigger Pages workflow rebuild

* chore: add FUNDING.yml (#11)

* fix(ci): repair pages-deploy.yml workflow-file parse error

* fix(pages): point pages-deploy at vitepress outDir (.vitepress-dist not docs/.vitepress/dist)

* fix(ci): repair legacy tooling gate yaml

Restore the malformed action steps so GitHub can parse and run the WARN-mode legacy tooling scan.

Co-authored-by: Codex <noreply@openai.com>

* fix(ci): run policystack checks locally

Replace unreachable reusable workflow references with local docs build, smoke test, and governance validation steps.

Co-authored-by: Codex <noreply@openai.com>

* fix(ci): avoid editable package discovery

Install only pytest for CI smoke tests because the repo flat layout is not packaged for editable installs.

Co-authored-by: Codex <noreply@openai.com>

* chore(deps): regenerate lockfiles for Dependabot advisories (2 alerts) (#12)

* fix(ci): restore workflow yaml syntax (#13)

Repair workflow steps whose pinned action comments swallowed step boundaries, restore valid with/env/if blocks, add a minimal permissions-audit job, and fix the stacked-PR audit argument handling flagged by actionlint.

Validation:
- actionlint -color=false .github/workflows/*.yml
- git diff --check
- uv run --with pytest --with pyyaml --with jsonschema pytest tests/test_resolve_cli_governance.py tests/test_policy_common.py tests/test_smoke_dispatch_host_hook.py -q (fails: pre-existing setuptools flat-layout package discovery)

Co-authored-by: Codex <noreply@openai.com>

* chore(deps): regenerate lockfiles for Dependabot advisories (2 alerts) (#14)

* ci: add CodeQL Rust analysis (security scanning) (#15)

Co-authored-by: Codex <noreply@openai.com>

* docs: add canonical worklog ledger (#16)

docs: add canonical worklog ledger

Add the missing chronological worklog entry point for PolicyStack governance maintenance and record the current workflow syntax baseline.

Validation:
- actionlint .github/workflows/*.yml
- npm run docs:build
- pre-push hook completed successfully

Co-authored-by: Codex <noreply@openai.com>

* chore(deps): pin docs vite toolchain (#17)

chore(deps): pin docs vite toolchain

Resolve PolicyStack docs Dependabot alerts by overriding Vite and esbuild to patched versions while keeping VitePress at the current release.

Validation:
- npm audit --omit=optional
- npm run docs:build
- actionlint .github/workflows/*.yml
- pre-push hook completed successfully

Co-authored-by: Codex <noreply@openai.com>

* chore(pages): add CNAME for policystack.phenotype.space (#18)

* chore: add CITATION.cff (#19)

Co-authored-by: Koosha Pari <koosha@phenotype.space>

* renovate-config (#20)

* Add Python Taskfile tasks (#21)

Co-authored-by: Codex <noreply@openai.com>

* add language-aware taskfile (#22)

Co-authored-by: Codex <noreply@openai.com>

* taskfile (#23)

Add quality and docs build tasks for the existing language-aware Taskfile.\n\nCo-authored-by: Codex <noreply@openai.com>

* Tune PolicyStack Taskfile tasks (#24)

Co-authored-by: Codex <noreply@openai.com>

* Tune PolicyStack Taskfile tasks (#25)

Co-authored-by: Codex <noreply@openai.com>

* polish PolicyStack taskfile common tasks (#26)

Co-authored-by: Codex <noreply@openai.com>

* Refine PolicyStack Taskfile common tasks (#27)

Centralize the scratch temp directory used by Python build and test tasks so the language-aware Taskfile remains easier to maintain.\n\nValidation:\n- task build\n- task test\n- task lint\n\nCo-authored-by: Codex <noreply@openai.com>

* Refine PolicyStack Taskfile build coverage (#28)

Derive Python compile targets from tracked files while keeping the existing scripts exclusion boundary for generated/auxiliary scripts.

Validation:
- task build
- task test
- task lint
- task clean

Co-authored-by: Codex <noreply@openai.com>

* Expose Taskfile language detection (#29)

Add a small language task so the detected primary repo language can be checked directly alongside the common build, test, lint, and clean tasks.

Co-authored-by: Codex <noreply@openai.com>

* Refine PolicyStack Taskfile lint (#30)

Co-authored-by: Codex <noreply@openai.com>

* Refine PolicyStack Taskfile Python tasks (#31)

Keep Python bytecode caches inside the Taskfile temp directory and put the repository root on PYTHONPATH for build, test, and lint tasks.

Co-authored-by: Codex <noreply@openai.com>

* Refine Taskfile clean cache coverage

Include Python type-checker cache directories in the common clean task so Taskfile cleanup covers the repo's current validation tools.

Co-authored-by: Codex <noreply@openai.com>

* Add PolicyStack Taskfile common tasks (#33)

Detected PolicyStack as Python-first and aligned the Taskfile build/test/lint/clean targets with the repository governance validation surface.

Co-authored-by: Codex <noreply@openai.com>

* Harden Taskfile common tasks (#34)

Co-authored-by: Codex <noreply@openai.com>

* Refine Taskfile language detection (#35)

Detect Python from uv.lock and detect Node projects from common lockfiles while continuing to prefer primary repo manifests over secondary docs tooling.

Co-authored-by: Codex <noreply@openai.com>

* Refine Taskfile clean cache coverage (#36)

Co-authored-by: Codex <noreply@openai.com>

* Refine Taskfile clean artifacts (#37)

Co-authored-by: Codex <noreply@openai.com>

* Refine Taskfile clean coverage (#38)

Include nested docs dependencies in the common clean task so Taskfile cleanup covers the repo's secondary docs package.

Co-authored-by: Codex <noreply@openai.com>

* Refine Taskfile clean coverage (#39)

Include nested docs dependencies in the common clean task so Taskfile cleanup covers the repo's secondary docs package.

Co-authored-by: Codex <noreply@openai.com>

* docs: add PR template (#40)

* ci: add trufflehog secrets scanning (#42)

* chore: pin actions to immutable SHA

* ci: expand pytest to full test suite + ruff lint gate

- Replace single-file smoke test run with full `pytest tests/ -q --tb=short`
- Add `ruff check .` and `ruff format --check .` gates
- Consolidate pip install into one step for ruff + pytest

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* chore: pin all GitHub Actions to commit SHAs

Pins all GitHub Actions to immutable commit SHAs.

* ci: add trufflehog secrets scanning

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>

* chore: pin all GitHub Actions to commit SHAs (#41)

* chore: pin actions to immutable SHA

* ci: expand pytest to full test suite + ruff lint gate

- Replace single-file smoke test run with full `pytest tests/ -q --tb=short`
- Add `ruff check .` and `ruff format --check .` gates
- Consolidate pip install into one step for ruff + pytest

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* chore: pin all GitHub Actions to commit SHAs

Pins all GitHub Actions to immutable commit SHAs.

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>

* chore: pin all GitHub Actions to commit SHAs (#41) (#43)

* chore: pin actions to immutable SHA

* ci: expand pytest to full test suite + ruff lint gate

- Replace single-file smoke test run with full `pytest tests/ -q --tb=short`
- Add `ruff check .` and `ruff format --check .` gates
- Consolidate pip install into one step for ruff + pytest



* chore: pin all GitHub Actions to commit SHAs

Pins all GitHub Actions to immutable commit SHAs.

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>

* docs: add journey-traceability + iconography implementation (#44)

Co-authored-by: Phenotype Agent <agent@phenotype.ai>

* fix(PolicyStack): add missing closing parens on lines 60-61

Both stall_count and breach_count calls were missing one ) to close int(_num(...))

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* ci: SHA-pin GitHub Actions (normalize to canonical SHAs)

Pin all action refs to immutable SHAs across workflow files:
- checkout@v4 → @11bd71901bbe5b1630ceea73d27597364c9af683
- checkout@v6 → @de0fac2e4500dabe0009e67214ff5f5447ce83dd
- setup-node@v4/v5, setup-python@v4/v5, setup-go@v5
- upload-artifact@v4/v7, download-artifact@v4
- cache@v3/v4, github-script@v7
- configure-pages@v5/v6, deploy-pages@v4/v5
- upload-pages-artifact@v3/v5, dependency-review-action@v4

Fixes version-tag normalization (add v4/v5 tags where missing).
Fixes double-SHA corruption artifacts from prior patching rounds.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* lint(PolicyStack): autofix F401, COM812, I001, format ruff --fix

705 errors auto-fixed via ruff --fix and ruff format:
- F401: removed unused imports (ASK_MODE_REVIEW, delegate/config_loader fns)
- COM812: trailing commas added throughout
- I001/I002: import blocks sorted/formatted
- RUF022: __all__ sorted
- T201/T204: print statements replaced with logging

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix(PolicyStack): apply --unsafe-fixes (1085 auto-fixes applied)

Resolves all F401 (unused import), T201 (bare print), I001 (sort),
COM812 (trailing comma), RUF022 (__all__ sort) in cli/ and tests/.

Remaining 51 errors: pre-existing style/complexity only.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* chore(security): bootstrap deny.toml (#46)

* chore: remove policystack README stub prior to subtree merge

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Koosha Paridehpour <koosha@phenotype.ai>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Claude Code <claude@anthropic.com>
Co-authored-by: Codex <codex@phenotype.dev>
Co-authored-by: Forge <forge@phenotype.dev>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Koosha Pari <koosha@phenotype.space>
Co-authored-by: Phenotype Agent <agent@phenotype.ai>
@KooshaPari KooshaPari added the pr-created PR has been created and is tracked label Jun 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr-created PR has been created and is tracked size:M This PR changes 30-99 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant