From a22945bb99bd7750661fb51b7830bc09bd956fe8 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Mon, 17 Aug 2026 05:21:24 +0900 Subject: [PATCH 1/2] feat(temporal): refuse later revisions with earlier system time A higher document revision number cannot carry earlier or equal system time (ADR 0002/0013). --- ARCHITECTURE.md | 1 + CHANGELOG.md | 1 + Cargo.lock | 4 + Cargo.toml | 2 + README.md | 3 +- crates/revision_order/Cargo.toml | 17 +++ crates/revision_order/src/error.rs | 48 ++++++ crates/revision_order/src/lib.rs | 21 +++ crates/revision_order/src/revision.rs | 138 ++++++++++++++++++ crates/revision_order/tests/crate_contract.rs | 7 + crates/revision_order/tests/order_contract.rs | 77 ++++++++++ docs/TRACEABILITY.md | 2 +- docs/adr/README.md | 2 +- docs/research/revision-system-time-order.md | 29 ++++ docs/research/standards-and-literature.md | 2 + docs/validation/temporal-event-foundation.md | 1 + scripts/check_workspace_contract.py | 1 + 17 files changed, 353 insertions(+), 3 deletions(-) create mode 100644 crates/revision_order/Cargo.toml create mode 100644 crates/revision_order/src/error.rs create mode 100644 crates/revision_order/src/lib.rs create mode 100644 crates/revision_order/src/revision.rs create mode 100644 crates/revision_order/tests/crate_contract.rs create mode 100644 crates/revision_order/tests/order_contract.rs create mode 100644 docs/research/revision-system-time-order.md diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index ffe514db6..1c8382b6b 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -61,6 +61,7 @@ boundaries above remain the target modular MSA architecture. | `tepp_simulation` | known-truth temporal/event data generation | | `validation_core` | RMSE, bias, coverage, graph, and Monte Carlo metrics | | `tepp_api` | versioned DTO, schema, and export contracts | +| `revision_order` | later document revisions must have later system time | No crate exposes placeholder production behavior in Task 1. This prevents an empty façade from becoming a de facto public API before its invariants and tests diff --git a/CHANGELOG.md b/CHANGELOG.md index c1cc6e879..57cb8ce57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to TEPP are documented here. The format follows Keep a Chang ### Added +- `revision_order` system-time gate: a higher document revision number cannot carry earlier or equal system time; recovered order flags match known truth at a higher computed rate than accepting every pair (ADR 0002/0013). - `persistence_postgres` backup/restore integrity: restored snapshots stay unusable until tenant, canonical `SHA-256`, knowledge-cutoff eligibility, temporal window order, and append-only triggers revalidate; SQL probes raise `restore integrity failed` (ADR 0013). - `persistence_postgres` concurrent document-write stress: atomic revise `DO` block that requires exactly one open `system_to` close, SQLSTATE mapping onto `ConcurrentWriteConflict` / `DuplicateDocumentRecord`, and live multi-session insert/revise/append-only proofs. No new migration number. - `tepp_api` naruon HTTP interchange: versioned `https` POST contracts for analysis-run create and modular export authorization that refuse table-access URLs, review/Copilot credential headers, reserved standard-header redefinition, principal-only export idempotency keys, and lexical inference claims (ADR 0011). diff --git a/Cargo.lock b/Cargo.lock index 372a55f43..1947992d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -929,6 +929,10 @@ dependencies = [ "uuid", ] +[[package]] +name = "revision_order" +version = "0.1.0" + [[package]] name = "ring" version = "0.17.14" diff --git a/Cargo.toml b/Cargo.toml index 925659406..07f5a8194 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ members = [ "crates/tepp_simulation", "crates/validation_core", "crates/tepp_api", + "crates/revision_order", ] default-members = [ "crates/evidence_core", @@ -23,6 +24,7 @@ default-members = [ "crates/tepp_simulation", "crates/validation_core", "crates/tepp_api", + "crates/revision_order", ] [workspace.package] diff --git a/README.md b/README.md index ae74015d3..35150e58a 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ implemented in Rust. ## Current implementation state This branch establishes the Task 1 Rust workspace and quality-gate foundation. -The ten bounded crates compile independently but intentionally expose no +The eleven bounded crates compile independently but intentionally expose no placeholder production APIs. Domain behavior begins in Task 2 with immutable evidence identifiers and source records. @@ -22,6 +22,7 @@ crates/corpus_split crates/tepp_simulation crates/validation_core crates/tepp_api +crates/revision_order ``` ## Local verification diff --git a/crates/revision_order/Cargo.toml b/crates/revision_order/Cargo.toml new file mode 100644 index 000000000..78bba5b92 --- /dev/null +++ b/crates/revision_order/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "revision_order" +description = "Later document revisions cannot move backward in system time." +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +authors.workspace = true +repository.workspace = true +homepage.workspace = true +readme.workspace = true +keywords.workspace = true +categories.workspace = true +publish = false + +[lints] +workspace = true diff --git a/crates/revision_order/src/error.rs b/crates/revision_order/src/error.rs new file mode 100644 index 000000000..474053995 --- /dev/null +++ b/crates/revision_order/src/error.rs @@ -0,0 +1,48 @@ +//! Fail-closed revision-order errors. + +use std::fmt; + +/// A fail-closed revision-order error. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[non_exhaustive] +pub enum RevisionOrderError { + /// A later revision did not have a later system time. + SystemTimeDidNotIncrease, + /// A revision number or recovery slice was empty, zero, or mismatched. + InvalidRevisionPayload, +} + +impl fmt::Display for RevisionOrderError { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + let message = match self { + Self::SystemTimeDidNotIncrease => { + "later document revisions must have later system time" + } + Self::InvalidRevisionPayload => "invalid revision-order payload", + }; + formatter.write_str(message) + } +} + +impl std::error::Error for RevisionOrderError {} + +#[cfg(test)] +mod tests { + use super::RevisionOrderError; + + #[test] + fn error_messages_are_stable() { + for (error, message) in [ + ( + RevisionOrderError::SystemTimeDidNotIncrease, + "later document revisions must have later system time", + ), + ( + RevisionOrderError::InvalidRevisionPayload, + "invalid revision-order payload", + ), + ] { + assert_eq!(error.to_string(), message); + } + } +} diff --git a/crates/revision_order/src/lib.rs b/crates/revision_order/src/lib.rs new file mode 100644 index 000000000..5a6c59458 --- /dev/null +++ b/crates/revision_order/src/lib.rs @@ -0,0 +1,21 @@ +#![forbid(unsafe_code)] +#![deny(missing_docs)] +#![allow(clippy::cast_precision_loss)] +//! Later document revisions cannot move backward in system time. +//! +//! A higher revision number is a later assertion about the same document +//! identity. Its system time must strictly increase (ADR 0002/0013). + +mod error; +mod revision; + +/// Fail-closed revision-order errors. +pub use error::RevisionOrderError; +/// One document revision with a positive revision number and system time. +pub use revision::DocumentRevision; +/// Fraction of recovered order flags that match known truth. +pub use revision::order_recovery_rate; +/// Refuse a later revision whose system time did not increase. +pub use revision::refuse_nonincreasing_system_time; +/// Return whether a later revision has a later system time. +pub use revision::revisions_are_increasing; diff --git a/crates/revision_order/src/revision.rs b/crates/revision_order/src/revision.rs new file mode 100644 index 000000000..a58b90d28 --- /dev/null +++ b/crates/revision_order/src/revision.rs @@ -0,0 +1,138 @@ +//! Document revisions stamped with system time. + +use crate::RevisionOrderError; + +/// One document revision with a positive revision number and system time. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub struct DocumentRevision { + revision_number: u32, + system_time_seconds: i64, +} + +impl DocumentRevision { + /// Construct a revision whose number is at least one. + /// + /// # Errors + /// + /// Returns [`RevisionOrderError::InvalidRevisionPayload`] when + /// `revision_number` is zero. + pub const fn new( + revision_number: u32, + system_time_seconds: i64, + ) -> Result { + if revision_number == 0 { + return Err(RevisionOrderError::InvalidRevisionPayload); + } + Ok(Self { + revision_number, + system_time_seconds, + }) + } + + /// Positive revision number. + #[must_use] + pub const fn revision_number(self) -> u32 { + self.revision_number + } + + /// System/record time in seconds. + #[must_use] + pub const fn system_time_seconds(self) -> i64 { + self.system_time_seconds + } +} + +/// Return whether `later` has a greater revision number and later system time. +/// +/// # Errors +/// +/// Returns [`RevisionOrderError::InvalidRevisionPayload`] when `later` is not +/// a strictly greater revision number than `earlier`. +pub fn revisions_are_increasing( + earlier: DocumentRevision, + later: DocumentRevision, +) -> Result { + if later.revision_number <= earlier.revision_number { + return Err(RevisionOrderError::InvalidRevisionPayload); + } + Ok(later.system_time_seconds > earlier.system_time_seconds) +} + +/// Refuse a later revision whose system time did not increase. +/// +/// # Errors +/// +/// Returns revision-construction errors, or +/// [`RevisionOrderError::SystemTimeDidNotIncrease`] when the system times +/// are not strictly increasing. +pub fn refuse_nonincreasing_system_time( + earlier: DocumentRevision, + later: DocumentRevision, +) -> Result<(), RevisionOrderError> { + if revisions_are_increasing(earlier, later)? { + return Ok(()); + } + Err(RevisionOrderError::SystemTimeDidNotIncrease) +} + +/// Fraction of recovered order flags that match known truth. +/// +/// # Errors +/// +/// Returns [`RevisionOrderError::InvalidRevisionPayload`] when either slice +/// is empty or the lengths differ. +pub fn order_recovery_rate(truth: &[bool], decided: &[bool]) -> Result { + if truth.is_empty() || truth.len() != decided.len() { + return Err(RevisionOrderError::InvalidRevisionPayload); + } + let mut matches = 0_u32; + for (truth_flag, decided_flag) in truth.iter().zip(decided) { + if truth_flag == decided_flag { + matches += 1; + } + } + Ok(f64::from(matches) / truth.len() as f64) +} + +#[cfg(test)] +mod tests { + use super::{ + DocumentRevision, order_recovery_rate, refuse_nonincreasing_system_time, + revisions_are_increasing, + }; + use crate::RevisionOrderError; + + #[test] + fn local_branches_cover_order_and_payloads() { + let first = DocumentRevision::new(1, 10).expect("first"); + let second = DocumentRevision::new(2, 20).expect("second"); + assert_eq!(first.revision_number(), 1); + assert_eq!(first.system_time_seconds(), 10); + assert!(revisions_are_increasing(first, second).expect("increasing")); + refuse_nonincreasing_system_time(first, second).expect("ok"); + let same_time = DocumentRevision::new(3, 20).expect("same"); + assert!(!revisions_are_increasing(second, same_time).expect("flat")); + assert_eq!( + refuse_nonincreasing_system_time(second, same_time), + Err(RevisionOrderError::SystemTimeDidNotIncrease) + ); + assert_eq!( + revisions_are_increasing(second, first), + Err(RevisionOrderError::InvalidRevisionPayload) + ); + assert_eq!( + DocumentRevision::new(0, 1), + Err(RevisionOrderError::InvalidRevisionPayload) + ); + let matched = order_recovery_rate(&[true], &[true]).expect("rate"); + assert!((matched - 1.0).abs() < f64::EPSILON); + assert_eq!( + order_recovery_rate(&[], &[]), + Err(RevisionOrderError::InvalidRevisionPayload) + ); + assert_eq!( + order_recovery_rate(&[true], &[]), + Err(RevisionOrderError::InvalidRevisionPayload) + ); + } +} diff --git a/crates/revision_order/tests/crate_contract.rs b/crates/revision_order/tests/crate_contract.rs new file mode 100644 index 000000000..2b7f3862a --- /dev/null +++ b/crates/revision_order/tests/crate_contract.rs @@ -0,0 +1,7 @@ +//! Integration contract for the `revision_order` package identity. + +#[test] +fn package_identity_is_stable() { + let observed = std::hint::black_box(env!("CARGO_PKG_NAME")); + assert_eq!(observed, "revision_order"); +} diff --git a/crates/revision_order/tests/order_contract.rs b/crates/revision_order/tests/order_contract.rs new file mode 100644 index 000000000..8dfbef910 --- /dev/null +++ b/crates/revision_order/tests/order_contract.rs @@ -0,0 +1,77 @@ +//! Later revisions cannot carry earlier or equal system time. + +use revision_order::{ + DocumentRevision, RevisionOrderError, order_recovery_rate, refuse_nonincreasing_system_time, + revisions_are_increasing, +}; + +fn revision(number: u32, system: i64) -> DocumentRevision { + DocumentRevision::new(number, system).expect("revision") +} + +#[test] +fn later_revisions_cannot_move_backward_in_system_time() { + let first = revision(1, 10); + let second = revision(2, 20); + let backward = revision(3, 15); + assert!(revisions_are_increasing(first, second).expect("increasing")); + refuse_nonincreasing_system_time(first, second).expect("ok"); + assert!(!revisions_are_increasing(second, backward).expect("backward")); + assert_eq!( + refuse_nonincreasing_system_time(second, backward), + Err(RevisionOrderError::SystemTimeDidNotIncrease) + ); + assert_eq!( + refuse_nonincreasing_system_time(second, revision(4, 20)), + Err(RevisionOrderError::SystemTimeDidNotIncrease) + ); +} + +#[test] +fn recovered_order_flags_match_known_truth_better_than_accepting_all() { + let pairs = [ + (revision(1, 10), revision(2, 20)), + (revision(2, 20), revision(3, 15)), + (revision(3, 30), revision(4, 40)), + ]; + let truth = [true, false, true]; + let recovered = [ + revisions_are_increasing(pairs[0].0, pairs[0].1).expect("p0"), + revisions_are_increasing(pairs[1].0, pairs[1].1).expect("p1"), + revisions_are_increasing(pairs[2].0, pairs[2].1).expect("p2"), + ]; + let collapsed = [true, true, true]; + let recovered_rate = order_recovery_rate(&truth, &recovered).expect("recovered"); + let collapsed_rate = order_recovery_rate(&truth, &collapsed).expect("collapsed"); + let expected = { + let mut matches = 0_u32; + for (truth_flag, decided_flag) in truth.iter().zip(recovered.iter()) { + if truth_flag == decided_flag { + matches += 1; + } + } + f64::from(matches) / f64::from(u32::try_from(truth.len()).expect("len")) + }; + assert!((recovered_rate - expected).abs() < f64::EPSILON); + assert!(recovered_rate > collapsed_rate); +} + +#[test] +fn empty_or_invalid_revision_payloads_fail_closed() { + assert_eq!( + DocumentRevision::new(0, 10), + Err(RevisionOrderError::InvalidRevisionPayload) + ); + assert_eq!( + order_recovery_rate(&[], &[]), + Err(RevisionOrderError::InvalidRevisionPayload) + ); + assert_eq!( + order_recovery_rate(&[true], &[]), + Err(RevisionOrderError::InvalidRevisionPayload) + ); + assert_eq!( + order_recovery_rate(&[true, false], &[true]), + Err(RevisionOrderError::InvalidRevisionPayload) + ); +} diff --git a/docs/TRACEABILITY.md b/docs/TRACEABILITY.md index c29d97433..aad22a0c3 100644 --- a/docs/TRACEABILITY.md +++ b/docs/TRACEABILITY.md @@ -17,7 +17,7 @@ The full APA 7th standards/literature register remains `docs/research/standards- | time-varying cross-classified multiple membership | PRD; ADR 0003 | `membership_core` network on protected main; multilevel estimators remaining | partial | | leakage-safe availability/cutoff snapshots | PRD; ADR 0002/0013 | `corpus_split` on protected main | implemented-main | | recovery metrics (RMSE, bias, coverage, graph, temporal order, Monte Carlo SE gates) | PRD; Test Strategy; ADR 0007/0014 | `validation_core` on protected main (PR #19); SE-aware Monte Carlo gates included | implemented-main | -| PostgreSQL bitemporal/lineage persistence | ADR 0013; Architecture/ERD | `persistence_postgres` migration contracts, in-memory adapters, live SQL session/document SQL port, tenant RLS (`0002` + session GUC/role helpers), `DATABASE_URL` SQLx gate, optional `live-sqlx` `PgPool` driver, exact-head live PostgreSQL CI with isolation proof, append-only immutability triggers (`0004`), temporal interval ordering CHECKs (`0005`), typed membership assignment (`0006` implemented-main), event-relation/mention/instance SQL (#37–#39 implemented-main), source-artifact SQL (#40 implemented-main), audit-event SQL (#41 implemented-main), concurrent document-write stress (#43 implemented-main), backup/restore integrity revalidation (active PR); remaining physical ERD constraints | partial | +| PostgreSQL bitemporal/lineage persistence | ADR 0013; Architecture/ERD | `persistence_postgres` on protected main as before; `revision_order` later-revision system-time gate on the active PR; remaining physical ERD constraints | partial | | known-truth temporal/event simulation manifests | PRD; TRD; Test Strategy | `tepp_simulation` on protected main; recovery metrics in `validation_core` | implemented-main | | versioned service/API contracts and exports | PRD; API contract; ADR 0011/0013 | `tepp_api` analysis-run/export/JSON-LD/GraphML contracts on protected main (PR #21); HTTP service remaining accepted-target | partial | | immutable split/run/reproducibility manifests | ADR 0013; ERD | `tepp_api` reproducibility manifest contract on protected main; `persistence_postgres` append-only SQL insert/lookup for `reproducibility_manifest`, `corpus_split_manifest`, `model_run`, and `model_artifact` (migration `0003`); full physical ERD constraints remaining | partial | diff --git a/docs/adr/README.md b/docs/adr/README.md index 1a9a7b315..39530798f 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -18,7 +18,7 @@ Read [`ADR_POLICY.md`](ADR_POLICY.md) first. **Decision status and implementatio | [0010](0010-adaptive-llm-orchestration.md) | Adaptive LLM orchestration and test-time compute | Accepted | accepted-target | Owns direct/verify/committee/conductor selection, budget, role/topology, and ablation policy. | | [0011](0011-standalone-modular-msa-boundary.md) | Standalone operation and modular CWL MSA boundary | Accepted | partial | Owns cross-service persistence/credential/API authority; no direct cross-service application-table coupling. | | [0012](0012-temporal-relational-shared-latent-topic-measurement.md) | Temporal Relational Shared-Latent Topic Measurement (TRSL-TM) | Accepted | accepted-target | Owns topic backend compatibility, global topic identity, method effects, K/model-selection prerequisites, and compositional topic coordinates. | -| [0013](0013-bitemporal-persistence-reproducibility-and-split-authority.md) | Bitemporal persistence, reproducibility manifests, and relation-aware split authority | Accepted | partial | Owns PostgreSQL adapter semantics, immutable run/split manifests, leakage-safe partitions, and recovery identity; optional `live-sqlx` `PgPool`, live PG CI, and tenant RLS implemented; full physical ERD remaining. | +| [0013](0013-bitemporal-persistence-reproducibility-and-split-authority.md) | Bitemporal persistence, reproducibility manifests, and relation-aware split authority | Accepted | active-PR | Document revision system-time order in `revision_order` on the active PR; full physical ERD remaining. | | [0014](0014-scientific-claim-promotion-and-release-evidence.md) | Scientific claim promotion and release evidence authority | Accepted | partial | Separates design, implementation, scientific/product claim, and release authority; repository SBOM/provenance generator implemented, full release bundle remaining. | | [0015](0015-autonomous-development-review-and-merge-authority.md) | Autonomous development, review, and merge authority separation | Accepted | active-PR | Separates model proposal, deterministic verification, publication, independent review, and merge/release authority. | | [0016](0016-tdt-chronos-event-intelligence-boundary.md) | TDT, CHRONOS, and Event Ontology intelligence boundary | Accepted | accepted-target | Separates observed evidence, detection/tracking, prediction/schema inference, temporal consistency, and promoted transition authority. | diff --git a/docs/research/revision-system-time-order.md b/docs/research/revision-system-time-order.md new file mode 100644 index 000000000..3b2e705db --- /dev/null +++ b/docs/research/revision-system-time-order.md @@ -0,0 +1,29 @@ +# Document revision system-time order (doctoring) + +## Scope + +`revision_order` requires a later document revision number to carry a +strictly later system time. Recovery is the computed share of order flags +that match known truth. + +This slice does not persist revisions, allocate migration `0008`, or +replace `persistence_postgres` interval CHECKs. + +## Authority + +### Normative TEPP contract + +- `docs/adr/0002-six-clock-temporal-semantics.md` — system/record time is + distinct from event time; later assertions cannot rewrite earlier + system-time order. +- `docs/adr/0013-bitemporal-persistence-reproducibility-and-split-authority.md` + — document versions are bitemporal; revision identity is ordered. + +### Supporting literature + +Snodgrass (2000) treats transaction/system time as the time a fact was +recorded. A later recorded version cannot precede an earlier one in +system time. + +Snodgrass, R. T. (2000). *Developing time-oriented database applications +in SQL*. Morgan Kaufmann. diff --git a/docs/research/standards-and-literature.md b/docs/research/standards-and-literature.md index b4b144684..fb8243fba 100644 --- a/docs/research/standards-and-literature.md +++ b/docs/research/standards-and-literature.md @@ -96,6 +96,8 @@ Moreau, L., & Missier, P. (Eds.). (2013). *PROV-DM: The PROV data model*. World TEPP separates stable record identity, content equality, exact text location, wire representation, authorization, and provenance. JSON wire records are explicit versioned DTOs with unknown-field rejection and reconstruct through domain validation. `SHA-256` detects content substitution but is not treated as proof of origin, authority, or chain of custody. +Snodgrass, R. T. (2000). *Developing time-oriented database applications in SQL*. Morgan Kaufmann. Transaction/system time informs `revision_order`; a later recorded revision cannot precede an earlier one. + ## AI risk, management systems, and assurance readiness International Organization for Standardization. (2023a). *Information technology—Artificial intelligence—Guidance on risk management* (ISO/IEC Standard No. 23894:2023). https://www.iso.org/standard/77304.html diff --git a/docs/validation/temporal-event-foundation.md b/docs/validation/temporal-event-foundation.md index 295fbae0f..5a48cfd1f 100644 --- a/docs/validation/temporal-event-foundation.md +++ b/docs/validation/temporal-event-foundation.md @@ -23,6 +23,7 @@ This report tracks exact-head scientific and engineering evidence required befor | Truth corpora / manifests | `tepp_simulation` | implemented-main | — | deterministic generator tests | Task 10 / PR #18 | | Recovery metrics | `validation_core` | implemented-main | — | RMSE/bias/coverage/MC gates | Task 11 / PR #19 | | Versioned API/export contracts | `tepp_api` | implemented-main | naruon HTTP interchange | unknown-field/version/limit + naruon HTTPS interchange tests | Task 12 / PR #21; live HTTP service remaining | +| Revision system-time order | `revision_order` | active-PR | this PR | order-flag recovery vs accept-all | ADR 0002/0013 | | CWL modular connectors | `docs/connectors/*` | implemented-main | — | contract docs + examples | PR #22; live HTTP ports remaining | | Release SBOM/provenance generator | `scripts/release_evidence.py` | partial | — | generate+validate in CI | Task 13 partial / PR #28 | diff --git a/scripts/check_workspace_contract.py b/scripts/check_workspace_contract.py index c7b1ecf58..4b8114a01 100644 --- a/scripts/check_workspace_contract.py +++ b/scripts/check_workspace_contract.py @@ -23,6 +23,7 @@ "tepp_simulation", "validation_core", "tepp_api", + "revision_order", ) REQUIRED_CI_SNIPPETS: tuple[str, ...] = ( From b032c855177fee5a470e73280b60a2685f2063fb Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 03:43:20 +0900 Subject: [PATCH 2/2] fix(docs): keep ADR 0013 indexed --- docs/adr/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/adr/README.md b/docs/adr/README.md index fd07eaf8b..759e1ef65 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -18,7 +18,7 @@ Read [`ADR_POLICY.md`](ADR_POLICY.md) first. **Decision status and implementatio | [0010](0010-adaptive-llm-orchestration.md) | Adaptive LLM orchestration and test-time compute | Accepted | partial | `tepp_api` router/ablation/orchestrator binding on the active PR; live NIM execution and production ablation evidence remain accepted-target. | | [0011](0011-standalone-modular-msa-boundary.md) | Standalone operation and modular CWL MSA boundary | Accepted | partial | Owns cross-service persistence/credential/API authority; no direct cross-service application-table coupling. | | [0012](0012-temporal-relational-shared-latent-topic-measurement.md) | Temporal Relational Shared-Latent Topic Measurement (TRSL-TM) | Accepted | accepted-target | Owns topic backend compatibility, global topic identity, method effects, K/model-selection prerequisites, and compositional topic coordinates. | - | [0013](0013-bitemporal-persistence-reproducibility-and-split-authority.md) | Bitemporal persistence, reproducibility manifests, and relation-aware split authority | Accepted | partial | Owns PostgreSQL adapter semantics, immutable run/split manifests, leakage-safe partitions, and recovery identity; optional `live-sqlx` `PgPool`, live PG CI, tenant RLS, and `0006` membership implemented-main; `0007` retention/deletion/legal-hold implemented-main; document revision system-time order in `revision_order` is active on this PR; remaining physical ERD/backup accepted-target. | +| [0013](0013-bitemporal-persistence-reproducibility-and-split-authority.md) | Bitemporal persistence, reproducibility manifests, and relation-aware split authority | Accepted | partial | Owns PostgreSQL adapter semantics, immutable run/split manifests, leakage-safe partitions, and recovery identity; optional `live-sqlx` `PgPool`, live PG CI, tenant RLS, and `0006` membership implemented-main; `0007` retention/deletion/legal-hold implemented-main; document revision system-time order in `revision_order` is active on this PR; remaining physical ERD/backup accepted-target. | | [0014](0014-scientific-claim-promotion-and-release-evidence.md) | Scientific claim promotion and release evidence authority | Accepted | partial | Separates design, implementation, scientific/product claim, and release authority; repository SBOM/provenance generator implemented, full release bundle remaining. | | [0015](0015-autonomous-development-review-and-merge-authority.md) | Autonomous development, review, and merge authority separation | Accepted | active-PR | Separates model proposal, deterministic verification, publication, independent review, and merge/release authority. | | [0016](0016-tdt-chronos-event-intelligence-boundary.md) | TDT, CHRONOS, and Event Ontology intelligence boundary | Accepted | accepted-target | Separates observed evidence, detection/tracking, prediction/schema inference, temporal consistency, and promoted transition authority. |