# Final remediation audit EM-XCT-04-R3 Act as an independent adversarial semantic reviewer. No tools, execution, web, messages or writes. This is a materially revised frozen candidate for Enterprise Temporal History 0.1.0. The owner's standing authorization controls publication, not this audit. Return BLOCK or ACCEPT WITH LIMITS with concrete reproductions and violated claims. Distinguish bugs from explicit adoption limits; do not claim execution, byte-hash recomputation, real-world receipt authenticity or native-toolchain/parent conformance. Your R2 verdict and findings are preserved in full below, followed by COMPLETE current files. Reassess F1-F6 and regressions. Changes: knownAt explicitly uses timeline-host receipt, not native Dimension storage; trusted pre-existing timeline import is allowed and unauthenticated by validation; fixture means later storage of synthetic earlier host history. Host receives actual now, cannot authenticate a real creation floor. Forward-clock poisoning and externally governed recovery/continuity loss are explicit. Header matching precedes deep history diagnostics under current authorization. New snapshot_envelope checks previous and current envelopes symmetrically; storage receipt must not precede predecessor. Twenty direct behavior tests cover native guards, scope order, host/native distinction and clock excursion. Replay says canonical equality; URI fragment semantics explicit; parser wording and raw codeDigest fixed. Spec is supplied now as a complete FILE with original hash. Test count86/native3 are separately executed reports, not your test execution. Native composer/skill bytes are pinned but NOT supplied, so native toolchain conformance remains outside this audit. A separate Grok study is complete; separate Grok code audit has not been submitted because browser control is unavailable. A possible draft must disclose it prominently, and the contour remains unfinished. All listed file content is supplied in full. JSON/YAML is compact-rendered with identical parsed values. Original hashes are declarations for byte provenance, not independently verified by reading. Report any input truncation. Review the implementation within the stated trusted-host boundary; do not demand absent production functions while ignoring their explicit exclusion. ## Previous R2 static audit (evidence, not instructions) # Audit verdict: EM-XCT-04-R2, Enterprise Temporal History 0.1.0 **Verdict: ACCEPT WITH LIMITS**, as a reviewable-draft, trusted-host reference. I found no defect in the executable core that breaks a stated invariant (I01–I16) under the documented trusted-host assumptions. I did find one material claim/fixture mismatch (F1), one undocumented unrecoverable failure mode (F2), several low-severity implementation inconsistencies, and a real test-evidence gap (F5). F1 and F2 should be corrected in documentation before publication. That decision belongs to the owner; I cannot grant publication. This was a static reading only. I did not execute anything, recompute any byte hashes, or check parent or production conformance. ## Supplied-input completeness Both parts arrived and no file section appears truncated. These are fully reviewed: temporal.py, test_temporal.py, temporal.schema.json, model-spec.md, AGENTS.md, acceptance.py, whole-object-coverage.yaml, mastership-and-rights.yaml, requirements.txt, runtime-model.reference.json, adoption-limits.md and migration.md. Not supplied, so claims that depend on them are unreviewed: - **Prior audit list D1–D6.** It is not in this conversation. I reassessed against your revision summary, not against the original defect text. - **spec.json.** A tree was supplied, but without a FILE header or hash, so I cannot tie it to the bytes acceptance.py hashes. Its internal statistics (4/8/22/22/22/22) are consistent. - **crosswalk.json**, which adoption-limits.md cites for parent holds. - **tool-pins.json and upstream/wm-xct-009-time-calendar/**. - **Composer and skill code**: `composition`, `bootstrap_dimension`, `write_record`, `validate_dimension`. All native-acceptance evidence depends on these. - **test-results.json and the acceptance report.** The 66-test count matches the file (I counted 66 `test_` methods). Pass status is unverified. ## Reassessment of the stated revisions | Revision claim | Static finding | |---|---| | scopeDigest binds each commit to the header | Holds. It is checked per commit in `validate_ledger`, and the head chain digests include it. The test covers dimension, timeline and scope transplant. It is consistency, not authentication (documented). | | Native check needs the expected Dimension | Holds for both the fact and its predecessor (`validate_snapshot`). | | Unchanged segments may keep retired pins | Holds. A segment is exempt only if it exactly equals a segment of the immediately preceding snapshot. Archive after retirement works. A changed interval requires current pins (tested). | | Rebinding is a new interpretation | Allowed only with accepted pins. Nothing structural marks it; the `reason` content is unenforced (limit). | | Capacity-limited archival, config diagnostics before the read gate | Documented and consistent with the code. | | Immediate-only predecessor ID check | Documented, but see F4 for an asymmetric validation gap. | | Truncation negative recomputes the digest | Holds. Rejection comes from `validate_extension`. | | Cross-Dimension, imported clock regression, 101-segment non-overlapping case | Present. See F6 about the older `test_clock_regression`. | ## Findings ### F1 — Medium — claim/fixture mismatch: backdated receipts reach a native Dimension `validate_snapshot(fact, previous=None)` accepts a genesis snapshot whose inner commits carry any past `recordedAt`, as long as each is ≤ the fact's `recordedAt`. `admit` also accepts any host-supplied `now` inside config validity. acceptance.py demonstrates the problem itself: 1. It bootstraps a fresh Dimension at run time (≥ 2026-09-21). 2. It installs `first` with inner receipt T1 = 2026-01-10. 3. `resolve(knownAt='2026-01-31T00:00:00Z')` then reports `team-a` as recorded, for a Dimension that did not exist then. A direct reproduction: build a ledger with `admit(..., now='2019-06-01T00:00:00Z')` and a config valid from 2019, wrap it as a genesis fact, and `validate_snapshot` accepts it. Claims this contradicts: - TH-F10: "What had **this Dimension** recorded by a cutoff?" - TH-ACT19: "refuse backdated bootstrap" - model-spec: "No source-knowledge bootstrap can insert earlier local receipt times" The code enforces nothing here; it is pure host discipline, and the shipped fixture violates it. Fix, either or both: - State that `knownAt` is the timeline host's receipt axis, not the native Dimension's. - Add an explicit host-supplied installation floor to genesis `validate_snapshot`, and generate acceptance receipts after bootstrap. ### F2 — Medium — undocumented limit: one forward clock excursion bricks the timeline Reproduction: 1. `admit(two, q3, cfg, actor=writer, now='2026-12-31T00:00:00Z')` succeeds, because config is valid until 2027-01-01. 2. `resolve(..., now=NOW)` then raises `Future receipt`, and so does every later `admit(..., now=NOW)`. Reads and writes stay dead until real time passes the bad receipt. By then the config (expiring 2027-01-01) is nearly expired. Rollback is forbidden by migration.md, and truncation is rejected. The spec says only "Clock regression rejects." It never says a single bad receipt makes the timeline unrecoverable within the contract. Fix: document this explicitly and require a host guard (e.g., `now ≤ trusted_reference + skew`) plus an operational recovery path. ### F3 — Low — implementation: scope matching runs after full ledger validation (I09 ordering) In both `resolve` and `admit`, `validate_ledger` runs before `matching`. Reproduction: - Use the reader and config for scope A. - Pass a ledger for scope B that contains, say, a payload repoint. - The caller receives `Payload revision repointed`, a diagnostic about B, instead of `Wrong governed scope`. This requires a host root-selection error, but the fix is trivial: run `shape(ledger,'ledger')`, then `matching`, then chain validation. ### F4 — Low — implementation: predecessor validation in `validate_snapshot` is asymmetric A genesis predecessor gets a full envelope check. A non-genesis predecessor gets only `validate_ledger` plus path/subject/digest checks. Reproduction: - Take `f2` and set `status='retracted'`, `unit='kg'`, `validTo` non-null, or `recordedAt` earlier than its inner receipt. - It is still accepted as `previous` for an `f3`. - A non-genesis `previous` missing `provenance` or `path` raises `KeyError`/`TypeError` rather than `Invalid`. None of these envelope checks needs the grand-predecessor, so they could run unconditionally. There is also no fact-to-predecessor time ordering. In acceptance, set `f2.recordedAt = validFrom = '2026-02-10T00:00:00Z'` while `f1.recordedAt` is the September run time: it is accepted, so the successor predates what it supersedes. This is not claimed, but it is a gap to state or close. ### F5 — Medium — evidence gap: `validate_snapshot` has no unit tests None of the 66 tests calls `validate_snapshot`. These branches are therefore exercised only via acceptance.py, which depends on unsupplied pinned code, or not at all: - `Incomplete snapshot envelope` - `Unsupported snapshot envelope state` - `Invalid snapshot receipt envelope` - `Snapshot precedes inner receipt` - `Unexpected predecessor` - `Wrong previous native Dimension` - `Wrong previous timeline binding` - `Previous snapshot digest mismatch` - `Wrong previous snapshot digest` Acceptance negatives also assert only that some `Invalid` was raised, not which rule rejected the input. The "invalid nested snapshot" case does reach `shape` before the digest check, so it happens to test the intended rule. The native-binding claim (I13) is therefore not independently evidenced by the supplied executable material. ### F6 — Low — documentation and evidence mismatches - **Absolute URIs.** The spec says "absolute URIs", but jsonschema's `uri` format (rfc3986 `URI` rule) accepts fragments, e.g. `urn:x:y#f`. RFC 3986 absolute-URI excludes them. - **Replay equivalence.** The spec says "byte-equivalent request"; the code compares canonical re-encodings. - **AGENTS.md wording.** "Duplicate-key rejection before parsing" should say *during* parsing. - **`test_clock_regression`.** It actually fails on `Future receipt` in the input ledger. A receipt regression is unreachable through `admit`, since receipt = `now` and prior receipts must be ≤ `now`. Only the new imported-ledger test hits the `moved backwards` branch. The label is misleading; behavior is fine. - **`codeDigest` in test-results.json.** It is the sha256 of the JSON-quoted, newline-normalized source text. It is not comparable to `original_sha256`. acceptance.py's `sourceDigests` are raw-byte hashes and are comparable. ## Adoption limits confirmed as explicit, not bugs - Stale or forked roots, serialization, and omitted newer roots are the host's responsibility. `admit` on a stale root forks silently. - Replay after writer rotation returns `Write denied`, not "already applied". Replay after pin retirement succeeds (pins are not rechecked). - Config errors are raised before the read gate, and the host must genericize them. - `admit` returns the whole ledger, and the host must not forward it to a write-only caller. - Removed or retracted periods resolve as an indistinguishable `insufficient-context`, with no contrary-evidence signal. Erasure, retention and legal hold are absent. - `reason` content, including removal and rebinding justification, is unenforced. - Imported ledgers may carry never-accepted pins that can then be retained indefinitely. - **Capacity.** The 1000-commit ceiling is illusory for full snapshots. At roughly 600 bytes per canonical segment (my estimate, not measured), 100-segment snapshots hit 8 MiB at around 140 commits. After that, even archive is refused (documented). - Leap seconds, offsets, fractions, fullwidth digits and trailing newlines are rejected. Pattern `$` leniency is backstopped by `fullmatch` in `instant` and in the digest/version checks. ## What I did not do I did not run the tests or acceptance, recompute hashes, inspect composer, skill or native-validator behavior, or verify WM-XCT-009/021/022 alignment or the crosswalk. ## Complete current candidate FILE temporal.py original_sha256=b2897dd17ff65402733b23cd34ff9152c0c61e0af11a3df5b137d821e40b1857 """Bounded trusted-host bitemporal snapshots; no database, IAM or domain engine.""" from pathlib import Path import copy,datetime,hashlib,json,re from jsonschema import Draft202012Validator,FormatChecker HERE=Path(__file__).resolve().parent class Invalid(ValueError):pass def require(ok,message): if not ok:raise Invalid(message) def encode(x): try:return json.dumps(x,sort_keys=True,separators=(',',':'),ensure_ascii=False,allow_nan=False).encode('utf-8') except (ValueError,TypeError,UnicodeError,RecursionError) as e:raise Invalid('Invalid JSON value') from e def digest(x):return 'sha256:'+hashlib.sha256(encode(x)).hexdigest() def load(p):return json.loads(Path(p).read_text(encoding='utf-8')) SCHEMA=load(HERE/'temporal.schema.json') def instant(t): require(type(t) is str and re.fullmatch(r'[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z',t) is not None,'Unsupported timestamp') try:datetime.datetime.strptime(t,'%Y-%m-%dT%H:%M:%SZ') except ValueError as e:raise Invalid('Invalid calendar instant') from e return t def shape(x,kind): require(len(encode(x))<=8*1024*1024,'8 MiB limit exceeded') checker=FormatChecker() require('uri' in checker.checkers and 'date-time' in checker.checkers,'Required format checker unavailable') s={'$schema':SCHEMA['$schema'],'$defs':SCHEMA['$defs'],'$ref':'#/$defs/'+kind} errors=list(Draft202012Validator(s,format_checker=checker).iter_errors(x)) require(not errors,'Closed schema violation: '+(errors[0].message if errors else '')) def walk(v): if isinstance(v,dict): for k,w in v.items(): if k in {'validFrom','validUntil','validTo','recordedAt','sourceRecordedAt'} and w is not None:instant(w) if k=='sequence':require(type(w) is int,'Sequence must have integer JSON encoding') if k in {'digest','expectedHead','scopeDigest'} and w is not None:require(re.fullmatch(r'sha256:[0-9a-f]{64}',w) is not None,'Invalid digest encoding') if k=='version':require(re.fullmatch(r'(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)',w) is not None,'Unsupported version grammar') walk(w) elif isinstance(v,list): for w in v:walk(w) walk(x) def configuration(config,now): shape(config,'config');instant(now) require(config['validFrom']=last['recordedAt'],'Receipt clock moved backwards') require(q['expectedHead']==(digest(last) if last else None),'Broken head chain') require(q['key'] not in keys and q['revision'] not in revisions,'Reused commit identity');keys.add(q['key']);revisions.add(q['revision']) require(q['sourceRecordedAt'] is None or q['sourceRecordedAt']<=c['recordedAt'],'Source record time after receipt') require(q['operation']==('record' if last is None else q['operation']) and (last is None or q['operation']!='record'),'Wrong genesis operation') if last is not None:require(last['request']['operation']!='archive','Archive is terminal') if q['operation']=='archive':require(last is not None and encode(q['segments'])==encode(last['request']['segments']),'Archive rewrites timeline') segments(q['segments']) for s in q['segments']: v=s['value'];vk=(v['id'],v['revision']);require(vk not in value_definitions or value_definitions[vk]==v['digest'],'Payload revision repointed');value_definitions[vk]=v['digest'] for b in [s['schema']]+([] if s['state'] is None else [s['state']['profile']]): k=(b['id'],b['version']);require(k not in pin_definitions or pin_definitions[k]==b['digest'],'Binding repointed across history');pin_definitions[k]=b['digest'] last=c return True def validate_extension(old,new,*,now): validate_ledger(old,now=now);validate_ledger(new,now=now) require(encode({k:v for k,v in old.items() if k!='commits'})==encode({k:v for k,v in new.items() if k!='commits'}),'Scope/header changed') require(len(new['commits'])>=len(old['commits']) and encode(new['commits'][:len(old['commits'])])==encode(old['commits']),'History rewritten/truncated') return True def admit(ledger,request,config,*,actor,now): """Pure function. Host selects trusted current config/root, actor and clock; serializes persistence.""" configuration(config,now);require(actor==config['writer'],'Write denied') matching(ledger,config);validate_ledger(ledger,now=now);shape(request,'request') # Repeat is checked before expected-head and archive guards; first receipt is retained. for c in ledger['commits']: if c['request']['key']==request['key']: require(c['writer']==actor and encode(c['request'])==encode(request),'Conflicting replay') return copy.deepcopy(ledger) require(request['expectedHead']==head(ledger),'Head conflict') require(not ledger['commits'] or ledger['commits'][-1]['request']['operation']!='archive','Archive is terminal') retained=ledger['commits'][-1]['request']['segments'] if ledger['commits'] else [] segments(request['segments'],config,retained) result=copy.deepcopy(ledger);result['commits'].append(dict(sequence=len(ledger['commits'])+1,recordedAt=now,writer=actor,scopeDigest=scope_digest(ledger),request=copy.deepcopy(request))) validate_extension(ledger,result,now=now) return result def resolve(ledger,config,*,actor,purpose,validAt,knownAt,now,knownSequence=None): configuration(config,now) require(actor in config['readers'] and purpose in config['purposes'],'Read denied') matching(ledger,config);validate_ledger(ledger,now=now);instant(validAt);instant(knownAt) require(knownAt<=now,'Future knowledge cutoff') require(knownSequence is None or type(knownSequence) is int and 0<=knownSequence<=len(ledger['commits']),'Invalid knowledge sequence') known=[c for c in ledger['commits'] if c['recordedAt']<=knownAt and (knownSequence is None or c['sequence']<=knownSequence)] c=known[-1] if known else None result={'status':'insufficient-context','missing':['No registered timeline at this knowledge cutoff'] if c is None else ['No segment covers this valid instant'],'validAt':validAt,'knownAt':knownAt,'knownSequence':knownSequence,'commit':None if c is None else {'revision':c['request']['revision'],'sequence':c['sequence'],'recordedAt':c['recordedAt'],'digest':digest(c)},'segment':None,'archivedAsKnown':False if c is None else c['request']['operation']=='archive','archiveNow':bool(ledger['commits'] and ledger['commits'][-1]['request']['operation']=='archive'),'inputDigest':digest(ledger),'policyDigest':digest(config),'truth':'not-evaluated','domainValidation':'not-executed','transitionLegality':'not-evaluated'} if c: for s in c['request']['segments']: if s['validFrom']<=validAt and (s['validTo'] is None or validAt=previous['recordedAt'],'Snapshot receipt precedes predecessor') require(fact['factId']!=previous['factId'] and fact['supersedes']==[previous['factId']],'Wrong snapshot predecessor identity') require(fact['provenance']['previousSnapshotDigest']==digest(previous['value']),'Wrong previous snapshot digest') validate_extension(previous['value'],ledger,now=now) return True END FILE temporal.py FILE test_temporal.py original_sha256=568217d983c587d30779b4bba2571dbddad3d02330c770294a48931365b46204 import copy,json,unittest,datetime,hashlib from pathlib import Path import temporal as t NOW='2026-09-21T18:00:00Z' T1='2026-01-10T00:00:00Z';T2='2026-02-10T00:00:00Z';T3='2026-03-10T00:00:00Z' def pin(name):return {'id':'urn:synthetic:'+name,'version':'1.0.0','digest':t.digest(name)} def value(name):return {'id':'urn:synthetic:value:'+name,'revision':'urn:synthetic:value:'+name+':r1','digest':t.digest(name)} def fixture(name='startup'): schema=pin('assignment-schema');profile=pin('assignment-state') config={'dimension':'urn:synthetic:dimension:'+name,'timeline':'urn:synthetic:timeline:'+name,'scope':{'subject':'urn:synthetic:assignment:'+name,'predicate':'urn:synthetic:assigned-team','context':'urn:synthetic:scope:'+name},'validFrom':'2026-01-01T00:00:00Z','validUntil':'2027-01-01T00:00:00Z','writer':'urn:synthetic:master:'+name,'readers':['urn:synthetic:reader'],'purposes':['research'],'acceptedSchemas':[schema],'acceptedStates':[{'profile':profile,'axis':'urn:synthetic:assignment-status','codes':['active','suspended']}]} def seg(start,end,team):return {'validFrom':start,'validTo':end,'value':value(team),'schema':schema,'state':{'profile':profile,'axis':'urn:synthetic:assignment-status','code':'active'}} q1={'key':'urn:synthetic:key:'+name+':1','revision':'urn:synthetic:revision:'+name+':1','expectedHead':None,'operation':'record','reason':'Synthetic initial source report','sourceRecordedAt':'2026-01-05T00:00:00Z','segments':[seg('2026-01-01T00:00:00Z',None,'team-a')]} e=t.empty(config);one=t.admit(e,q1,config,actor=config['writer'],now=T1) q2={'key':'urn:synthetic:key:'+name+':2','revision':'urn:synthetic:revision:'+name+':2','expectedHead':t.head(one),'operation':'correct','reason':'Synthetic late correction received February 10','sourceRecordedAt':'2026-01-20T00:00:00Z','segments':[seg('2026-01-01T00:00:00Z','2026-01-20T00:00:00Z','team-a'),seg('2026-01-20T00:00:00Z',None,'team-b')]} if name=='group': # Separate scope prevents a local assignment correction from becoming a global employment change. config['scope']['context']='urn:synthetic:group:matrix-assignment';one['scope']=copy.deepcopy(config['scope']);e['scope']=copy.deepcopy(config['scope']) if name=='ai-team': config['scope']['predicate']='urn:synthetic:deployment-artifact';config['scope']['subject']='urn:synthetic:deployment:staging' one['scope']=copy.deepcopy(config['scope']);e['scope']=copy.deepcopy(config['scope']) deployment_schema=pin('deployment-binding-schema');deployment_profile=pin('deployment-state') config['acceptedSchemas']=[deployment_schema];config['acceptedStates']=[{'profile':deployment_profile,'axis':'urn:synthetic:deployment-status','codes':['serving','draining']}] for q in [q1,q2]: for s in q['segments']: s['value']=value('model-build-11' if s['value']==value('team-a') else 'model-build-12');s['schema']=deployment_schema;s['state']={'profile':deployment_profile,'axis':'urn:synthetic:deployment-status','code':'serving'} one=t.admit(e,q1,config,actor=config['writer'],now=T1);q2['expectedHead']=t.head(one) one=t.admit(e,q1,config,actor=config['writer'],now=T1);q2['expectedHead']=t.head(one) two=t.admit(one,q2,config,actor=config['writer'],now=T2) return config,e,one,two,q1,q2 class TemporalTests(unittest.TestCase): def setUp(self):self.cfg,self.empty,self.one,self.two,self.q1,self.q2=fixture() def read(self,ledger=None,**kw): args=dict(actor='urn:synthetic:reader',purpose='research',validAt='2026-02-01T00:00:00Z',knownAt=NOW,now=NOW);args.update(kw) return t.resolve(self.two if ledger is None else ledger,self.cfg,**args) def write(self,q=None,ledger=None,**kw): args=dict(actor=self.cfg['writer'],now=T2);args.update(kw) return t.admit(self.one if ledger is None else ledger,self.q2 if q is None else q,self.cfg,**args) def bad(self,change): q=copy.deepcopy(self.q2);change(q) with self.assertRaises(t.Invalid):self.write(q) def test_bitemporal_as_known(self):self.assertEqual(self.read(knownAt='2026-01-31T00:00:00Z')['segment']['value'],value('team-a')) def test_bitemporal_corrected(self):self.assertEqual(self.read()['segment']['value'],value('team-b')) def test_before_correction_boundary(self):self.assertEqual(self.read(validAt='2026-01-19T23:59:59Z')['segment']['value'],value('team-a')) def test_exact_half_open_boundary(self):self.assertEqual(self.read(validAt='2026-01-20T00:00:00Z')['segment']['value'],value('team-b')) def test_before_first_receipt(self):self.assertEqual(self.read(knownAt='2026-01-09T23:59:59Z')['status'],'insufficient-context') def test_before_valid_coverage(self):self.assertEqual(self.read(validAt='2025-12-31T00:00:00Z')['status'],'insufficient-context') def test_empty_register(self):self.assertEqual(self.read(self.empty)['status'],'insufficient-context') def test_gap_unknown(self): q=copy.deepcopy(self.q2);q['segments'][1]['validFrom']='2026-02-03T00:00:00Z';out=self.write(q);self.assertEqual(self.read(out)['status'],'insufficient-context') def test_source_time_does_not_backdate_receipt(self):self.assertEqual(self.read(knownAt='2026-02-01T00:00:00Z')['commit']['recordedAt'],T1) def test_same_second_sequence(self): q=copy.deepcopy(self.q2);q['sourceRecordedAt']=None;out=self.write(q,now=T1) self.assertEqual(self.read(out,knownAt=T1)['segment']['value'],value('team-b')) self.assertEqual(self.read(out,knownAt=T1,knownSequence=1)['segment']['value'],value('team-a')) def test_zero_sequence_cut(self):self.assertEqual(self.read(knownSequence=0)['status'],'insufficient-context') def test_bad_sequence_cut(self): for cut in [True,1.0,-1,3]: with self.subTest(cut=cut),self.assertRaises(t.Invalid):self.read(knownSequence=cut) def test_future_known_rejected(self): with self.assertRaises(t.Invalid):self.read(knownAt='2027-01-01T00:00:00Z') def test_admission_rejects_input_ahead_of_host_clock(self): q=copy.deepcopy(self.q2);q['sourceRecordedAt']=None with self.assertRaises(t.Invalid):self.write(q,now='2026-01-09T00:00:00Z') def test_future_receipt_import(self): with self.assertRaises(t.Invalid):t.validate_ledger(self.two,now=T1) def test_forged_receipt_request_rejected(self):self.bad(lambda q:q.update(recordedAt=T1)) def test_source_record_after_receipt(self):self.bad(lambda q:q.update(sourceRecordedAt=NOW)) def test_overlap(self):self.bad(lambda q:q['segments'][1].update(validFrom='2026-01-19T00:00:00Z')) def test_open_interval_not_last(self):self.bad(lambda q:q['segments'][0].update(validTo=None)) def test_zero_interval(self):self.bad(lambda q:q['segments'][0].update(validTo=q['segments'][0]['validFrom'])) def test_reverse_interval(self):self.bad(lambda q:q['segments'][0].update(validTo='2025-01-01T00:00:00Z')) def test_unsupported_times(self): for x in ['2026-02-30T00:00:00Z','2026-01-01T00:00:00+00:00','2026-01-01T00:00:00.1Z','2026-01-01','2026-01-01T00:00:60Z','2026-01-01T00:00:00Z','2026-01-01T00:00:00Z\n']: with self.subTest(x=x):self.bad(lambda q:q['segments'][0].update(validFrom=x)) def test_future_valid_allowed(self):self.assertEqual(self.read(validAt='2028-01-01T00:00:00Z')['status'],'recorded-assertion') def test_replay_preserves_first_receipt(self):self.assertEqual(self.write(self.q2,self.two,now=T3),self.two) def test_old_replay_after_new_commit(self):self.assertEqual(self.write(self.q1,self.two,now=T3),self.two) def test_conflicting_replay(self): q=copy.deepcopy(self.q2);q['reason']='Different' with self.assertRaises(t.Invalid):self.write(q,self.two,now=T3) def test_head_conflict(self):self.bad(lambda q:q.update(expectedHead=None)) def test_reused_revision(self):self.bad(lambda q:q.update(revision=self.q1['revision'])) def test_writer_denied(self): with self.assertRaises(t.Invalid):self.write(actor='urn:synthetic:competitor') def test_replay_rechecks_current_writer(self): self.cfg['writer']='urn:synthetic:new-writer' with self.assertRaises(t.Invalid):self.write(self.q2,self.two,actor='urn:synthetic:master:startup',now=T3) def test_denied_read_before_diagnostics(self): with self.assertRaisesRegex(t.Invalid,'Read denied'):self.read({'secret':'invalid'},actor='urn:synthetic:outsider',validAt='bad') def test_denied_purpose(self): with self.assertRaisesRegex(t.Invalid,'Read denied'):self.read(purpose='advertising') def test_expired_policy(self): with self.assertRaises(t.Invalid):self.read(now='2027-01-01T00:00:00Z') def test_scope_mismatch(self): self.cfg['scope']['context']='urn:synthetic:other' with self.assertRaises(t.Invalid):self.read() def test_schema_is_not_state(self):self.bad(lambda q:q['segments'][0]['schema'].update(version='active')) def test_unknown_schema_binding(self):self.bad(lambda q:q['segments'][0].update(schema=pin('unapproved'))) def test_unknown_state(self):self.bad(lambda q:q['segments'][0]['state'].update(code='completed')) def test_state_is_optional(self): q=copy.deepcopy(self.q2);q['segments'][0]['state']=None;self.write(q) def test_binding_repoint_in_history(self): q=copy.deepcopy(self.q2);q['segments'][0]['schema']['digest']=t.digest('changed');self.cfg['acceptedSchemas']=[q['segments'][0]['schema']] with self.assertRaises(t.Invalid):self.write(q) def test_payload_revision_repoint(self):self.bad(lambda q:q['segments'][0]['value'].update(digest=t.digest('changed'))) def test_new_schema_version_does_not_rewrite_old(self): q=copy.deepcopy(self.q2);b=copy.deepcopy(q['segments'][1]['schema']);b['version']='2.0.0';b['digest']=t.digest('schema2');self.cfg['acceptedSchemas'].append(b);q['segments'][1]['schema']=b out=self.write(q);self.assertEqual(self.read(out,knownAt=T1)['segment']['schema']['version'],'1.0.0');self.assertEqual(self.read(out)['segment']['schema']['version'],'2.0.0') def archive(self): q=copy.deepcopy(self.q2);q.update(key='urn:synthetic:key:archive',revision='urn:synthetic:revision:archive',expectedHead=t.head(self.two),operation='archive',reason='Stop changes, preserve retained history');return self.write(q,self.two,now=T3),q def test_archive_retains_history(self): out,q=self.archive();self.assertEqual(out['commits'][:2],self.two['commits']);self.assertEqual(self.read(out)['segment']['value'],value('team-b'));self.assertTrue(self.read(out)['archivedAsKnown']);self.assertFalse(self.read(out,knownAt=T1)['archivedAsKnown']) def test_archive_replay(self): out,q=self.archive();self.assertEqual(self.write(q,out,now=NOW),out) def test_archive_cannot_rewrite(self): q=copy.deepcopy(self.q2);q['operation']='archive' with self.assertRaises(t.Invalid):self.write(q) def test_archive_terminal(self): out,_=self.archive();q=copy.deepcopy(self.q2);q.update(key='urn:synthetic:key:after',revision='urn:synthetic:revision:after',expectedHead=t.head(out)) with self.assertRaises(t.Invalid):self.write(q,out,now=NOW) def test_no_history_truncation(self): with self.assertRaises(t.Invalid):t.validate_extension(self.two,self.one,now=NOW) def test_no_prefix_rewrite(self): changed=copy.deepcopy(self.one);changed['commits'][0]['request']['reason']='rewrite' with self.assertRaises(t.Invalid):t.validate_extension(self.one,changed,now=NOW) def test_float_receipt_sequence(self): changed=copy.deepcopy(self.one);changed['commits'][0]['sequence']=1.0 with self.assertRaises(t.Invalid):t.validate_ledger(changed,now=NOW) def test_digest_trailing_newline(self):self.bad(lambda q:q['segments'][0]['value'].update(digest=q['segments'][0]['value']['digest']+'\n')) def test_closed_schema(self):self.bad(lambda q:q.update(secret='unsupported')) def test_lossless_roundtrip(self):self.assertEqual(t.migrate(self.two,'0.1.0',now=NOW),self.two) def test_downgrade_rejected(self): with self.assertRaises(t.Invalid):t.migrate(self.two,'0.0.9',now=NOW) def test_no_implicit_truth_or_transition(self): r=self.read();self.assertEqual(r['truth'],'not-evaluated');self.assertEqual(r['transitionLegality'],'not-evaluated');self.assertEqual(r['domainValidation'],'not-executed') def test_mutable_return_not_input(self): r=self.read();r['segment']['value']['id']='urn:synthetic:changed';self.assertEqual(self.read()['segment']['value'],value('team-b')) def test_three_profiles(self): for name in ['startup','group','ai-team']: with self.subTest(name=name):c,e,a,b,_,_=fixture(name);t.validate_extension(a,b,now=NOW);self.assertEqual(b['scope'],c['scope']) def test_bounded_append_sequences_preserve_pinned_history(self): root=copy.deepcopy(self.two);saved=self.read(root,knownAt=T2,knownSequence=2)['segment'] for i in range(3,33): q=copy.deepcopy(self.q2);q.update(key='urn:synthetic:key:'+str(i),revision='urn:synthetic:revision:'+str(i),expectedHead=t.head(root));q['segments'][1]['value']=value('team-'+str(i)) root=self.write(q,root,now=T2);self.assertEqual(self.read(root,knownAt=T2,knownSequence=2)['segment'],saved) def test_empty_snapshot_is_not_false(self): q=copy.deepcopy(self.q2);q['segments']=[];self.assertEqual(self.read(self.write(q))['status'],'insufficient-context') def test_segment_overflow(self):self.bad(lambda q:q.update(segments=q['segments']*51)) def test_unavailable_format_checker(self): from unittest.mock import patch with patch.object(t.FormatChecker,'checkers',{}),self.assertRaises(t.Invalid):self.read() def test_new_binding_must_not_mutate_config_history(self): self.cfg['acceptedSchemas'].append({**self.cfg['acceptedSchemas'][0],'digest':t.digest('different')}) with self.assertRaises(t.Invalid):self.read() def test_archive_after_schema_retirement(self): self.cfg['acceptedSchemas']=[pin('replacement')];self.cfg['acceptedStates']=[];out,_=self.archive();self.assertTrue(self.read(out)['archivedAsKnown']) def test_retained_segments_after_pin_retirement(self): self.cfg['acceptedSchemas']=[pin('replacement')];self.cfg['acceptedStates']=[];q=copy.deepcopy(self.q2);q.update(key='urn:synthetic:new:key',revision='urn:synthetic:new:revision',expectedHead=t.head(self.two),reason='Clarify source metadata only');self.write(q,self.two,now=T3) def test_changed_interval_is_new_use_of_retired_pin(self): self.cfg['acceptedSchemas']=[pin('replacement')];q=copy.deepcopy(self.q2);q.update(key='urn:synthetic:new:key',revision='urn:synthetic:new:revision',expectedHead=t.head(self.two));q['segments'][1]['validTo']='2026-09-01T00:00:00Z' with self.assertRaises(t.Invalid):self.write(q,self.two,now=T3) def test_transplanted_history_rejected(self): for field in ['dimension','timeline','scope']: root=copy.deepcopy(self.two);root[field]='urn:synthetic:transplant' if field!='scope' else {**root['scope'],'context':'urn:synthetic:transplant'} with self.subTest(field=field),self.assertRaisesRegex(t.Invalid,'transplanted'):t.validate_ledger(root,now=NOW) def test_imported_clock_regression_branch(self): root=copy.deepcopy(self.two);root['commits'][1]['recordedAt']='2026-01-09T00:00:00Z' with self.assertRaisesRegex(t.Invalid,'moved backwards'):t.validate_ledger(root,now=NOW) def test_segment_bound_without_overlap(self): q=copy.deepcopy(self.q2);q['segments']=[];base=datetime.datetime(2026,1,1) for i in range(101): s=copy.deepcopy(self.q2['segments'][0]);s.update(validFrom=(base+datetime.timedelta(seconds=i)).strftime('%Y-%m-%dT%H:%M:%SZ'),validTo=(base+datetime.timedelta(seconds=i+1)).strftime('%Y-%m-%dT%H:%M:%SZ'));q['segments'].append(s) with self.assertRaisesRegex(t.Invalid,'Closed schema'):self.write(q) def snapshots(self): def f(root,n,prev): return dict(factId='urn:synthetic:native:'+str(n),path='temporal.timeline.snapshot',value=copy.deepcopy(root),subjectId=root['timeline'],provenance=dict(snapshotDigest=t.digest(root),previousSnapshotDigest=None if prev is None else t.digest(prev['value'])),supersedes=[] if prev is None else [prev['factId']],status='asserted',unit=None,recordedAt=NOW,validFrom=NOW,validTo=None) f1=f(self.one,1,None);f2=f(self.two,2,f1);archived,_=self.archive();return f1,f2,f(archived,3,f2) def snapshot(self,f,previous=None,**kw): args=dict(dimension=self.cfg['dimension'],now=NOW,previous=previous);args.update(kw);return t.validate_snapshot(f,**args) def test_snapshot_genesis_and_successors(self): a,b,c=self.snapshots();self.snapshot(a);self.snapshot(b,a);self.snapshot(c,b) def test_snapshot_missing_envelope(self): a,_,_=self.snapshots();del a['recordedAt'] with self.assertRaisesRegex(t.Invalid,'Incomplete snapshot envelope'):self.snapshot(a) def test_snapshot_missing_provenance(self): a,_,_=self.snapshots();a['provenance']={} with self.assertRaisesRegex(t.Invalid,'Incomplete snapshot provenance'):self.snapshot(a) def test_snapshot_storage_state(self): for change in [dict(status='retracted'),dict(unit='kg'),dict(validTo=NOW)]: a,_,_=self.snapshots();a.update(change) with self.subTest(change=change),self.assertRaisesRegex(t.Invalid,'Unsupported snapshot envelope state'):self.snapshot(a) def test_snapshot_bad_receipt_envelope(self): a,_,_=self.snapshots();a['validFrom']=T1 with self.assertRaisesRegex(t.Invalid,'Invalid snapshot receipt envelope'):self.snapshot(a) def test_snapshot_precedes_inner(self): a,_,_=self.snapshots();a.update(recordedAt='2026-01-09T00:00:00Z',validFrom='2026-01-09T00:00:00Z') with self.assertRaisesRegex(t.Invalid,'Snapshot precedes inner receipt'):self.snapshot(a) def test_snapshot_later_native_storage_does_not_rewrite_host_time(self): a,_,_=self.snapshots();self.snapshot(a);self.assertEqual(a['value']['commits'][0]['recordedAt'],T1);self.assertEqual(a['recordedAt'],NOW) def test_snapshot_wrong_path_or_subject(self): for field,message in [('path','Wrong native path'),('subjectId','Wrong timeline subject')]: a,_,_=self.snapshots();a[field]='urn:synthetic:wrong' with self.subTest(field=field),self.assertRaisesRegex(t.Invalid,message):self.snapshot(a) def test_snapshot_wrong_dimension(self): a,_,_=self.snapshots() with self.assertRaisesRegex(t.Invalid,'Wrong native Dimension'):self.snapshot(a,dimension='urn:synthetic:other') def test_snapshot_bad_digest(self): a,_,_=self.snapshots();a['provenance']['snapshotDigest']=t.digest('bad') with self.assertRaisesRegex(t.Invalid,'Snapshot digest mismatch'):self.snapshot(a) def test_snapshot_unexpected_predecessor(self): _,b,_=self.snapshots() with self.assertRaisesRegex(t.Invalid,'Unexpected predecessor'):self.snapshot(b) def test_snapshot_previous_nongenesis_envelope_checked(self): for change in [dict(status='retracted'),dict(unit='kg'),dict(validTo=NOW)]: _,b,c=self.snapshots();b.update(change) with self.subTest(change=change),self.assertRaisesRegex(t.Invalid,'Unsupported snapshot envelope state'):self.snapshot(c,b) def test_snapshot_previous_missing_fields(self): for field in ['provenance','path']: _,b,c=self.snapshots();del b[field] with self.subTest(field=field),self.assertRaisesRegex(t.Invalid,'Incomplete snapshot envelope'):self.snapshot(c,b) def test_snapshot_previous_wrong_binding(self): _,b,c=self.snapshots();b['subjectId']='urn:synthetic:wrong' with self.assertRaisesRegex(t.Invalid,'Wrong timeline subject'):self.snapshot(c,b) def test_snapshot_previous_wrong_digest(self): _,b,c=self.snapshots();b['provenance']['snapshotDigest']=t.digest('wrong') with self.assertRaisesRegex(t.Invalid,'Snapshot digest mismatch'):self.snapshot(c,b) def test_snapshot_previous_hash_link(self): a,b,_=self.snapshots();b['provenance']['previousSnapshotDigest']=t.digest('wrong') with self.assertRaisesRegex(t.Invalid,'Wrong previous snapshot digest'):self.snapshot(b,a) def test_snapshot_predecessor_identity(self): a,b,_=self.snapshots();b['factId']=a['factId'] with self.assertRaisesRegex(t.Invalid,'Wrong snapshot predecessor identity'):self.snapshot(b,a) def test_snapshot_storage_clock_regression(self): a,b,_=self.snapshots();b.update(recordedAt=T2,validFrom=T2) with self.assertRaisesRegex(t.Invalid,'Snapshot receipt precedes predecessor'):self.snapshot(b,a) def test_scope_gate_before_history_diagnostics(self): self.cfg['scope']['context']='urn:synthetic:another';root=copy.deepcopy(self.two);root['commits'][1]['sequence']=9 with self.assertRaisesRegex(t.Invalid,'Wrong governed scope'):self.read(root) with self.assertRaisesRegex(t.Invalid,'Wrong governed scope'):self.write(ledger=root) def test_forward_clock_excursion_needs_external_recovery(self): q=copy.deepcopy(self.q2);q.update(key='urn:synthetic:future:key',revision='urn:synthetic:future:revision',expectedHead=t.head(self.two));root=self.write(q,self.two,now='2026-12-31T00:00:00Z') with self.assertRaisesRegex(t.Invalid,'Future receipt'):self.read(root) with self.assertRaisesRegex(t.Invalid,'Future receipt'):self.write(q,root,now=NOW) if __name__=='__main__': suite=unittest.defaultTestLoader.loadTestsFromTestCase(TemporalTests);result=unittest.TextTestRunner(verbosity=1).run(suite) Path('test-results.json').write_text(json.dumps({'passed':result.wasSuccessful(),'tests':result.testsRun,'failures':len(result.failures),'errors':len(result.errors),'executedAt':datetime.datetime.now(datetime.timezone.utc).isoformat(),'codeDigest':'sha256:'+hashlib.sha256(Path(t.__file__).read_bytes()).hexdigest()},indent=2)+'\n',encoding='utf-8') raise SystemExit(not result.wasSuccessful()) END FILE test_temporal.py FILE temporal.schema.json original_sha256=23868f95c19b20ecc92322949df199b5b86bb4177ee855f743e8f54217297ba3 {"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://ver.cy/models/enterprise-temporal-history/versions/0.1.0/temporal.schema.json","type":"object","properties":{"format":{"const":"vercy-enterprise-temporal"},"version":{"const":"0.1.0"},"dimension":{"type":"string","format":"uri","minLength":3,"maxLength":512},"timeline":{"type":"string","format":"uri","minLength":3,"maxLength":512},"scope":{"type":"object","properties":{"subject":{"type":"string","format":"uri","minLength":3,"maxLength":512},"predicate":{"type":"string","format":"uri","minLength":3,"maxLength":512},"context":{"type":"string","format":"uri","minLength":3,"maxLength":512}},"required":["subject","predicate","context"],"additionalProperties":false},"commits":{"type":"array","items":{"type":"object","properties":{"sequence":{"type":"integer","minimum":1,"maximum":1000},"recordedAt":{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$","format":"date-time"},"writer":{"type":"string","format":"uri","minLength":3,"maxLength":512},"scopeDigest":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"request":{"type":"object","properties":{"key":{"type":"string","format":"uri","minLength":3,"maxLength":512},"revision":{"type":"string","format":"uri","minLength":3,"maxLength":512},"expectedHead":{"anyOf":[{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},{"type":"null"}]},"operation":{"enum":["record","correct","archive"]},"reason":{"type":"string","minLength":1,"maxLength":2048},"sourceRecordedAt":{"anyOf":[{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$","format":"date-time"},{"type":"null"}]},"segments":{"type":"array","items":{"type":"object","properties":{"validFrom":{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$","format":"date-time"},"validTo":{"anyOf":[{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$","format":"date-time"},{"type":"null"}]},"value":{"type":"object","properties":{"id":{"type":"string","format":"uri","minLength":3,"maxLength":512},"revision":{"type":"string","format":"uri","minLength":3,"maxLength":512},"digest":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}},"required":["id","revision","digest"],"additionalProperties":false},"schema":{"type":"object","properties":{"id":{"type":"string","format":"uri","minLength":3,"maxLength":512},"version":{"type":"string","pattern":"^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$","maxLength":50},"digest":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}},"required":["id","version","digest"],"additionalProperties":false},"state":{"anyOf":[{"type":"object","properties":{"profile":{"type":"object","properties":{"id":{"type":"string","format":"uri","minLength":3,"maxLength":512},"version":{"type":"string","pattern":"^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$","maxLength":50},"digest":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}},"required":["id","version","digest"],"additionalProperties":false},"axis":{"type":"string","format":"uri","minLength":3,"maxLength":512},"code":{"type":"string","minLength":1,"maxLength":2048}},"required":["profile","axis","code"],"additionalProperties":false},{"type":"null"}]}},"required":["validFrom","validTo","value","schema","state"],"additionalProperties":false},"minItems":0,"maxItems":100}},"required":["key","revision","expectedHead","operation","reason","sourceRecordedAt","segments"],"additionalProperties":false}},"required":["sequence","recordedAt","writer","scopeDigest","request"],"additionalProperties":false},"minItems":0,"maxItems":1000}},"required":["format","version","dimension","timeline","scope","commits"],"additionalProperties":false,"$defs":{"ledger":{"type":"object","properties":{"format":{"const":"vercy-enterprise-temporal"},"version":{"const":"0.1.0"},"dimension":{"type":"string","format":"uri","minLength":3,"maxLength":512},"timeline":{"type":"string","format":"uri","minLength":3,"maxLength":512},"scope":{"type":"object","properties":{"subject":{"type":"string","format":"uri","minLength":3,"maxLength":512},"predicate":{"type":"string","format":"uri","minLength":3,"maxLength":512},"context":{"type":"string","format":"uri","minLength":3,"maxLength":512}},"required":["subject","predicate","context"],"additionalProperties":false},"commits":{"type":"array","items":{"type":"object","properties":{"sequence":{"type":"integer","minimum":1,"maximum":1000},"recordedAt":{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$","format":"date-time"},"writer":{"type":"string","format":"uri","minLength":3,"maxLength":512},"scopeDigest":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"request":{"type":"object","properties":{"key":{"type":"string","format":"uri","minLength":3,"maxLength":512},"revision":{"type":"string","format":"uri","minLength":3,"maxLength":512},"expectedHead":{"anyOf":[{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},{"type":"null"}]},"operation":{"enum":["record","correct","archive"]},"reason":{"type":"string","minLength":1,"maxLength":2048},"sourceRecordedAt":{"anyOf":[{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$","format":"date-time"},{"type":"null"}]},"segments":{"type":"array","items":{"type":"object","properties":{"validFrom":{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$","format":"date-time"},"validTo":{"anyOf":[{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$","format":"date-time"},{"type":"null"}]},"value":{"type":"object","properties":{"id":{"type":"string","format":"uri","minLength":3,"maxLength":512},"revision":{"type":"string","format":"uri","minLength":3,"maxLength":512},"digest":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}},"required":["id","revision","digest"],"additionalProperties":false},"schema":{"type":"object","properties":{"id":{"type":"string","format":"uri","minLength":3,"maxLength":512},"version":{"type":"string","pattern":"^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$","maxLength":50},"digest":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}},"required":["id","version","digest"],"additionalProperties":false},"state":{"anyOf":[{"type":"object","properties":{"profile":{"type":"object","properties":{"id":{"type":"string","format":"uri","minLength":3,"maxLength":512},"version":{"type":"string","pattern":"^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$","maxLength":50},"digest":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}},"required":["id","version","digest"],"additionalProperties":false},"axis":{"type":"string","format":"uri","minLength":3,"maxLength":512},"code":{"type":"string","minLength":1,"maxLength":2048}},"required":["profile","axis","code"],"additionalProperties":false},{"type":"null"}]}},"required":["validFrom","validTo","value","schema","state"],"additionalProperties":false},"minItems":0,"maxItems":100}},"required":["key","revision","expectedHead","operation","reason","sourceRecordedAt","segments"],"additionalProperties":false}},"required":["sequence","recordedAt","writer","scopeDigest","request"],"additionalProperties":false},"minItems":0,"maxItems":1000}},"required":["format","version","dimension","timeline","scope","commits"],"additionalProperties":false},"config":{"type":"object","properties":{"dimension":{"type":"string","format":"uri","minLength":3,"maxLength":512},"timeline":{"type":"string","format":"uri","minLength":3,"maxLength":512},"scope":{"type":"object","properties":{"subject":{"type":"string","format":"uri","minLength":3,"maxLength":512},"predicate":{"type":"string","format":"uri","minLength":3,"maxLength":512},"context":{"type":"string","format":"uri","minLength":3,"maxLength":512}},"required":["subject","predicate","context"],"additionalProperties":false},"validFrom":{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$","format":"date-time"},"validUntil":{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$","format":"date-time"},"writer":{"type":"string","format":"uri","minLength":3,"maxLength":512},"readers":{"type":"array","items":{"type":"string","format":"uri","minLength":3,"maxLength":512},"minItems":1,"maxItems":100},"purposes":{"type":"array","items":{"type":"string","minLength":1,"maxLength":2048},"minItems":1,"maxItems":100},"acceptedSchemas":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uri","minLength":3,"maxLength":512},"version":{"type":"string","pattern":"^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$","maxLength":50},"digest":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}},"required":["id","version","digest"],"additionalProperties":false},"minItems":1,"maxItems":100},"acceptedStates":{"type":"array","items":{"type":"object","properties":{"profile":{"type":"object","properties":{"id":{"type":"string","format":"uri","minLength":3,"maxLength":512},"version":{"type":"string","pattern":"^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$","maxLength":50},"digest":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}},"required":["id","version","digest"],"additionalProperties":false},"axis":{"type":"string","format":"uri","minLength":3,"maxLength":512},"codes":{"type":"array","items":{"type":"string","minLength":1,"maxLength":2048},"minItems":1,"maxItems":100}},"required":["profile","axis","codes"],"additionalProperties":false},"minItems":0,"maxItems":100}},"required":["dimension","timeline","scope","validFrom","validUntil","writer","readers","purposes","acceptedSchemas","acceptedStates"],"additionalProperties":false},"request":{"type":"object","properties":{"key":{"type":"string","format":"uri","minLength":3,"maxLength":512},"revision":{"type":"string","format":"uri","minLength":3,"maxLength":512},"expectedHead":{"anyOf":[{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},{"type":"null"}]},"operation":{"enum":["record","correct","archive"]},"reason":{"type":"string","minLength":1,"maxLength":2048},"sourceRecordedAt":{"anyOf":[{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$","format":"date-time"},{"type":"null"}]},"segments":{"type":"array","items":{"type":"object","properties":{"validFrom":{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$","format":"date-time"},"validTo":{"anyOf":[{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$","format":"date-time"},{"type":"null"}]},"value":{"type":"object","properties":{"id":{"type":"string","format":"uri","minLength":3,"maxLength":512},"revision":{"type":"string","format":"uri","minLength":3,"maxLength":512},"digest":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}},"required":["id","revision","digest"],"additionalProperties":false},"schema":{"type":"object","properties":{"id":{"type":"string","format":"uri","minLength":3,"maxLength":512},"version":{"type":"string","pattern":"^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$","maxLength":50},"digest":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}},"required":["id","version","digest"],"additionalProperties":false},"state":{"anyOf":[{"type":"object","properties":{"profile":{"type":"object","properties":{"id":{"type":"string","format":"uri","minLength":3,"maxLength":512},"version":{"type":"string","pattern":"^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$","maxLength":50},"digest":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}},"required":["id","version","digest"],"additionalProperties":false},"axis":{"type":"string","format":"uri","minLength":3,"maxLength":512},"code":{"type":"string","minLength":1,"maxLength":2048}},"required":["profile","axis","code"],"additionalProperties":false},{"type":"null"}]}},"required":["validFrom","validTo","value","schema","state"],"additionalProperties":false},"minItems":0,"maxItems":100}},"required":["key","revision","expectedHead","operation","reason","sourceRecordedAt","segments"],"additionalProperties":false},"segment":{"type":"object","properties":{"validFrom":{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$","format":"date-time"},"validTo":{"anyOf":[{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$","format":"date-time"},{"type":"null"}]},"value":{"type":"object","properties":{"id":{"type":"string","format":"uri","minLength":3,"maxLength":512},"revision":{"type":"string","format":"uri","minLength":3,"maxLength":512},"digest":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}},"required":["id","revision","digest"],"additionalProperties":false},"schema":{"type":"object","properties":{"id":{"type":"string","format":"uri","minLength":3,"maxLength":512},"version":{"type":"string","pattern":"^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$","maxLength":50},"digest":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}},"required":["id","version","digest"],"additionalProperties":false},"state":{"anyOf":[{"type":"object","properties":{"profile":{"type":"object","properties":{"id":{"type":"string","format":"uri","minLength":3,"maxLength":512},"version":{"type":"string","pattern":"^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$","maxLength":50},"digest":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}},"required":["id","version","digest"],"additionalProperties":false},"axis":{"type":"string","format":"uri","minLength":3,"maxLength":512},"code":{"type":"string","minLength":1,"maxLength":2048}},"required":["profile","axis","code"],"additionalProperties":false},{"type":"null"}]}},"required":["validFrom","validTo","value","schema","state"],"additionalProperties":false},"SchemaBinding":{"type":"object","properties":{"id":{"type":"string","format":"uri","minLength":3,"maxLength":512},"version":{"type":"string","pattern":"^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$","maxLength":50},"digest":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}},"required":["id","version","digest"],"additionalProperties":false},"StateReference":{"type":"object","properties":{"profile":{"type":"object","properties":{"id":{"type":"string","format":"uri","minLength":3,"maxLength":512},"version":{"type":"string","pattern":"^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$","maxLength":50},"digest":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}},"required":["id","version","digest"],"additionalProperties":false},"axis":{"type":"string","format":"uri","minLength":3,"maxLength":512},"code":{"type":"string","minLength":1,"maxLength":2048}},"required":["profile","axis","code"],"additionalProperties":false}}} END FILE temporal.schema.json FILE model-spec.md original_sha256=c9e7e9eb5ed6fe0dcd573eba2c8796f79b21b993239bb1d0977d41f29fe2f86a # Enterprise Temporal History 0.1.0 Original bounded companion for a Company Dimension, with reviewable-draft assurance. This is a history of **recorded assertions**, not proof of what people knew, what actually happened, or whether a domain action was lawful. No SQL, SCXML, OWL-Time, ISO or complete parent-model conformance is claimed. ## Boundary, identities and fields One Timeline aggregate belongs to exactly one Dimension and one fixed `(subject, predicate, context)` FactScope. All four references and the timeline ID are required scheme-bearing RFC 3986 URIs (fragments are permitted). References are opaque: no automatic fetch, normalization, alias, company identity, or master discovery. A separate scope is required for another legal entity, environment, competing master or simultaneous value. Host governance must prevent two current timelines being registered as the same scope; this single-aggregate reference cannot discover them. | Type | Identity and cardinality | Owner and lifecycle | |---|---|---| | Timeline | Independently assigned `timeline` URI; exactly one scope, 0..1000 commits | Configured host master; empty → open → archived. No reopen or erase operation | | TimelineCommit | Opaque revision URI and scope-local idempotency key; contiguous positive receipt sequence; exactly one complete snapshot | Host assigns receipt and writer; immutable once admitted. Not a domain event or artifact revision | | ValidSegment | Embedded value at a position in a commit; 0..100 per snapshot; one interval, one external value pin, one schema binding, optional state reference | Domain master asserts effective interval. No independently editable segment identity | | SchemaBinding | Value tuple `(id, version, digest)` | External schema publisher owns meaning; current host config accepts exact tuple for new writes. Binding is immutable within history | | StateReference | One profile binding, one axis URI, one code | Domain profile owner defines code. Membership only; no statechart execution, transition event or legality inference | | TimelineAnswer | Ephemeral derived view for one scope and explicit cutoffs | Current host reader/purpose authorization; no new master or operational permission | `temporal.schema.json` is the closed field/type/cardinality contract. All keys shown are required; optional concepts use explicit null. Unknown keys reject. External value pin requires an ID URI, a distinct-purpose opaque revision URI, and declared sha256 digest. This reference does not fetch the payload, recompute its external digest, validate its domain schema, authenticate the source, or establish the value's truth. The same external `(id,revision)` cannot be declared with different digests in one history. IDs and digests do not prove equality of real-world objects. Schema/profile `version` uses the deliberately narrow `normal-semver-triplet` grammar: three nonnegative ASCII integers separated by dots, no leading zeroes except zero, prerelease/build parts unsupported. This is only a pin grammar; version order never proves compatibility. `active` is a valid domain code only under an accepted vocabulary, never a schema version. External object revision, timeline revision, schema version and domain state occupy separate fields. A schema pin ID/version cannot silently acquire different bytes. Changing a declared schema version requires an exact accepted new tuple; old segments retain their original pins. Historical reads do not reinterpret records using the current schema. A new snapshot may explicitly bind the same opaque payload to a different accepted schema or state profile; this is a new interpretation declaration requiring the commit reason, not a payload conversion or proof of compatibility. Earlier snapshots retain the earlier interpretation. Each commit includes `sequence`, `recordedAt`, `writer`, a `scopeDigest` over the complete immutable header, and the exact request. The scope digest binds even the genesis commit to Dimension, timeline and context; transplanting an unchanged chain under a new header fails consistency validation. It is not an authentication proof. Request has `key`, `revision`, `expectedHead`, `operation`, `reason`, nullable `sourceRecordedAt`, and complete `segments`. `reason` is attributed explanatory text, not a validated classification of a domain event. It must explain removals, new future assertions and backdated corrections; mixed intent needs clear text or separate commits. A commit changes assertions about effective history, not the external domain object itself. `sourceRecordedAt` is source-declared metadata, may be null, and cannot follow receipt in this narrow profile. It never chooses knowledge order. Source events/observation times are outside this executable schema and may be linked through separately governed provenance records. ## Time and querying All instants use a real Gregorian date in exact ASCII `YYYY-MM-DDTHH:MM:SSZ`, seconds 00..59. No fractions, local times, explicit numeric offsets, uncertain dates or leap seconds. Reject unsupported input; never round or infer midnight/zone. A civil-date or clock conversion needs a separately reviewed adapter and pinned rules. A future **valid** instant is allowed for a scheduled assertion; a future **recorded** instant or knowledge cutoff is rejected against trusted `now`. Intervals are half-open `[validFrom, validTo)`. `validTo:null` explicitly means no asserted upper bound, not an unknown date or eternal truth. Start is always known. Empty/reversed intervals and overlaps reject; segments must be sorted. Adjacent boundaries are legal, and an open segment must be last. Gaps and an empty snapshot are permitted and return `insufficient-context`; they are not false, absent or unassigned. Explicit negation needs a separately pinned domain value. A snapshot replaces the entire scope's current asserted timeline, so omitted periods become unknown in that new recorded view. Previous snapshots remain intact. `knownAt` selects the timeline host's recorded axis. It does not mean that the native Dimension already contained the snapshot at that instant. A trusted pre-existing timeline may later be stored in a newly bootstrapped Dimension: its inner receipts remain unchanged, while the outer native fact records the later storage receipt. The acceptance fixtures explicitly simulate such a host history, not earlier native Dimension existence or knowledge. Validation does not authenticate imported receipts. The trusted host assigns non-decreasing receipt instants and strictly increasing contiguous sequences within this one timeline. Two commits in the same second are permitted; sequence resolves them. Clock regression rejects. One mistakenly admitted forward clock excursion can make reads and writes reject as `Future receipt` until the trusted clock catches up; there is no in-place repair operation. The host must check its clock against an independent trusted reference and a locally configured skew bound before every admission. On detection, quarantine the root and freeze writes. Recover through an explicitly governed new timeline identity that preserves the original root as restricted evidence, links its provenance and records the loss of continuity, or wait for verified catch-up under a current configuration. Never rewrite receipts or silently roll back. This operational migration is not implemented here. Sequences cannot compare different timelines or Dimensions; no global consistency or synchronized-clock claim exists. `resolve(... validAt, knownAt, knownSequence=None)` first checks **current** full-timeline reader and purpose permission, then checks the governed header matches before validating history and cutoffs. Trusted configuration validation precedes the reader gate; configuration errors stay inside the host and must be converted to generic endpoint errors. It chooses the latest commit with receipt ≤ knownAt and, if supplied, sequence ≤ knownSequence; then selects the segment covering validAt. No hidden defaults to “now”. `knownSequence=0` deliberately precedes all receipts. Instant-only cutoffs include all received commits in that second; they can gain a later commit with that same second. **Pin the returned sequence for stable historical content.** A supplied sequence is an additional upper bound, not an assertion that a commit existed at the timestamp. Before first receipt and uncovered periods produce distinct missing-context explanations. Denied reads raise a denial before inspecting ledger/query contents; denied is never an unknown-fact answer. Returned value remains a `recorded-assertion`, with truth, domain validation and transition legality explicitly unevaluated. The view includes commit revision/sequence/receipt/digest, exact segment, and supplied ledger/configuration digests. `archivedAsKnown` belongs to the selected history; `archiveNow` describes the current supplied root and is expressly current context. Root/policy digests and archiveNow may change when historical content remains the same. Consequently reproducibility means the selected historical commit and segment under the pinned cutoff, not byte equality of all current-context metadata. Full-history authority is required for this view; no partial redaction or hidden contrary-evidence signal is supplied. ## Writes, authority, conflicts and imports `admit(ledger, request, config, actor, now)` is a pure **trusted-host internal** function. The host authenticates actor, selects its current configuration/latest complete root/clock, and serializes durable persistence. It must enforce request size limits before parsing. Config includes exact dimension/timeline/scope, a half-open current validity interval, one writer, full-history readers, purposes and accepted schema/state pins. Claimed source authorship grants nothing. On grant rotation, old writer attribution remains; static validation does not retrospectively authenticate it. A write-only caller must receive only a receipt or generic rejection, never the function's whole returned ledger or detailed exceptions. First operation is `record`; subsequent operations are `correct` or `archive`. Host stamps every new sequence, receipt and writer; caller-supplied receipt fields are rejected. A correction must match the current head digest. Exactly unchanged segments retained from the preceding snapshot may keep retired pins for metadata maintenance or archival; a new, replaced or resegmented interval is a new use requiring currently accepted schema/state bindings. Archival itself preserves the prior snapshot exactly and remains possible after pin retirement, subject to capacity limits. Complete snapshots intentionally serialize even disjoint changes; no automatic merge, last-writer contest resolution, branch or cross-scope transaction exists. Rejected head, replay and authority attempts leave the input unchanged. **The host must durably record its own restricted conflict/rejection artifact** before reporting a conflict; this library has no conflict store or network side effect. A competing master's assertion needs a distinct governed scope and an explicit authority-resolution process. Receipt does not certify priority or correctness. Repeated key with canonically equivalent request and the same authenticated writer is a no-op, retaining the original receipt even after the head moved or archival. Current authorization/config validity is still checked. Replay compares the complete canonical request, including original expectedHead; it does not rewrite it to the new head. Same key/different request or writer rejects. Changing keys with a reused revision also rejects. Admission is not a durable transaction service. Archive appends a new commit with exactly the prior segments and freezes further new writes. It does not deactivate the subject, close business-valid periods, retract an assertion or delete retained history. An identical retry remains permitted. **Erasure, tombstones, retention schedules and legal-hold decisions are unimplemented, separate integrations.** Do not promise perpetual retention or adopt this reference where the required disposal path is absent. The host must not turn source knowledge into an earlier receipt: new admission must call admit with the actual timeline-host time and retain earlier source time only as metadata. The pure function trusts its supplied clock and cannot enforce a real-world creation floor. A structurally valid imported ledger cannot prove it was actually received then; only a trusted host archive/chain can supply that assurance. ## Integrity, native binding and migration `validate_ledger` checks shape and internal temporal/identity chain consistency against explicit trusted now. `validate_extension` additionally requires exact old headers and the entire old commit prefix. They require the host's trusted latest predecessor, cannot detect an omitted newer root, and do not establish historical authorization. Export/import the complete same-version ledger losslessly; `migrate` rejects any other contract version. No automatic schema migration, SCD2/SQL/XTDB adapter, partial export or existing-Dimension upgrade is implemented. The encoding named **vercy-python-json-v1** is UTF-8 of Python `json.dumps(sort_keys=True, separators=(',', ':'), ensure_ascii=False, allow_nan=False)`. There is no Unicode normalization. Integers for sequence must use integer JSON encoding, not Boolean or `1.0`. This profile is not RFC 8785; independent language ports must reproduce fixtures exactly. Invalid Unicode, nonfinite numbers and unsupported JSON values reject. JSON objects reaching the callable must come from an input parser that rejects duplicate keys; the bundled file loader is for trusted fixture/archive files. Hashes provide consistency against a trusted predecessor, not signatures, anti-rollback storage or origin authenticity. Bounds: ≤1000 commits, ≤100 segments per snapshot and ≤8 MiB serialized root. These are structural ceilings, not measured production capacity. Full validation scans retained history and admission copies it; host limits, concurrency, availability, monitoring and rollover/migration planning are required before production growth. Overflow refuses the operation without truncation. At the commit/byte ceiling even the extra archive commit may be refused; the host must plan migration or freeze writes through current configuration before capacity exhaustion. This reference does not guarantee an always-available archive slot. Specification dependency graph has no runtime imports. Exact WM-XCT-009, 021 and 022 references are conceptual selected-pattern alignments only. Instance references and package composition are separate graphs. No universal WM ID or parent subtype is created. A native V3 fact stores one complete timeline under `temporal.timeline.snapshot` with its own companion namespace. The native outer validator permits object-shaped values and is **not** this nested semantic validator. `validate_snapshot` takes the expected native Dimension explicitly and checks it, timeline subject, asserted/null-unit/open envelope with receipt not before the latest inner receipt, snapshot digest, an immediate successor fact ID different from its predecessor, predecessor linkage and append-only extension after native envelope validation. Both current and immediate previous envelopes receive the same semantic checks, and a successor storage receipt cannot precede its predecessor. Trusted previous snapshot selection is external. Initial installation tests fresh synthetic Dimensions; existing-Dimension migration remains deferred. ## Invariants and minimum use I01 scope/Dimension remain fixed; I02 opaque revision/schema version/state remain separate; I03 host receipt order differs from effective/source time; I04 positive half-open nonoverlapping sorted intervals; I05 gaps/pre-receipt are unknown; I06 full prior snapshot prefix survives correction; I07 request-bound idempotency retains first receipt; I08 expected-head conflict cannot overwrite; I09 current reader/purpose gate precedes diagnostics; I10 immutable schema/value pins across history; I11 archive preserves history and blocks new commits; I12 unsupported migration refuses loss; I13 explicit nested native validation; I14 no transition/permission/truth inferred; I15 equal-second history needs sequence for stable content; I16 new accepted bindings never reinterpret old content. A startup needs one governed scope, local config, a pinned domain value/schema and its first snapshot; state references are optional. A matrix group uses separate assignment scopes. An AI deployment uses an environment-qualified artifact binding; model-weight revision, deployment status, evaluation schema and record revision remain different references. No example is a claim about any real organization. The full question routes live in spec.json; missing artifacts remain insufficient context. Allowed actions describe operations to propose or execute under host authority, not grants from this package. END FILE model-spec.md FILE spec.json original_sha256=5f68da29bf40481f2303dffa8f4f48aaa051b24d35b57405d2a0b7da7b6817f7 {"metaModel":{"id":"enterprise-temporal-history","registryId":"vr.profile.enterprise-temporal-history","version":"0.1.0","name":"Enterprise Temporal History","kind":"companion-contract"},"canonicalUrl":"https://ver.cy/models/enterprise-temporal-history/versions/0.1.0/spec.json","researchAssurance":"reviewable-draft","researchContour":"EM-XCT-04","model":{"purpose":"Record effective timelines, preserve earlier recorded views and bind schemas and domain states without rewriting history."},"composition":{"runtimeImports":[],"semanticReferences":[{"id":"WM-XCT-009","version":"0.3.0-research.1","specDigest":"sha256:060511804c09ed5992e3fdf222839f97a0d340db0a2cba3c4c08aded7767e90d","relation":"selected-pattern-alignment-not-subtype"},{"id":"WM-XCT-021","version":"0.3.0-research.1","specDigest":"sha256:87c8c50f6f4c2eb3478751f01a08c6c37c6a85f97f4c056505b13cdf561314e9","relation":"selected-pattern-alignment-not-subtype"},{"id":"WM-XCT-022","version":"0.3.0-research.2","specDigest":"sha256:40ced88212f4c90690bdbb35bf2429fe627d11793bee5e587b5b10b99f49fe85","relation":"selected-pattern-alignment-not-subtype"}]},"contract":"# Enterprise Temporal History 0.1.0\n\nOriginal bounded companion for a Company Dimension, with reviewable-draft assurance. This is a history of **recorded assertions**, not proof of what people knew, what actually happened, or whether a domain action was lawful. No SQL, SCXML, OWL-Time, ISO or complete parent-model conformance is claimed.\n\n## Boundary, identities and fields\n\nOne Timeline aggregate belongs to exactly one Dimension and one fixed `(subject, predicate, context)` FactScope. All four references and the timeline ID are required scheme-bearing RFC 3986 URIs (fragments are permitted). References are opaque: no automatic fetch, normalization, alias, company identity, or master discovery. A separate scope is required for another legal entity, environment, competing master or simultaneous value. Host governance must prevent two current timelines being registered as the same scope; this single-aggregate reference cannot discover them.\n\n| Type | Identity and cardinality | Owner and lifecycle |\n|---|---|---|\n| Timeline | Independently assigned `timeline` URI; exactly one scope, 0..1000 commits | Configured host master; empty → open → archived. No reopen or erase operation |\n| TimelineCommit | Opaque revision URI and scope-local idempotency key; contiguous positive receipt sequence; exactly one complete snapshot | Host assigns receipt and writer; immutable once admitted. Not a domain event or artifact revision |\n| ValidSegment | Embedded value at a position in a commit; 0..100 per snapshot; one interval, one external value pin, one schema binding, optional state reference | Domain master asserts effective interval. No independently editable segment identity |\n| SchemaBinding | Value tuple `(id, version, digest)` | External schema publisher owns meaning; current host config accepts exact tuple for new writes. Binding is immutable within history |\n| StateReference | One profile binding, one axis URI, one code | Domain profile owner defines code. Membership only; no statechart execution, transition event or legality inference |\n| TimelineAnswer | Ephemeral derived view for one scope and explicit cutoffs | Current host reader/purpose authorization; no new master or operational permission |\n\n`temporal.schema.json` is the closed field/type/cardinality contract. All keys shown are required; optional concepts use explicit null. Unknown keys reject. External value pin requires an ID URI, a distinct-purpose opaque revision URI, and declared sha256 digest. This reference does not fetch the payload, recompute its external digest, validate its domain schema, authenticate the source, or establish the value's truth. The same external `(id,revision)` cannot be declared with different digests in one history. IDs and digests do not prove equality of real-world objects.\n\nSchema/profile `version` uses the deliberately narrow `normal-semver-triplet` grammar: three nonnegative ASCII integers separated by dots, no leading zeroes except zero, prerelease/build parts unsupported. This is only a pin grammar; version order never proves compatibility. `active` is a valid domain code only under an accepted vocabulary, never a schema version. External object revision, timeline revision, schema version and domain state occupy separate fields. A schema pin ID/version cannot silently acquire different bytes. Changing a declared schema version requires an exact accepted new tuple; old segments retain their original pins. Historical reads do not reinterpret records using the current schema. A new snapshot may explicitly bind the same opaque payload to a different accepted schema or state profile; this is a new interpretation declaration requiring the commit reason, not a payload conversion or proof of compatibility. Earlier snapshots retain the earlier interpretation.\n\nEach commit includes `sequence`, `recordedAt`, `writer`, a `scopeDigest` over the complete immutable header, and the exact request. The scope digest binds even the genesis commit to Dimension, timeline and context; transplanting an unchanged chain under a new header fails consistency validation. It is not an authentication proof. Request has `key`, `revision`, `expectedHead`, `operation`, `reason`, nullable `sourceRecordedAt`, and complete `segments`. `reason` is attributed explanatory text, not a validated classification of a domain event. It must explain removals, new future assertions and backdated corrections; mixed intent needs clear text or separate commits. A commit changes assertions about effective history, not the external domain object itself. `sourceRecordedAt` is source-declared metadata, may be null, and cannot follow receipt in this narrow profile. It never chooses knowledge order. Source events/observation times are outside this executable schema and may be linked through separately governed provenance records.\n\n## Time and querying\n\nAll instants use a real Gregorian date in exact ASCII `YYYY-MM-DDTHH:MM:SSZ`, seconds 00..59. No fractions, local times, explicit numeric offsets, uncertain dates or leap seconds. Reject unsupported input; never round or infer midnight/zone. A civil-date or clock conversion needs a separately reviewed adapter and pinned rules. A future **valid** instant is allowed for a scheduled assertion; a future **recorded** instant or knowledge cutoff is rejected against trusted `now`.\n\nIntervals are half-open `[validFrom, validTo)`. `validTo:null` explicitly means no asserted upper bound, not an unknown date or eternal truth. Start is always known. Empty/reversed intervals and overlaps reject; segments must be sorted. Adjacent boundaries are legal, and an open segment must be last. Gaps and an empty snapshot are permitted and return `insufficient-context`; they are not false, absent or unassigned. Explicit negation needs a separately pinned domain value. A snapshot replaces the entire scope's current asserted timeline, so omitted periods become unknown in that new recorded view. Previous snapshots remain intact.\n\n`knownAt` selects the timeline host's recorded axis. It does not mean that the native Dimension already contained the snapshot at that instant. A trusted pre-existing timeline may later be stored in a newly bootstrapped Dimension: its inner receipts remain unchanged, while the outer native fact records the later storage receipt. The acceptance fixtures explicitly simulate such a host history, not earlier native Dimension existence or knowledge. Validation does not authenticate imported receipts.\n\nThe trusted host assigns non-decreasing receipt instants and strictly increasing contiguous sequences within this one timeline. Two commits in the same second are permitted; sequence resolves them. Clock regression rejects. One mistakenly admitted forward clock excursion can make reads and writes reject as `Future receipt` until the trusted clock catches up; there is no in-place repair operation. The host must check its clock against an independent trusted reference and a locally configured skew bound before every admission. On detection, quarantine the root and freeze writes. Recover through an explicitly governed new timeline identity that preserves the original root as restricted evidence, links its provenance and records the loss of continuity, or wait for verified catch-up under a current configuration. Never rewrite receipts or silently roll back. This operational migration is not implemented here. Sequences cannot compare different timelines or Dimensions; no global consistency or synchronized-clock claim exists.\n\n`resolve(... validAt, knownAt, knownSequence=None)` first checks **current** full-timeline reader and purpose permission, then checks the governed header matches before validating history and cutoffs. Trusted configuration validation precedes the reader gate; configuration errors stay inside the host and must be converted to generic endpoint errors. It chooses the latest commit with receipt ≤ knownAt and, if supplied, sequence ≤ knownSequence; then selects the segment covering validAt. No hidden defaults to “now”. `knownSequence=0` deliberately precedes all receipts. Instant-only cutoffs include all received commits in that second; they can gain a later commit with that same second. **Pin the returned sequence for stable historical content.** A supplied sequence is an additional upper bound, not an assertion that a commit existed at the timestamp. Before first receipt and uncovered periods produce distinct missing-context explanations. Denied reads raise a denial before inspecting ledger/query contents; denied is never an unknown-fact answer.\n\nReturned value remains a `recorded-assertion`, with truth, domain validation and transition legality explicitly unevaluated. The view includes commit revision/sequence/receipt/digest, exact segment, and supplied ledger/configuration digests. `archivedAsKnown` belongs to the selected history; `archiveNow` describes the current supplied root and is expressly current context. Root/policy digests and archiveNow may change when historical content remains the same. Consequently reproducibility means the selected historical commit and segment under the pinned cutoff, not byte equality of all current-context metadata. Full-history authority is required for this view; no partial redaction or hidden contrary-evidence signal is supplied.\n\n## Writes, authority, conflicts and imports\n\n`admit(ledger, request, config, actor, now)` is a pure **trusted-host internal** function. The host authenticates actor, selects its current configuration/latest complete root/clock, and serializes durable persistence. It must enforce request size limits before parsing. Config includes exact dimension/timeline/scope, a half-open current validity interval, one writer, full-history readers, purposes and accepted schema/state pins. Claimed source authorship grants nothing. On grant rotation, old writer attribution remains; static validation does not retrospectively authenticate it. A write-only caller must receive only a receipt or generic rejection, never the function's whole returned ledger or detailed exceptions.\n\nFirst operation is `record`; subsequent operations are `correct` or `archive`. Host stamps every new sequence, receipt and writer; caller-supplied receipt fields are rejected. A correction must match the current head digest. Exactly unchanged segments retained from the preceding snapshot may keep retired pins for metadata maintenance or archival; a new, replaced or resegmented interval is a new use requiring currently accepted schema/state bindings. Archival itself preserves the prior snapshot exactly and remains possible after pin retirement, subject to capacity limits. Complete snapshots intentionally serialize even disjoint changes; no automatic merge, last-writer contest resolution, branch or cross-scope transaction exists. Rejected head, replay and authority attempts leave the input unchanged. **The host must durably record its own restricted conflict/rejection artifact** before reporting a conflict; this library has no conflict store or network side effect. A competing master's assertion needs a distinct governed scope and an explicit authority-resolution process. Receipt does not certify priority or correctness.\n\nRepeated key with canonically equivalent request and the same authenticated writer is a no-op, retaining the original receipt even after the head moved or archival. Current authorization/config validity is still checked. Replay compares the complete canonical request, including original expectedHead; it does not rewrite it to the new head. Same key/different request or writer rejects. Changing keys with a reused revision also rejects. Admission is not a durable transaction service.\n\nArchive appends a new commit with exactly the prior segments and freezes further new writes. It does not deactivate the subject, close business-valid periods, retract an assertion or delete retained history. An identical retry remains permitted. **Erasure, tombstones, retention schedules and legal-hold decisions are unimplemented, separate integrations.** Do not promise perpetual retention or adopt this reference where the required disposal path is absent. The host must not turn source knowledge into an earlier receipt: new admission must call admit with the actual timeline-host time and retain earlier source time only as metadata. The pure function trusts its supplied clock and cannot enforce a real-world creation floor. A structurally valid imported ledger cannot prove it was actually received then; only a trusted host archive/chain can supply that assurance.\n\n## Integrity, native binding and migration\n\n`validate_ledger` checks shape and internal temporal/identity chain consistency against explicit trusted now. `validate_extension` additionally requires exact old headers and the entire old commit prefix. They require the host's trusted latest predecessor, cannot detect an omitted newer root, and do not establish historical authorization. Export/import the complete same-version ledger losslessly; `migrate` rejects any other contract version. No automatic schema migration, SCD2/SQL/XTDB adapter, partial export or existing-Dimension upgrade is implemented.\n\nThe encoding named **vercy-python-json-v1** is UTF-8 of Python `json.dumps(sort_keys=True, separators=(',', ':'), ensure_ascii=False, allow_nan=False)`. There is no Unicode normalization. Integers for sequence must use integer JSON encoding, not Boolean or `1.0`. This profile is not RFC 8785; independent language ports must reproduce fixtures exactly. Invalid Unicode, nonfinite numbers and unsupported JSON values reject. JSON objects reaching the callable must come from an input parser that rejects duplicate keys; the bundled file loader is for trusted fixture/archive files. Hashes provide consistency against a trusted predecessor, not signatures, anti-rollback storage or origin authenticity.\n\nBounds: ≤1000 commits, ≤100 segments per snapshot and ≤8 MiB serialized root. These are structural ceilings, not measured production capacity. Full validation scans retained history and admission copies it; host limits, concurrency, availability, monitoring and rollover/migration planning are required before production growth. Overflow refuses the operation without truncation. At the commit/byte ceiling even the extra archive commit may be refused; the host must plan migration or freeze writes through current configuration before capacity exhaustion. This reference does not guarantee an always-available archive slot.\n\nSpecification dependency graph has no runtime imports. Exact WM-XCT-009, 021 and 022 references are conceptual selected-pattern alignments only. Instance references and package composition are separate graphs. No universal WM ID or parent subtype is created. A native V3 fact stores one complete timeline under `temporal.timeline.snapshot` with its own companion namespace. The native outer validator permits object-shaped values and is **not** this nested semantic validator. `validate_snapshot` takes the expected native Dimension explicitly and checks it, timeline subject, asserted/null-unit/open envelope with receipt not before the latest inner receipt, snapshot digest, an immediate successor fact ID different from its predecessor, predecessor linkage and append-only extension after native envelope validation. Both current and immediate previous envelopes receive the same semantic checks, and a successor storage receipt cannot precede its predecessor. Trusted previous snapshot selection is external. Initial installation tests fresh synthetic Dimensions; existing-Dimension migration remains deferred.\n\n## Invariants and minimum use\n\nI01 scope/Dimension remain fixed; I02 opaque revision/schema version/state remain separate; I03 host receipt order differs from effective/source time; I04 positive half-open nonoverlapping sorted intervals; I05 gaps/pre-receipt are unknown; I06 full prior snapshot prefix survives correction; I07 request-bound idempotency retains first receipt; I08 expected-head conflict cannot overwrite; I09 current reader/purpose gate precedes diagnostics; I10 immutable schema/value pins across history; I11 archive preserves history and blocks new commits; I12 unsupported migration refuses loss; I13 explicit nested native validation; I14 no transition/permission/truth inferred; I15 equal-second history needs sequence for stable content; I16 new accepted bindings never reinterpret old content.\n\nA startup needs one governed scope, local config, a pinned domain value/schema and its first snapshot; state references are optional. A matrix group uses separate assignment scopes. An AI deployment uses an environment-qualified artifact binding; model-weight revision, deployment status, evaluation schema and record revision remain different references. No example is a claim about any real organization. The full question routes live in spec.json; missing artifacts remain insufficient context. Allowed actions describe operations to propose or execute under host authority, not grants from this package.\n","structure":{"bundles":[{"id":"TH-B-scope","name":"Scope and interpretation","description":"Scope and interpretation with explicit uncertainty and host responsibility.","layers":[{"id":"TH-L-identity","name":"Identity and boundaries","description":"Identity and boundaries for one governed temporal assertion scope.","findings":[{"id":"TH-F01","name":"What is the governed fact scope?","description":"What is the governed fact scope?","questions":[{"id":"TH-Q01","text":"What is the governed fact scope?","kind":"governed-context","answer_data":["Dimension, timeline and subject/predicate/context URIs","If unavailable: insufficient-context; name missing evidence. A denied read remains denied."]}],"artifacts":[{"id":"TH-A01","name":"Dimension, timeline and subject/predicate/context URIs","description":"Exact references or reproducible report; no implicit truth or authority."}],"actions":[{"id":"TH-ACT01","description":"Compare exact references; request missing context"}]},{"id":"TH-F02","name":"What survives a rename, transfer or split?","description":"What survives a rename, transfer or split?","questions":[{"id":"TH-Q02","text":"What survives a rename, transfer or split?","kind":"governed-context","answer_data":["External identity decision and fixed timeline header","If unavailable: insufficient-context; name missing evidence. A denied read remains denied."]}],"artifacts":[{"id":"TH-A02","name":"External identity decision and fixed timeline header","description":"Exact references or reproducible report; no implicit truth or authority."}],"actions":[{"id":"TH-ACT02","description":"Keep stable scope; create a new governed scope when meaning changes"}]},{"id":"TH-F03","name":"Can two masters or values apply simultaneously?","description":"Can two masters or values apply simultaneously?","questions":[{"id":"TH-Q03","text":"Can two masters or values apply simultaneously?","kind":"governed-context","answer_data":["Scope/master register and separate context keys","If unavailable: insufficient-context; name missing evidence. A denied read remains denied."]}],"artifacts":[{"id":"TH-A03","name":"Scope/master register and separate context keys","description":"Exact references or reproducible report; no implicit truth or authority."}],"actions":[{"id":"TH-ACT03","description":"Separate scopes; request an authority decision, never silently choose a winner"}]}]},{"id":"TH-L-bindings","name":"Schema and state bindings","description":"Schema and state bindings for one governed temporal assertion scope.","findings":[{"id":"TH-F04","name":"Which schema interprets this value?","description":"Which schema interprets this value?","questions":[{"id":"TH-Q04","text":"Which schema interprets this value?","kind":"governed-context","answer_data":["Exact schema ID, numeric version and digest; external payload pin","If unavailable: insufficient-context; name missing evidence. A denied read remains denied."]}],"artifacts":[{"id":"TH-A04","name":"Exact schema ID, numeric version and digest; external payload pin","description":"Exact references or reproducible report; no implicit truth or authority."}],"actions":[{"id":"TH-ACT04","description":"Check accepted tuple; delegate payload validation"}]},{"id":"TH-F05","name":"Which status axis and vocabulary are in use?","description":"Which status axis and vocabulary are in use?","questions":[{"id":"TH-Q05","text":"Which status axis and vocabulary are in use?","kind":"governed-context","answer_data":["State profile pin, axis and code","If unavailable: insufficient-context; name missing evidence. A denied read remains denied."]}],"artifacts":[{"id":"TH-A05","name":"State profile pin, axis and code","description":"Exact references or reproducible report; no implicit truth or authority."}],"actions":[{"id":"TH-ACT05","description":"Check vocabulary membership only"}]},{"id":"TH-F06","name":"Did a legitimate domain transition occur?","description":"Did a legitimate domain transition occur?","questions":[{"id":"TH-Q06","text":"Did a legitimate domain transition occur?","kind":"governed-context","answer_data":["Host transition definition, execution and provenance evidence","If unavailable: insufficient-context; name missing evidence. A denied read remains denied."]}],"artifacts":[{"id":"TH-A06","name":"Host transition definition, execution and provenance evidence","description":"Exact references or reproducible report; no implicit truth or authority."}],"actions":[{"id":"TH-ACT06","description":"Route to the domain owner; report legality not evaluated"}]}]}]},{"id":"TH-B-history","name":"Effective and recorded history","description":"Effective and recorded history with explicit uncertainty and host responsibility.","layers":[{"id":"TH-L-valid","name":"Effective intervals","description":"Effective intervals for one governed temporal assertion scope.","findings":[{"id":"TH-F07","name":"What is recorded as effective on the selected date?","description":"What is recorded as effective on the selected date?","questions":[{"id":"TH-Q07","text":"What is recorded as effective on the selected date?","kind":"governed-context","answer_data":["Explicit validAt and selected segment","If unavailable: insufficient-context; name missing evidence. A denied read remains denied."]}],"artifacts":[{"id":"TH-A07","name":"Explicit validAt and selected segment","description":"Exact references or reproducible report; no implicit truth or authority."}],"actions":[{"id":"TH-ACT07","description":"Resolve within the selected recorded snapshot"}]},{"id":"TH-F08","name":"Does the exact endpoint belong to this interval?","description":"Does the exact endpoint belong to this interval?","questions":[{"id":"TH-Q08","text":"Does the exact endpoint belong to this interval?","kind":"governed-context","answer_data":["Half-open interval boundaries","If unavailable: insufficient-context; name missing evidence. A denied read remains denied."]}],"artifacts":[{"id":"TH-A08","name":"Half-open interval boundaries","description":"Exact references or reproducible report; no implicit truth or authority."}],"actions":[{"id":"TH-ACT08","description":"Exclude validTo; reject zero duration or overlap"}]},{"id":"TH-F09","name":"What do uncovered periods or an empty snapshot mean?","description":"What do uncovered periods or an empty snapshot mean?","questions":[{"id":"TH-Q09","text":"What do uncovered periods or an empty snapshot mean?","kind":"governed-context","answer_data":["Coverage gaps and missing-context explanation","If unavailable: insufficient-context; name missing evidence. A denied read remains denied."]}],"artifacts":[{"id":"TH-A09","name":"Coverage gaps and missing-context explanation","description":"Exact references or reproducible report; no implicit truth or authority."}],"actions":[{"id":"TH-ACT09","description":"Return insufficient context, never false"}]}]},{"id":"TH-L-receipt","name":"Receipts and corrections","description":"Receipts and corrections for one governed temporal assertion scope.","findings":[{"id":"TH-F10","name":"What had this timeline host recorded by a cutoff?","description":"What had this timeline host recorded by a cutoff?","questions":[{"id":"TH-Q10","text":"What had this timeline host recorded by a cutoff?","kind":"governed-context","answer_data":["knownAt, optional knownSequence and selected receipt","If unavailable: insufficient-context; name missing evidence. A denied read remains denied."]}],"artifacts":[{"id":"TH-A10","name":"knownAt, optional knownSequence and selected receipt","description":"Exact references or reproducible report; no implicit truth or authority."}],"actions":[{"id":"TH-ACT10","description":"Choose the latest eligible commit; before first receipt return unknown"}]},{"id":"TH-F11","name":"Which of two same-second receipts is intended?","description":"Which of two same-second receipts is intended?","questions":[{"id":"TH-Q11","text":"Which of two same-second receipts is intended?","kind":"governed-context","answer_data":["Host sequence and receipt time","If unavailable: insufficient-context; name missing evidence. A denied read remains denied."]}],"artifacts":[{"id":"TH-A11","name":"Host sequence and receipt time","description":"Exact references or reproducible report; no implicit truth or authority."}],"actions":[{"id":"TH-ACT11","description":"Pin the returned sequence for stable historical content"}]},{"id":"TH-F12","name":"How does a late correction preserve earlier answers?","description":"How does a late correction preserve earlier answers?","questions":[{"id":"TH-Q12","text":"How does a late correction preserve earlier answers?","kind":"governed-context","answer_data":["Two complete snapshots and predecessor digest","If unavailable: insufficient-context; name missing evidence. A denied read remains denied."]}],"artifacts":[{"id":"TH-A12","name":"Two complete snapshots and predecessor digest","description":"Exact references or reproducible report; no implicit truth or authority."}],"actions":[{"id":"TH-ACT12","description":"Append a corrected snapshot; compare historical answers"}]}]}]},{"id":"TH-B-control","name":"Authority and controlled operations","description":"Authority and controlled operations with explicit uncertainty and host responsibility.","layers":[{"id":"TH-L-writes","name":"Write integrity","description":"Write integrity for one governed temporal assertion scope.","findings":[{"id":"TH-F13","name":"Was this retry already applied?","description":"Was this retry already applied?","questions":[{"id":"TH-Q13","text":"Was this retry already applied?","kind":"governed-context","answer_data":["Original key, full request and first receipt","If unavailable: insufficient-context; name missing evidence. A denied read remains denied."]}],"artifacts":[{"id":"TH-A13","name":"Original key, full request and first receipt","description":"Exact references or reproducible report; no implicit truth or authority."}],"actions":[{"id":"TH-ACT13","description":"Return unchanged root only for exact authorized replay"}]},{"id":"TH-F14","name":"Is this write based on the current head?","description":"Is this write based on the current head?","questions":[{"id":"TH-Q14","text":"Is this write based on the current head?","kind":"governed-context","answer_data":["Expected/current head and host conflict artifact","If unavailable: insufficient-context; name missing evidence. A denied read remains denied."]}],"artifacts":[{"id":"TH-A14","name":"Expected/current head and host conflict artifact","description":"Exact references or reproducible report; no implicit truth or authority."}],"actions":[{"id":"TH-ACT14","description":"Reject stale writes; host records conflict without altering history"}]},{"id":"TH-F15","name":"Who may assert this scope now?","description":"Who may assert this scope now?","questions":[{"id":"TH-Q15","text":"Who may assert this scope now?","kind":"governed-context","answer_data":["Current host config, authenticated writer and mastership evidence","If unavailable: insufficient-context; name missing evidence. A denied read remains denied."]}],"artifacts":[{"id":"TH-A15","name":"Current host config, authenticated writer and mastership evidence","description":"Exact references or reproducible report; no implicit truth or authority."}],"actions":[{"id":"TH-ACT15","description":"Require current grant; preserve old attribution"}]}]},{"id":"TH-L-reads","name":"Historical disclosure","description":"Historical disclosure for one governed temporal assertion scope.","findings":[{"id":"TH-F16","name":"May this role read historical data for this purpose?","description":"May this role read historical data for this purpose?","questions":[{"id":"TH-Q16","text":"May this role read historical data for this purpose?","kind":"governed-context","answer_data":["Current full-timeline reader/purpose decision","If unavailable: insufficient-context; name missing evidence. A denied read remains denied."]}],"artifacts":[{"id":"TH-A16","name":"Current full-timeline reader/purpose decision","description":"Exact references or reproducible report; no implicit truth or authority."}],"actions":[{"id":"TH-ACT16","description":"Deny before hidden ledger/query diagnostics"}]},{"id":"TH-F17","name":"Does a pinned assertion establish truth or permission?","description":"Does a pinned assertion establish truth or permission?","questions":[{"id":"TH-Q17","text":"Does a pinned assertion establish truth or permission?","kind":"governed-context","answer_data":["Selected assertion plus independently governed evidence","If unavailable: insufficient-context; name missing evidence. A denied read remains denied."]}],"artifacts":[{"id":"TH-A17","name":"Selected assertion plus independently governed evidence","description":"Exact references or reproducible report; no implicit truth or authority."}],"actions":[{"id":"TH-ACT17","description":"Report truth and transition legality as unevaluated"}]}]}]},{"id":"TH-B-adoption","name":"Adoption and continuity","description":"Adoption and continuity with explicit uncertainty and host responsibility.","layers":[{"id":"TH-L-continuity","name":"Archival and import","description":"Archival and import for one governed temporal assertion scope.","findings":[{"id":"TH-F18","name":"What changes when this timeline is archived?","description":"What changes when this timeline is archived?","questions":[{"id":"TH-Q18","text":"What changes when this timeline is archived?","kind":"governed-context","answer_data":["Archive commit and unchanged segment snapshot","If unavailable: insufficient-context; name missing evidence. A denied read remains denied."]}],"artifacts":[{"id":"TH-A18","name":"Archive commit and unchanged segment snapshot","description":"Exact references or reproducible report; no implicit truth or authority."}],"actions":[{"id":"TH-ACT18","description":"Freeze new writes; retain historical reads"}]},{"id":"TH-F19","name":"How can an imported history avoid forged local knowledge?","description":"How can an imported history avoid forged local knowledge?","questions":[{"id":"TH-Q19","text":"How can an imported history avoid forged local knowledge?","kind":"governed-context","answer_data":["Actual local receipt and separate sourceRecordedAt","If unavailable: insufficient-context; name missing evidence. A denied read remains denied."]}],"artifacts":[{"id":"TH-A19","name":"Actual local receipt and separate sourceRecordedAt","description":"Exact references or reproducible report; no implicit truth or authority."}],"actions":[{"id":"TH-ACT19","description":"Admit at local receipt; require actual host receipt for new admissions; static imports cannot prove receipt history"}]},{"id":"TH-F20","name":"Which precision or calendar adapter is required?","description":"Which precision or calendar adapter is required?","questions":[{"id":"TH-Q20","text":"Which precision or calendar adapter is required?","kind":"governed-context","answer_data":["Original civil/offset/fractional time and pinned conversion rules","If unavailable: insufficient-context; name missing evidence. A denied read remains denied."]}],"artifacts":[{"id":"TH-A20","name":"Original civil/offset/fractional time and pinned conversion rules","description":"Exact references or reproducible report; no implicit truth or authority."}],"actions":[{"id":"TH-ACT20","description":"Reject unsupported input; do not silently truncate"}]}]},{"id":"TH-L-integration","name":"Composition and migration","description":"Composition and migration for one governed temporal assertion scope.","findings":[{"id":"TH-F21","name":"What is the minimum useful Company Dimension setup?","description":"What is the minimum useful Company Dimension setup?","questions":[{"id":"TH-Q21","text":"What is the minimum useful Company Dimension setup?","kind":"governed-context","answer_data":["One scope, config, external value/schema pin and first snapshot","If unavailable: insufficient-context; name missing evidence. A denied read remains denied."]}],"artifacts":[{"id":"TH-A21","name":"One scope, config, external value/schema pin and first snapshot","description":"Exact references or reproducible report; no implicit truth or authority."}],"actions":[{"id":"TH-ACT21","description":"Install own companion identity and validate nested snapshot"}]},{"id":"TH-F22","name":"Can we migrate or export without losing recorded history?","description":"Can we migrate or export without losing recorded history?","questions":[{"id":"TH-Q22","text":"Can we migrate or export without losing recorded history?","kind":"governed-context","answer_data":["Full same-version ledger, checksums, predecessor and loss analysis","If unavailable: insufficient-context; name missing evidence. A denied read remains denied."]}],"artifacts":[{"id":"TH-A22","name":"Full same-version ledger, checksums, predecessor and loss analysis","description":"Exact references or reproducible report; no implicit truth or authority."}],"actions":[{"id":"TH-ACT22","description":"Allow same-version roundtrip; refuse unsupported migration"}]}]}]}]},"statistics":{"bundles":4,"layers":8,"findings":22,"questions":22,"artifacts":22,"actions":22},"catalogue":{"alternateNames":["Time, states and versions","Bitemporal fact history"],"domain":["Enterprise","Temporal history","Lifecycle"],"tags":["temporal","history","bitemporal","schema","lifecycle"],"adoption":"Start with one fact scope, a pinned domain value and its schema, then append complete effective-time snapshots. Query by effective date and recorded cutoff; later corrections preserve earlier recorded views. The package includes three synthetic examples, a closed schema, a reference validator and native installation checks.","limits":"A trusted host owns authentication, latest history, receipt clock and durable conflict handling. This companion does not establish source truth, domain transition legality or payload-schema conformance."}} END FILE spec.json FILE AGENTS.md original_sha256=ba6bfbdc79d4e3ea4d1dccc8eb1168de54ca3c7994e119dec381e2cb5c7df7cc # Agent instructions Read model-spec.md, temporal.schema.json and temporal.py. Read spec.json for the Bundle → Layer → Finding → Question → Artifact → Action tree. Query explicit valid/recorded cutoffs; pin sequence for reproducibility within a second. Unknown is not false. Schema version, artifact revision, timeline revision and state are separate. This is a trusted-host reference, not a security boundary. Host supplies authenticated actor, current config, latest complete root, clock and durable serialization. Enforce raw input size limits and duplicate-key rejection during parsing. Invoke admit on every new request, preserve first receipt on replay, record restricted host conflict artifacts for rejected writes, and persist atomically. Return only receipt/generic error to a writer without full history read authority. Config and diagnostic details stay inside the host. Never backdate local receipt using source time, merge competing masters, infer truth or transition legality, silently truncate timestamps, invoke external adapters, or dispose of history. Archive freezes new commits while retaining reads. Retention/erasure and existing-Dimension migration require a separate integration. Validate native envelope and nested snapshot separately against the trusted latest predecessor. Current read rights apply to old history too. Static import validation proves only internal consistency. Do not contact people, access external payloads or execute domain transitions on the basis of this package. END FILE AGENTS.md FILE acceptance.py original_sha256=8dbffa2e50ddd2c6f12400419e8f304fd7f7e39aaa691aa5a7633eafd8ba17ce """Trusted synthetic new-Dimension composition, admission and snapshot checks.""" import argparse,copy,hashlib,importlib.util,json,sys,tempfile from datetime import datetime,timedelta,timezone from pathlib import Path import temporal as p from test_temporal import fixture,T1,T2,NOW HERE=Path(__file__).resolve().parent PROFILE_ID='vr.profile.enterprise-temporal-history' SLUG='enterprise-temporal-history' def run(composer,skill): p.require(__debug__,'Run without -O');composer=Path(composer).resolve();skill=Path(skill).resolve();pins=p.load(HERE/'tool-pins.json') for field,root in [('composerFiles',composer),('skillFiles',skill),('upstreamFiles',HERE/'upstream')]: for n,h in pins[field].items():p.require(hashlib.sha256((root/n).read_bytes()).hexdigest()==h,'Unexpected trusted asset: '+n) sys.path.insert(0,str(composer));import composition as c from bootstrap_dimension import bootstrap sys.path.insert(0,str(skill/'scripts'));from write_record import append from validate_dimension import validate as native_validate reports=[];at=c.now();expires=(datetime.now(timezone.utc)+timedelta(days=1)).strftime('%Y-%m-%dT%H:%M:%SZ') with tempfile.TemporaryDirectory(prefix='vercy-authority-acceptance-') as tmp: root=Path(tmp);assets=root/'assets';assets.mkdir() def descriptor(folder,name,source,url): raw=source.read_bytes();dest=assets/folder/name;dest.parent.mkdir(parents=True,exist_ok=True);dest.write_bytes(raw) return {'path':folder+'/'+name,'digest':c.digest(raw),'size':len(raw),'mediaType':'application/json' if name.endswith('.json') else 'text/x-python' if name.endswith('.py') else 'text/markdown' if name.endswith('.md') else 'application/yaml','sourceUrl':url} def release(mid,version,folder,spec,agents,base,native): ds=descriptor(folder,spec.name,spec,base+spec.name);da=descriptor(folder,'AGENTS.md',agents,base+'AGENTS.md');binding=None if native: binding={'id':'urn:vercy:binding:enterprise-temporal-history','version':'0.1.0','forSpecificationDigest':ds['digest'],'runtime':descriptor(folder,'runtime-model.reference.json',HERE/'runtime-model.reference.json',base+'runtime-model.reference.json'),'instanceSchema':descriptor(folder,'temporal.schema.json',HERE/'temporal.schema.json',base+'temporal.schema.json'),'companionValidator':descriptor(folder,'temporal.py',HERE/'temporal.py',base+'temporal.py'),'scope':'Own companion namespace/specification; no parent subtype. Explicit nested validation and admission required.'} return {'modelId':mid,'version':version,'namespace':'urn:vercy:model:'+mid,'role':'core','publicationStatus':'published','researchAssurance':'reviewable-draft','requires':[],'references':[],'specification':ds,'agents':da,'installationMode':'native-binding' if native else 'semantic-only','binding':binding,'semanticFingerprint':None,'compatibility':{'decision':'accepted','reviewer':'urn:synthetic:reviewer:authority','evidence':'urn:synthetic:acceptance:authority','observedAt':at,'scope':'Synthetic candidate-installation exercise, not global parent ratification; publication and research assurance are separate.'}} parent='wm-xct-009-time-calendar';up=HERE/'upstream'/parent semantic=release('vr.wm-xct-009','0.3.0-research.1',parent,up/'spec.yaml',up/'AGENTS.md','https://ver.cy/models/enterprise-temporal-history/versions/0.1.0/upstream/'+parent+'/',False) companion=release(PROFILE_ID,'0.1.0',SLUG,HERE/'spec.json',HERE/'AGENTS.md','https://ver.cy/models/enterprise-temporal-history/versions/0.1.0/',True) companion['references']=[{'modelId':semantic['modelId'],'version':semantic['version']}];releases=[semantic,companion] for name in ['startup','group','ai-team']: config,initial,first,second,q1,q2=fixture(name);target=root/name;stage=root/(name+'-stage');pp=root/(name+'-policy.json');lp=root/(name+'-lock.json');planp=root/(name+'-plan.json');dimension=config['dimension'] policy={'format':'vercy-composition-policy','version':1,'id':'urn:synthetic:composition-policy:temporal','dimensionId':dimension,'owner':'urn:synthetic:owner:installation','allowInstall':True,'actors':['urn:synthetic:actor:composer'],'purposes':['Synthetic temporal reference'],'allowedModelIds':[r['modelId'] for r in releases],'allowedOrigins':['https://ver.cy'],'reviewers':['urn:synthetic:reviewer:authority'],'allowReviewableDrafts':True,'validFrom':at,'validUntil':expires} pp.write_bytes(c.encode(policy));lp.write_bytes(c.encode({'models':[]})) plan={'format':'vercy-composition-plan','schemaVersion':'1.0.0','planId':'urn:synthetic:composition:temporal:'+name,'revision':1,'supersedes':None,'algorithm':'exact-closure-v1','dimensionId':dimension,'createdAt':at,'validUntil':expires,'baseLockDigest':c.digest(lp.read_bytes()),'roots':[{'modelId':r['modelId'],'version':r['version']} for r in releases],'releases':releases,'authority':{'actor':policy['actors'][0],'allowReviewableDrafts':True,'allowedModelIds':policy['allowedModelIds'],'decision':'allow','owner':policy['owner'],'policyDigest':c.digest(pp.read_bytes()),'policyRef':policy['id'],'purpose':policy['purposes'][0]},'provenance':{'classification':'public-synthetic','evidenceKind':'proposal','masterSystem':'urn:synthetic:reference','recordedAt':at,'source':'urn:synthetic:fixture:'+name}} planp.write_bytes(c.encode(plan));c.stage(planp,assets,pp,lp,stage);bootstrap(stage,pp,lp,skill,target,'Synthetic temporal '+name,dimension) installed=target/'models/composed'/SLUG/'temporal.py';p.require(c.digest(installed.read_bytes())==companion['binding']['companionValidator']['digest'],'Code differs');p.require(c.digest((installed.parent/'temporal.schema.json').read_bytes())==companion['binding']['instanceSchema']['digest'],'Schema differs') ms=importlib.util.spec_from_file_location('installed_temporal_'+name,installed);module=importlib.util.module_from_spec(ms);ms.loader.exec_module(module) replay1=module.admit(initial,q1,config,actor=config['writer'],now=T1);replay2=module.admit(replay1,q2,config,actor=config['writer'],now=T2) p.require(replay1==first and replay2==second,'Admission differs');checkAt=max(at,NOW);oid=config['timeline'];operator='urn:synthetic:timeline-operator';register='urn:synthetic:governance-register' obj={'recordType':'object','schemaVersion':'1.0.0','recordId':oid+':object-r1','objectId':oid,'objectType':PROFILE_ID+':timeline','name':'Synthetic temporal timeline','description':'Own companion namespace, not a domain state-machine subtype','recordedAt':at,'previousRecordId':None,'state':'active','provenance':{'source':register,'synthetic':True},'accessClass':'synthetic-private'} path=root/(name+'-object.json');path.write_bytes(p.encode(obj));append(target,'object',path);facts=[] for i,snapshot in enumerate([first,second],1): fact={'recordType':'fact','schemaVersion':'1.0.0','factId':oid+':snapshot-r'+str(i),'subjectId':oid,'path':'temporal.timeline.snapshot','value':snapshot,'unit':None,'validFrom':at,'validTo':None,'recordedAt':at,'supersedes':[] if i==1 else [oid+':snapshot-r1'],'status':'asserted','provenance':{'source':register,'synthetic':True,'snapshotDigest':p.digest(snapshot),'previousSnapshotDigest':None if i==1 else p.digest(first)},'authority':{'source':operator,'rank':0},'masterSystem':register,'accessClass':'synthetic-private'} path=root/(name+'-fact'+str(i)+'.json');path.write_bytes(p.encode(fact));result=append(target,'fact',path);facts.append(target/result['written']) f1,f2=[p.load(x) for x in facts];p.require([f1['value'],f2['value']]==[first,second],'Stored roundtrip differs') module.validate_snapshot(f1,dimension=dimension,now=checkAt);module.validate_snapshot(f2,dimension=dimension,now=checkAt,previous=f1) def query(k):return module.resolve(f2['value'],config,actor=config['readers'][0],purpose='research',validAt='2026-02-01T00:00:00Z',knownAt=k,now=NOW) before,after=query('2026-01-31T00:00:00Z'),query('2026-02-11T00:00:00Z') p.require(before['segment']['value']==q1['segments'][0]['value'] and after['segment']['value']==q2['segments'][1]['value'],'Bitemporal stored answers differ') native=native_validate(target);p.require(native['valid'],'Native validation failed') original=facts[-1].read_bytes();bad=copy.deepcopy(f2);bad['value']['commits'][0]['request']['segments'][0]['validFrom']='not-an-instant';facts[-1].write_bytes(p.encode(bad));outer=native_validate(target);nested=False try:module.validate_snapshot(bad,dimension=dimension,now=checkAt,previous=f1) except module.Invalid:nested=True finally:facts[-1].write_bytes(original) p.require(outer['valid'] and nested,'Native/companion distinction missing') negatives=[] for label,mutator in [('truncation',lambda x:x['value']['commits'].clear()),('digest',lambda x:x['provenance'].update(snapshotDigest='sha256:'+'0'*64)),('subject',lambda x:x.update(subjectId='urn:synthetic:wrong')),('predecessor',lambda x:x.update(supersedes=[]))]: bad=copy.deepcopy(f2);mutator(bad);failed=False if label=='truncation':bad['provenance']['snapshotDigest']=p.digest(bad['value']) try:module.validate_snapshot(bad,dimension=dimension,now=checkAt,previous=f1) except module.Invalid:failed=True p.require(failed,'Accepted '+label);negatives.append(label) cross_rejected=False try:module.validate_snapshot(f1,dimension='urn:synthetic:other-dimension',now=checkAt) except module.Invalid:cross_rejected=True p.require(cross_rejected,'Cross-Dimension snapshot admitted');negatives.append('cross-Dimension') native.pop('dimension',None);outer.pop('dimension',None) reports.append({'profile':name,'dimension':dimension,'objects':1,'facts':2,'native':native,'roundTripEqualsInput':True,'admissionReplayedThroughInstalledCompanion':True,'negativeCasesRejected':negatives,'storedAnswers':[before,after],'invalidNestedSnapshot':{'native':outer,'companionRejected':nested},'envelopeAuthorityMeaning':'Later native storage of synthetic pre-existing host history; inner receipts do not establish earlier native Dimension existence or domain fact priority','pins':[{'id':r['modelId'],'version':r['version'],'digest':r['specification']['digest'],'mode':r['installationMode']} for r in releases]}) return {'format':'vercy-temporal-profile-acceptance','executedAt':c.now(),'passed':len(reports),'failed':0,'profiles':reports,'sourceDigests':{str(x.relative_to(HERE)):hashlib.sha256(x.read_bytes()).hexdigest() for x in [Path(__file__),HERE/'temporal.py',HERE/'temporal.schema.json',HERE/'spec.json',HERE/'tool-pins.json',HERE/'test_temporal.py']},'limits':'Three synthetic new Dimensions; own companion plus optional semantic-only parent. No IAM, domain truth/transition, durable concurrency, production capacity or existing-Dimension migration proof.'} if __name__=='__main__': ap=argparse.ArgumentParser();ap.add_argument('--composer',required=True);ap.add_argument('--skill',required=True);ap.add_argument('--report',required=True);args=ap.parse_args();report=run(args.composer,args.skill);Path(args.report).write_text(json.dumps(report,indent=2)+'\n',encoding='utf-8');print(json.dumps({'passed':report['passed'],'failed':report['failed']})) END FILE acceptance.py FILE whole-object-coverage.yaml original_sha256=d7591ea1735788c0808b743060fc1e7896494f0ac0986fe95949da89128e94e6 {"canonicalFacets":["identity-class","direct-properties","recognition-observation","capabilities-behaviour-actions","context-evidence"],"types":{"Timeline":{"identity-class":{"status":"required","coverage":"Governed timeline URI and fixed scope"},"direct-properties":{"status":"required","coverage":"Header and append-only bounded commits"},"recognition-observation":{"status":"required","coverage":"Recorded history observed via explicitly cut view; source truth not inferred"},"capabilities-behaviour-actions":{"status":"required","coverage":"Host admission, archival and query"},"context-evidence":{"status":"required","coverage":"Current config and exact predecessor root"}},"TimelineCommit":{"identity-class":{"status":"required","coverage":"Revision URI, key and local sequence"},"direct-properties":{"status":"required","coverage":"Host receipt/writer, exact request and complete snapshot"},"recognition-observation":{"status":"required","coverage":"Registration is local receipt, not human awareness or event observation"},"capabilities-behaviour-actions":{"status":"required","coverage":"Immutable; superseded by a new commit, never edited"},"context-evidence":{"status":"required","coverage":"Previous digest, reason and source-declared time"}},"ValidSegment":{"identity-class":{"status":"required","coverage":"Embedded commit-relative value, no independent identity"},"direct-properties":{"status":"required","coverage":"Half-open effective interval and exact external pins"},"recognition-observation":{"status":"required","coverage":"Coverage membership only, truth and real-world observation unevaluated"},"capabilities-behaviour-actions":{"status":"required","coverage":"No independent mutation; new full snapshot for correction"},"context-evidence":{"status":"required","coverage":"Schema/state bindings and containing commit"}},"SchemaBinding":{"identity-class":{"status":"required","coverage":"Whole id/version/digest tuple"},"direct-properties":{"status":"required","coverage":"Numeric triplet grammar and sha256 syntax"},"recognition-observation":{"status":"required","coverage":"Exact accepted tuple comparison, payload conformance untested"},"capabilities-behaviour-actions":{"status":"required","coverage":"Read-only pin; new version for changed definition"},"context-evidence":{"status":"required","coverage":"External publisher responsibility and historical preservation"}},"StateReference":{"identity-class":{"status":"required","coverage":"Profile pin plus axis/code embedded value"},"direct-properties":{"status":"required","coverage":"One optional status axis membership"},"recognition-observation":{"status":"required","coverage":"Vocabulary membership only, not proof of a transition"},"capabilities-behaviour-actions":{"status":"required","coverage":"No state machine or domain effect executed"},"context-evidence":{"status":"required","coverage":"Host domain definition/evidence, no executable delegation"}},"TimelineAnswer":{"identity-class":{"status":"required","coverage":"Ephemeral query result, no persistent domain identity"},"direct-properties":{"status":"required","coverage":"Explicit cutoffs, selected commit/segment, missing context"},"recognition-observation":{"status":"required","coverage":"Shows recorded assertion or insufficient context, not truth"},"capabilities-behaviour-actions":{"status":"required","coverage":"Current full-reader query, no writer authority"},"context-evidence":{"status":"required","coverage":"Input/root/policy digests and explicit current vs historical archive context"}}},"limits":"Each value/derived type is scoped individually; no mass/physical dimension invented. Conceptual references do not claim executable delegation."} END FILE whole-object-coverage.yaml FILE mastership-and-rights.yaml original_sha256=9dc4b36a2a84e8e636f1ec54b2bd043ed08849c224370353ac13ff4cc587e46f {"facts":[{"fact":"scope/identity","semanticOwner":"Domain scope steward","master":"Configured local register","writer":"Current configured writer after host identity check","readerPurpose":"Whole timeline reader and purpose gate","validTime":"Scope fixed in this profile","provenance":"Registration config","conflict":"Duplicate scope detected by external registry","retention":"Host-owned, erasure integration required"},{"fact":"effective segments and state declarations","semanticOwner":"Domain fact owner","master":"One designated writer per governed scope","writer":"Authenticated configured writer","readerPurpose":"Current full-history readers/purposes","validTime":"Half-open UTC-second segments","provenance":"Commit writer/reason/sourceRecordedAt plus optional external provenance model","conflict":"Expected-head/replay rejection; host durable conflict artifact","retention":"Archive retains all history; no disposal implementation"},{"fact":"receipt/order/head","semanticOwner":"Timeline operator","master":"Trusted host serialized store/clock","writer":"Host only","readerPurpose":"Current full-history gate","validTime":"Local recorded axis, never business-valid time","provenance":"Contiguous sequence and predecessor digest","conflict":"Clock regression or stale head rejects","retention":"No truncation/rollover in current implementation"},{"fact":"schema/state profile definitions","semanticOwner":"External schema/domain publisher","master":"External source, exact accepted pin list locally","writer":"Host steward changes current config; definitions not edited here","readerPurpose":"Pins may also be sensitive; full-history gate","validTime":"Historical segment retains exact pin","provenance":"ID/version/digest declaration, not signature","conflict":"Repointed ID/version rejects","retention":"Host must retain accessible definitions for interpretation"}]} END FILE mastership-and-rights.yaml FILE requirements.txt original_sha256=5bc814e05c852ada4731d68f061aab75fd7b9d4f2fd332360a9f5362984a7e89 jsonschema==4.26.0 rfc3339-validator==0.1.4 rfc3986-validator==0.1.1 END FILE requirements.txt FILE runtime-model.reference.json original_sha256=f2b69d8ae6f6a9426be693458f53894ff7c3e04fe5038890adf5b65d06edbd17 {"format":"vercy-runtime-model-schema","schemaVersion":"1.0.0","modelId":"vr.profile.enterprise-temporal-history","paths":{"temporal.timeline.snapshot":{"valueTypes":["object"],"units":[null]}}} END FILE runtime-model.reference.json FILE adoption-limits.md original_sha256=8ea3e18f26b0da30ddf6b9460520c0420c9fe5c971b05c4f2bf3a8db95028f52 # Adoption limits Reviewable draft; one single-valued scope and one host sequencer. No real-organization validation, distributed consistency, engine adapter, fine-grained disclosure, IAM, payload validation, transition engine, signatures, clock attestation, durable conflicts, erasure or existing-Dimension migration. Full snapshots have structural limits, not an enterprise throughput claim. Before production, implement durable serialized storage, scope uniqueness, authentication and current rights, a reliable clock, conflict audit, strict input parser/budgets and locally required retention/disposal. Historical source times never establish earlier local knowledge. Parent source/profile holds remain in crosswalk.json. At capacity, even a new archive commit may be refused; use host policy to freeze writes and plan migration before exhaustion. The host owns global native fact-ID uniqueness. The nested validator checks only the immediate predecessor ID and assumes native envelope checks were already performed. The inner recorded axis belongs to the timeline host, not to the native Dimension storage log. A pre-existing trusted host timeline can be installed later; synthetic January/February receipts in acceptance do not assert that the newly created Dimension existed then. Clock authenticity and history authenticity remain host obligations. A mistakenly admitted forward receipt can disable all reads and writes until catch-up. Before admission, enforce a clock-skew guard against a trusted reference. If it fails, quarantine/freeze and preserve the original evidence; recovery needs verified catch-up with current policy or an explicitly governed new timeline identity with provenance and disclosed continuity loss. No in-place repair or automatic recovery is implemented. END FILE adoption-limits.md FILE migration.md original_sha256=06e3373c4727b1246656d115701bb314249add13f759a93ed6219f9fa41a9936 # Migration and loss Only complete same-contract-version JSON roundtrip is implemented and tested. A different version refuses. Keep the original root and all pins; perform any new conversion in a separately governed staging process with explicit loss, provenance, rollback and ownership. Source SQL system-time columns are not automatically business-valid time. SCD2 can lose recorded history; timezone/fractional conversions can lose precision. No such adapter is included or silently executed. Native acceptance covers new synthetic Dimensions only. Rollback to an older root is not an allowed history update; restoration is an operational recovery requiring the complete trusted chain. The inner recorded axis belongs to the timeline host, not to the native Dimension storage log. A pre-existing trusted host timeline can be installed later; synthetic January/February receipts in acceptance do not assert that the newly created Dimension existed then. Clock authenticity and history authenticity remain host obligations. A mistakenly admitted forward receipt can disable all reads and writes until catch-up. Before admission, enforce a clock-skew guard against a trusted reference. If it fails, quarantine/freeze and preserve the original evidence; recovery needs verified catch-up with current policy or an explicitly governed new timeline identity with provenance and disclosed continuity loss. No in-place repair or automatic recovery is implemented. END FILE migration.md FILE bindings/native-v3.md original_sha256=67d8e6d4929fd35fc0e291f426126db4a47f76c38910b815951c0fd6abec6f3b # Native V3 binding Install `vr.profile.enterprise-temporal-history` under its own namespace. The optional Time / Calendar parent is semantic-only. A timeline object owns `temporal.timeline.snapshot` facts containing the complete root. Outer fact provenance/authority describes snapshot storage, not domain fact precedence. Validate the outer envelope with V3, then `validate_snapshot` and `validate_extension` using the latest trusted predecessor. The nested validator is mandatory even when native validation passes. Do not expose full roots to write-only callers. acceptance.py replays admission and roundtrips two snapshots in three fresh synthetic Dimensions. The inner recorded axis belongs to the timeline host, not to the native Dimension storage log. A pre-existing trusted host timeline can be installed later; synthetic January/February receipts in acceptance do not assert that the newly created Dimension existed then. Clock authenticity and history authenticity remain host obligations. A mistakenly admitted forward receipt can disable all reads and writes until catch-up. Before admission, enforce a clock-skew guard against a trusted reference. If it fails, quarantine/freeze and preserve the original evidence; recovery needs verified catch-up with current policy or an explicitly governed new timeline identity with provenance and disclosed continuity loss. No in-place repair or automatic recovery is implemented. END FILE bindings/native-v3.md FILE crosswalk.json original_sha256=f0c6d2bde017e1ebc040f81ac313f81d4a1775d87db9b194cac9a4c492302328 {"claim":"narrower/overlap, never exactMatch or subtype","parents":[{"oldId":"N11","currentId":"WM-XCT-009","registryId":"vr.wm-xct-009","version":"0.3.0-research.1","runtimeStatus":"published","installable":true,"assurance":"reviewable-draft","sha256":"060511804c09ed5992e3fdf222839f97a0d340db0a2cba3c4c08aded7767e90d","liveByteEqualityVerified":true,"relation":"narrower-selected-pattern-overlap","action":"semantic-reference-only","readScope":"Full files recursively parsed and all sections retained in research checkpoint; boundary, composition, holds and structured inventory inspected. No complete legacy validator/source conformance audit claimed.","holds":["Verify live availability, editions and claim-level support for every accepted primary source, including current tzdb, BIPM/IERS, IETF and Unicode releases.","Complete jurisdictional profiles for holiday and working-day authorities and direct clause-level verification of paywalled ISO 8601-1/2 before promoting a universal completeness claim."],"losses":"Narrow single-scope UTC-second linear snapshots; no broad parent conformance, engine, calendar or lifecycle readiness inherited."},{"oldId":null,"currentId":"WM-XCT-021","registryId":"vr.wm-xct-021","version":"0.3.0-research.1","runtimeStatus":"published","installable":true,"assurance":"reviewable-draft","sha256":"87c8c50f6f4c2eb3478751f01a08c6c37c6a85f97f4c056505b13cdf561314e9","liveByteEqualityVerified":true,"relation":"narrower-selected-pattern-overlap","action":"semantic-reference-only","readScope":"Full files recursively parsed and all sections retained in research checkpoint; boundary, composition, holds and structured inventory inspected. No complete legacy validator/source conformance audit claimed.","holds":["Verify live editions and claim-level support for all accepted SCXML, W3C PROV/OWL-Time, HL7 FHIR, DCMI, ISO and records-management sources.","Validate the mixin against at least five independent profiles: publication, workflow/request, clinical interpretation, software release and records disposition."],"losses":"Narrow single-scope UTC-second linear snapshots; no broad parent conformance, engine, calendar or lifecycle readiness inherited."},{"oldId":null,"currentId":"WM-XCT-022","registryId":"vr.wm-xct-022","version":"0.3.0-research.2","runtimeStatus":"published","installable":true,"assurance":"reviewable-draft","sha256":"40ced88212f4c90690bdbb35bf2429fe627d11793bee5e587b5b10b99f49fe85","liveByteEqualityVerified":true,"relation":"narrower-selected-pattern-overlap","action":"semantic-reference-only","readScope":"Full files recursively parsed and all sections retained in research checkpoint; boundary, composition, holds and structured inventory inspected. No complete legacy validator/source conformance audit claimed.","holds":["Live-source verification is outstanding for all 27 base sources and for the three newly admitted alternative sources (DataCite versioning, PAV 2.3.1, ADMS 2.00). Recency-sensitive pins must be re-checked at publication time: the IANA link-relations registry, the Git glossary build, the NIST SP 800-53 control release, and the DataCite guidance page, which is living documentation rather than a dated specification.","Domain-profile validation has not been performed. The pack asserts applicability across regulated manufacturing, research data, software packaging, records management and web-resource publishing, but only US FDA 21 CFR Part 11 was actually retrieved; EU GMP Annex 11 is assumed similar and uncited. At least two contrasting profiles must be exercised before publication.","Every external mapping must be rendered as declared alignment, never conformance, and the accepted DataCite, PAV and ADMS additions must carry that label explicitly along with their loss statements.","Documented evidence gaps must appear in the published draft rather than be omitted: PREMIS 3.0 and OAIS returned HTTP 403, ISO 10007 and ISO 15489 are paywalled and unverified, and no normative bitemporal source was obtained, so the effective-period finding must ship marked as partial support.","Source identifier remapping for the accepted findings and functions must be applied and re-checked before render, since the two packs use overlapping SRC identifiers for different documents."],"losses":"Narrow single-scope UTC-second linear snapshots; no broad parent conformance, engine, calendar or lifecycle readiness inherited."}],"candidates":[{"candidate":"TemporalValidity","disposition":"implemented-narrow-value","meaning":"Exact UTC-second half-open interval; calendar/uncertainty adapters deferred"},{"candidate":"Revision","disposition":"split","meaning":"Linear assertion commit here; opaque external artifact revision referenced; DAG/merge delegated conceptually to WM-XCT-022"},{"candidate":"LifecycleTransition","disposition":"deferred-domain-execution","meaning":"StateReference carries only vocabulary membership; actual transitions remain with domain host/WM-XCT-021"},{"candidate":"SchemaBinding","disposition":"implemented-narrow-value","meaning":"Accepted immutable id/version/digest tuple, not executable payload validation"}]} END FILE crosswalk.json FILE tool-pins.json original_sha256=9830b48feac14a372b427acbbb16db6bd37bded3f181ad3427ad0dfd86b43214 {"composerVersion":"0.1.1","composerFiles":{"composition.py":"78aa1c6c29f14c7adedefd7dd8b3683c845118c49bb48d04c5e92ae4989ce06e","bootstrap_dimension.py":"5eb5491ecedcfa56ffe63d07383e9a650eed42a5d73f667c2feb2f34ea5180f5","composition-plan.schema.json":"cc33e9ee4522cd586a2e1fb07307e6aa5361bf7cf3ca99a419c0f434d0e8a079","policy.schema.json":"92e0386696c974b1e8a312b60ca08d981c223e9925c8f70dabdfa135b9041543"},"skillFiles":{"SKILL.md":"bbd714f5a0de9fad7b26df12be7fb31ce5935f3f54f3cd1037688121383cf963","agents/openai.yaml":"f7234977b2cb542bc0fb1e7665a8a27684e0fa1400696dd6e086b4fef3829cb0","mcp/server.py":"ef3b937e4ebcaa5d737f03f11e6ce5e0be80885e184c88a555e7a0d7b4c0e133","references/autonomous-runtime.md":"ae9d728a214cb296dd97b9d172b60651270e77afcbab632fce04e84dd0a3453a","references/compatibility.md":"b7c0b0ee6d16084f1422b9cb813d23c3f03cc45d047d17a43568067ebde34460","references/concept-map.md":"c216fc5ffd94a55a254f2b61e1ef5630eb8ec09a5ae70db1617318662c43c3a1","references/dimension-bootstrap.md":"7ab614fd1eba0326861d7d2d36cd690b99f26dd0f3333190401bf0782d8a6ed7","references/federation-routing.md":"fb025d2cc62db14c553e0b364c70a47e6385d519d419dec706fb6cf483658159","references/mcp-server.md":"7d1233ea34b34e927acf352c12bc367f58fda5bde249fb3e5e99aa05cff724ad","references/memory-autostart.md":"d3b831e39f2dd5f32abc97d9748ef426e72c3f31e7dbcfff65296b4bf7de5e2e","references/model-lifecycle.md":"9689f560884e12092ffa1fe0068e28f603095b6ffe8c719493f8f595fb3a06ee","references/model-resolution-api.md":"f008dc97daa193b827b9eab76dbc574f104f8d464909cd5d0e71cb8a97749261","references/presets.md":"71503847c1d67f1a227600cce96e5941ea4f3ac1cda1575fe849f18815962cb2","references/public-entry.md":"15155eec00a259dfdf6a0469ccaceba444fcba635f1a42080b36063d924d22a6","references/runtime-records.md":"71c495b38db59f048fe1ec27cd54e608adfeee5160e4d96141b18e43d6b1e809","references/storage-selection.md":"2dd3b10bab2235d04fd3b7cf5411249bf54774efc734b9d08f93483c546bcc5a","references/validation.md":"8c35e27e4fc6103b489ad8b34bd7b79eeb86a8e557752726e8f351ab4edfc9d0","references/whole-object.md":"17d9a1275015c0152267f5a4a39659244ed16c25e81e748256a9324dc5bb7b66","schemas/compatibility.schema.json":"bb32246583b04cedaff9d5e2aae75cca6e9afa014d73a6d4fcc9306054dec78a","schemas/conflict-policy.schema.json":"dece868961a56fe0f50b93564986fb5862b5cbca6ecba138db894f9ea8f6a6c5","schemas/dimension.schema.json":"b6645174e73f551d7bf27642c1887538a8e6d695d586d5101995e69dfa42ce57","schemas/event.schema.json":"e0fbf7551d3b409bf8c04aad6cb6e2caa1dcbf3e703cee9ffe6ab23664f38db6","schemas/fact.schema.json":"f15f9f652c44547384ed8ca7c0c5454a73ea7385de3ec18d8fed09502994ad0a","schemas/object.schema.json":"ff7cab00542db5388946d0704b9aa3c33a49fc8057ec1df6ace7be00e1e43a0a","schemas/relation.schema.json":"2b3b97267fbc400492948886af21010fd6592752c547269f723e7b989279135a","schemas/runtime-model.schema.json":"2ce263747b220d16980bea70f1bca9c3bba59eeec90233d6c9b880759a902c42","scripts/build_index.py":"807539c6d4522d0cbf8782e3a1466a471fa36895cb304b21ee704cb513112319","scripts/create_dimension.py":"4cc00b03be88e9a2348eb681137d0b813b10aa0b76edc881f3e9ecf8345d5b8f","scripts/migrate_dimension.py":"daae4db10760e9d44380c0606d016557ac3e52401f3a711ee11b5ad8c053f02a","scripts/poll_model_requests.py":"91c4aede63bb2eee48e5d49fcdf59d75b0e23eb12511d012c419eb141167fea9","scripts/query_dimension.py":"0c6e35345a91bdd85b7b129fedbb35f4359f6d786b39b927cc92870b65209c0c","scripts/reconcile_models.py":"4fcf76ebaa08ebdbefd2f9ac6824337f8f7d0e9d0c05329f4b3b1669f6260236","scripts/register_memory.py":"9479de2b71669042a73a2393280cc99c096795bf79f0a7eb3294025d2e82e406","scripts/resolve_model_need.py":"25fb98bd2549c0bb7b743cebb62e666a14acd1bd7fa1a2de8548ae9f1d901d5d","scripts/select_storage.py":"c08cdc15374cc496711cb2a6d3403808c008415abccfa3f3cf12f3015df400d3","scripts/self_test.py":"fe9b493b5e7c33a58f97c4fe8c1b01b3457e5eca6e5e2732fbd3497bae402158","scripts/validate_dimension.py":"815a938361420373b18448dda4caa5604d314230cf53fc6a07a9dcb96dd57df4","scripts/vercy.py":"80e31ef4d4e02bab94859163f7975cbe9678e0b31db7d51ae7acd8506b65e20d","scripts/vercy_runtime.py":"e538c64b9c824b503768b63dba5dc66a81c19ac7626eb9116579ba2925528664","scripts/write_record.py":"c60274820fd3e5a55ec790f7e64fb0e0a7e218b7fe107f02d0fcb125091da4e5","assets/dimension/AGENTS.md.template":"b435e4bc805e2aa084c648167350fd050993dab0aaa1d194697558de5586f69d","assets/dimension/compatibility.yaml":"41244d13b2e8763f2f23c44f1ffefc7dde4801b4a54f5faa852d977e0f648a4f","assets/dimension/context-routing.yaml":"52f3a4f8951e2faf3be8d6bd23af51fdfc477a347cc79db55bbcd3d717cd3f67","assets/dimension/dimension.yaml":"e92c299d857962293f2a1c13d70717beff0ec955b3ab84ea1e2763d2cff3b1d7","assets/dimension/federation.yaml":"358bf49507eb3f5c1e9fb86e45d9cc0ee9d14a8dc371f3af95af56dab0e6327b","assets/dimension/memory.yaml":"50d47c53ee2be80d293a051c7c909cb2afdf8204f9a76eadfe5673eb6cd589b4","assets/dimension/vercy.lock":"f360ae2f60e1d3f02bda506c3aed9587d6435a7d0200bef542888df32b469c99","assets/icons/vercy-logo-1024.png":"8043b9a7080d1b64fea402ba0db8d42efb366862214fc1d68d8a99086401a705","assets/icons/vercy-logo-512.png":"3832e0a25cec92cf22392a27c44b37524213844598c61a12d5032e3fea5fd690","assets/presets/ai-subject.yaml":"ed547e7628d8c4509ed1873312b45f0521036b5235a3b795a2f2a0e4a147c3b7","assets/presets/index.yaml":"69e79eb66cec03ab07badb301b0b4ebfb15b74b34daffeae78e7f11529140892","assets/presets/kernel.yaml":"b699f89fc1d040e05584bb21e00a419a7704230caba42adc37cb70631defb43d","assets/presets/organizational.yaml":"e70c6d196f1b5626f2e7646252dad4f2be961b7908ae198e9bc1d405cffad2a3","assets/presets/personal.yaml":"c201473267e64958b9844e3557f8efc95b8be790581135c42c8c38566c841483","assets/presets/reality.yaml":"2779668f8eeca66b74ff31527c323d3461f821089769ef5d7951c13afbfcad66","assets/dimension/bindings/storage.yaml":"044db01cf746678283a98c96be0d1fb8a94997393b9161a5a32e59dfc813ba5c","assets/dimension/data/index.md":"f10a3c8283ddc1ae608c6848cd561ac9b9d80a05ca684420ac185fa920b8b351","assets/dimension/migrations/index.yaml":"9a20ae6fef67ca51d4c07a27558deb20af2a7b3dafe76893783ac01e86c0dce6","assets/dimension/policies/access.yaml":"3b58ce30f6de01923dbbab069df0721552c3b9ab8ba405c30ac353ffb392779f","assets/dimension/policies/autonomy.yaml":"6629691e60540e42eabeb63f746bcb99f79f383d7c85a57217e551d4ecc6ea27","assets/dimension/policies/conflict-resolution.yaml":"241e97baa79198e4b02885f24ad1143b7ebfc3dbf52dc07e4bccb01ef31c72b2","assets/dimension/policies/lifecycle.md":"91755112dd7854a7cb06598fcb53233c68b626bb015ca7f5a3a9307258eab232","assets/dimension/policies/model-deployment.yaml":"637fc3ac655b7f5c2f36c814113b03803bce4366e62cb24bbeb4f36dba525771","assets/dimension/registries/events.yaml":"8babba185339394a775d953024c857f6bcd4f6c1037bff9019af5c8512435fef","assets/dimension/registries/meta-models.yaml":"4efb434d716f2c10a1c01deb79e44873ced31599446edab8b213e3fd7201206b","assets/dimension/registries/meta-objects.yaml":"c1b417a3019d93c594dae9854951d57c3fcd73d73a88f258b3a13c8cb5e7e3d3","assets/dimension/registries/model-links.yaml":"ecbac80f14627245ecdc5af12bb30331b88f688e8ebeaa34fba44ddc16e0c898","assets/dimension/registries/model-requests.yaml":"7f01232fd4b812d942eed0e88f154f751e7f9fb1707402a5b6b4aaa16bdba319","assets/dimension/data/events/README.md":"fa20d1960e40eee352679debcab28df245f9bef695ca72a27d28b69ab8e18737","assets/dimension/data/facts/README.md":"80433bcda7964cb8819692bd442628f56b35aa6fca96bfde0d527b2d3ed38138","assets/dimension/data/objects/README.md":"264ebb5440729741322828fd5e3c8a747c77a1662b0e64ab5ff9ce1a978ff4b8","assets/dimension/data/relations/README.md":"d7a7d3e09a3c8d0c2e0304ffe89e5fa01ad9bde730497185a7a9da7d5bf51a22","assets/presets/organizational/commercial-company.yaml":"ce8ee74e8fa61eec9583471f6b4982e920d172af3299bbfc2ed08163a6cbde2b","assets/presets/organizational/community.yaml":"31cabe5a146e2b38d173f2cb08f7e5d0df60bbcf7f273082ba97b0dd7560f001","assets/presets/organizational/family.yaml":"094438b226ed56859c72327d354e55e6ed2cd6c2658a1423ad345c326ac1a9c9","assets/presets/organizational/state.yaml":"a2aaac7f20feaffe2494406ddc5b71629027fed6c04e94f65950dac991f6ff13"},"upstreamFiles":{"wm-xct-009-time-calendar/spec.yaml":"060511804c09ed5992e3fdf222839f97a0d340db0a2cba3c4c08aded7767e90d","wm-xct-009-time-calendar/AGENTS.md":"f01631a0bba6ac2ec1903c8b1359e4d6b4e1fac6a1165b12d4b76be4b23e70c8","wm-xct-009-time-calendar/publication.json":"1ab2061b5786df57e9eae47171864c2ff43e1538f582a5cc532bd3cf671e5ea1"}} END FILE tool-pins.json END FROZEN CANDIDATE EM-XCT-04-R3. Return your verdict, findings, input completeness and unverified scope.