feat: reconcile granted ops run closes
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a06bfe-2a55-7ed3-bacd-879977b099bf
This commit is contained in:
parent
b72fdb5452
commit
b63131e863
21 changed files with 1240 additions and 43 deletions
82
tests/test_repository_grant.py
Normal file
82
tests/test_repository_grant.py
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
"""Repository-grant v1 validation and identity compatibility."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from activity_core.models import ActionDef, InstructionDef
|
||||
from activity_core.orm import OpsRun
|
||||
from activity_core.repository_grant import (
|
||||
RepositoryGrant,
|
||||
RepositoryGrantError,
|
||||
validate_repository_grant,
|
||||
)
|
||||
|
||||
|
||||
def _grant(**changes: object) -> dict:
|
||||
value = {
|
||||
"version": "1",
|
||||
"allowed_paths": ["docs/", "README.md"],
|
||||
"commit_count": {"min": 1, "max": 1},
|
||||
"publish": False,
|
||||
}
|
||||
value.update(changes)
|
||||
return value
|
||||
|
||||
|
||||
def test_repository_grant_preserves_payload_and_has_stable_identity() -> None:
|
||||
raw = _grant()
|
||||
grant = RepositoryGrant.model_validate(raw)
|
||||
reordered = RepositoryGrant.model_validate(
|
||||
_grant(allowed_paths=["README.md", "docs/"])
|
||||
)
|
||||
|
||||
assert grant.payload() == raw
|
||||
assert grant.payload() is not raw
|
||||
assert grant.grant_id == reordered.grant_id
|
||||
assert grant.acceptance_policy_id == reordered.acceptance_policy_id
|
||||
assert grant.grant_id == "af2e7c8275c9ba8c8f78485067f9608e"
|
||||
assert grant.acceptance_policy_id == "2ed31282d721f4466bc9ea722067d9d0"
|
||||
|
||||
|
||||
def test_action_and_instruction_parse_repository_grant_as_typed_authority() -> None:
|
||||
action = ActionDef(task_template="Do work", repository_grant=_grant())
|
||||
instruction = InstructionDef(
|
||||
id="do-work",
|
||||
trusted_fields=[],
|
||||
model="model",
|
||||
prompt="Do work",
|
||||
output_schema="schema.json",
|
||||
repository_grant=_grant(),
|
||||
)
|
||||
|
||||
assert isinstance(action.repository_grant, RepositoryGrant)
|
||||
assert isinstance(instruction.repository_grant, RepositoryGrant)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"value",
|
||||
[
|
||||
_grant(extra="not-allowed"),
|
||||
_grant(version=1),
|
||||
_grant(allowed_paths=[]),
|
||||
_grant(allowed_paths=["docs/", "docs/"]),
|
||||
_grant(allowed_paths=["../escape"]),
|
||||
_grant(allowed_paths=[".git/config"]),
|
||||
_grant(commit_count={"min": True, "max": 1}),
|
||||
_grant(commit_count={"min": 2, "max": 1}),
|
||||
_grant(commit_count={"min": 1, "max": 33}),
|
||||
_grant(publish=True),
|
||||
_grant(publish=0),
|
||||
],
|
||||
)
|
||||
def test_repository_grant_rejects_ambiguous_or_unsafe_values(value: dict) -> None:
|
||||
with pytest.raises(RepositoryGrantError):
|
||||
validate_repository_grant(value)
|
||||
|
||||
|
||||
def test_ops_run_schema_has_separate_grant_and_close_identity_columns() -> None:
|
||||
columns = OpsRun.__table__.columns
|
||||
|
||||
assert columns["repository_grant"].nullable is True
|
||||
assert columns["close_intent_digest"].nullable is True
|
||||
Loading…
Add table
Add a link
Reference in a new issue