Walkthroughs topic
DEMO_GUIDE-Mitosis.md (Mitosis Edition)
(Cell + Flow + Tissue) Demo Guide — Mitosis Edition
From Reactive Cells to a Single Composed Instruction
A comprehensive guide to the decision side of the Cell Framework:
how a requirement paragraph becomes a Cell, how Instructions are
composed into a FlowInstructionChain, and how the (Cell) demos in
the umbrella example/ directory relate to their (tissue)
counterparts in packages/cell_tissue/example/.
Table of Contents
- Introduction
- Mitose Pipeline 2.0 — tide-warden and what changed from Pipeline 1
- The Purpose of the (Cell) Counterparts
- Core Concepts
- Mitosis Learning Path
- Level 1: Cell Ingress and Pulse
- Level 2: Stock Instructions and Chains
- Level 3: Custom Instruction — Extending FlowInstructionBase
- Level 4: Chain → Cell — toHandle and the Public API
- Level 5: Real-World Applications
- Cell / Flow Instruction Reference
- Combining Patterns
- Common Pitfalls
- Next Steps
Introduction
The Cell Framework provides a reactive programming model where Cells
hold state, Pulses carry signals, Flow orchestrates decisions,
and Tissue keeps governed books. The umbrella example/ directory
holds the Mitosis (Cell) editions of the demos whose Tissue
editions live in packages/cell_tissue/example/.
What You'll Learn
- What the
(Cell)counterparts are for, and how they differ from the(tissue)originals. - How to compose stock Instructions with
operator +into oneFlowInstructionChain. - How to extend
FlowInstructionBasewith a single custom Instruction that encapsulates policy + latch + filter, the wayAsyncMapdoes. - How
toHandlematerialises the blueprint into a live Cell, and which public API the harness uses around that moment. - The golden rule and the two-lock discipline, unchanged from the Tissue edition.
The Two Subsystem Split
Every demo follows the same architectural pattern:
| Subsystem | Responsibility | Examples |
|---|---|---|
| Flow | Decision, interpretation, transformation | MapValue, DistinctUntilChanged, Filter, Tap, custom instructions |
| Tissue | Durable state, validation, audit trail | TissueList, TissueValue, TissueMap |
The Golden Rule: Flow decides. Tissue records. The observer is the only glue. Never mix these responsibilities.
TestCell vs TestTissue — do not swap:
| Host | Rule type | Parameter |
|---|---|---|
Cell.ingress / toHandle |
TestCell |
testRule: |
TissueList / Set / Map / Queue / Value |
TestTissue<E, C> |
testRule: |
tissue.deputy(...) |
TestTissue |
testRule: |
TestCell is the integrity rule on a Cell (shape of an incoming
pulse). TestTissue is the integrity rule on a Tissue (shape of a
mutation, a member, a value write). Grep for testRule: TestCell on a
Tissue constructor: zero hits.
Mitose Pipeline 2.0 — tide-warden and what changed from Pipeline 1
Start here for a Mitose 2.0 solution. The worked sample is
tide-warden (Harbor City estuary flood desk). It was generated by
the Mitose 2.0 pipeline, not by the earlier hand-shaped (Cell) demos.
| Artifact | Path |
|---|---|
| BRD | tide-warden-BRD.md |
| WalkThrough | tide-warden-WalkThrough.md |
| Demo | tide-warden-Demo.dart |
| Test | tide-warden-test.dart |
| Residual ledger | tide-warden-LEDGER.md |
| Comprehension | tide-warden-COMPREHENSION.md |
The seam is the same golden rule: Flow decides. Tissue records. The
observer is the only glue. The flood order is an all-or-nothing
commit (Cell.txApply on Tissue): gate, road closure, and shelter
opening are recorded together or not at all. A higher flood level can
replace an unissued order. Weather and duty can hold or refuse.
What Pipeline 1 produced
The earlier (Cell) demos (card-auth-pipeline, grid-demand-response,
ride-hail-dispatch) and their companions were the decision-side
counterparts of the Tissue demos. Pipeline 1 produced:
<stem>-BRD.md
<stem>(Cell)-WalkThrough.md
<stem>(Cell)-Demo.dart
<stem>(Cell)-ARCHITECTURE.md
<stem>(Cell)-FEATURES.md
There was no residual ledger, no always-on test file, no comprehension
check, no change mode, and no version plate. Atomic work used whatever
the harness wrote; Cell.transaction was not yet deferred.
What Pipeline 2 produces
<stem>-BRD.md
<stem>-WalkThrough.md
<stem>-Demo.dart
<stem>-test.dart
<stem>-LEDGER.md
<stem>-COMPREHENSION.md
<stem>-ARCHITECTURE.md
<stem>-FEATURES.md
<stem>-CHANGE-<nnn>.md (change mode only)
| Change | Pipeline 1 | Pipeline 2 |
|---|---|---|
| Output names | <stem>(Cell)-* |
<stem>-* (no (Cell) suffix). The executable is still the Cell variant. |
| Test file | Not required | <stem>-test.dart is always written with the Demo. Groups align to public APIs and documented contracts. |
| Fail-closed groups | Not present | constraint, provenance, and boundary fail the suite. They do not move a BRD ledger row. |
| Residual ledger | Not present | <stem>-LEDGER.md from the test file’s BRD group LEDGER lines. Verified requires an executed run. Reading the code is not Verified. |
| Comprehension | Not present | Optional C1–C3 checks and a decision log. Skipping is allowed and recorded. |
| Change | Not present | Change mode writes an immutable <stem>-CHANGE-<nnn>.md. An old acceptance does not survive. |
| Versioning | Informal | MAJOR.MINOR.PATCH on every generated file. Name plate carries Version and Supersedes. Later steps resolve only the latest. |
| Atomic commit | Harness-written | Cell.txApply on Tissue is the only atomic commit. Cell.transaction is not used. |
| After Demo Assessment | ARCHITECTURE / FEATURES next | The agent offers three choices for recommendations: as a Change, in place, or skip. |
| Length | Soft caps on some generators | Caps removed. Documents open with a short summary when useful. |
| Precision | Implicit | Explicit: recorded, explicit, bounded, checkable, traceable, verifiable, changeable, expandable, predictable. Six components, no seventh. |
How to read tide-warden against the older demos
- Read the BRD parameter register (§7.5) and decision precedence (§7.6).
- Read the WalkThrough seam sentence and the layer map.
- Read the custom
FloodRiskInstructionintide-warden-Demo.dart— the sameFlowInstructionBasetemplate asGridDecisionInstructionandMatchDecisionInstruction. - Read the observer that glues the projected level to Tissue, and the
Cell.txApplybody that records the three legs or none of them. - Read
tide-warden-test.dartfor the BRD group (the only group that printsLEDGERlines) and the three fail-closed groups. - Read
tide-warden-LEDGER.mdfor residual error: Verified only where a run produced a line.
The older (Cell) demos remain the learning path for stock-operator
chains and the custom-instruction template. tide-warden is the learning
path for the full Mitose 2.0 cycle: requirement → placement → Demo and
test → residual ledger → later change.
The Purpose of the (Cell) Counterparts
The (tissue) demos in packages/cell_tissue/example/ teach the
books side: Tissue collections, TestTissue rules, deputies, and
the money/fleet/reserve write protocols. Their (Cell) counterparts in
the umbrella example/ directory exist to teach the decision side
of the very same seam:
The
(Cell)demos are not replacements. They are the same seam, same scenarios, and same books — viewed from the instruction side of the Flow layer.
Specifically:
Tissue edition (in packages/cell_tissue/example/) |
Cell edition (in umbrella example/) |
Purpose of the Cell edition |
|---|---|---|
card-auth-pipeline(tissue)-Demo.dart |
card-auth-pipeline(Cell)-Demo.dart |
Demonstrates the stock-operator chain: MapValue + DistinctUntilChanged + Filter + Tap + MapValue composed into one FlowInstructionChain, materialised once with toHandle. The whole risk gate is one reusable blueprint; the books stay in the Tap side effect and observers. |
grid-demand-response(tissue)-Demo.dart |
grid-demand-response(Cell)-Demo.dart |
Demonstrates the custom instruction: GridDecisionInstruction extends FlowInstructionBase encapsulates type-check, policyOf, the distinct latch, and the hold filter in one class, exactly like AsyncMap; it is chained with a stock MapValue and materialised with toHandle. Public API: policyOf, lastDecision, reset, pass, protected. |
ride-hail-dispatch(tissue)-Demo.dart |
ride-hail-dispatch(Cell)-Demo.dart |
Demonstrates the custom instruction in a second domain: MatchDecisionInstruction encapsulates matchOf, the distinct latch, and the idle filter; chained with MapValue<MatchDecision, Match>; public API: matchOf, lastDecision, reset, pass, noGo. |
What moved from the (tissue) edition to the (Cell) edition:
In the (tissue) edition |
In the (Cell) edition |
|---|---|
MapValue(policy) + closure-Distinct + Filter with latch fields on the harness |
One GridDecisionInstruction / MatchDecisionInstruction holding policy + latch + filter inside |
| Ad-hoc gate closures owned by the harness | A named, reusable instruction class with a public API |
The decision logic is scattered across installGates and latch helpers |
The decision logic reads as one sentence: GridDecisionInstruction(protected: …, pass: Action.shed) |
| The seam is demonstrated from the books outward | The seam is demonstrated from the instruction inward |
What did not change: the Tissue collections, the TestTissue
rules, the observers, the reserve/fleet protocols, the scenario table,
and the trailer counts. That is deliberate — a reader can diff the two
editions and see exactly what the Cell edition adds: a custom
Instruction, composed into a FlowInstructionChain, turned into a Cell
at last.
Core Concepts
What is a Cell?
A Cell is the atomic reactive node. It holds state, validates incoming
pulses with TestCell, and propagates evolved pulses downstream.
Ingress Cells are created with Cell.ingress<T>(); handle Cells are
created when an instruction chain is materialised with toHandle.
final hzIn = Cell.ingress<double>(testRule: _hzRange); // ingress Cell
hzIn.emit(49.70); // Pulse<double> in
What is a Pulse?
A Pulse is the signal that travels the graph. It carries a payload,
source, type, priority, and a provenance step. Users care about
one surface: what goes into each Cell (parameters) and what comes out
(Pulse<type>).
Cell.observe(source: shedCell, effect: (Pulse p) {
if (p.payload == Action.shed) { /* write the books */ }
});
What is an Instruction?
An Instruction is a stateless blueprint that describes how a pulse is transformed or filtered. It is independent of any source Cell.
MapValue— Rxmap.DistinctUntilChanged— RxdistinctUntilChanged.Filter— Rxfilter.Tap— Rxtap/do.
What is a FlowInstructionChain?
A FlowInstructionChain is what operator + builds when you compose
Instructions:
final chain = MapValue<BayTick, GridDecision>(decide)
+ MapValue<GridDecision, Action>((d) => d.action);
Each + returns a FlowInstruction; the whole expression is one
chain. The chain is still only a blueprint — nothing runs until
toHandle materialises it.
What is FlowInstructionBase?
FlowInstructionBase<Cell, Pulse, Pulse> is the base class for custom
Instructions. AsyncMap in
async_map.dart is the canonical
template: the essential logic lives inside the instruction, and the
class exposes a public API that the caller uses when turning the
instruction into a Cell.
What is toHandle?
toHandle(source: cell) compiles a blueprint into a live Cell bound to
a source. It returns a FlowHandle record whose .cell is the
observable output Cell:
final handle = chain.toHandle(source: tickIn.cell);
final gateCell = handle.cell; // the Cell observers subscribe to
Exactly one toHandle per lane. ACK resets never call toHandle
again.
Mitosis Learning Path
Level 1: Cell Ingress and Pulse (Start Here)
├── Cell.ingress - the input parameter surface
├── Pulse.payload - the output Pulse<type>
└── TestCell - shape validation at the edge
Level 2: Stock Instructions and Chains
├── MapValue - Rx map
├── Filter - Rx filter
├── DistinctUntilChanged- Rx distinctUntilChanged
├── Tap - Rx tap / do
└── operator + - builds a FlowInstructionChain
Level 3: Custom Instruction — Extending FlowInstructionBase
├── encapsulate policy - pure decision inside the class
├── encapsulate latch - distinct state per instruction instance
├── encapsulate filter - product lane suppression
└── public API - policyOf / matchOf, lastDecision, reset
Level 4: Chain → Cell — toHandle and the Public API
├── + stock projection - narrow the rich output to the seam type
├── toHandle(source:) - materialise the chain into a Cell
└── harness access - reset() on ACK, lastDecision in the trailer
Level 5: Real-World Applications
├── Tide Warden - Mitose 2.0 worked sample (flood desk)
├── Card Auth - stock-operator chain (payments)
├── Ride-Hail Dispatch - custom MatchDecisionInstruction (mobility)
└── Grid Demand-Response- custom GridDecisionInstruction (energy)
Level 1: Cell Ingress and Pulse
1. Cell.ingress — the Input Parameter Surface
What it does: Creates an ingress Cell with an optional TestCell
shape rule.
When to use: Every sensor, command, or ACK that enters the demo.
final hzIn = Cell.ingress<double>(
testRule: TestCell<Cell>((value, {host, arguments, user}) {
final v = value is Pulse ? value.payload : value;
return v is num && v >= 49.00 && v <= 51.00;
}),
);
Key Insight: The ingress wraps the raw input in a Pulse before
the rule runs, so the rule unwraps Pulse.payload first. The input
parameter type (double) and the emitted Pulse<double> are the
user-facing contract.
2. Pulse.payload — the Output Surface
What it does: Carries the typed payload a downstream observer reads.
When to use: Every observer on a gate Cell.
Cell.observe(source: shedCell, effect: (Pulse pulse) {
if (pulse.payload == Action.shed) { /* ... */ }
});
Key Insight: Users care about inputs (parameters) and outputs
(Pulse<type>). The WalkThrough Parts table, the Demo header, and
the FEATURES rows all state this surface.
Level 2: Stock Instructions and Chains
3. MapValue — Rx map
final toAction = MapValue<GridDecision, Action>((d) => d.action);
4. Filter — Rx filter
Filter<Action>((a) => a == Action.shed);
5. DistinctUntilChanged — Rx distinctUntilChanged
DistinctUntilChanged<CardAuthRecord>(
equals: (a, b) => a.decision == b.decision,
);
6. Tap — Rx tap / do
Tap<CardAuthRecord>((r) {
if (r.decision == Decision.decline) { /* write the books */ }
});
7. operator + — Builds a FlowInstructionChain
final cardAuth = MapValue<AuthAttempt, CardAuthRecord>(snapshot)
+ DistinctUntilChanged<CardAuthRecord>(byDecision)
+ Filter<CardAuthRecord>(declineOrStepUp)
+ Tap<CardAuthRecord>(writeBooks)
+ MapValue<CardAuthRecord, Decision>(emitDecision);
Key Insight: Each + returns a FlowInstruction, so the whole
expression is one FlowInstructionChain — a reusable blueprint
with no live Cell yet. This is the card-auth-pipeline(Cell)-Demo.dart
pattern.
Level 3: Custom Instruction — Extending FlowInstructionBase
8. The AsyncMap Template
AsyncMap (in async_map.dart)
extends FlowInstructionBase<Cell, Pulse, Pulse>, puts the mapping
logic inside the class, and exposes its constructor parameters as the
public surface. The (Cell) demos follow the same template for a
synchronous gate:
final class GridDecisionInstruction
extends FlowInstructionBase<Cell, Pulse, Pulse> {
factory GridDecisionInstruction({
required Set<String> protected,
required Action pass,
dynamic user,
}) {
final state = _GridGateState();
return GridDecisionInstruction._(protected, pass, state, user);
}
GridDecisionInstruction._(
Set<String> protected,
Action pass,
_GridGateState state,
dynamic user,
) : _protected = protected,
_pass = pass,
_state = state,
super(_build(protected, pass, state), user: user);
static Pulse? Function(Pulse pulse, {Cell? cell, dynamic user}) _build(
Set<String> protected,
Action pass,
_GridGateState state,
) {
return (pulse, {cell, user}) {
final tick = pulse.payload;
if (tick is! BayTick) return null; // type check
final action = policyOf(tick, protected); // policy
if (state.last == action) return null; // distinct latch
state.last = action;
if (action != pass) return null; // product filter
return Pulse<GridDecision>(
GridDecision(tick: tick, action: action),
source: cell ?? pulse.source,
type: pulse.type,
priority: pulse.priority,
step: 'GridDecision.${pass.name}',
);
};
}
static Action policyOf(BayTick tick, Set<String> protected) { /* ... */ }
Action? get lastDecision => _state.last;
Action get pass => _pass;
Set<String> get protected => _protected;
void reset() => _state.last = null;
}
Key Insight: One class encapsulates type-check, policy, latch, and
filter. Two instances (pass: Action.shed and pass: Action.warn)
give two independent lanes without duplicating the logic.
9. Ride-Hail Variant
MatchDecisionInstruction is the same template in the mobility domain:
MatchDecisionInstruction(noGo: noGo, pass: Match.dispatch);
MatchDecisionInstruction(noGo: noGo, pass: Match.surge);
with static Match matchOf(MatchTick tick, Set<String> noGo) as the
pure policy.
Key Insight: The policy stays pure and static. The live
protected / noGo TissueSet is passed in at construction and read on
every pulse, so ops can mutate the set at runtime without redeploying
the graph.
Level 4: Chain → Cell — toHandle and the Public API
10. Compose the Custom Instruction with a Stock Projection
The custom instruction emits the rich type (GridDecision /
MatchDecision). The seam type is the narrow Action / Match.
A shared stock MapValue performs that projection:
final toAction = MapValue<GridDecision, Action>((d) => d.action);
final shedChain = shedGate + toAction; // FlowInstructionChain
final shedHandle = shedChain.toHandle(source: tickIn.cell);
shedCell = shedHandle.cell;
Key Insight: The + is the composition point, toHandle is the
materialisation point, and the returned Cell is what observers
subscribe to. Two lanes, two chains, two toHandle calls.
11. The Public API Around toHandle
| API | Used when |
|---|---|
policyOf / matchOf |
unit-testing the decision with a bare tick and a plain Set |
lastDecision |
reading the latch state in the trailer |
reset() |
ACK authority clears the latch without rebuilding the graph |
pass / protected / noGo |
docs, debug, and reuse of the blueprint |
The ACK observer calls reset(); it never calls toHandle again. The
trailer prints lastDecision to prove the reset happened.
Level 5: Real-World Applications
12. Tide Warden — Flood desk (Mitose Pipeline 2.0)
Files: tide-warden-BRD.md, tide-warden-WalkThrough.md,
tide-warden-Demo.dart, tide-warden-test.dart,
tide-warden-LEDGER.md
What it demonstrates: The full Mitose 2.0 cycle. A custom
FloodRiskInstruction (the same FlowInstructionBase template as the
Pipeline 1 custom instructions) decides the flood level. A stock
projection narrows it. The observer glues. Cell.txApply on Tissue
records the gate, the road closure, and the shelter opening together,
or none of them. The test file prints LEDGER lines; the residual
ledger records what an executed run actually proved.
Key Lessons:
- Output names have no
(Cell)suffix. The executable is still the Cell variant. <stem>-test.dartis always written with the Demo. Only the BRD group moves ledger rows.constraint,provenance, andboundaryfail the suite and do not move a BRD row.- Verified requires an executed
LEDGERline. Reading the code is not Verified. - Atomic commit is
Cell.txApplyon Tissue.Cell.transactionis not used.
13. Card Auth — Payments (stock-operator chain)
File: card-auth-pipeline(Cell)-Demo.dart (umbrella example/)
What it demonstrates: The whole risk gate as one
FlowInstructionChain of stock Rx operators —
MapValue + DistinctUntilChanged + Filter + Tap + MapValue —
materialised once. The books are written from the Tap side effect and
the observers.
Key Lessons:
- Stock operators mean less code.
- Stock
DistinctUntilChangedholds its own internal previous value and cannot be reset externally; the scenario sequence is arranged so this does not change the visible output (documented deviation). - Exactly one
toHandlefor the gate; ACK still never re-materialises. - Tissue books and money methods are unchanged from the
(tissue)edition.
14. Grid Demand-Response — Energy (custom instruction)
File: grid-demand-response(Cell)-Demo.dart (umbrella example/)
What it demonstrates: GridDecisionInstruction extends FlowInstructionBase encapsulating policyOf, the distinct latch, and
the hold filter; chained with MapValue<GridDecision, Action>; two
lanes (SHED / WARN); public API policyOf / lastDecision / reset.
Key Lessons:
- One instruction reads as one sentence:
GridDecisionInstruction(protected: …, pass: Action.shed). - Distinct-before-filter lives inside the instruction, so
hold → shed → hold → shedfires twice. - The instruction reads
protectedbut never writes Tissue. - Reserve invariant and compensation ladder are unchanged.
15. Ride-Hail Dispatch — Mobility (custom instruction)
File: ride-hail-dispatch(Cell)-Demo.dart (umbrella example/)
What it demonstrates: MatchDecisionInstruction encapsulating
matchOf, the distinct latch, and the idle filter; chained with
MapValue<MatchDecision, Match>; two lanes (DISPATCH / SURGE); public
API matchOf / lastDecision / reset.
Key Lessons:
- The custom instruction template ports across domains by renaming the domain types and rewriting the policy.
- The no-go
TissueSetis a live policy input, not a const. - The push pump, fleet protocol, and auditor deputy are unchanged from
the
(tissue)edition.
Cell / Flow Instruction Reference
Stock Instructions Used
| Instruction | Rx analogue | Used in |
|---|---|---|
MapValue<S, T> |
map |
every (Cell) demo |
DistinctUntilChanged<S> |
distinctUntilChanged |
card-auth-pipeline(Cell)-Demo.dart |
Filter<S> |
filter |
card-auth-pipeline(Cell)-Demo.dart |
Tap<S> |
tap / do |
card-auth-pipeline(Cell)-Demo.dart |
Custom Instructions
| Class | Domain | Encapsulates | Public API |
|---|---|---|---|
FloodRiskInstruction |
Flood desk (Mitose 2.0) | type-check, riskOf, latch, hold filter |
riskOf, last decision, reset |
GridDecisionInstruction |
Energy | type-check, policyOf, latch, hold filter |
policyOf, lastDecision, reset, pass, protected |
MatchDecisionInstruction |
Mobility | type-check, matchOf, latch, idle filter |
matchOf, lastDecision, reset, pass, noGo |
Chain Materialisation
| Step | API | Notes |
|---|---|---|
| Compose | operator + |
builds a FlowInstructionChain |
| Materialise | toHandle(source: cell) |
returns FlowHandle; .cell is the output Cell |
| Observe | Cell.observe(source: gateCell, ...) |
the only glue to Tissue |
| Reset | instruction.reset() |
ACK path; never toHandle again |
Combining Patterns
Pattern: Stock-Operator Gate
final gate = MapValue<AuthAttempt, CardAuthRecord>(snapshot)
+ DistinctUntilChanged<CardAuthRecord>(byDecision)
+ Filter<CardAuthRecord>(actionable)
+ Tap<CardAuthRecord>(writeBooks)
+ MapValue<CardAuthRecord, Decision>(emitDecision);
final cell = gate.toHandle(source: attemptIn.cell).cell;
Use when the stock operators cover the policy and you accept their internal state semantics.
Pattern: Custom Instruction + Stock Projection
final shedGate = GridDecisionInstruction(
protected: protected,
pass: Action.shed,
);
final chain = shedGate + MapValue<GridDecision, Action>((d) => d.action);
final shedCell = chain.toHandle(source: tickIn.cell).cell;
Use when the policy + latch + filter should be one named, reusable class with an externally resettable latch.
Pattern: Two Lanes, Two Latches, One Shared Projection
final toMatch = MapValue<MatchDecision, Match>((d) => d.match);
final dispatchChain = dispatchGate + toMatch; // lane 1
final surgeChain = surgeGate + toMatch; // lane 2 (shared projection)
Use for two-product demos. The shared MapValue is stateless, so
reusing it across lanes is safe.
Pattern: ACK Resets the Instruction, Not the Graph
Cell.observe(source: ackIn.cell, effect: (pulse) {
shedGate.reset();
warnGate.reset();
// optionally restore / accept
});
Never call toHandle from the observer.
Common Pitfalls
| Anti-pattern | Why it breaks the lesson |
|---|---|
| Writing Tissue inside the custom instruction | Collapses the seam; the instruction must stay pure Flow. |
Scattering the policy across MapValue closures in the harness |
The (Cell) edition exists to encapsulate it in one instruction. |
Calling toHandle from the ACK observer |
Doubles every downstream effect. ACK calls reset(). |
| Reusing one instruction instance for both lanes | The two latches collapse into one. |
| Returning the narrow seam type directly from the custom instruction | The chain's MapValue then has nothing to project; emit the rich type (GridDecision / MatchDecision). |
Storing the latch in a Cell/Tissue |
Adds lock traffic and rebuild complexity for a one-field assignment. |
| Using a boolean for two products | Two products need two lanes; a boolean cannot express the middle state. |
Passing TestCell to a Tissue constructor |
Wrong rule family; Tissue wants TestTissue. |
| Holding the Receptor lock across a Tissue write | Violates the two-lock discipline. |
Making policyOf / matchOf async |
Purity is the lesson; async reads belong at ingress. |
Next Steps
For Dart Developers New to Cell
- Read the Mitose Pipeline 2.0 section above, then open
tide-warden-Demo.dartandFloodRiskInstruction. - Read the
(Cell)header ofgrid-demand-response(Cell)-Demo.dartfor the same template in the Pipeline 1 shape. - Trace one SHED from
setHzthrough the chain toevents.add. - Diff it against
grid-demand-response(tissue)-Demo.dartto see what moved from harness closures into the instruction.
For Framework Extenders
- Read
async_map.dart— theFlowInstructionBasetemplate. - Read
flow_core.dart—toHandle,FlowHandle, and the+composition. - Read
map.dart— the sync instruction closure contract. - Write a custom Instruction for your own policy.
For Domain Porters
- Pick the closest
(Cell)sibling. - Rename the domain types (
BayTick/MatchTick→YourTick). - Rewrite the policy (
policyOf/matchOf→yourPolicy). - Keep the seam: one custom instruction per product lane, one stock
MapValueprojection, onetoHandleper lane, one observer per gate, oneTestTissueper collection. - Keep the two-lock discipline and the golden rule.
Sibling Demos
| Cell edition | Tissue edition | Domain |
|---|---|---|
tide-warden-Demo.dart (Mitose 2.0; no (Cell) suffix) |
— (standalone desk) | Flood desk — custom FloodRiskInstruction, residual ledger |
card-auth-pipeline(Cell)-Demo.dart |
card-auth-pipeline(tissue)-Demo.dart |
Payments — stock-operator chain |
ride-hail-dispatch(Cell)-Demo.dart |
ride-hail-dispatch(tissue)-Demo.dart |
Mobility — custom MatchDecisionInstruction |
grid-demand-response(Cell)-Demo.dart |
grid-demand-response(tissue)-Demo.dart |
Energy — custom GridDecisionInstruction |
Companion Documents
For each demo, the following companions exist:
| Document | Purpose |
|---|---|
<stem>-Demo.dart |
Executable implementation (no (Cell) suffix in Pipeline 2) |
<stem>-test.dart |
Always written with the Demo. BRD group prints LEDGER lines. |
<stem>-WalkThrough.md |
Requirement document and scenario contract |
<stem>-LEDGER.md |
Residual error from an executed test run |
<stem>-ARCHITECTURE.md |
Layering, ownership, locking, failure semantics, anti-patterns |
<stem>-FEATURES.md |
Operator catalogue and feature index |
Read them in this order:
- This file — the guide in ten minutes.
*-Demo.dart— skim the class doc, then read the custom instruction and the gate installation.*-WalkThrough.md— the requirement and the scenario contract.*-FEATURES.md— the operator catalogue.*-ARCHITECTURE.md— the layering and ownership note.
End of DEMO_GUIDE-Mitosis.md (Mitosis Edition).
Libraries
- mitosis Walkthroughs
- 🧬 Mitosis — the unified reactive framework for Dart.
Classes
- Flow
- The Transcription Orchestrator for the Cell framework, responsible for converting (transcribing) external stimuli, persistent state, and logic into reactive Cell topographies.
-
Tissue<
E> -
A reactive collection that behaves like a normal Dart Iterable but is
fully governed, observable, and thread‑safe – the foundation of all
reactive containers in
cell_tissue.