REG-056 — after (protobuf codegen pinned: regeneration path + drift guard)
=============================================================================

Row: REG-056 [P2-5] CODE P3 'Checked-in protobuf codegen' — SEED -> FIXED

The hazard, confirmed before any edit:
  $ grep -rn '\bprotoc\b' --include=* . | grep -v '^./.venv' | wc -l
    0            (no regeneration path anywhere in the tree)
  $ grep -rn 'audit_node_pb2' --include=*.py . | grep -v '^./.venv'
    (only the generated file's own builder line)  -> no consumer
  $ head -3 aegis/core/audit_node_pb2.py
    # Generated by the protocol buffer compiler.  DO NOT EDIT!
    # source: audit_node.proto
    # Protobuf Python Version: 4.25.2
  $ python -c 'import google.protobuf; print(google.protobuf.__version__)'
    7.36.0            (gencode 4.25.2, runtime 7.36.0 -> drift risk, not a failure)

Route chosen: keep-and-pin (deletion changes the wheel's declared dependencies -> owner).

1) scripts/regenerate_protobuf.sh — the missing regeneration path.
   Fail-closed when the tool is absent:
   $ bash scripts/regenerate_protobuf.sh
     error: grpc_tools is not importable in python3.
     Install it into that interpreter (python -m pip install grpcio-tools) and re-run.
     The checked-in descriptor is verified without protoc by
       python3 -m pytest tests/test_audit_node_proto_freshness.py -q
   exit=0

2) tests/test_audit_node_proto_freshness.py — the missing drift guard (5 tests).
   $ python -m pytest tests/test_audit_node_proto_freshness.py -q
     5 passed in 0.49s

3) Mutation proof that the guard fails closed (not just green):
   injected 'string injected_drift = 10;' into aegis/core/audit_node.proto
   $ python -m pytest tests/test_audit_node_proto_freshness.py -q
     FAILED test_proto_source_and_checked_in_descriptor_agree
     1 failed, 4 passed
   .proto restored from backup -> 'git diff --stat' empty -> 5 passed again

4) ruff:
   $ ruff check tests/test_audit_node_proto_freshness.py
     All checks passed!

Documentation gates (registry corpus touched):
verify_docs: PASS (0 findings)
verify_claims: PASS (102 claims, 0 findings)
verify_links: PASS (1285 relative links and anchors resolved)
verify_documentation --strict: status=PASS errors=0 warnings=0
