feat(security): add safety profile model and enforcement stubs #450

Merged
CoreRasurae merged 1 commit from feature/post-safety-profile into master 2026-03-02 20:09:47 +00:00
Member

Summary

Add SafetyProfile domain model with configurable safety constraints (allowed skill categories, sandbox/checkpoint requirements, human-approval flag, unsafe-tool gating, cost/retry limits) and integrate it into the Action model via from_config/as_cli_dict support. Persistence is backed by a safety_profile_json column on LifecycleActionModel with Alembic migration c4_001_safety_profile_column and a merge migration for multiple heads.

The resolve_safety_profile() stub raises NotImplementedError in local mode, signalling that real enforcement is deferred to server mode. Resolution follows plan > action > project > global precedence.

Covered by 26 Behave BDD scenarios, 6 Robot Framework smoke tests, 5 ASV benchmark suites (11 timing functions), and docs/reference/safety_profile.md reference documentation.

Issue Reference

Closes #332

Dependencies

This PR blocks issue #332 (safety profile model and enforcement stubs).

## Summary Add `SafetyProfile` domain model with configurable safety constraints (allowed skill categories, sandbox/checkpoint requirements, human-approval flag, unsafe-tool gating, cost/retry limits) and integrate it into the `Action` model via `from_config`/`as_cli_dict` support. Persistence is backed by a `safety_profile_json` column on `LifecycleActionModel` with Alembic migration `c4_001_safety_profile_column` and a merge migration for multiple heads. The `resolve_safety_profile()` stub raises `NotImplementedError` in local mode, signalling that real enforcement is deferred to server mode. Resolution follows plan > action > project > global precedence. Covered by 26 Behave BDD scenarios, 6 Robot Framework smoke tests, 5 ASV benchmark suites (11 timing functions), and `docs/reference/safety_profile.md` reference documentation. ## Issue Reference Closes #332 ## Dependencies This PR blocks issue #332 (safety profile model and enforcement stubs).
CoreRasurae added this to the v3.6.0 milestone 2026-02-25 23:50:06 +00:00
CoreRasurae force-pushed feature/post-safety-profile from ccb96e8261
All checks were successful
CI / lint (pull_request) Successful in 21s
CI / typecheck (pull_request) Successful in 58s
CI / security (pull_request) Successful in 48s
CI / benchmark-publish (pull_request) Has been skipped
CI / build (pull_request) Successful in 25s
CI / quality (pull_request) Successful in 29s
CI / integration_tests (pull_request) Successful in 5m34s
CI / unit_tests (pull_request) Successful in 22m58s
CI / docker (pull_request) Successful in 1m0s
CI / benchmark-regression (pull_request) Successful in 24m0s
CI / coverage (pull_request) Successful in 1h55m34s
to fff9da60ee
Some checks failed
CI / lint (pull_request) Successful in 23s
CI / quality (pull_request) Successful in 31s
CI / benchmark-publish (pull_request) Has been skipped
CI / security (pull_request) Successful in 55s
CI / typecheck (pull_request) Successful in 1m3s
CI / build (pull_request) Successful in 38s
CI / integration_tests (pull_request) Successful in 5m8s
CI / unit_tests (pull_request) Failing after 21m20s
CI / docker (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 26m21s
CI / coverage (pull_request) Successful in 1h33m40s
2026-02-26 19:38:17 +00:00
Compare
brent.edwards requested changes 2026-02-26 20:05:46 +00:00
Dismissed
brent.edwards left a comment

Review Summary

Scope: SafetyProfile domain model + Action integration + persistence JSON field + tests/bench/docs.

CI status isn’t visible via the API on my side. Please confirm required checks per docs/development/ci-cd.md (lint, typecheck, security, quality, unit_tests, integration_tests, coverage, build) pass before merge.

Findings

P1:must-fix — Missing Alembic migration for the new safety_profile_json column. The ORM now reads/writes safety_profile_json, but no migration exists (and docs reference c4_001_safety_profile_column which is missing). This will break persistence once an Action uses safety_profile.

  • Code: src/cleveragents/infrastructure/database/models.py:268, src/cleveragents/infrastructure/database/models.py:368, src/cleveragents/infrastructure/database/models.py:421
  • Docs mention nonexistent migration: docs/reference/safety_profile.md:174

P2:should-fixAction.from_config silently ignores invalid safety_profile types. If a user supplies a non-dict, the field is dropped instead of raising a validation error. Consider raising when safety_profile is present but not a dict/SafetyProfile for strict config validation.

  • Code: src/cleveragents/domain/models/core/action.py:626

P2:should-fixdocs/timeline.md contains a large, unrelated historical rewrite (dates/status regressions). Please split it into a separate PR or revert to keep this change focused on safety profiles.

  • Doc: docs/timeline.md

P3:nit — New docs/reference/safety_profile.md isn’t added to the reference nav list. Add it in docs/gen_ref_pages.py so it appears in the Reference sidebar.

  • Doc: docs/reference/safety_profile.md
  • Nav list: docs/gen_ref_pages.py

Positive Notes

  • SafetyProfile validation coverage and Behave/Robot suites are thorough and follow existing patterns.
  • Action integration (CLI dict + persistence JSON) is straightforward and consistent.
## Review Summary Scope: SafetyProfile domain model + Action integration + persistence JSON field + tests/bench/docs. CI status isn’t visible via the API on my side. Please confirm required checks per `docs/development/ci-cd.md` (lint, typecheck, security, quality, unit_tests, integration_tests, coverage, build) pass before merge. ## Findings **P1:must-fix** — Missing Alembic migration for the new `safety_profile_json` column. The ORM now reads/writes `safety_profile_json`, but no migration exists (and docs reference `c4_001_safety_profile_column` which is missing). This will break persistence once an Action uses `safety_profile`. - Code: `src/cleveragents/infrastructure/database/models.py:268`, `src/cleveragents/infrastructure/database/models.py:368`, `src/cleveragents/infrastructure/database/models.py:421` - Docs mention nonexistent migration: `docs/reference/safety_profile.md:174` **P2:should-fix** — `Action.from_config` silently ignores invalid `safety_profile` types. If a user supplies a non-dict, the field is dropped instead of raising a validation error. Consider raising when `safety_profile` is present but not a dict/SafetyProfile for strict config validation. - Code: `src/cleveragents/domain/models/core/action.py:626` **P2:should-fix** — `docs/timeline.md` contains a large, unrelated historical rewrite (dates/status regressions). Please split it into a separate PR or revert to keep this change focused on safety profiles. - Doc: `docs/timeline.md` **P3:nit** — New `docs/reference/safety_profile.md` isn’t added to the reference nav list. Add it in `docs/gen_ref_pages.py` so it appears in the Reference sidebar. - Doc: `docs/reference/safety_profile.md` - Nav list: `docs/gen_ref_pages.py` ## Positive Notes - SafetyProfile validation coverage and Behave/Robot suites are thorough and follow existing patterns. - Action integration (CLI dict + persistence JSON) is straightforward and consistent.
CoreRasurae force-pushed feature/post-safety-profile from fff9da60ee
Some checks failed
CI / lint (pull_request) Successful in 23s
CI / quality (pull_request) Successful in 31s
CI / benchmark-publish (pull_request) Has been skipped
CI / security (pull_request) Successful in 55s
CI / typecheck (pull_request) Successful in 1m3s
CI / build (pull_request) Successful in 38s
CI / integration_tests (pull_request) Successful in 5m8s
CI / unit_tests (pull_request) Failing after 21m20s
CI / docker (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 26m21s
CI / coverage (pull_request) Successful in 1h33m40s
to 78142df33b
Some checks failed
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 14s
CI / build (pull_request) Successful in 15s
CI / quality (pull_request) Successful in 16s
CI / security (pull_request) Successful in 42s
CI / typecheck (pull_request) Successful in 58s
CI / integration_tests (pull_request) Failing after 1m52s
CI / unit_tests (pull_request) Failing after 10m5s
CI / docker (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 23m8s
CI / coverage (pull_request) Failing after 37m10s
2026-02-27 17:22:10 +00:00
Compare
CoreRasurae force-pushed feature/post-safety-profile from 78142df33b
Some checks failed
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 14s
CI / build (pull_request) Successful in 15s
CI / quality (pull_request) Successful in 16s
CI / security (pull_request) Successful in 42s
CI / typecheck (pull_request) Successful in 58s
CI / integration_tests (pull_request) Failing after 1m52s
CI / unit_tests (pull_request) Failing after 10m5s
CI / docker (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 23m8s
CI / coverage (pull_request) Failing after 37m10s
to 1b6e585b9d
All checks were successful
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 15s
CI / build (pull_request) Successful in 17s
CI / quality (pull_request) Successful in 19s
CI / security (pull_request) Successful in 32s
CI / typecheck (pull_request) Successful in 33s
CI / unit_tests (pull_request) Successful in 1m50s
CI / docker (pull_request) Successful in 38s
CI / integration_tests (pull_request) Successful in 2m56s
CI / coverage (pull_request) Successful in 3m57s
CI / benchmark-regression (pull_request) Successful in 23m7s
2026-03-02 11:21:15 +00:00
Compare
CoreRasurae force-pushed feature/post-safety-profile from 1b6e585b9d
All checks were successful
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 15s
CI / build (pull_request) Successful in 17s
CI / quality (pull_request) Successful in 19s
CI / security (pull_request) Successful in 32s
CI / typecheck (pull_request) Successful in 33s
CI / unit_tests (pull_request) Successful in 1m50s
CI / docker (pull_request) Successful in 38s
CI / integration_tests (pull_request) Successful in 2m56s
CI / coverage (pull_request) Successful in 3m57s
CI / benchmark-regression (pull_request) Successful in 23m7s
to 2677abb4ad
All checks were successful
CI / lint (pull_request) Successful in 24s
CI / quality (pull_request) Successful in 24s
CI / benchmark-publish (pull_request) Has been skipped
CI / typecheck (pull_request) Successful in 40s
CI / build (pull_request) Successful in 22s
CI / security (pull_request) Successful in 48s
CI / unit_tests (pull_request) Successful in 1m58s
CI / docker (pull_request) Successful in 49s
CI / integration_tests (pull_request) Successful in 3m4s
CI / coverage (pull_request) Successful in 3m37s
CI / benchmark-regression (pull_request) Successful in 24m52s
2026-03-02 14:34:53 +00:00
Compare
freemo left a comment

Code Review: PR #450feat(security): add safety profile model and enforcement stubs

Overall Assessment

The SafetyProfile domain model, its Action integration, persistence layer, and test coverage are technically well-implemented. The composition approach (AutomationProfile.safety: SafetyProfile) correctly follows the project owner's guidance from issue #332 comments, and the code quality is solid throughout. However, there are several process-level violations of CONTRIBUTING.md that must be addressed before this PR can be merged.


Critical / High Priority — Process Violations

H1: Empty PR Description (CONTRIBUTING.md §PR Process #1)

The PR body is completely empty. Per CONTRIBUTING.md:

Every PR must include a clear, descriptive body that explains the purpose of the change [...] At a minimum, the description must contain: a summary of the changes, an issue reference using a closing keyword (e.g., Closes #332), and a dependency link.

The guidelines also state: "PRs submitted without a description or without an issue reference will not be reviewed."

Action required: Add a PR description with a summary, Closes #332 closing keyword, and set up the Forgejo dependency (PR blocks #332, issue #332 depends on the PR).


H2: Non-Atomic Commit — Unrelated Deletions (CONTRIBUTING.md §Atomic Commits)

This single commit bundles the safety profile feature with the deletion of unrelated code:

Deleted File Concern
src/cleveragents/acp/clients.py Server client protocol stubs
src/cleveragents/acp/server_config.py Server connection configuration
src/cleveragents/cli/commands/server.py Server CLI commands
src/cleveragents/application/services/subplan_service.py Subplan spawning service
src/cleveragents/domain/models/acms/__init__.py + crp.py CRP domain models
features/consolidated_*.feature (17 files) Consolidated test files
benchmarks/crp_model_bench.py, server_stub_bench.py, subplan_spawn_bench.py Unrelated benchmarks
robot/crp_models.robot, server_stubs.robot, subplan_spawn.robot Unrelated robot tests

Per CONTRIBUTING.md: "One logical change per commit. Each commit must encapsulate a single, focused change." and "Never bundle cosmetic changes with functional changes in the same commit."

The safety profile feature, the removal of server/CRP/subplan code, and the feature file reorganization are three separate logical changes that should be in separate commits, each with their own issue.

Action required: The unrelated deletions (server stubs, CRP models, subplan service) and the feature file reorganization should be extracted into separate commits under their own issues. The PR should contain only the safety profile changes.


H3: Incorrect Labels on PR (CONTRIBUTING.md §PR Process #12)

The PR currently carries: MoSCoW/Must have, Points/8, Priority/Low, State/Verified, Type/Feature.

Per CONTRIBUTING.md:

Every PR must carry exactly one Type/ label [...] No other label scopes (State/, Priority/, MoSCoW/) are applied to Pull Requests; those scopes are reserved for issues only.

Action required: Remove State/Verified, Priority/Low, MoSCoW/Must have, and Points/8 from the PR. Only Type/Feature should remain.


Medium Priority — Process Items

M1: Missing Changelog Update (CONTRIBUTING.md §PR Process #6)

The PR must include an update to the changelog file. Add one new entry per commit in the PR that describes the change from the user's perspective.

No changelog update is present in the diff.

M2: Missing CONTRIBUTORS.md Update (CONTRIBUTING.md §PR Process #8)

Add your name to CONTRIBUTORS.md if it is not already listed.

No CONTRIBUTORS.md update is present in the diff. Please verify if your name is already listed; if not, add it.

M3: Issue #332 Ref Field Not Set

The issue Metadata specifies branch feature/post-safety-profile, but the Forgejo Ref field on issue #332 is empty. Per CONTRIBUTING.md: "The Ref field must be set to the same branch named in the issue body's Metadata section" for development issues in active states.

M4: Needs feedback Label Still on Issue #332

The Needs feedback label appears to be stale — the feedback from the project owner (composition approach, spec updates) has been addressed in the current implementation. This label should be removed if the feedback is resolved.


Low Priority — Code Quality Notes

See inline comments below for specific code observations on:

  • resolve_safety_profile() stub implementation
  • from_yaml() missing explicit encoding
  • _row_to_domain() hardcoded safety field defaults

L1: Commit Body Inaccuracy

The commit message body states "20 BDD scenarios" but features/safety_profile.feature contains approximately 30 scenarios. The numbers should match the actual content.


Positive Observations

  • Model design: SafetyProfile is well-designed with proper Pydantic validation, frozen immutability, cross-field validators, factory methods, and comprehensive type annotations. Stays under 500 lines.
  • Composition: The AutomationProfile.safety: SafetyProfile composition correctly follows the project owner's directive and eliminates dual authority for overlapping safety flags.
  • Test coverage: 30 BDD scenarios covering defaults, parsing, constraint validation, cross-field validation, type guards, immutability, factories, refs, stub behavior, round-trip serialization, and action integration. Robot smoke tests and ASV benchmarks are also included.
  • Documentation: docs/reference/safety_profile.md is thorough — covers schema, defaults, validation, precedence, YAML config, action integration, stub enforcement, and persistence.
  • Commit message: First line matches the issue Metadata exactly, follows Conventional Changelog format, body is descriptive, and footer references issue #332.
  • Migration: Proper Alembic migration with merge migration for multiple heads.

Summary

The safety profile feature itself is well-implemented and demonstrates good engineering practices. The blocking issues are primarily process-related: the empty PR body (H1), the bundled unrelated deletions (H2), and the incorrect labels (H3). Of these, H2 is the most significant as it makes the commit non-atomic and non-revertible in isolation. H1 and H3 are straightforward to fix.

Requesting changes primarily for H1 (empty PR body) and H2 (non-atomic commit). Once these are addressed, this PR should be in good shape for approval.

## Code Review: PR #450 — `feat(security): add safety profile model and enforcement stubs` ### Overall Assessment The **SafetyProfile** domain model, its Action integration, persistence layer, and test coverage are technically well-implemented. The composition approach (`AutomationProfile.safety: SafetyProfile`) correctly follows the project owner's guidance from issue #332 comments, and the code quality is solid throughout. However, there are several process-level violations of `CONTRIBUTING.md` that must be addressed before this PR can be merged. --- ### Critical / High Priority — Process Violations #### H1: Empty PR Description (CONTRIBUTING.md §PR Process #1) The PR body is completely empty. Per CONTRIBUTING.md: > Every PR must include a clear, descriptive body that explains the purpose of the change [...] At a minimum, the description must contain: a **summary** of the changes, an **issue reference** using a closing keyword (e.g., `Closes #332`), and a **dependency link**. The guidelines also state: *"PRs submitted without a description or without an issue reference will not be reviewed."* **Action required**: Add a PR description with a summary, `Closes #332` closing keyword, and set up the Forgejo dependency (PR **blocks** #332, issue #332 **depends on** the PR). --- #### H2: Non-Atomic Commit — Unrelated Deletions (CONTRIBUTING.md §Atomic Commits) This single commit bundles the safety profile feature with the **deletion of unrelated code**: | Deleted File | Concern | |---|---| | `src/cleveragents/acp/clients.py` | Server client protocol stubs | | `src/cleveragents/acp/server_config.py` | Server connection configuration | | `src/cleveragents/cli/commands/server.py` | Server CLI commands | | `src/cleveragents/application/services/subplan_service.py` | Subplan spawning service | | `src/cleveragents/domain/models/acms/__init__.py` + `crp.py` | CRP domain models | | `features/consolidated_*.feature` (17 files) | Consolidated test files | | `benchmarks/crp_model_bench.py`, `server_stub_bench.py`, `subplan_spawn_bench.py` | Unrelated benchmarks | | `robot/crp_models.robot`, `server_stubs.robot`, `subplan_spawn.robot` | Unrelated robot tests | Per CONTRIBUTING.md: *"One logical change per commit. Each commit must encapsulate a single, focused change."* and *"Never bundle cosmetic changes with functional changes in the same commit."* The safety profile feature, the removal of server/CRP/subplan code, and the feature file reorganization are **three separate logical changes** that should be in separate commits, each with their own issue. **Action required**: The unrelated deletions (server stubs, CRP models, subplan service) and the feature file reorganization should be extracted into separate commits under their own issues. The PR should contain only the safety profile changes. --- #### H3: Incorrect Labels on PR (CONTRIBUTING.md §PR Process #12) The PR currently carries: `MoSCoW/Must have`, `Points/8`, `Priority/Low`, `State/Verified`, `Type/Feature`. Per CONTRIBUTING.md: > Every PR must carry exactly one `Type/` label [...] No other label scopes (`State/`, `Priority/`, `MoSCoW/`) are applied to Pull Requests; those scopes are reserved for issues only. **Action required**: Remove `State/Verified`, `Priority/Low`, `MoSCoW/Must have`, and `Points/8` from the PR. Only `Type/Feature` should remain. --- ### Medium Priority — Process Items #### M1: Missing Changelog Update (CONTRIBUTING.md §PR Process #6) > The PR must include an update to the changelog file. Add one new entry per commit in the PR that describes the change from the user's perspective. No changelog update is present in the diff. #### M2: Missing CONTRIBUTORS.md Update (CONTRIBUTING.md §PR Process #8) > Add your name to `CONTRIBUTORS.md` if it is not already listed. No CONTRIBUTORS.md update is present in the diff. Please verify if your name is already listed; if not, add it. #### M3: Issue #332 Ref Field Not Set The issue Metadata specifies branch `feature/post-safety-profile`, but the Forgejo Ref field on issue #332 is empty. Per CONTRIBUTING.md: *"The Ref field must be set to the same branch named in the issue body's Metadata section"* for development issues in active states. #### M4: `Needs feedback` Label Still on Issue #332 The `Needs feedback` label appears to be stale — the feedback from the project owner (composition approach, spec updates) has been addressed in the current implementation. This label should be removed if the feedback is resolved. --- ### Low Priority — Code Quality Notes See inline comments below for specific code observations on: - `resolve_safety_profile()` stub implementation - `from_yaml()` missing explicit encoding - `_row_to_domain()` hardcoded safety field defaults #### L1: Commit Body Inaccuracy The commit message body states *"20 BDD scenarios"* but `features/safety_profile.feature` contains approximately 30 scenarios. The numbers should match the actual content. --- ### Positive Observations - **Model design**: `SafetyProfile` is well-designed with proper Pydantic validation, frozen immutability, cross-field validators, factory methods, and comprehensive type annotations. Stays under 500 lines. - **Composition**: The `AutomationProfile.safety: SafetyProfile` composition correctly follows the project owner's directive and eliminates dual authority for overlapping safety flags. - **Test coverage**: 30 BDD scenarios covering defaults, parsing, constraint validation, cross-field validation, type guards, immutability, factories, refs, stub behavior, round-trip serialization, and action integration. Robot smoke tests and ASV benchmarks are also included. - **Documentation**: `docs/reference/safety_profile.md` is thorough — covers schema, defaults, validation, precedence, YAML config, action integration, stub enforcement, and persistence. - **Commit message**: First line matches the issue Metadata exactly, follows Conventional Changelog format, body is descriptive, and footer references issue #332. - **Migration**: Proper Alembic migration with merge migration for multiple heads. --- ### Summary The safety profile feature itself is well-implemented and demonstrates good engineering practices. The blocking issues are primarily process-related: the empty PR body (H1), the bundled unrelated deletions (H2), and the incorrect labels (H3). Of these, H2 is the most significant as it makes the commit non-atomic and non-revertible in isolation. H1 and H3 are straightforward to fix. Requesting changes primarily for H1 (empty PR body) and H2 (non-atomic commit). Once these are addressed, this PR should be in good shape for approval.
@ -0,0 +222,4 @@
file_path = Path(path)
if not file_path.exists():
raise FileNotFoundError(f"Safety profile YAML file not found: {file_path}")
with open(file_path) as fh:
Owner

[L2] Missing explicit encoding parameter

open(file_path) should specify encoding="utf-8" explicitly. While the default encoding on most systems is UTF-8, relying on the platform default is fragile and can cause issues on Windows or in non-standard environments. Per Python best practices:

with open(file_path, encoding="utf-8") as fh:
**[L2] Missing explicit encoding parameter** `open(file_path)` should specify `encoding="utf-8"` explicitly. While the default encoding on most systems is UTF-8, relying on the platform default is fragile and can cause issues on Windows or in non-standard environments. Per Python best practices: ```python with open(file_path, encoding="utf-8") as fh: ```
Author
Member

addressed

addressed
@ -0,0 +312,4 @@
Raises:
NotImplementedError: Always, in local mode.
"""
raise NotImplementedError(
Owner

[L3] Stub does no resolution before raising

This function accepts four precedence levels (plan_profile, action_profile, project_profile, global_profile) but performs zero resolution logic before raising NotImplementedError. Even as a stub, it would be valuable to include the intended resolution flow as commented-out logic or pseudocode, so that the future implementer has a clear roadmap. For example:

# Future implementation should resolve in this order:
# 1. plan_profile (highest precedence)
# 2. action_profile
# 3. project_profile
# 4. global_profile (lowest precedence)
# Return the first non-None profile with its provenance.
raise NotImplementedError(...)

This would also make the function more self-documenting and align with the docstring's description of the resolution order.

**[L3] Stub does no resolution before raising** This function accepts four precedence levels (`plan_profile`, `action_profile`, `project_profile`, `global_profile`) but performs zero resolution logic before raising `NotImplementedError`. Even as a stub, it would be valuable to include the intended resolution flow as commented-out logic or pseudocode, so that the future implementer has a clear roadmap. For example: ```python # Future implementation should resolve in this order: # 1. plan_profile (highest precedence) # 2. action_profile # 3. project_profile # 4. global_profile (lowest precedence) # Return the first non-None profile with its provenance. raise NotImplementedError(...) ``` This would also make the function more self-documenting and align with the docstring's description of the resolution order.
Author
Member

comments inserted

comments inserted
@ -4291,0 +4289,4 @@
safety=SafetyProfile(
require_sandbox=bool(row.require_sandbox),
require_checkpoints=bool(row.require_checkpoints),
require_human_approval=False,
Owner

[L4] Hardcoded safety field defaults deserve a comment

The new SafetyProfile fields (require_human_approval, max_retries_per_step) are hardcoded here because the database table does not have columns for them — only the original three booleans (require_sandbox, require_checkpoints, allow_unsafe_tools) are persisted. This is a reasonable approach for backwards compatibility, but a clarifying comment would prevent future confusion:

# NOTE: require_human_approval and max_retries_per_step are not
# persisted in the automation_profiles table (only the original
# three safety booleans are stored).  Defaults are used here for
# backwards compatibility.  See c4_001_safety_profile_column for
# the Action-level safety_profile_json column.
**[L4] Hardcoded safety field defaults deserve a comment** The new `SafetyProfile` fields (`require_human_approval`, `max_retries_per_step`) are hardcoded here because the database table does not have columns for them — only the original three booleans (`require_sandbox`, `require_checkpoints`, `allow_unsafe_tools`) are persisted. This is a reasonable approach for backwards compatibility, but a clarifying comment would prevent future confusion: ```python # NOTE: require_human_approval and max_retries_per_step are not # persisted in the automation_profiles table (only the original # three safety booleans are stored). Defaults are used here for # backwards compatibility. See c4_001_safety_profile_column for # the Action-level safety_profile_json column. ```
Author
Member

addressed as requested

addressed as requested
CoreRasurae force-pushed feature/post-safety-profile from 2677abb4ad
All checks were successful
CI / lint (pull_request) Successful in 24s
CI / quality (pull_request) Successful in 24s
CI / benchmark-publish (pull_request) Has been skipped
CI / typecheck (pull_request) Successful in 40s
CI / build (pull_request) Successful in 22s
CI / security (pull_request) Successful in 48s
CI / unit_tests (pull_request) Successful in 1m58s
CI / docker (pull_request) Successful in 49s
CI / integration_tests (pull_request) Successful in 3m4s
CI / coverage (pull_request) Successful in 3m37s
CI / benchmark-regression (pull_request) Successful in 24m52s
to 01686f8cd0
Some checks failed
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Failing after 14s
CI / build (pull_request) Successful in 16s
CI / quality (pull_request) Successful in 18s
CI / typecheck (pull_request) Successful in 36s
CI / coverage (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Has been skipped
CI / security (pull_request) Successful in 39s
CI / unit_tests (pull_request) Successful in 1m45s
CI / docker (pull_request) Has been skipped
CI / integration_tests (pull_request) Successful in 2m54s
2026-03-02 17:38:34 +00:00
Compare
CoreRasurae force-pushed feature/post-safety-profile from 01686f8cd0
Some checks failed
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Failing after 14s
CI / build (pull_request) Successful in 16s
CI / quality (pull_request) Successful in 18s
CI / typecheck (pull_request) Successful in 36s
CI / coverage (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Has been skipped
CI / security (pull_request) Successful in 39s
CI / unit_tests (pull_request) Successful in 1m45s
CI / docker (pull_request) Has been skipped
CI / integration_tests (pull_request) Successful in 2m54s
to 66b9a4279f
All checks were successful
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 15s
CI / build (pull_request) Successful in 15s
CI / quality (pull_request) Successful in 17s
CI / security (pull_request) Successful in 32s
CI / typecheck (pull_request) Successful in 35s
CI / unit_tests (pull_request) Successful in 1m55s
CI / docker (pull_request) Successful in 39s
CI / integration_tests (pull_request) Successful in 2m50s
CI / coverage (pull_request) Successful in 4m13s
CI / benchmark-regression (pull_request) Successful in 23m10s
CI / lint (push) Successful in 12s
CI / quality (push) Successful in 15s
CI / build (push) Successful in 15s
CI / security (push) Successful in 29s
CI / typecheck (push) Successful in 32s
CI / benchmark-regression (push) Has been skipped
CI / unit_tests (push) Successful in 3m10s
CI / docker (push) Successful in 38s
CI / integration_tests (push) Successful in 4m1s
CI / coverage (push) Successful in 3m58s
CI / benchmark-publish (push) Successful in 13m21s
2026-03-02 17:44:30 +00:00
Compare
brent.edwards left a comment

Approve.

Approve.
CoreRasurae deleted branch feature/post-safety-profile 2026-03-02 20:09:47 +00:00
aditya approved these changes 2026-03-03 08:40:49 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
4 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
cleveragents/cleveragents-core!450
No description provided.