# Debt Waterline Freeze Policy

**Status**: ACTIVE
**Effective Date**: 2026-03-03
**Version**: 1.0

---

## Purpose

Define baseline quality thresholds for contract coverage and static spec coverage, establish non-regression rules, and codify freeze protocol for downstream verification cycles.

**Environment Consistency**: All verification commands use canonical interpreter contexts per [docs/operations/verifier-environment-spec.md](verifier-environment-spec.md). Import checks MUST use `uv run python` (project venv), verification tools use `uvx invar-tools` (isolated).

---

## Baseline Metrics (Captured 2026-03-07)

### Static Analysis Baseline

| Metric | Value | Threshold | Status |
|--------|-------|-----------|--------|
| **Guard Status** | PASSED | Must PASS | ✅ |
| **Files Checked** | 69 | N/A | Recorded |
| **Static Errors** | 0 | Max 0 | ✅ |
| **Static Warnings** | 56 | Max 56 | ✅ |
| **Static Infos** | 11 | Max 11 | ✅ |

**Command Used**:
```bash
uvx invar-tools guard --all
```

**Output Snapshot**:
```json
{
  "status": "passed",
  "static": {
    "passed": true,
    "errors": 0,
    "warnings": 56,
    "infos": 11
  },
  "summary": {
    "files_checked": 69,
    "errors": 0,
    "warnings": 56,
    "infos": 11
  }
}
```

### Contract Coverage Baseline

| Module | Coverage | Functions | Target | Status | Notes |
|--------|----------|-----------|--------|--------|-------|
| `core/schemas/models.py` | 20% | 2/10 | 80% | ⚠️ Below | Escape: Pydantic validators |
| `core/schemas/errors.py` | 13% | 3/20 | 80% | ⚠️ Below | Escape: Error boilerplate |

**Escape Hatch Count**: 272 total

**Top Escape Reasons**:
1. `shell_result` (74) - Shell functions returning Result types
2. `missing_contract` (26) - Functions without explicit contracts
3. `function_size` (29) - Functions exceeding size limits
4. `entry_point_too_thick` (24) - CLI entry points with many options
5. `file_size` (9) - Files approaching size limits
6. `file_size_warning` (3) - Files at 80%+ size limit

### Escape Hatch Distribution by Rule

| Rule | Count | Acceptable? |
|------|-------|-------------|
| `shell_result` | 74 | ✅ Shell functions using Result types correctly |
| `missing_contract` | 26 | ⚠️ Should add contracts progressively |
| `function_size` | 29 | ⚠️ Consider refactoring opportunistic |
| `entry_point_too_thick` | 24 | ✅ CLI entry points, acceptable |
| `file_size` | 9 | ⚠️ Monitor for growth |
| `file_size_warning` | 3 | ⚠️ Near limits |
| `shell_pure_logic` | 11 | ⚠️ Consider moving to Core |
| `contract_quality_ratio` | 2 | ⚠️ Low coverage, has escape reasons |
| `review_suggested` | 2 | ⚠️ High escape count, review recommended |
| `forbidden_import` | 1 | ✅ Shell needs os/pathlib |
| `shell_complexity` | 1 | ⚠️ Minor complexity |

---

## Non-Regression Policy

### Hard Constraints (MUST NOT Violate)

1. **Guard Status**: `invar guard --all` MUST return `"status": "passed"`
2. **Error Count**: Static errors MUST remain at 0
3. **Warning Budget**: Warnings MUST NOT exceed 56 (current: 56)
4. **Escape Hatch Budget**: Total escape hatches MUST NOT exceed 272 (current: 272)

### Soft Constraints (Should Improve Over Time)

1. **Contract Coverage**: Target 80%+ for Core modules
   - Current exemptions documented with reasons in code
   - New Core functions SHOULD include contracts unless exempted

2. **Warning Count**: Target < 10 warnings
     - Current: 56 (within budget, but improve over time)

3. **Escape Hatch Hygiene**: Reduce duplicate escape reasons
   - Current: 16 files share "Forwards to base class, CODE is constant"
   - Action: Consider rule refinement instead of escape proliferation

---

## Freeze Protocol

> **Protocol Evidence Fields**: Each freeze verification requires capture of:
> - `git rev-parse HEAD` - Exact commit hash
> - `git status --short` - Working tree state (must be clean)
> - `environment declaration` - OS, Python version, working directory
> - `no-code-change assertion` - Confirm baseline is unchanged from committed state

### Pre-Verification Checklist

Before running verification cycles, complete this checklist:

**Step 0: Capture Freeze Evidence**
```bash
# Commit hash (immutable baseline reference)
export FREEZE_COMMIT=$(git rev-parse HEAD)
echo "Freeze commit: $FREEZE_COMMIT"

# Working tree state (must be empty for reproducible results)
export FREEZE_STATUS=$(git status --short)
if [ -n "$FREEZE_STATUS" ]; then
  echo "WARNING: Working tree not clean"; echo "$FREEZE_STATUS"
else
  echo "✓ Working tree clean"
fi

# Environment declaration (canonical: use project venv, not system Python)
# See docs/operations/verifier-environment-spec.md for context
export FREEZE_ENV="$(uname -s) $(uname -m), Python $(uv run python --version 2>/dev/null || echo 'N/A')"
echo "Environment: $FREEZE_ENV"

# No-code-change assertion (compare to policy baseline)
echo "Baseline captured at: $FREEZE_COMMIT"
echo "Current HEAD matches: $(git rev-parse HEAD)"
[ "$FREEZE_COMMIT" = "$(git rev-parse HEAD)" ] && echo "✓ No code drift" || echo "✗ CODE CHANGED - re-verify"
```

- [ ] `git rev-parse HEAD` recorded
- [ ] `git status` shows clean working tree
- [ ] Environment declared and recorded
- [ ] No-code-change assertion confirmed (commit hash matches)

**Step 1: Capture Current State**
- [ ] Run `uvx invar-tools guard --all` and record output
- [ ] Check guard status is "passed"
- [ ] Record warning/error counts
- [ ] Count total escape hatches

**Step 2: Validate Non-Regression**
- [ ] Compare static errors to baseline (MUST be 0)
- [ ] Compare warnings to budget (MUST be ≤56)
- [ ] Compare escape hatches to budget (MUST be ≤272)
- [ ] Check no new high-severity warnings introduced

**Step 3: Document Exceptions**
- [ ] If thresholds exceeded, document reason
- [ ] If new escape hatches added, justify in code comments
- [ ] If coverage decreased, explain why

**Step 4: Update Baseline (if needed)**
- [ ] If improvements made, update baseline metrics in this document
- [ ] If temporary regression accepted, create ticket to resolve

### Verification Cycle Protocol

For each verification cycle (gate, retest, release):

1. **Run Guard**:
   ```bash
   uvx invar-tools guard --all
   ```

2. **Extract Metrics**:
   ```bash
   # Extract summary
   uvx invar-tools guard --all | jq '.summary'
   
   # Count escape hatches
   uvx invar-tools guard --all | jq '.escape_hatches.count'
   ```

3. **Validate Against Waterline**:
   - Errors: 0 (hard constraint)
    - Warnings: ≤56 (hard constraint)
    - Escape hatches: ≤272 (hard constraint)

4. **Report Status**:
   ```
   ✓ Waterline Check: PASS
     - Errors: 0/0 ✅
       - Warnings: 56/56 ✅
      - Escape Hatches: 272/272 ✅
   ```
   
   OR
   
   ```
✗ Waterline Check: FAIL
      - Errors: 2/0 ❌ (regression!)
       - Warnings: 57/56 ❌
       - Escape Hatches: 273/272 ❌
    ```

---

## Escalation Rules

### When Waterline Fails

1. **Immediate**: Block merge/deployment
2. **Document**: Record failure reason in PR/commit
3. **Remediate**: Fix regression or justify exception
4. **Exception Process**: 
   - MUST be documented in code with `# @invar:allow` and reason
   - MUST be reviewed by code owner
   - MUST create tracking issue for resolution

### Exception Criteria

Exceptions to waterline are granted for:

1. **Technical Debt Reduction**: Temporarily increasing warnings while refactoring
   - MUST have tracking issue
   - MUST have resolution timeline < 1 sprint

2. **Emergency Fixes**: Critical bugs requiring immediate deployment
   - MUST have post-mortem ticket
   - MUST be resolved within 48 hours

3. **Tooling Changes**: Updates to invar-tools that surface new warnings
   - MUST document tooling change
   - MUST create remediation plan

---

## Metric Refresh Schedule

### Automatic Refresh Triggers

Update this document's baseline metrics when:

1. **After Major Refactor**: Any PR affecting >10 files
2. **After Tooling Update**: Changes to `invar-tools` version
3. **After Quality Sprint**: Dedicated technical debt reduction work
4. **Before Release**: As part of release checklist

### Refresh Procedure

1. Run: `uvx invar-tools guard --all > /tmp/guard_baseline.json`
2. Update metrics in this document
3. Commit with message: "docs: update waterline baseline metrics"

---

## Appendix: Commands Reference

### Capture Baseline
```bash
# Full guard output
uvx invar-tools guard --all | tee /tmp/guard_baseline.json

# Summary only
uvx invar-tools guard --all | jq '.summary'

# Escape hatches count
uvx invar-tools guard --all | jq '.escape_hatches.count'

# Contract coverage by file
uvx invar-tools guard --all | jq '.fixes[] | select(.rule == "contract_quality_ratio")'
```

### Verify Non-Regression
```bash
# Quick check
uvx invar-tools guard --all | jq '{status: .status, errors: .static.errors, warnings: .static.warnings}'

# Waterline validation script
uvx invar-tools guard --all | jq '
   if .static.errors == 0 and .static.warnings <= 56 and .escape_hatches.count <= 272
   then "✓ WATERLINE PASS"
  else "✗ WATERLINE FAIL"
  end
'
```

### Automated Gate Command
```bash
# Policy-driven gate used by CI workflow
uv run python scripts/waterline_guard_gate.py
```

This command reads thresholds directly from this document and fails fast on the first hard-constraint regression.

### Compare to Baseline
```bash
# Compare current to baseline
diff <(cat /tmp/guard_baseline.json | jq '.summary') \
     <(uvx invar-tools guard --all | jq '.summary')
```

---

## Version History

| Version | Date | Changes | Author |
|---------|------|---------|--------|
| 1.1 | 2026-03-07 | Refresh baseline metrics for static/escape budgets after context-compaction remediation. Current budget levels: warnings 56, escape hatches 272. | vectl:context-compaction-remediation |
| 1.0 | 2026-03-03 | Initial baseline capture | vectl:freeze-waterline |
