Merge develop into release/0.1 for 0.1.0-RC.6 (#41 performance fix) #42

Merged
james.maes merged 3 commits from merge/develop-into-release-0.1-rc6 into release/0.1 2026-11-10 21:38:15 +00:00
Owner

Brings PR 41 (request-scoped access fingerprint; retention, policy and classification rows read once per change with cluster invalidation and a 30 second maximum age) to the release branch. The merge is clean (5 files). Merging this publishes 0.1.0-RC.6 through the shared release workflow, as PR 40 did for RC.5. GG Forge then pins 0.1.0-RC.6.

🤖 Generated with Claude Code

Brings PR 41 (request-scoped access fingerprint; retention, policy and classification rows read once per change with cluster invalidation and a 30 second maximum age) to the release branch. The merge is clean (5 files). Merging this publishes 0.1.0-RC.6 through the shared release workflow, as PR 40 did for RC.5. GG Forge then pins 0.1.0-RC.6. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
james.maes added 3 commits 2026-11-10 21:37:49 +00:00
perf: keep the access fingerprint for the request and read rule rows once per change
maven / build (push) Successful in 1m32s
build / maven (push) Successful in 1m32s
ab283c79b9
Core asks the field access resolver for its fingerprint before every field
decision (FieldAccessHelper.getDecision), that is once per field of every
record of a result and of every table in the metaData document. Each call
recomputed it: a JSON key, a permission lookup for every table, another JSON
document and a digest. Core also asks for the retention rules of a field on
every audited field and every filter criterion, and each question was a
query.

- getAccessFingerprint keeps its value in the request context (QContext) and
  returns it while the session, its permission set, the channel, the policy
  and classification versions are unchanged and no active break-glass grant
  has expired. Nothing outlives the request.
- RetentionRules.active answers from the active rules the runtime read once
  (SecuredDataRuntime.activeRetentionRules). A rule write clears them after
  commit; a thread that edits rules inside a transaction reads its own edits.
- Policy, classification and retention changes are announced on QQQ's cluster
  bus (ClusterCaches, memo-invalidate), so every node reads again. Before,
  the versions were node-local and another node kept old rules until restart.
- No node uses rule rows older than 30 seconds without reading them again
  (the safety net for a lost event).
- A read that fails throws and replaces nothing: never an empty rule list.

Measured in one JVM with GG Forge's composed instance (222 tables, secured
data and collaboration wired, in-memory backend, platform administrator),
released 0.1.0-RC.4 against this change, same machine, back to back:
metaData request 866.6 ms to 125.3 ms (930 MB to 74 MB allocated, 96 to 34
queries); a 300-row list 1,566 ms to 24 ms; a 27-row list 174 to 230 ms down
to 13 to 17 ms; queries per list 23 to 8.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Merge develop into release/0.1 for 0.1.0-RC.6 (#41 request-scoped fingerprint, cached rule rows)
maven / build (push) Successful in 1m27s
build / maven (push) Successful in 1m27s
41b39d535b
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
james.maes merged commit 726a84889d into release/0.1 2026-11-10 21:38:15 +00:00
Sign in to join this conversation.