1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
//! # qontinui-types
//!
//! Canonical DTO types shared across the Qontinui stack.
//!
//! Rust is the **single source of truth**. TypeScript and Python bindings are
//! generated from the JSON Schemas emitted by `schemars` on these types; see
//! `qontinui-schemas/scripts/` and the `just generate-types` task.
//!
//! ## Conventions
//!
//! - Every field that is optional on the wire uses
//! `#[serde(default, skip_serializing_if = "Option::is_none")]` so absence and
//! `null` are distinguishable and round-trip faithfully.
//! - Dates and times are ISO 8601 `String`s. Do **not** introduce
//! `chrono::DateTime<Utc>` here — it complicates JSON Schema output and
//! couples the DTO layer to a particular chrono version. The types crate is a
//! wire-format layer, not a domain model.
//! - UUIDs are `String`s (wire-format), not `uuid::Uuid`. Same reason.
//! - Polymorphic step arrays use `Vec<serde_json::Value>`. JSON Schema emits
//! `{ "type": "array", "items": {} }` → `unknown[]` in TS, `list[Any]` in
//! Python. Typed step discriminated unions are a future migration (Wave 4).
//!
//! Drift between these Rust sources and the checked-in TS/Python bindings is
//! caught in CI by `.github/workflows/schema-drift.yml`, which regenerates
//! the bindings on every PR touching `rust/src/**` and fails if `git diff`
//! reports any non-timestamp change. The codegen toolchain (Tauri Linux deps,
//! datamodel-code-generator version) is pinned in that workflow — bump the
//! pins deliberately when upstream output changes.
//!
//! ## The functional-spec-contract v0 artifact set (frozen 2026-06-13)
//!
//! Three modules form the keystone contract for the website → mobile
//! regeneration program (`2026-06-13-functional-spec-contract.md`):
//!
//! - [`functional_spec`] — **Artifact 1**, the backend-agnostic [`functional_spec::FunctionalSpec`]
//! that comprehension writes and generation reads. Its `ui_states` / `navigation`
//! reuse [`ir`]`::{IrState, IrTransition}` (a literal type-level superset of the IR).
//! - [`completeness_verdict`] — **Artifact 2**, the Completeness Rubric +
//! [`completeness_verdict::CompletenessVerdict`]. Borrows the `DriftVerdict` field
//! vocabulary and embeds [`spec_check::SpecCheckResult`] for the UI dimension.
//! - [`priorities_profile`] — **Artifact 3**, the [`priorities_profile::Profile`] that
//! parameterizes the generators.
//!
//! **v0 stability contract:** the `specVersion` / `profileVersion` fields are `"0"`.
//! Until they bump to `"1"`, changes are **additive-only** — new optional fields and
//! new enum variants only, never a rename, removal, or type change of an existing
//! field. (`deny_unknown_fields` is deliberately omitted on these three so a reader
//! tolerates a forward document.) Downstream plans #1 (app-gen), #2 (backend-gen),
//! and #3 (comprehension) build against this frozen interface in parallel.
/// Completeness **evaluation** — the deterministic rubric walk that turns a
/// [`functional_spec::FunctionalSpec`] + coverage evidence into a
/// [`completeness_verdict::CompletenessVerdict`] (node enumeration + gap diff +
/// per-section breakdown). The verify-phase rubric the website→mobile slice proves.
/// Completeness Rubric + Verdict — Artifact 2 of the functional-spec-contract
/// keystone. Scores a generated app against the [`functional_spec`] in spec
/// units; embeds [`spec_check`] for the UI dimension and borrows the
/// `DriftVerdict` field vocabulary. See
/// `2026-06-13-functional-spec-contract.md`.
/// Canonical `DEV-*` dev-event outcome signatures (effect-side classification).
/// Companion to [`dev_states`]; same `UB-*`-style plain-enum template.
/// Canonical dev-environment state vocabulary (cause-side context) for the
/// dev-event cause-effect ledger. Plain Rust enum mirroring the
/// [`ui_bridge_diagnostics`] `UB-*` pattern — intentionally no DB, not codegen'd
/// to TS/Python. See `plans/2026-06-07-twin-dev-event-cause-effect-ledger.md`.
/// Shared operation→endpoint derivation for the website→mobile regeneration program.
/// The single deterministic rule the app-generator (#1) and backend-generator (#2)
/// both call so the generated app's data layer and the generated backend's routes
/// agree without a runtime handoff. See `2026-06-14-app-generator-ir-inversion.md` /
/// `2026-06-14-backend-generator-from-spec.md` (the reconciliation block).
/// Functional Spec — Artifact 1 of the functional-spec-contract keystone: the
/// backend-agnostic contract between comprehension and generation. Reuses
/// [`ir`]`::{IrState, IrTransition}` for the `ui_states`/`navigation` section.
/// See `2026-06-13-functional-spec-contract.md`.
/// Priorities Profile — Artifact 3 of the functional-spec-contract keystone:
/// the declarative, gate-checkable generator parameterization. See
/// `2026-06-13-functional-spec-contract.md`.
/// Canonical UI Bridge diagnostic code enum. **Generated** from
/// `ui-bridge/diagnostics/codes.json` by `ui-bridge/scripts/gen-diagnostics.ts`
/// — not from a `schemars` Rust source like the rest of this crate. Hand-edits
/// are overwritten; drift is gated by ui-bridge's `diagnostics:check`.
/// Rust-only cross-crate runner↔supervisor types.
///
/// See `wire/mod.rs` for the strictness convention. NOT generated to TS or
/// Python — these types only ever flow between Rust crates inside this
/// workspace.
// =========================================================================
// Forward-compat device-namespace aliases — unified-devices-registry rollout
// =========================================================================
//
// The unified-devices plan renames `Runner` → `Device` across the qontinui
// ecosystem. This 0.2.0 release ships **only the forward-compat aliases**:
// the underlying Rust types remain named `Runner*`, with `Device*` aliases
// added so new consumer code can write `qontinui_types::device::*` against
// this release.
//
// The actual rename direction-flip (move struct defs from `runner` to
// `device`, reverse the alias direction) is deferred to a coordinated
// future PR after every consumer has migrated to `device::*` imports and
// the runner-side `schema_export.rs` registers Device-named schemars
// titles. Doing the flip prematurely would drift the codegen output
// (schemars emits the Rust struct's actual name as the schema title)
// against the runner's hardcoded `add!("Runner", qrn::Runner)` calls.
//
// Removed (along with the reverse `runner::*` aliases) once the flip
// lands. The aliases are additive public API; semver-wise this is a
// minor bump (0.1.x → 0.2.0).