← Advanced course and all videos

Video 15 of 53 · 9:36 · Execution, sharing and reuse

CM-IR Persistence

In this video

  1. 0:00 · One policy, many requests
  2. 0:40 · Give the conditions a meaning
  3. 1:20 · Work the first decision
  4. 1:45 · What compilation saves
  5. 2:23 · A cache miss, then a cache hit
  6. 3:12 · Same program, different answer
  7. 3:44 · Change the policy itself
  8. 4:18 · Follow the revision to a changed decision
  9. 4:58 · A revision need not discard every valid piece
  10. 5:40 · Identity cannot supply missing meaning
  11. 6:17 · End one process, start another
  12. 6:56 · Saving and reloading is a separate path
  13. 7:37 · Admit a saved structure before using it
  14. 8:20 · Matching source, unsupported format
  15. 8:58 · Resolve the four situations

Caption transcript

Show transcript
An access service may apply the same policy thousands of times. Rebuilding its internal representation for every request can repeat preparation that has already been done. This lesson follows one small policy through new requests, a policy revision, and a process restart. We will separate the rule we can reuse from the answer we must obtain for the current request. That distinction matters whenever cached work outlives the circumstances that made it valid. Our examples are about exact behavior and reuse. They are not new speed measurements. For this teaching policy, role means that the person is approved staff. Region means that the request comes from an allowed location. One means the condition is true, and zero means it is false. Version one permits access only when both conditions are true. We write that as role and region. The word and requires both inputs to be one. These are deliberately simple conditions. The application is responsible for supplying their current values and keeping their meanings consistent. Our first request has role one and region one. The person is approved staff, and the location is allowed. Substitute those values into the rule. One and one gives one. Both requirements are satisfied, so this request is allowed. This allow decision belongs to this request under version one. It is not a promise about the next request. Compilation turns the source expression into an internal representation that an evaluator can use. For our small rule, it records the inputs and the and operation connecting them. The input values are supplied when we evaluate a request. The resulting allow or deny bit is a different object from the compiled representation. In the current C M I R path, the persistent cache stores compiled representation nodes. Reusing those nodes does not mean that every later preparation step or every requested output has already been computed. A cache keeps reusable work under an identifying key. Before lookup, this compiler checks that the expression graph is acceptable, including its structural limits. With the cache enabled and initially empty, the lookup misses. The system builds the representation and stores it. A later admitted lookup for the same compatible structure can hit that entry and reuse it. In the current implementation, the key includes an expression-structure digest and the flattening option. A hit also depends on the entry still being present. Clearing the cache or evicting an entry can turn a later lookup into a miss. Reuse is conditional, even inside the same process. Now a second request arrives. The person is still approved staff, but the location is not allowed. The policy remains role and region. We can reuse the compiled representation and evaluate it with these new inputs. One and zero gives zero, so the second request is denied. The same program has produced two different answers. Copying the previous allow bit would be wrong. Caching a representation and caching a request result require different validity conditions. Suppose the policy changes. Version two adds a resource requirement. Resource is one when the requested resource meets that requirement, and zero when it does not. The new rule requires role, region, and resource all to be true. This changes the expression structure. It is a new complete rule to compile or retrieve under its own compatible identity. We have changed the policy, not merely the request values. Keep both versions visible while we work the consequence. Consider one request with role one, region one, and resource zero. Version one looks only at role and region. It computes one and one, and allows access. Version two begins with the same two values, giving an intermediate one. It then combines that one with resource zero. One and zero gives zero, so the revised policy denies access. The old result is not an approximate answer to the new policy. It is the answer to a different rule. The complete version-one artifact cannot substitute for version two. Changing the complete rule does not mean that every unchanged piece must be thrown away. The subexpression role and region still occurs inside version two. The current compiler can reuse compatible cached subtrees in suitable contexts. Where shared associative structure makes compilation context-dependent, it uses a root-level cache path instead. The practical conclusion is precise: do not reuse an obsolete complete rule, but do not confuse that requirement with discarding all valid shared work. The compiler decides which compatible pieces it can safely reuse. There is another kind of change. Suppose the expression still says role and region, but the application's definition of an allowed location changes. A structural digest cannot discover a meaning that was never encoded in the expression. The application must update the values or dependencies that represent the new location policy. The same representation may still be usable with correctly updated inputs. What is unsafe is treating unchanged symbols or a matching digest as evidence that an old decision remains valid. A process is one running instance of the program. While process A runs, it can retain its cache between calls. Now end that process. Start a fresh, independent process B. The source expression may be identical, but the old in-memory cache entry has not automatically travelled into the new process. In this C M I R API, persistent describes reuse within the process. The cache itself does not promise storage on disk or survival across this restart. To carry structure across a restart, something must explicitly save it and later reconstruct it. That is a separate serialization and reload path. The repository has bounded research bundles containing flat instructions or clauses. Those bundles exclude cached query answers. Loading their structure is not the same operation as finding a live node in the process cache. A reload includes decoding, validation, and reconstruction before the requested outputs are evaluated. Those steps have their own cost and correctness obligations. For these research bundles, first check the format and backend. Then check the expected scenario, variable count, and version identities. A file for a different scenario is not interchangeable just because it can be decoded. Next validate the serialized instructions or clauses and reconstruct the structure. The research validation also compares the resulting behavior with independently computed scalar reference outputs. These are separate checks. A byte hash can identify the payload being examined, but it does not replace format admission or an exact behavior check. Imagine a saved bundle that still names the expected scenario, but declares an unsupported format version. Keep the source identity fixed and change only this format field. The loader must refuse that artifact. It has not evaluated the policy and found the request false. It has declined to accept this representation. The application can use a supported rebuild path where available. It must not silently turn a loading failure into a cached allow decision, or mistake it for a valid deny result. For a new request under the same valid rule, reuse the representation when available and evaluate the current inputs. For a revised rule, use the revised complete artifact. For a fresh process, rebuild or follow a separately supported and validated reload path. For an unsupported saved format, refuse the artifact rather than infer a policy decision. Reliable reuse means knowing what was saved, what stayed valid, and what still has to be computed. That is the foundation for both correct behavior and an honest measurement of any saved work.