# Project Context Policy

A `ProjectContextPolicy` controls what context (resources and files) is available
during each ACMS phase. It uses **view inheritance** so each phase can selectively
override or inherit from its parent.

## Inheritance Chain

```
default → strategize → execute → apply
```

| Phase        | Inherits from |
|--------------|---------------|
| `default`    | *(none)*      |
| `strategize` | `default`     |
| `execute`    | `strategize`  |
| `apply`      | `execute`     |

When resolving a view for a phase, the system walks up the inheritance chain and
returns the first explicitly-set `ContextView`. If no overrides are found, the
`default_view` is returned.

## ContextView

Each view controls:

| Field               | Type           | Default | Description                              |
|---------------------|----------------|---------|------------------------------------------|
| `include_resources` | `list[str]`    | `[]`    | Resource names/patterns to include       |
| `exclude_resources` | `list[str]`    | `[]`    | Resource names/patterns to exclude       |
| `include_paths`     | `list[str]`    | `[]`    | File path globs to include               |
| `exclude_paths`     | `list[str]`    | `[]`    | File path globs to exclude               |
| `max_file_size`     | `int \| None`  | `None`  | Max file size in bytes (None = no limit) |
| `max_total_size`    | `int \| None`  | `None`  | Max total context size (None = no limit) |

**Empty lists mean "include everything"** — no filtering is applied.
Exclusions always take precedence over inclusions.

## Examples

### Empty policy (include everything)

```python
from cleveragents.domain.models.core.context_policy import (
    ProjectContextPolicy,
)

policy = ProjectContextPolicy()
view = policy.resolve_view("execute")
# view.include_resources == []  (all resources)
# view.include_paths == []      (all paths)
# view.max_file_size is None    (no limit)
```

### Default view with overrides at strategize

```python
from cleveragents.domain.models.core.context_policy import (
    ContextView,
    ProjectContextPolicy,
)

policy = ProjectContextPolicy(
    default_view=ContextView(
        include_resources=["db-*"],
        exclude_paths=["*.pyc"],
        max_file_size=1_048_576,  # 1 MB
    ),
    strategize_view=ContextView(
        include_resources=["db-*", "cache-*"],
        max_file_size=2_097_152,  # 2 MB
    ),
)

# Strategize uses its own view
view = policy.resolve_view("strategize")
assert view.include_resources == ["db-*", "cache-*"]
assert view.max_file_size == 2_097_152

# Execute inherits from strategize (no execute_view set)
view = policy.resolve_view("execute")
assert view.include_resources == ["db-*", "cache-*"]

# Apply also inherits from strategize
view = policy.resolve_view("apply")
assert view.include_resources == ["db-*", "cache-*"]
```

### Override at execute level only

```python
from cleveragents.domain.models.core.context_policy import (
    ContextView,
    ProjectContextPolicy,
)

policy = ProjectContextPolicy(
    default_view=ContextView(
        include_resources=["db-*"],
    ),
    execute_view=ContextView(
        include_resources=["db-*", "api-*"],
        max_total_size=10_485_760,  # 10 MB
    ),
)

# Strategize inherits from default (no strategize_view set)
view = policy.resolve_view("strategize")
assert view.include_resources == ["db-*"]

# Execute uses its own view
view = policy.resolve_view("execute")
assert view.include_resources == ["db-*", "api-*"]

# Apply inherits from execute
view = policy.resolve_view("apply")
assert view.include_resources == ["db-*", "api-*"]
```

### Size limits

```python
from cleveragents.domain.models.core.context_policy import (
    ContextView,
)

# Valid size limits
view = ContextView(
    max_file_size=1_048_576,    # 1 MB per file
    max_total_size=10_485_760,  # 10 MB total
)

# None means no limit (default)
view = ContextView()
assert view.max_file_size is None
assert view.max_total_size is None

# Zero or negative values are rejected
# ContextView(max_file_size=0)   -> ValidationError
# ContextView(max_file_size=-1)  -> ValidationError
```

## JSON Serialization

```python
import json
from cleveragents.domain.models.core.context_policy import (
    ContextView,
    ProjectContextPolicy,
)

policy = ProjectContextPolicy(
    default_view=ContextView(include_resources=["db-*"]),
    strategize_view=ContextView(include_resources=["cache-*"]),
)

# Serialize
data = json.loads(policy.model_dump_json())

# Deserialize
restored = ProjectContextPolicy.model_validate(data)
assert restored == policy
```
