-
-
Candidates stay visible with constraint checks, failure reasons, and unavailable controls.
-
Explicit confirmation creates the canonical plan only after all four participants approve.
-
A context change reopens only the affected component while preserving the unaffected part of the plan.
-
Scoped reapproval: one rejection blocks confirmation until consensus is restored.
Inspiration
Four people, one Saturday, and a plan that never quite becomes a plan. It happens in a group chat where agreement scrolls away and whoever holds their phone becomes the decision-maker. Then it rains, and the whole thing reopens from scratch — including the parts rain had nothing to do with.
The television is the one screen a household already shares, and almost nothing uses it that way. DECORDA started from one conviction: a shared decision is not a form somebody fills in — it is a lifecycle with an explicit commit point.
What it does
DECORDA is a TV-native shared decision room. The household's constraints — a 60 EUR budget, a return by 18:00, a preference for being outdoors — stay on screen throughout, and candidates are checked against them in the open. Failing options are never hidden: Forest Activity Course stays listed as NOT FEASIBLE, "Costs 72 EUR, above the 60 EUR limit", with UNAVAILABLE controls.
The central invariant is that READY is not CONFIRMED. Four approvals make a decision ready; they commit nothing. A plan exists only once someone performs an explicit Confirm. A persistent left-hand TruthSpine keeps canonical state, both version axes, participants and constraints on screen throughout, so a draft is never mistaken for what is saved.
Then the context changes: a synthetic condition — rain, from a fixture, not a live forecast — makes the outdoor activity unsuitable. That is classification, not a reset: the activity becomes AFFECTED · MAY CHANGE, the return-by-18:00 arrangement becomes PRESERVED · STAYS AS SAVED, and replanning is scoped to the affected component. Stage A lists the eligible replacements with reasons; Stage B re-asks only the affected scope, where one rejection sets SCOPED CONSENSUS · REJECTED and makes Confirm genuinely inert. Consensus still commits nothing — a second explicit Confirm produces plan version 2, the preserved component untouched — and leaving an unfinished replan writes nothing durable. Everything on screen is deterministic synthetic fixture data — no live external source, no model call.
How we built it
DECORDA is built with React Native for Vega (React 19.2 / React Native 0.83) in TypeScript, targeting Vega OS 1.2 at 1920x1080 and driven entirely by D-pad, Select and Back. Four layers import one way, with a pure deterministic domain at the bottom, the lifecycle in application, and persistence reached only through a port that infrastructure adapters implement.
It runs natively: the Release package was launched on a Vega Virtual Device (tv - aarch64) and driven through its own on-screen controls with real guest-side input injection, captured as full 1920x1080 guest-framebuffer frames — no stitching, no crop, no state injection. The screenshots here are those frames, unmodified.
The durable path was qualified separately, through a second implementation of that same port: a Node.js backend compiled from this repository, running on AWS Lambda behind HTTPS, writing one canonical item per decision to Amazon DynamoDB through the AWS SDK with compare-and-set conditional writes, operation-id receipts and classified outcomes instead of exceptions. It passed 28 of 28 effective qualification rows, with durable state observed independently by strongly consistent reads. That stack was deliberately ephemeral — it lived under 25 minutes and was deleted, its absence confirmed by querying afterwards. The default demonstration mode is a local fixture session with zero network requests. Durable mode requires an authorized configuration and never falls back to memory.
Challenges we ran into
The complete replan screen did not fit: against 976 available logical pixels it measured roughly 1581, and even an over-aggressive squeeze landed 290 px too tall. Shrinking text below the 19 px task-critical floor, clipping, or hiding a control were all rejected — an option you cannot read is not a fitted option. Replan became two stages on an unchanged application state machine, with the resulting budgets frozen as tests.
Proving a negative was harder than proving a feature. Entering a replan stage snaps the TruthSpine to its top; unrelated transitions deliberately must not. So the native session captured a falsifying control frame: the spine genuinely scrolled immediately before the transition, at the origin one transition later, and no normalization outside Replan.
The hardest discipline was refusing to let one kind of evidence stand in for another: a 200 response is not a durable write, a passing suite is not a television, and a delete request is not an observed absence.
Accomplishments that we're proud of
The central invariant was not asserted — it was observed in durable storage: all four participants approved, all four responses stored, and confirmed_plan simply absent; the plan appeared only after the explicit Confirm. Scoped replanning holds the same line, with the preserved component provably unchanged, and an abandoned draft left version, plan version and both components identical. Three surfaces show their complete spine and stage in one native viewport, 424 tests across 25 suites.
What we learned
Constraints design better than preferences do: a layout that would not fit became a two-stage composition that reads better than the screen we wanted. Classification beats resetting: naming what a change affects, and what it explicitly does not, turns a disruption into a small scoped question. And honesty is a feature — showing why an option was excluded buys more trust than a tidier screen.
What's next for DECORDA
Today DECORDA runs one deterministic scenario end to end. Next is making the room general: authored decisions with their own participants, options and constraints, several alive at once, and a history of plan versions, so a household can ask why a plan changed and get the answer from the record.
After that, real context: the classification boundary is shaped so a genuine signal — a weather or calendar change — can name affected and preserved components without choosing on the household's behalf. A companion path follows: responses from personal devices while the television stays the canonical shared surface. Accessibility deserves depth next: spoken-first flows validated against real assistive technology on device.
Built With
- amazon-dynamodb
- aws-lambda
- aws-sdk
- node.js
- react-native
- typescript
- vega-os

Log in or sign up for Devpost to join the conversation.