ekp/postmortem/20260728-paragraph-fast-path-identity.md
Kinneyzhang fd1210e557 fix: close repository audit findings
Complete task002 through task016 across cache correctness, editor lifecycle, C boundaries, build and release governance, dictionary provenance, performance, interactive workflows, tests, documentation, and final cleanup.
2026-07-28 22:43:10 +08:00

56 lines
2.0 KiB
Markdown

# Give Both Paragraph Cache Paths One Identity Owner
## Context
The paragraph hash cache used `ekp--para-key`, including filtered
text-property intervals and every paragraph preprocessing input. The
one-entry `ekp--last-para` path bypassed that key and compared a smaller
tuple. Mutating `ekp-no-break` on the exact cached string object therefore
returned stale boxes and break permissions.
## Decision
Compute `ekp--para-key` before either lookup. The one-entry path may skip the
hash-table operation when both string identity and that complete key match,
but it does not own a second signature. Remove style-variable watchers whose
only purpose was to compensate for the partial fast-path tuple.
## Alternatives Rejected
### Add Text Properties to the Partial Tuple
That repairs one omission while preserving two independently maintained
identity rules. The next paragraph input would recreate the bug.
### Clear All Paragraph Caches on Property Mutation
Standalone strings have no general mutation hook, and eager global
invalidation would discard unrelated paragraphs.
### Remove the One-Entry Path
That is correct but needlessly adds a hash-table lookup to repeated resolution
inside one formatting call. Comparing the already-owned key keeps the narrow
optimization without duplicate semantics.
## Consequences
- Same-object text-property mutations now miss both lookup paths.
- Style, language, spacing, display context, and text properties have one
paragraph identity owner.
- Six watcher registrations and their anonymous invalidation function are
removed.
- The fast path still avoids the hash lookup, but no longer avoids computing
the correctness key.
## Verification
The new regression failed 0/1 before the change. It passes for both CJK and
Latin-with-space strings after the change, and the related cache/style/
display-context matrix passes 6/6.
## Rollback
Restore the partial tuple and watchers. No persisted data needs migration,
but the same-object property regression returns.