Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/temper-authz/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ impl SecurityContext {
self
}

/// Attach ADR-0040 action-context provenance to the principal entity.
/// Attach ADR-0161 action-context provenance to the principal entity.
///
/// Cedar policies can then match on `principal.action_context`, for
/// example `principal.action_context == "composite:Apps.Fork"`.
Expand Down
2 changes: 1 addition & 1 deletion crates/temper-jit/src/table/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ impl TransitionTable {
.push(i);
}

// ADR-0045 / ADR-0047: collect per-state-variable overflow metadata.
// ADR-0166 / ADR-0047: collect per-state-variable overflow metadata.
let mut state_var_metadata = std::collections::BTreeMap::new();
for sv in &automaton.state {
if sv.overflow_inline_max_bytes.is_some() || sv.overflow_ttl_seconds.is_some() {
Expand Down
8 changes: 4 additions & 4 deletions crates/temper-jit/src/table/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ pub struct TransitionTable {
/// kNN reads (`Temper.Nearest`). Empty when the spec declared no `[[vector]]`.
#[serde(default)]
pub vectors: Vec<DeclaredVector>,
/// Per-state-variable metadata for platform primitives (ADR-0045, ADR-0047).
/// Per-state-variable metadata for platform primitives (ADR-0166, ADR-0047).
/// Keyed by state-variable name. Empty map when the IOA spec did not
/// declare any per-field overrides.
#[serde(default)]
pub state_var_metadata: BTreeMap<String, StateVarMetadata>,
/// Composite-action metadata keyed by action name (ADR-0040).
/// Composite-action metadata keyed by action name (ADR-0161).
#[serde(default)]
pub composite_actions: BTreeMap<String, CompositeActionMetadata>,
/// Pre-built index: action name → indices into `rules`.
Expand All @@ -77,14 +77,14 @@ pub struct TransitionTable {

/// Platform-primitive metadata for a single state variable.
///
/// - `overflow_inline_max_bytes` (ADR-0045): serialized-byte ceiling above
/// - `overflow_inline_max_bytes` (ADR-0166): serialized-byte ceiling above
/// which the value is moved to the content-addressed blob store. `None`
/// falls back to the crate-wide `DEFAULT_FIELD_INLINE_MAX` (128KB).
/// - `overflow_ttl_seconds` (ADR-0047): TTL for overflow blobs written on
/// behalf of this field. `None` = permanent (pre-ADR behavior).
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
pub struct StateVarMetadata {
/// Per-field inline byte ceiling for field overflow (ADR-0045).
/// Per-field inline byte ceiling for field overflow (ADR-0166).
#[serde(default, skip_serializing_if = "Option::is_none")]
pub overflow_inline_max_bytes: Option<usize>,
/// Per-field TTL in seconds for overflow blobs (ADR-0047).
Expand Down
2 changes: 1 addition & 1 deletion crates/temper-platform/src/bearer_auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ pub async fn bearer_auth_check(
.as_ref()
.is_some_and(|expected| constant_time_eq(token.as_bytes(), expected.as_bytes()));

// ADR-0043 guest override path: internal loopback callers may present the
// ADR-0165 guest override path: internal loopback callers may present the
// platform API key while explicitly declaring the principal they are acting
// as. Preserve those headers instead of collapsing the request into the
// bootstrapped operator credential.
Expand Down
6 changes: 3 additions & 3 deletions crates/temper-server/src/blobs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ pub(crate) async fn hydrate_blob_refs_in_value(store: &BlobStore, value: &mut Va
/// `BTreeMap` of blob keys to bytes for refs at or above the ceiling (the
/// "deferred" set). Callers that hand `value` off to a WASM guest forward
/// the deferred map as `blob_cache` so guests can resolve oversize fields
/// via `host_read_field_stream`. See ADR-0046.
/// via `host_read_field_stream`. See ADR-0169.
#[cfg(test)]
pub(crate) async fn hydrate_blob_refs_in_value_with_ceiling(
store: &BlobStore,
Expand Down Expand Up @@ -365,7 +365,7 @@ mod tests {

/// End-to-end: ceiling-aware hydration inlines small blob refs and defers
/// large ones into the returned map. This is the WASM-dispatch path from
/// ADR-0046.
/// ADR-0169.
#[tokio::test]
async fn hydrate_with_ceiling_inlines_small_and_defers_large() {
let (store, _dir) = open_store().await;
Expand Down Expand Up @@ -425,7 +425,7 @@ mod tests {
/// Per-field `overflow_inline_max_bytes` in the spec overrides the mode
/// default. Declaring a 1024-byte ceiling forces a 4KB field into the
/// overflow path even though the default 128KB ceiling would keep it
/// inline. ADR-0045 Phase 4b.
/// inline. ADR-0166 Phase 4b.
#[tokio::test]
async fn per_field_inline_max_override_forces_overflow() {
use crate::entity_actor::effects::sync_fields_with_metadata;
Expand Down
22 changes: 11 additions & 11 deletions crates/temper-server/src/entity_actor/actor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,7 @@ impl EntityActor {
// action already persisted the blob, INSERT OR IGNORE
// is a no-op. If the prior server died between emitting
// the event and persisting the blob, this is the
// recovery path. See ADR-0040, ADR-0045.
// recovery path. See ADR-0040, ADR-0166.
if !overflow_blobs.is_empty()
&& let Err(e) =
Self::persist_overflow_blobs(blob_store, &overflow_blobs).await
Expand Down Expand Up @@ -948,15 +948,15 @@ impl Actor for EntityActor {
return Ok(());
}

// Captured BEFORE the action applies. The retry path (ADR-0046)
// Captured BEFORE the action applies. The retry path (ADR-0168)
// updates these in lockstep with replay so postconditions hold
// across the race window.
let mut event_count_before = state.total_event_count;
let mut state_before = state.clone();
let field_sync_mode =
Self::field_sync_mode_for_backend(self.event_backend, self.blob_store.as_ref());

// `result` and `event` are `mut` so that a successful ADR-0046
// `result` and `event` are `mut` so that a successful ADR-0168
// retry can replace them with values re-evaluated against the
// caught-up state. The downstream telemetry and reply use
// whichever pair last succeeded in persist.
Expand Down Expand Up @@ -1000,7 +1000,7 @@ impl Actor for EntityActor {
}

// Persist to Postgres (if configured). On
// `ConcurrencyViolation` enter the ADR-0046 retry cycle —
// `ConcurrencyViolation` enter the ADR-0168 retry cycle —
// replay events, re-evaluate the action against the caught-up
// state, and retry the persist up to two more times. Other
// error variants fail immediately (same as before).
Expand All @@ -1019,7 +1019,7 @@ impl Actor for EntityActor {
expected: _,
actual,
}) => {
// ADR-0046 Sub-Decision 3: dedicated APM span
// ADR-0168 Sub-Decision 3: dedicated APM span
// covering the retry cycle. `attempts` and
// `outcome` are recorded at the end so Datadog
// APM can filter and chart conflict-handling
Expand All @@ -1039,17 +1039,17 @@ impl Actor for EntityActor {
entity = %state.entity_id,
action = %name,
actual_seq = actual,
"persist hit optimistic-concurrency violation; entering ADR-0046 retry"
"persist hit optimistic-concurrency violation; entering ADR-0168 retry"
);

// 2 retries + 1 initial = 3 total attempts (ADR-0046).
// 2 retries + 1 initial = 3 total attempts (ADR-0168).
const MAX_RETRIES: u32 = 2;
let mut retry_idx: u32 = 0;
let mut retry_final: Option<(
crate::runtime_metrics::ConcurrencyRetryOutcome,
Option<String>,
)> = None;
// ADR-0046 Sub-Decision 4: track the most
// ADR-0168 Sub-Decision 4: track the most
// recent authoritative sequence across retries
// so the post-replay assertion catches a
// divergent replay even on a multi-conflict
Expand Down Expand Up @@ -1077,7 +1077,7 @@ impl Actor for EntityActor {
)
.await?;

// ADR-0046 Sub-Decision 4: replay must at
// ADR-0168 Sub-Decision 4: replay must at
// minimum reach the sequence the store
// reported. Reaching further is fine (a
// later writer may have appended during
Expand Down Expand Up @@ -1150,7 +1150,7 @@ impl Actor for EntityActor {
tokio::time::sleep(std::time::Duration::from_millis(
backoff_ms,
))
.await; // determinism-ok: rare retry backoff (ADR-0046)
.await; // determinism-ok: rare retry backoff (ADR-0168)

match self
.persist_event(
Expand Down Expand Up @@ -1218,7 +1218,7 @@ impl Actor for EntityActor {
// 1-based; `retry_idx` counts completed retries.
let total_attempts = u64::from(1 + retry_idx);
if let Some((outcome, err_msg)) = retry_final {
// Close the ADR-0046 APM span with the
// Close the ADR-0168 APM span with the
// final attempt count + outcome so APM
// views can filter by either.
retry_span.record("attempts", total_attempts);
Expand Down
6 changes: 3 additions & 3 deletions crates/temper-server/src/entity_actor/effects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -730,7 +730,7 @@ pub fn apply_new_state_fallback(state: &mut EntityState, from_status: &str, new_
/// rest of `entity_state` (counters, booleans, lists, other fields) while
/// covering p99 of observed oversize-field traffic.
///
/// See ADR-0045.
/// See ADR-0166.
pub const DEFAULT_FIELD_INLINE_MAX: usize = 131_072; // 128 KB

/// Sync all state variables into the `fields` JSON object.
Expand All @@ -740,7 +740,7 @@ pub const DEFAULT_FIELD_INLINE_MAX: usize = 131_072; // 128 KB
/// the effective per-field inline ceiling are either truncated or projected
/// through blob refs, depending on `mode`. When `state_var_metadata` is
/// `Some`, per-field `overflow_inline_max_bytes` and `overflow_ttl_seconds`
/// overrides are consulted (ADR-0045, ADR-0047).
/// overrides are consulted (ADR-0166, ADR-0047).
pub fn sync_fields(
state: &mut EntityState,
params: &serde_json::Value,
Expand Down Expand Up @@ -1782,7 +1782,7 @@ params = ["NewCommitSha"]

#[test]
fn field_over_legacy_32k_stays_inline_under_new_ceiling() {
// Regression test for ADR-0045: fields in the 32KB-128KB band that
// Regression test for ADR-0166: fields in the 32KB-128KB band that
// previously overflowed now stay inline.
let mut state = make_state("Session", "s-1");
let mid = "z".repeat(80 * 1024); // 80 KB — above old 32KB cap, below new 128KB
Expand Down
12 changes: 6 additions & 6 deletions crates/temper-server/src/runtime_metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ fn metrics() -> &'static RuntimeMetrics {
.with_description(
"WASM integration dispatches that fell back to the default timeout because the \
spec did not set `timeout_secs`. Apps firing this frequently should wire an \
explicit timeout in their integration config. See ADR-0045.",
explicit timeout in their integration config. See ADR-0167.",
)
.build(),
entity_concurrency_retry_total: meter
Expand All @@ -146,15 +146,15 @@ fn metrics() -> &'static RuntimeMetrics {
"Entity-actor persist attempts that hit an optimistic concurrency conflict \
and either recovered, exhausted the retry budget, or found the action no \
longer legal after replay. Treat sustained activity as a canary for an \
unknown scheduler race — not a retry budget to raise. See ADR-0046.",
unknown scheduler race — not a retry budget to raise. See ADR-0168.",
)
.build(),
entity_concurrency_retry_attempts: meter
.u64_histogram("temper_entity_concurrency_retry_attempts")
.with_description(
"Number of persist attempts a single action consumed before success or \
exhaustion. Value of 1 is the no-retry happy path; anything higher is a \
canary. See ADR-0046.",
canary. See ADR-0168.",
)
.build(),
dispatch_ask_attempts: meter
Expand Down Expand Up @@ -522,7 +522,7 @@ pub fn record_process_resident_memory_bytes(bytes: u64) {
/// Record a WASM integration dispatch that fell back to the default timeout
/// because the integration spec did not set `timeout_secs`.
///
/// See ADR-0045.
/// See ADR-0167.
pub fn record_wasm_default_timeout_used(tenant: &str, entity_type: &str, module: &str) {
metrics().wasm_integration_default_timeout_used_total.add(
1,
Expand All @@ -536,7 +536,7 @@ pub fn record_wasm_default_timeout_used(tenant: &str, entity_type: &str, module:

/// Possible outcomes for an entity-actor concurrency retry cycle.
///
/// See ADR-0046.
/// See ADR-0168.
#[derive(Debug, Clone, Copy)]
pub enum ConcurrencyRetryOutcome {
/// The action persisted successfully (possibly after one or more retries).
Expand All @@ -562,7 +562,7 @@ impl ConcurrencyRetryOutcome {
/// Record the outcome of an entity-actor concurrency retry cycle plus the
/// number of attempts consumed. Attempts is 1-based (1 = no retries).
///
/// See ADR-0046.
/// See ADR-0168.
pub fn record_entity_concurrency_retry(
entity_type: &str,
outcome: ConcurrencyRetryOutcome,
Expand Down
4 changes: 2 additions & 2 deletions crates/temper-server/src/state/dispatch/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ impl crate::state::ServerState {
.integration_config
.insert("temper_api_url".to_string(), api_url);
}
// ADR-0046: inline-hydrate blob refs below the 128KB ceiling; defer
// ADR-0169: inline-hydrate blob refs below the 128KB ceiling; defer
// oversize refs into a blob_cache the WASM guest can read via
// host_read_field_stream. No-op on tenants without a Turso store.
let blob_cache = instrument_wasm_dispatch_phase(
Expand Down Expand Up @@ -608,7 +608,7 @@ impl crate::state::ServerState {
//
// When no explicit `timeout_secs` is configured, fall back to the
// platform default (`WasmResourceLimits::default().max_duration`, 120s
// per ADR-0045). The fallback is observable:
// per ADR-0167). The fallback is observable:
// - `tracing::warn!` for human debugging
// - counter `temper_wasm_integration_default_timeout_used_total` for alerting
// - span attribute `wasm.timeout_source = default` for APM correlation
Expand Down
6 changes: 3 additions & 3 deletions crates/temper-server/tests/dst_concurrency_retry.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! DST tests for the ADR-0046 optimistic-concurrency retry path.
//! DST tests for the ADR-0168 optimistic-concurrency retry path.
//!
//! Uses `SimEventStore::inject_concurrency_violations` to deterministically
//! queue `ConcurrencyViolation` errors on specific append calls, then verifies
Expand All @@ -8,7 +8,7 @@
//! 2. Violations for every attempt → retry budget exhausts cleanly and the
//! caller sees a distinct error.
//!
//! These tests cover ADR-0046 Rollout Phase 0 "DST race test" follow-up.
//! These tests cover ADR-0168 Rollout Phase 0 "DST race test" follow-up.

use std::collections::BTreeMap;
use std::sync::{Arc, RwLock};
Expand Down Expand Up @@ -201,7 +201,7 @@ async fn dst_retry_exhausts_under_sustained_violation() {
//
// The single-violation success path should hold across many seeds. This
// catches any hidden wall-clock ordering assumption and is the DST "race
// coverage" ask from ADR-0046 Rollout Phase 0.
// coverage" ask from ADR-0168 Rollout Phase 0.
#[tokio::test]
async fn dst_retry_succeeds_after_one_violation_many_seeds() {
for seed in 0..25u64 {
Expand Down
6 changes: 3 additions & 3 deletions crates/temper-spec/src/automaton/toml_parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ enum Section {
/// skips the body; triggers are extracted via serde in the second pass
/// and merged into their action by name.
ActionTrigger,
/// ADR-0040: nested composite-action metadata blocks. Hand-rolled parser
/// ADR-0161: nested composite-action metadata blocks. Hand-rolled parser
/// skips the body; metadata is extracted via serde in the second pass.
CompositeActionMetadata,
}
Expand Down Expand Up @@ -191,7 +191,7 @@ impl ParseState {
"name" => state_var.name = value.to_string(),
"type" => state_var.var_type = value.to_string(),
"initial" => state_var.initial = value.to_string(),
// ADR-0045 / ADR-0047: per-field overflow knobs.
// ADR-0166 / ADR-0047: per-field overflow knobs.
"overflow_inline_max_bytes" => {
if let Ok(v) = value.parse::<usize>() {
state_var.overflow_inline_max_bytes = Some(v);
Expand Down Expand Up @@ -521,7 +521,7 @@ struct ParsedCompositeActionMetadata {
}

/// Extract nested `[[action.cedar_gate]]` and `[[action.sub_writes]]`
/// sections via serde (ADR-0040).
/// sections via serde (ADR-0161).
fn extract_action_composite_metadata(
source: &str,
) -> Result<std::collections::BTreeMap<String, ParsedCompositeActionMetadata>, AutomatonParseError>
Expand Down
6 changes: 3 additions & 3 deletions crates/temper-spec/src/automaton/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ pub struct StateVar {
/// Initial value (as a string, parsed by type).
pub initial: String,
/// Optional per-field inline ceiling in bytes for the field-overflow
/// primitive (ADR-0045). Values above this size are moved to the blob
/// primitive (ADR-0166). Values above this size are moved to the blob
/// store; values at or below stay inline in `fields`. When `None`, the
/// crate-wide `DEFAULT_FIELD_INLINE_MAX` applies.
#[serde(default, skip_serializing_if = "Option::is_none")]
Expand Down Expand Up @@ -220,10 +220,10 @@ pub struct Action {
/// source). Kind-specific fields are validated at parse time.
#[serde(default, rename = "triggers")]
pub triggers: Vec<ActionTrigger>,
/// Composite-action Cedar gate declaration (ADR-0040).
/// Composite-action Cedar gate declaration (ADR-0161).
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cedar_gate: Option<CompositeCedarGate>,
/// Declared sub-write contract for Composite actions (ADR-0040).
/// Declared sub-write contract for Composite actions (ADR-0161).
#[serde(default, rename = "sub_writes")]
pub sub_writes: Vec<SubWriteSpec>,
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
-- 0003_published_artifacts.sql
--
-- Persist ADR-0082 generic PublishedArtifact metadata on the canonical
-- Persist ADR-0173 generic PublishedArtifact metadata on the canonical
-- Postgres storage backend. The table is a rebuildable read model for public
-- artifact provenance; application entities remain the publication authority.

Expand Down
Loading
Loading