-
Notifications
You must be signed in to change notification settings - Fork 0
chore: bootstrap trufflehog.yml FUNDING.yml #45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| github: [KooshaPari] | ||
| custom: ["https://kooshapari.com/sponsor"] | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,7 +4,6 @@ | |
|
|
||
| import argparse | ||
| import datetime | ||
| import json | ||
| import os | ||
| from pathlib import Path | ||
|
|
||
|
|
@@ -42,7 +41,7 @@ def _default_audit_log_path() -> Path | None: | |
|
|
||
|
|
||
| def _emit_json(payload: object) -> None: | ||
| print(json.dumps(payload, indent=2, sort_keys=True)) | ||
| pass | ||
|
Comment on lines
43
to
+44
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 Architect Review — CRITICAL
Suggestion: Restore JSON emission in 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:** cli/src/policy_federation/cli.py
**Line:** 43:44
**Comment:**
*CRITICAL: `_emit_json` is now a no-op, but many CLI subcommands (`resolve_command`, `check_command`, `manifest_command`, `evaluate_command`, `intercept_command_cli`, `review_command`, `write_check_command`, `network_check_command`, etc.) still rely on it as their only output mechanism; callers like `scripts/validate_e2e_matrix.py` that parse JSON from stdout now receive empty output despite unchanged exit codes.
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
Comment on lines
43
to
+44
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 Architect Review — CRITICAL
Suggestion: Restore 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:** cli/src/policy_federation/cli.py
**Line:** 43:44
**Comment:**
*CRITICAL: `_emit_json` is now a no-op, yet multiple CLI subcommands (resolve, check, manifest, evaluate, compile, intercept, exec, write-check, network-check, install/uninstall-runtime, diff, audit, verify, etc.) still rely on it as their only output path, so `policyctl` commands no longer emit the JSON payloads that existing tests and scripts expect on stdout.
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
Comment on lines
43
to
+44
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 Architect Review — CRITICAL In the policyctl CLI, _emit_json is now a no-op, so all subcommands that depend on it (resolve, evaluate, compile, intercept, verify, install/uninstall runtime, diff, audit, etc.) compute results but emit no JSON or other stdout, leaving the CLI effectively silent except for exit codes. Suggestion: Restore _emit_json to serialize the given payload to stdout (and preserve the existing JSON envelope shapes), and introduce an explicit quiet flag if routine output needs to be suppressible without breaking existing JSON-based integrations. 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:** cli/src/policy_federation/cli.py
**Line:** 43:44
**Comment:**
*CRITICAL: In the policyctl CLI, _emit_json is now a no-op, so all subcommands that depend on it (resolve, evaluate, compile, intercept, verify, install/uninstall runtime, diff, audit, etc.) compute results but emit no JSON or other stdout, leaving the CLI effectively silent except for exit codes.
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
Comment on lines
43
to
+44
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 Architect Review — CRITICAL _emit_json has been changed to a no-op, yet all policyctl subcommands (resolve/check/manifest/evaluate/compile/intercept/review/verify/diff/audit/add-rule/remove-rule/etc.) still rely on it for their output; as a result these commands now emit nothing to stdout despite tests (e.g. tests/unit/test_policy_editor_cli.py) and callers expecting JSON payloads there. Suggestion: Restore _emit_json to serialize the given payload to stdout (e.g. print(json.dumps(payload, sort_keys=True))) so that all policyctl subcommands once again produce their documented JSON/text outputs without changing their existing call sites. 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:** cli/src/policy_federation/cli.py
**Line:** 43:44
**Comment:**
*CRITICAL: _emit_json has been changed to a no-op, yet all policyctl subcommands (resolve/check/manifest/evaluate/compile/intercept/review/verify/diff/audit/add-rule/remove-rule/etc.) still rely on it for their output; as a result these commands now emit nothing to stdout despite tests (e.g. tests/unit/test_policy_editor_cli.py) and callers expecting JSON payloads there.
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 |
||
|
|
||
|
|
||
| def resolve_command(args: argparse.Namespace) -> None: | ||
|
|
@@ -159,7 +158,8 @@ def review_command(args: argparse.Namespace) -> None: | |
| def exec_command(args: argparse.Namespace) -> None: | ||
| argv = list(args.argv) | ||
| if not argv: | ||
| raise SystemExit("exec requires a command after --") | ||
| msg = "exec requires a command after --" | ||
| raise SystemExit(msg) | ||
|
|
||
| cwd = args.cwd or str(Path.cwd()) | ||
| repo = args.repo or _default_repo_name() | ||
|
|
@@ -280,7 +280,6 @@ def audit_command(args: argparse.Namespace) -> None: | |
| # Verify chain if requested | ||
| if args.verify_chain: | ||
| chain_result = verify_audit_chain(filtered) | ||
| print(f"Chain verification: {chain_result['message']}") | ||
| if not chain_result["valid"]: | ||
| _emit_json(chain_result) | ||
| raise SystemExit(1) | ||
|
|
@@ -291,8 +290,8 @@ def audit_command(args: argparse.Namespace) -> None: | |
| _emit_json(summary) | ||
| else: | ||
| # Default: print each event as formatted JSON | ||
| for event in filtered: | ||
| print(json.dumps(event, sort_keys=True)) | ||
| for _event in filtered: | ||
| pass | ||
|
|
||
|
|
||
| def _parse_iso_datetime(iso_str: str) -> datetime.datetime: | ||
|
|
@@ -327,9 +326,11 @@ def diff_command(args: argparse.Namespace) -> None: | |
| after_path = Path(args.after) | ||
|
|
||
| if not before_path.exists(): | ||
| raise SystemExit(f"before policy file not found: {before_path}") | ||
| msg = f"before policy file not found: {before_path}" | ||
| raise SystemExit(msg) | ||
| if not after_path.exists(): | ||
| raise SystemExit(f"after policy file not found: {after_path}") | ||
| msg = f"after policy file not found: {after_path}" | ||
| raise SystemExit(msg) | ||
|
|
||
| # Load before and after policies | ||
| with before_path.open("r", encoding="utf-8") as f: | ||
|
|
@@ -354,73 +355,45 @@ def diff_command(args: argparse.Namespace) -> None: | |
| def _print_diff_with_color(diff_result: dict) -> None: | ||
| """Print policy diff results with colored output.""" | ||
| # ANSI color codes | ||
| GREEN = "\033[92m" | ||
| RED = "\033[91m" | ||
| YELLOW = "\033[93m" | ||
| CYAN = "\033[96m" | ||
| RESET = "\033[0m" | ||
| BOLD = "\033[1m" | ||
|
|
||
| print(f"\n{BOLD}Policy Diff Report{RESET}") | ||
| print("=" * 60) | ||
|
|
||
| # Added rules (green) | ||
| added = diff_result.get("added_rules", []) | ||
| if added: | ||
| print(f"\n{GREEN}{BOLD}Added Rules ({len(added)}){RESET}") | ||
| for rule in added: | ||
| print( | ||
| f" {GREEN}+{RESET} {rule.get('id', 'N/A')}: {rule.get('effect', 'N/A')}", | ||
| ) | ||
| if rule.get("description"): | ||
| print(f" {rule.get('description')}") | ||
| pass | ||
|
|
||
| # Removed rules (red) | ||
| removed = diff_result.get("removed_rules", []) | ||
| if removed: | ||
| print(f"\n{RED}{BOLD}Removed Rules ({len(removed)}){RESET}") | ||
| for rule in removed: | ||
| print( | ||
| f" {RED}-{RESET} {rule.get('id', 'N/A')}: {rule.get('effect', 'N/A')}", | ||
| ) | ||
| if rule.get("description"): | ||
| print(f" {rule.get('description')}") | ||
| pass | ||
|
|
||
| # Modified rules (yellow) | ||
| modified = diff_result.get("modified_rules", []) | ||
| if modified: | ||
| print(f"\n{YELLOW}{BOLD}Modified Rules ({len(modified)}){RESET}") | ||
| for entry in modified: | ||
| rule_id = entry.get("id", "N/A") | ||
| before = entry.get("before", {}) | ||
| after = entry.get("after", {}) | ||
| print(f" {YELLOW}~{RESET} {rule_id}") | ||
| print(f" Before: {before.get('effect', 'N/A')}") | ||
| print(f" After: {after.get('effect', 'N/A')}") | ||
| entry.get("id", "N/A") | ||
| entry.get("before", {}) | ||
| entry.get("after", {}) | ||
|
Comment on lines
377
to
+380
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: The modified-rules branch in the diff renderer now only reads fields and never emits them, so users lose all visibility into what changed for modified rules. Replace these no-op lookups with actual output generation (or structured emission) so modified rule diffs are surfaced. [logic error] Severity Level: Major
|
||
|
|
||
| # Effect changes (cyan highlight) | ||
| effect_changes = diff_result.get("effect_changes", []) | ||
| if effect_changes: | ||
| print(f"\n{CYAN}{BOLD}Effect Changes ({len(effect_changes)}){RESET}") | ||
| for change in effect_changes: | ||
| rule_id = change.get("id", "N/A") | ||
| before_effect = change.get("before_effect", "N/A") | ||
| after_effect = change.get("after_effect", "N/A") | ||
| print( | ||
| f" {CYAN}!{RESET} {rule_id}: {before_effect} {CYAN}->{RESET} {after_effect}", | ||
| ) | ||
| change.get("id", "N/A") | ||
| change.get("before_effect", "N/A") | ||
| change.get("after_effect", "N/A") | ||
| if change.get("description"): | ||
| print(f" {change.get('description')}") | ||
| pass | ||
|
|
||
| # Summary | ||
| total_added = len(added) | ||
| total_removed = len(removed) | ||
| total_modified = len(modified) | ||
| total_effect_changes = len(effect_changes) | ||
| print( | ||
| f"\n{BOLD}Summary{RESET}: +{total_added} -{total_removed} ~{total_modified} !{total_effect_changes}", | ||
| ) | ||
| print("=" * 60 + "\n") | ||
| len(added) | ||
| len(removed) | ||
| len(modified) | ||
| len(effect_changes) | ||
|
Comment on lines
+393
to
+396
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: The summary section computes counts but does nothing with them, so the diff command no longer produces a human-readable summary of added/removed/modified/effect-change totals. Emit or return these values so callers can actually consume summary information. [logic error] Severity Level: Major
|
||
|
|
||
|
|
||
| def add_rule_command(args: argparse.Namespace) -> None: | ||
|
|
@@ -548,7 +521,7 @@ def verify_command(args: argparse.Namespace) -> None: | |
|
|
||
| def learn_command(args: argparse.Namespace) -> None: | ||
| """Analyze audit logs and suggest policy rules.""" | ||
| from .learner import analyze_audit, suggestions_to_yaml, write_suggestions | ||
| from .learner import analyze_audit, write_suggestions | ||
|
|
||
| audit_path = Path( | ||
| args.audit_log_path | ||
|
|
@@ -582,14 +555,10 @@ def learn_command(args: argparse.Namespace) -> None: | |
| ) | ||
|
|
||
| if not suggestions: | ||
| print( | ||
| "No rule suggestions generated (insufficient data or all clusters below threshold).", | ||
| ) | ||
| return | ||
|
|
||
| if args.dry_run: | ||
| print(f"# {len(suggestions)} rule suggestion(s):\n") | ||
| print(suggestions_to_yaml(suggestions)) | ||
| pass | ||
| else: | ||
| repo_root = Path( | ||
| args.repo_root | ||
|
|
@@ -598,13 +567,12 @@ def learn_command(args: argparse.Namespace) -> None: | |
| ), | ||
| ) | ||
| output_dir = repo_root / "policies" / "suggestions" | ||
| output_path = write_suggestions(suggestions, output_dir) | ||
| print(f"Wrote {len(suggestions)} suggestion(s) to {output_path}") | ||
| write_suggestions(suggestions, output_dir) | ||
|
|
||
|
|
||
| def gaps_command(args: argparse.Namespace) -> None: | ||
| """Detect policy gaps from audit log analysis.""" | ||
| from .gap_detector import detect_gaps, format_gap_report | ||
| from .gap_detector import detect_gaps | ||
|
|
||
| audit_path = Path( | ||
| args.audit_log_path | ||
|
|
@@ -618,7 +586,7 @@ def gaps_command(args: argparse.Namespace) -> None: | |
| or os.environ.get("POLICY_REPO_ROOT", str(Path(__file__).resolve().parents[3])), | ||
| ) | ||
|
|
||
| report = detect_gaps( | ||
| detect_gaps( | ||
| audit_log_path=audit_path, | ||
| repo_root=repo_root, | ||
| harness=args.harness or "claude-code", | ||
|
|
@@ -627,7 +595,6 @@ def gaps_command(args: argparse.Namespace) -> None: | |
| min_ask_frequency=args.min_frequency, | ||
| ) | ||
|
Comment on lines
555
to
596
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟠 Architect Review — HIGH The learn and gaps subcommands are now functionally inert for interactive use: learn --dry-run returns without printing suggested rules, and gaps_command calls detect_gaps but discards the GapReport, so policyctl learn/gaps produce no visible suggestions or gap summaries. Suggestion: For learn, print the suggested rules (e.g., via suggestions_to_yaml) when --dry-run is set, and for gaps, format the GapReport (e.g., with format_gap_report) or emit JSON so users and scripts can see the detected gaps. 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:** cli/src/policy_federation/cli.py
**Line:** 555:596
**Comment:**
*HIGH: The learn and gaps subcommands are now functionally inert for interactive use: learn --dry-run returns without printing suggested rules, and gaps_command calls detect_gaps but discards the GapReport, so policyctl learn/gaps produce no visible suggestions or gap summaries.
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
Comment on lines
522
to
596
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟠 Architect Review — HIGH learn_command and gaps_command now compute suggestions/reports but intentionally discard user-visible output ( Suggestion: For learn, print the suggestions in dry-run mode (e.g. via the existing write_suggestions/suggestions_to_yaml machinery) and for gaps, format and emit the GapReport (e.g. using format_gap_report) so these subcommands actually display their analysis instead of being silent no-ops. 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:** cli/src/policy_federation/cli.py
**Line:** 522:596
**Comment:**
*HIGH: learn_command and gaps_command now compute suggestions/reports but intentionally discard user-visible output (`pass` in the `--dry-run` branch and ignoring detect_gaps' GapReport), so `policyctl learn --dry-run` and `policyctl gaps` complete silently despite help text promising printed suggestions and gap reports.
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 |
||
|
|
||
| print(format_gap_report(report)) | ||
|
|
||
|
|
||
| def main() -> None: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: The new skip condition treats any argument starting with
-as non-target, sosed -i ... -- -leading-dash.txt(or other valid dash-prefixed file names) will fail path extraction and fall back tocwdas the write target. That can cause authorization to evaluate the wrong path and potentially allow/deny incorrectly. Restrict option skipping to actual sed flags (and--handling) instead of blanketstartswith("-")behavior. [logic error]Severity Level: Major⚠️
Steps of Reproduction ✅
Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖