`Audit` exposes `records: Vec<EntityRecord>` as a public field, and the engine reaches in to mutate it from several places:
- Detection appends new `EntityRecord`s after each block scan.
- The redaction evaluator finds a record by entity id, then assigns its `audit` field.
- The validator amends records when post-redaction leaks are detected.
Today every mutation is open-coded as a field access. The type doesn't model these as operations.
Proposal
Add two methods that name what callers actually do:
```rust
impl<M: Modality> Audit {
/// Append a new entity record (the typical detection path).
pub fn push_record(&mut self, record: EntityRecord);
/// Attach an audit entry to the entity with the given id,
/// returning whether it landed.
pub fn set_audit(&mut self, entity_id: Uuid, entry: AuditEntry<M>) -> bool;
}
```
The field can stay public — these are conveniences, not encapsulation. The win is that future readers see the type's operational surface in the impl block instead of grepping for `audit.records.` accesses across `nvisy-engine`.
Pure addition, local change.
Found during the nvisy-ontology polish pass (audit item 12.19).
`Audit` exposes `records: Vec<EntityRecord>` as a public field, and the engine reaches in to mutate it from several places:
Today every mutation is open-coded as a field access. The type doesn't model these as operations.
Proposal
Add two methods that name what callers actually do:
```rust
impl<M: Modality> Audit {
/// Append a new entity record (the typical detection path).
pub fn push_record(&mut self, record: EntityRecord);
}
```
The field can stay public — these are conveniences, not encapsulation. The win is that future readers see the type's operational surface in the impl block instead of grepping for `audit.records.` accesses across `nvisy-engine`.
Pure addition, local change.
Found during the nvisy-ontology polish pass (audit item 12.19).