From 9ac8c7a133e34f5c6943916c02762015d335ded7 Mon Sep 17 00:00:00 2001 From: Kinneyzhang Date: Tue, 1 Sep 2026 00:50:32 +0800 Subject: [PATCH] feat: expose bounded final-accept markers --- tests/tp-transaction-tests.el | 26 ++++++++++++++++++++++++++ tp-reactive.el | 17 +++++++++++++++++ tp-transaction.el | 10 ++++++++++ 3 files changed, 53 insertions(+) diff --git a/tests/tp-transaction-tests.el b/tests/tp-transaction-tests.el index c60e16b..b43b06b 100644 --- a/tests/tp-transaction-tests.el +++ b/tests/tp-transaction-tests.el @@ -452,6 +452,32 @@ :type 'tp-final-marker-error) (should (eq (aref target 0) 'old)))))) +(ert-deftest tp-transaction-test-public-final-marker-wrappers-share-contract () + "Public marker constructors and registration retain the bounded core rules." + (tp-transaction-test--with-surface (_buffer _surface source) + (let ((target (vector 'detached 'token 0))) + (tp-with-transaction + (tp-signal-set source 2) + (tp-transaction-register-final-marker + :owner-key 'public-host + :expected-token + (tp-final-marker-expectation-create + :target target :index 1 :value 'token) + :expected-version + (tp-final-marker-expectation-create + :target target :index 2 :value 0) + :next-values + (vector + (tp-final-marker-slot-write-create + :target target :index 0 :value 'attached)) + :inverse-values + (vector + (tp-final-marker-slot-write-create + :target target :index 0 :value 'detached)) + :slot-write-count 1 + :operation-key 'tp-vector-slots/v1)) + (should (eq (aref target 0) 'attached))))) + (ert-deftest tp-transaction-test-marker-partial-apply-restores-in-reverse () "Partial marker apply restores applied owners before normal rollback." (tp-transaction-test--with-surface (buffer _surface source) diff --git a/tp-reactive.el b/tp-reactive.el index bcd442b..49e5016 100644 --- a/tp-reactive.el +++ b/tp-reactive.el @@ -986,6 +986,23 @@ against the trusted OPERATION-KEY descriptor and the transaction bound." (cl-incf tp--transaction-final-marker-slot-writes slot-write-count) marker)) +(cl-defun tp-transaction-register-final-marker + (&key owner-key expected-token expected-version next-values inverse-values + slot-write-count operation-key) + "Register one bounded final-accept authority marker. +OWNER-KEY must be unique in the active transaction. EXPECTED-TOKEN and +EXPECTED-VERSION bind owner state; NEXT-VALUES and INVERSE-VALUES are prebuilt +slot-write vectors with fixed SLOT-WRITE-COUNT. OPERATION-KEY must resolve +through TP's closed marker-operation whitelist." + (tp--transaction-register-final-marker + :owner-key owner-key + :expected-token expected-token + :expected-version expected-version + :next-values next-values + :inverse-values inverse-values + :slot-write-count slot-write-count + :operation-key operation-key)) + (defun tp--transaction-freeze-final-markers () "Validate and seal every marker before signal commit and final accept." (when (and (> tp--transaction-final-marker-count 0) diff --git a/tp-transaction.el b/tp-transaction.el index 7dc2937..05b8d0f 100644 --- a/tp-transaction.el +++ b/tp-transaction.el @@ -588,12 +588,22 @@ ROLLBACK-FAILURES and DIAGNOSTICS are observational snapshots." (tp--make-final-marker-expectation :target target :index index :value value)) +(cl-defun tp-final-marker-expectation-create (&key target index value) + "Create a final-marker expectation for TARGET slot INDEX and VALUE." + (tp--final-marker-expectation-create + :target target :index index :value value)) + (cl-defun tp--final-marker-slot-write-create (&key target index value) "Create one prebuilt write of VALUE into TARGET slot INDEX." (unless (tp--final-marker-vector-index-p target index) (signal 'tp-final-marker-error (list :slot-write target index))) (tp--make-final-marker-slot-write :target target :index index :value value)) +(cl-defun tp-final-marker-slot-write-create (&key target index value) + "Create one bounded final-marker write to TARGET slot INDEX with VALUE." + (tp--final-marker-slot-write-create + :target target :index index :value value)) + (defun tp--final-marker-expectation-current-p (expectation) "Return non-nil when EXPECTATION matches its current fixed slot." (and (tp-final-marker-expectation-p expectation)